Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,40 @@ jobs:
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}

- name: Post Lighthouse results to PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = '.lighthouseci';

// Read Lighthouse results
let comment = '## 🚦 Lighthouse CI Results\n\n';
comment += '### Core Web Vitals\n';
comment += '- LCP (Largest Contentful Paint): Target < 2.5s\n';
comment += '- CLS (Cumulative Layout Shift): Target < 0.10\n';
comment += '- TTFB (Time to First Byte): Target < 600ms\n\n';
comment += '### Category Scores\n';
comment += '- Performance: ≥ 90%\n';
comment += '- Accessibility: ≥ 95%\n';
comment += '- Best Practices: ≥ 95%\n';
comment += '- SEO: ≥ 90%\n\n';
comment += 'Full results uploaded as artifacts.';

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});

- name: Pages deployment message
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
run: |
echo "✅ Merged to ${{ github.ref_name }}. GitHub Pages serves from /docs at:"
echo " https://hutoczky.github.io/FormatX/scifi-ui/"

- name: Upload Lighthouse results
uses: actions/upload-artifact@v4
if: always()
Expand Down
51 changes: 40 additions & 11 deletions docs/scifi-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ npx lighthouse http://localhost:8000/scifi-ui/ --view

### Lighthouse Thresholds (CI)

The CI workflow enforces the following Lighthouse thresholds:

**Core Web Vitals:**
- LCP (Largest Contentful Paint): < 2.5s
- CLS (Cumulative Layout Shift): < 0.10
- TTFB (Time to First Byte): < 600ms

**Lighthouse Categories:**
- Performance: ≥ 90%
- Accessibility: ≥ 95%
- Best Practices: ≥ 95%
Expand All @@ -135,6 +143,8 @@ npm install -g @lhci/cli
lhci autorun
```

The CI workflow runs automatically on pull requests and pushes to main/master branches that modify files under `docs/scifi-ui/`.

## 🔧 JavaScript Modules

### theme-switcher.js
Expand All @@ -160,27 +170,34 @@ document.addEventListener('theme:changed', (e) => {
### preloader.js

**Behavior:**
- Preloads critical CSS/SVG assets
- Adds `role="status"` and `aria-live="polite"` to preloader container
- Preloads critical CSS/SVG assets via `fetch()` with `cache:'force-cache'`
- Shows LCARS-style boot bar with `role="progressbar"`
- Respects `prefers-reduced-motion` (simplified indicator)
- Respects `prefers-reduced-motion` (100ms shortcut to completion)
- Updates `aria-valuenow` as resources load
- Hides and dispatches `CustomEvent('preloader:done')` on completion
- Sets `aria-hidden="true"` and hides preloader on completion
- Dispatches `CustomEvent('preloader:done')` when finished

**Accessible Features:**
- ARIA progressbar with live value updates
- `role="status"` and `aria-live="polite"` for screen reader announcements
- Visual boot animation (LCARS style)
- Status text for screen readers
- Reduced motion support
- Reduced motion support with fast completion

### anim-controller.js

**Behavior:**
- Manages background SVG/CSS layers per theme
- Star Wars: HUD grid overlay with animated scanning line
- Star Wars: HUD grid overlay with animated scanning line (2s linear animation)
- Cyberpunk: Neon noise overlay with shift animation
- LCARS: Minimal/none (clean interface)
- Applies gentle pointer parallax after preloader (disabled for reduced-motion)
- Listens for `theme:changed` and `preloader:done` events
- Activates theme-specific animations:
- LCARS: 1.6s cubic-bezier(.2,.9,.2,1) transitions
- Star Wars: 1.8s ease-in-out with HUD class activation
- Cyberpunk: 1.2s steps(6,end) with 'glitch' class
- Sets loader-sample `.bar` width to 100% and adds 'active' class on preloader:done

**Parallax:**
- Smooth lerp-based movement
Expand All @@ -194,25 +211,37 @@ document.addEventListener('theme:changed', (e) => {
All visual assets are created with CSS and SVG:

- **hud-grid.svg**: Minimal Star Wars-style HUD grid (original work)
- **lcars-panels.svg**: LCARS-style decorative panels placeholder (original work)
- **hologram-activation.svg**: Holographic activation effect placeholder (original work)
- **CSS animations**: All effects implemented in pure CSS
- **Fonts**: System font stacks used (no external fonts loaded)

### Asset Inventory

- **SVG Files**: 3 original placeholder files (hud-grid, lcars-panels, hologram-activation)
- **Images**: Empty directory with .gitkeep (ready for WebP/AVIF assets)
- **Fonts**: Empty directory with .gitkeep; using system font stacks
- **Audio**: Empty directory with .gitkeep (optional ambient sounds)

### Fonts Used

System fallbacks (no licensing required):
- LCARS: `"Eurostile", "Microgramma", "Orbitron", "Exo 2", system-ui`
- Star Wars: `"Share Tech Mono", "Orbitron", ui-monospace`
- Cyberpunk: `"OCR A", "Audiowide", "Exo 2", system-ui`
- LCARS: `"Eurostile", "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif`
- Star Wars: `"Orbitron", "Roboto Mono", ui-monospace, system-ui, monospace`
- Cyberpunk: `"OCR-A", "VT323", ui-monospace, monospace`

