diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f27197..d1b4b17 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,3 +39,13 @@ jobs: name: lighthouse-results path: .lighthouseci/ retention-days: 30 + + - name: Confirm Pages deployment configuration + if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main') + run: | + echo "✅ GitHub Pages is configured to serve from /docs directory" + echo "📦 Demo will be available at: https://hutoczky.github.io/FormatX/scifi-ui/" + echo "📋 Lighthouse thresholds enforced:" + echo " - LCP < 2.5s" + echo " - CLS < 0.10" + echo " - TTFB < 600ms" diff --git a/docs/scifi-ui/README.md b/docs/scifi-ui/README.md index 62c811b..2c87900 100644 --- a/docs/scifi-ui/README.md +++ b/docs/scifi-ui/README.md @@ -123,11 +123,17 @@ npx lighthouse http://localhost:8000/scifi-ui/ --view ### Lighthouse Thresholds (CI) +**Category Scores:** - Performance: ≥ 90% - Accessibility: ≥ 95% - Best Practices: ≥ 95% - SEO: ≥ 90% +**Core Web Vitals:** +- LCP (Largest Contentful Paint): < 2.5s +- CLS (Cumulative Layout Shift): < 0.10 +- TTFB (Time to First Byte): < 600ms + Run Lighthouse CI: ```bash diff --git a/docs/scifi-ui/assets/enterprise.svg b/docs/scifi-ui/assets/enterprise.svg deleted file mode 100644 index 863777e..0000000 --- a/docs/scifi-ui/assets/enterprise.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NCC-1701 - - - \ No newline at end of file diff --git a/docs/scifi-ui/assets/svgs/hologram-activation.svg b/docs/scifi-ui/assets/svgs/hologram-activation.svg new file mode 100644 index 0000000..9a2cb19 --- /dev/null +++ b/docs/scifi-ui/assets/svgs/hologram-activation.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/scifi-ui/assets/svgs/lcars-panels.svg b/docs/scifi-ui/assets/svgs/lcars-panels.svg new file mode 100644 index 0000000..211b3be --- /dev/null +++ b/docs/scifi-ui/assets/svgs/lcars-panels.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/scifi-ui/index.html b/docs/scifi-ui/index.html index 6ec99b4..3054b84 100644 --- a/docs/scifi-ui/index.html +++ b/docs/scifi-ui/index.html @@ -10,6 +10,10 @@ content="default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; font-src 'self' data:; media-src 'self'; connect-src 'self'"> + + + + @@ -37,7 +41,7 @@ -
+
diff --git a/docs/scifi-ui/scripts/theme-switcher.js b/docs/scifi-ui/scripts/theme-switcher.js index 19e52e4..705227e 100644 --- a/docs/scifi-ui/scripts/theme-switcher.js +++ b/docs/scifi-ui/scripts/theme-switcher.js @@ -6,7 +6,7 @@ const brand=document.getElementById('brand'); function setPressed(btn,on){btn.setAttribute('aria-pressed',String(on));btn.setAttribute('aria-selected',String(on));} function toggleGlitch(theme){if(!brand)return; if(theme==='cyberpunk'){brand.setAttribute('data-glitch','on');}else{brand.removeAttribute('data-glitch');}} - function setTheme(name){if(!THEMES[name])return; linkEl.setAttribute('href',THEMES[name]); root.setAttribute('data-theme',name); try{localStorage.setItem(STORAGE_KEY,name);}catch(e){}; toggleGlitch(name); document.querySelectorAll('.switcher .theme').forEach(b=>setPressed(b,b.dataset.theme===name)); document.dispatchEvent(new CustomEvent('theme:changed',{detail:{theme:name}}));} + function setTheme(name){if(!THEMES[name])return; linkEl.setAttribute('href',THEMES[name]); root.setAttribute('data-theme',name); try{localStorage.setItem(STORAGE_KEY,name);}catch(e){}; toggleGlitch(name); document.querySelectorAll('.switcher .theme').forEach(b=>setPressed(b,b.dataset.theme===name)); document.querySelectorAll('.loader-sample').forEach(s=>{const show=s.dataset.themeSample===name; s.setAttribute('aria-hidden',show?'false':'true'); s.style.display=show?'':'none';}); document.dispatchEvent(new CustomEvent('theme:changed',{detail:{theme:name}}));} let start='lcars'; try{const saved=localStorage.getItem(STORAGE_KEY); if(saved&&THEMES[saved]) start=saved;}catch(e){}; setTheme(start); document.querySelectorAll('.switcher .theme').forEach(btn=>{btn.addEventListener('click',()=>setTheme(btn.dataset.theme)); btn.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();setTheme(btn.dataset.theme);}})}); })(); diff --git a/docs/scifi-ui/styles/base.css b/docs/scifi-ui/styles/base.css index de8ff53..40a7cef 100644 --- a/docs/scifi-ui/styles/base.css +++ b/docs/scifi-ui/styles/base.css @@ -12,6 +12,8 @@ body{min-height:100%;background:radial-gradient(1200px 600px at 50% -10%,#121622 a{color:inherit;text-decoration:none} button{font:inherit;color:inherit;background:none;border:none;cursor:pointer} img{max-width:100%;height:auto} +*:focus-visible{outline:2px solid var(--accent);outline-offset:2px} +button:focus-visible,a:focus-visible{outline-color:var(--accent-2);outline-width:2px;outline-style:solid;outline-offset:3px} .fx{position:fixed;inset:0;pointer-events:none;z-index:0} .fx-scanlines{background-image:repeating-linear-gradient(180deg,transparent 0 2px,rgba(255,255,255,.05) 2px 3px);mix-blend-mode:soft-light;opacity:.25} .fx-noise{background-image:url("data:image/svg+xml;utf8,"); @@ -24,7 +26,7 @@ img{max-width:100%;height:auto} .switcher .theme[aria-pressed="true"]{background:linear-gradient(180deg,var(--accent),color-mix(in oklab,var(--accent),black 30%));color:#141518} .hero{max-width:var(--max);margin:40px auto 12px;padding:0 20px;text-align:center} .progress{position:relative;height:44px;max-width:620px;margin:0 auto 18px;border-radius:24px;background:#0b0d10;box-shadow:inset 0 0 0 2px rgba(0,0,0,.55);overflow:hidden} -.progress .bar{position:absolute;inset:2px 52px 2px 2px;border-radius:22px 0 0 22px;background:linear-gradient(90deg,#ffa726,#cc6f00);animation:fill var(--progress-dur) cubic-bezier(.2,.9,.2,1) infinite} +.progress .bar{position:absolute;inset:2px 52px 2px 2px;border-radius:22px 0 0 22px;background:linear-gradient(90deg,#ffa726,#cc6f00);transition:none;width:0;animation:fill var(--progress-dur) cubic-bezier(.2,.9,.2,1) infinite} .progress .cap{position:absolute;top:2px;right:2px;bottom:2px;width:50px;border-radius:0 22px 22px 0;background:linear-gradient(180deg,#181a1e,#0f1216);} @keyframes fill{0%{transform:translateX(-100%)}100%{transform:translateX(0)}} .brand{margin:0 0 12px;font:900 clamp(34px,6.5vw,66px)/1.05 "Segoe UI",system-ui,Roboto,Arial,sans-serif;letter-spacing:.1em;color:var(--accent-2);text-shadow:0 0 12px #ff9d00aa,0 0 1px #000} diff --git a/docs/scifi-ui/styles/cyberpunk.css b/docs/scifi-ui/styles/cyberpunk.css index 7c7b800..cdfc7b7 100644 --- a/docs/scifi-ui/styles/cyberpunk.css +++ b/docs/scifi-ui/styles/cyberpunk.css @@ -2,6 +2,7 @@ :root[data-theme="cyberpunk"] body{background:radial-gradient(1200px 600px at 50% -10%,#1a0024 0%,#0a0010 45%) fixed,#0a0010;filter:contrast(1.06) saturate(1.25);font-family:"OCR-A","VT323",ui-monospace,monospace} :root[data-theme="cyberpunk"] .brand{font-family:"OCR-A","VT323",ui-monospace,monospace;color:var(--yellow);text-shadow:0 0 6px rgba(255,46,192,.35),0 0 2px #000,0 0 16px rgba(0,229,255,.25)} :root[data-theme="cyberpunk"] .panel,:root[data-theme="cyberpunk"] .card,:root[data-theme="cyberpunk"] .chip{border-color:color-mix(in oklab,var(--magenta),#000 35%);box-shadow:0 0 0 1px rgba(255,255,255,.02) inset,0 0 40px #ff00ff22,inset 0 0 30px #ff00ff11} +:root[data-theme="cyberpunk"] .progress .bar{background:linear-gradient(90deg,var(--cyan),#8c2eff)} @keyframes cp-glitch{0%{clip-path:inset(0 0 0 0);transform:translateX(0)}10%{clip-path:inset(0 0 85% 0);transform:translateX(-2px)}20%{clip-path:inset(80% 0 0 0);transform:translateX(1px)}30%{clip-path:inset(10% 0 60% 0);transform:translateX(-1px)}40%{clip-path:inset(60% 0 20% 0);transform:translateX(2px)}50%{clip-path:inset(0 0 0 0);transform:translateX(0)}60%{clip-path:inset(0 0 70% 0);transform:translateX(2px)}70%{clip-path:inset(65% 0 0 0);transform:translateX(-2px)}80%{clip-path:inset(20% 0 40% 0);transform:translateX(1px)}100%{clip-path:inset(0 0 0 0);transform:translateX(0)}} @keyframes huePulse{0%{filter:hue-rotate(0)}50%{filter:hue-rotate(12deg)}100%{filter:hue-rotate(0)}} :root[data-theme="cyberpunk"] .brand[data-glitch="on"]{animation:cp-glitch 800ms steps(6) infinite, huePulse 800ms linear infinite} diff --git a/docs/scifi-ui/styles/lcars.css b/docs/scifi-ui/styles/lcars.css index af618f7..7e4a067 100644 --- a/docs/scifi-ui/styles/lcars.css +++ b/docs/scifi-ui/styles/lcars.css @@ -2,3 +2,6 @@ :root[data-theme="lcars"] body{background:radial-gradient(1200px 600px at 50% -10%,#161008 0%,#070809 45%) fixed,#070809;font-family:"Eurostile","Segoe UI",system-ui,-apple-system,Roboto,Arial,sans-serif;font-weight:600} :root[data-theme="lcars"] .brand{font-family:"Eurostile","Segoe UI",system-ui,-apple-system,Roboto,Arial,sans-serif;font-weight:600;letter-spacing:.1em} :root[data-theme="lcars"] .panel,:root[data-theme="lcars"] .card,:root[data-theme="lcars"] .chip{box-shadow:0 0 0 1px rgba(255,255,255,.02) inset,0 10px 30px rgba(0,0,0,.45),0 0 40px var(--panel-glow) inset} +:root[data-theme="lcars"] .progress .bar{background:linear-gradient(90deg,#FF9A3C,#FFD79A)} +:root[data-theme="lcars"] .preloader__lcars .preloader__bar{background:linear-gradient(90deg,#FF9A3C,#FFD79A);animation:fill var(--progress-dur) cubic-bezier(.2,.9,.2,1) infinite,lcars-sheen 1.6s linear infinite} +@keyframes lcars-sheen{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}} diff --git a/docs/scifi-ui/styles/starwars.css b/docs/scifi-ui/styles/starwars.css index 7b2751f..5ba3406 100644 --- a/docs/scifi-ui/styles/starwars.css +++ b/docs/scifi-ui/styles/starwars.css @@ -2,9 +2,10 @@ :root[data-theme="starwars"] body{background:radial-gradient(1200px 600px at 50% -10%,#0f2a3a 0%,#061118 45%) fixed,#061118;font-family:"Orbitron","Roboto Mono",ui-monospace,system-ui,monospace;letter-spacing:.06em} :root[data-theme="starwars"] .brand{font-family:"Orbitron","Roboto Mono",ui-monospace,system-ui,monospace;letter-spacing:.06em;text-shadow:0 0 18px #73ffff55,0 0 3px #72ffff} :root[data-theme="starwars"] .panel,:root[data-theme="starwars"] .card,:root[data-theme="starwars"] .chip{border-color:color-mix(in oklab,var(--accent),#000 35%);box-shadow:0 0 0 1px rgba(255,255,255,.05) inset,0 0 22px #6df6ff22,inset 0 0 26px #6df6ff11} +:root[data-theme="starwars"] .progress .bar{background:linear-gradient(90deg,rgba(46,230,255,0.12),rgba(144,240,255,0.06))} :root[data-theme="starwars"] .fx.holo-grid{opacity:.28;mix-blend-mode:screen;filter:drop-shadow(0 0 6px var(--grid-glow))} -:root[data-theme="starwars"] .fx.holo-grid .hud-line{stroke:#2EE6FF;stroke-opacity:.35;stroke-width:.3;stroke-dasharray:6 8;stroke-dashoffset:0;animation:hud-dash 2s linear infinite} -@keyframes hud-dash{to{stroke-dashoffset:-14}} +:root[data-theme="starwars"] .fx.holo-grid .hud-line{stroke:#2EE6FF;stroke-opacity:.35;stroke-width:.3;stroke-dasharray:6 8;stroke-dashoffset:0;animation:sw-grid 2s linear infinite} +@keyframes sw-grid{to{stroke-dashoffset:-14}} :root[data-theme="starwars"] .preloader__lcars .preloader__bar{background:linear-gradient(90deg,#2EE6FF,#0AA1C4)} :root[data-theme="starwars"] .preloader__label{color:#bff5ff} :root[data-theme="starwars"] .brand::after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(120deg,transparent 30%, rgba(144,240,255,.18) 45%, transparent 60%);animation:holo-sheen 1.8s ease-in-out infinite;mask:linear-gradient(#000,#000)} diff --git a/lighthouserc.json b/lighthouserc.json index 47cd665..33e93a4 100644 --- a/lighthouserc.json +++ b/lighthouserc.json @@ -13,7 +13,10 @@ "categories:performance": ["error", {"minScore": 0.9}], "categories:accessibility": ["error", {"minScore": 0.95}], "categories:best-practices": ["error", {"minScore": 0.95}], - "categories:seo": ["error", {"minScore": 0.9}] + "categories:seo": ["error", {"minScore": 0.9}], + "largest-contentful-paint": ["error", {"maxNumericValue": 2500}], + "cumulative-layout-shift": ["error", {"maxNumericValue": 0.1}], + "server-response-time": ["error", {"maxNumericValue": 600}] } }, "upload": {