**Font Preloading**: Font preload tags are commented in `index.html` until licensed fonts are added. See commented examples for woff2 format.

### No Unlicensed IP

This demo does **NOT** include:
- Trademarked logos or symbols
- Trademarked logos or symbols (e.g., Starfleet insignia, Star Wars emblems)
- Copyrighted imagery from films/shows
- Licensed sound effects or music
- Proprietary typefaces
- Star Trek ship designs (enterprise.svg removed in commit 4)

All designs are inspired aesthetics created from scratch.
All designs are inspired aesthetics created from scratch using generic geometric shapes and color schemes.

## ✅ Testing Steps

Expand Down
37 changes: 0 additions & 37 deletions docs/scifi-ui/assets/enterprise.svg

This file was deleted.

18 changes: 18 additions & 0 deletions docs/scifi-ui/assets/svgs/hologram-activation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions docs/scifi-ui/assets/svgs/lcars-panels.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions docs/scifi-ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
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'">
<link rel="preload" as="style" href="styles/base.css" />
<link rel="preload" as="style" href="styles/themes.css" />
<!-- Font preload examples (uncomment when licensed fonts are added):
<link rel="preload" as="font" type="font/woff2" href="assets/fonts/eurostile-extended.woff2" crossorigin />
<link rel="preload" as="font" type="font/woff2" href="assets/fonts/orbitron-variable.woff2" crossorigin />
<link rel="preload" as="font" type="font/woff2" href="assets/fonts/ocra-regular.woff2" crossorigin />
-->
<link rel="stylesheet" href="styles/base.css" />
<link rel="stylesheet" href="styles/themes.css" />
<link id="theme-css" rel="stylesheet" href="styles/lcars.css" />
Expand Down
38 changes: 34 additions & 4 deletions docs/scifi-ui/scripts/anim-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,38 @@
cyberpunk:`<svg class="fx glitch-overlay" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true"><defs><filter id="noise"><feTurbulence type="fractalNoise" baseFrequency="1.2" numOctaves="2" stitchTiles="stitch"/></filter></defs><rect width="100%" height="100%" filter="url(#noise)" fill="#FF2EC0" opacity=".06"/></svg>`,
lcars:''
};
function activate(theme){clearLayers(); if(SVGS[theme]) layersHost.appendChild(elFrom(SVGS[theme]));}
activate(document.documentElement.getAttribute('data-theme')||'lcars');
document.addEventListener('theme:changed',e=>{activate(e.detail.theme)});
document.addEventListener('preloader:done',()=>{ if(prefersReduced) return; let raf=0; const onMove=(ev)=>{cancelAnimationFrame(raf); raf=requestAnimationFrame(()=>{const x=(ev.clientX/innerWidth-.5)*4; const y=(ev.clientY/innerHeight-.5)*4; layersHost.style.transform=`translate(${x}px, ${y}px)`;});}; window.addEventListener('pointermove',onMove,{passive:true});});
function activateThemeAnimations(theme){
clearLayers();
if(SVGS[theme]) layersHost.appendChild(elFrom(SVGS[theme]));
const root=document.documentElement;
if(theme==='lcars'){
root.style.setProperty('--progress-dur','1.6s');
}else if(theme==='starwars'){
root.style.setProperty('--progress-dur','1.8s');
document.body.classList.add('hud-active');
}else if(theme==='cyberpunk'){
root.style.setProperty('--progress-dur','1.2s');
document.body.classList.add('glitch-active');
}
}
activateThemeAnimations(document.documentElement.getAttribute('data-theme')||'lcars');
document.addEventListener('theme:changed',e=>{activateThemeAnimations(e.detail.theme)});
document.addEventListener('preloader:done',()=>{
const loaderSamples=document.querySelectorAll('.loader-sample .bar');
loaderSamples.forEach(bar=>{
bar.style.width='100%';
bar.closest('.loader-sample')?.classList.add('active');
});
if(prefersReduced) return;
let raf=0;
const onMove=(ev)=>{
cancelAnimationFrame(raf);
raf=requestAnimationFrame(()=>{
const x=(ev.clientX/innerWidth-.5)*4;
const y=(ev.clientY/innerHeight-.5)*4;
layersHost.style.transform=`translate(${x}px, ${y}px)`;
});
};
window.addEventListener('pointermove',onMove,{passive:true});
});
})();
24 changes: 22 additions & 2 deletions docs/scifi-ui/scripts/preloader.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
(function(){
const pre=document.getElementById('preloader'); if(!pre) return;
pre.setAttribute('role','status');
pre.setAttribute('aria-live','polite');
const prefersReduced=window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const assets=['styles/base.css','styles/themes.css','styles/lcars.css','styles/starwars.css','styles/cyberpunk.css','assets/svgs/hud-grid.svg'];
let done=0; function tick(){done++; const now=Math.min(100,Math.round(done/assets.length*100)); pre.setAttribute('aria-valuenow',String(now));}
Promise.all(assets.map(u=>fetch(u,{cache:'force-cache'}).then(r=>{tick();return r.ok;}).catch(()=>{tick();}))).then(()=>new Promise(res=>setTimeout(res,prefersReduced?100:600))).finally(()=>{pre.hidden=true; document.dispatchEvent(new CustomEvent('preloader:done'));});
let done=0;
function tick(){
done++;
const now=Math.min(100,Math.round(done/assets.length*100));
pre.setAttribute('aria-valuenow',String(now));
}
if(prefersReduced){
pre.setAttribute('aria-valuenow','100');
setTimeout(()=>{
pre.hidden=true;
pre.setAttribute('aria-hidden','true');
document.dispatchEvent(new CustomEvent('preloader:done'));
},100);
}else{
Promise.all(assets.map(u=>fetch(u,{cache:'force-cache'}).then(r=>{tick();return r.ok;}).catch(()=>{tick();}))).then(()=>new Promise(res=>setTimeout(res,600))).finally(()=>{
pre.hidden=true;
pre.setAttribute('aria-hidden','true');
document.dispatchEvent(new CustomEvent('preloader:done'));
});
}
})();
4 changes: 2 additions & 2 deletions docs/scifi-ui/styles/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,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}
Expand Down Expand Up @@ -54,7 +54,7 @@ img{max-width:100%;height:auto}
.preloader{position:fixed;inset:0;display:grid;place-items:center;background:#070809;z-index:1000}
.preloader[hidden]{display:none}
.preloader__lcars{position:relative;height:44px;max-width:520px;width:80%;border-radius:24px;background:#0b0d10;box-shadow:inset 0 0 0 2px rgba(0,0,0,.55)}
.preloader__lcars .preloader__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}
.preloader__lcars .preloader__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}
.preloader__lcars .preloader__cap{position:absolute;top:2px;right:2px;bottom:2px;width:50px;border-radius:0 22px 22px 0;background:linear-gradient(180deg,#181a1e,#0f1216)}
.preloader__label{margin-top:16px;color:#ffd089;text-align:center}
@keyframes fill{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}
Expand Down
7 changes: 4 additions & 3 deletions docs/scifi-ui/styles/cyberpunk.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading