feat: establish nightdrive visual foundation

This commit is contained in:
2026-09-02 13:55:01 +03:00
parent f1e156fba7
commit 24afda8710
8 changed files with 193 additions and 47 deletions

View File

@@ -65,51 +65,40 @@
**Files:**
- Modify: `package.json`
- Modify: `package-lock.json`
- Modify: `src/App.vue`
- Modify: `src/styles/tokens.css`
- Modify: `src/styles/base.css`
- Modify: `scripts/build-contract.mjs`
- Create: `docs/third-party-notices.md`
- Test: `tests/unit/toolchain.test.ts`
- Modify: `tests/unit/build-contract.test.ts`
- Modify: `tests/browser/semantic.spec.ts`
**Interfaces:**
- Consumes: existing Vite CSS import order and Vue application entry.
- Produces: `Geist Variable`, `Geist Mono`, Phosphor Vue components, Simple Icons exports, and stable CSS tokens used by every subsequent task.
- Consumes: existing Vite CSS pipeline, manifest closure validator, and generated preview.
- Produces: `Geist Variable`, `Geist Mono`, font-aware asset closure, and stable CSS tokens used by every subsequent task. Phosphor Vue and Simple Icons are installed only when their tested consumers are introduced in Tasks 7 and 10.
- [ ] **Step 1: Write dependency and typography assertions**
- [ ] **Step 1: Write the browser typography assertion**
Add assertions that exact direct dependencies exist and that the application imports the two font stylesheets before local CSS:
Load the generated preview, await `document.fonts.ready`, and assert the actual rendered heading and route-label families:
```ts
expect(packageJson.dependencies).toMatchObject({
'@fontsource-variable/geist': '5.3.0',
'@fontsource-variable/geist-mono': '5.3.0',
'@phosphor-icons/vue': '2.2.1',
'simple-icons': '16.29.0',
});
expect(appSource).toContain("@fontsource-variable/geist/wght.css");
expect(appSource).toContain("@fontsource-variable/geist-mono/wght.css");
expect(fonts.headingFamily).toContain('Geist Variable');
expect(fonts.routeFamily).toContain('Geist Mono Variable');
```
- [ ] **Step 2: Run the focused test and verify it fails**
Run: `npx vitest run tests/unit/toolchain.test.ts`
Run: `npm run build:preview && npx playwright test tests/browser/semantic.spec.ts --project=desktop-chromium --grep "loads the self-hosted Geist"`
Expected: FAIL because the dependencies and font imports are absent.
Expected: FAIL because rendered text still uses Inter and the system monospace stack.
- [ ] **Step 3: Install verified dependencies and import fonts**
- [ ] **Step 3: Install verified font dependencies and define only required subsets**
Run:
```bash
npm install --save-exact @fontsource-variable/geist@5.3.0 @fontsource-variable/geist-mono@5.3.0 @phosphor-icons/vue@2.2.1 simple-icons@16.29.0
npm install --save-exact @fontsource-variable/geist@5.3.0 @fontsource-variable/geist-mono@5.3.0
```
Add before local CSS in `src/App.vue`:
```ts
import '@fontsource-variable/geist/wght.css';
import '@fontsource-variable/geist-mono/wght.css';
```
Define Latin and Latin Extended Geist faces plus the Latin Geist Mono face in `src/styles/tokens.css`. Reference package-owned `.woff2` files directly so Vite emits only the three subsets used by visible content.
Define the stable visual tokens:
@@ -141,18 +130,18 @@ Define the stable visual tokens:
}
```
Record the package names, versions, licenses, copyright owners, and source URLs in `docs/third-party-notices.md`.
Teach `resolveViteAssetClosure` to accept a non-entry manifest record only when its emitted file is already named by the `assets` field of a reachable module. Keep unrelated records rejected. Record the font package names, versions, licenses, copyright owners, and source URLs in `docs/third-party-notices.md`.
- [ ] **Step 4: Run the focused test and static verification**
Run: `npx vitest run tests/unit/toolchain.test.ts && npm run typecheck`
Run: `npx vitest run tests/unit/build-contract.test.ts && npm run build:preview && npx playwright test tests/browser/semantic.spec.ts --project=desktop-chromium --grep "loads the self-hosted Geist"`
Expected: PASS.
Expected: PASS with `initialFonts` below the existing 122880-byte threshold.
- [ ] **Step 5: Commit the foundation**
```bash
git add package.json package-lock.json src/App.vue src/styles/tokens.css src/styles/base.css docs/third-party-notices.md tests/unit/toolchain.test.ts
git add package.json package-lock.json src/styles/tokens.css scripts/build-contract.mjs docs/third-party-notices.md tests/unit/build-contract.test.ts tests/browser/semantic.spec.ts docs/superpowers/plans/2026-09-02-portfolio-nightdrive-redesign-implementation.md
git commit -m "feat: establish nightdrive visual foundation"
```
@@ -538,6 +527,8 @@ git commit -m "feat: integrate the cinematic nightdrive scene"
### Task 7: Replace exposed controls with the compact vehicle HUD
**Files:**
- Modify: `package.json`
- Modify: `package-lock.json`
- Create: `src/components/IconGlyph.vue`
- Modify: `src/components/DriveControls.vue`
- Modify: `src/components/JourneyHud.vue`
@@ -573,6 +564,12 @@ Expected: FAIL because the current controls expose every setting and use text-on
- [ ] **Step 3: Implement the icon contract and control states**
Install the verified Vue interface-icon package:
```bash
npm install --save-exact @phosphor-icons/vue@2.2.1
```
Use tree-shaken Phosphor imports with a standard `20px`, weight `regular`, and visual stroke weight. Keep button labels in `aria-label` and tooltips, not duplicate visible strings.
```vue
@@ -603,7 +600,7 @@ Expected: PASS.
- [ ] **Step 6: Commit the HUD milestone**
```bash
git add src/components/IconGlyph.vue src/components/DriveControls.vue src/components/JourneyHud.vue src/components/AppShell.vue src/styles/world.css tests/unit/SceneCanvas.test.ts tests/browser/audio-controls.spec.ts tests/browser/scene-controls.spec.ts tests/browser/responsive-layout.spec.ts
git add package.json package-lock.json src/components/IconGlyph.vue src/components/DriveControls.vue src/components/JourneyHud.vue src/components/AppShell.vue src/styles/world.css tests/unit/SceneCanvas.test.ts tests/browser/audio-controls.spec.ts tests/browser/scene-controls.spec.ts tests/browser/responsive-layout.spec.ts docs/third-party-notices.md
git commit -m "feat: introduce the compact vehicle HUD"
```
@@ -770,6 +767,8 @@ git commit -m "feat: recompose the portfolio information layer"
### Task 10: Build the infrastructure flow and official icon registries
**Files:**
- Modify: `package.json`
- Modify: `package-lock.json`
- Create: `src/components/BrandIcon.vue`
- Create: `src/icons/brand-icons.ts`
- Modify: `src/components/InfrastructureDiagram.vue`
@@ -807,6 +806,12 @@ Expected: FAIL because the registry and real flow diagram do not exist.
- [ ] **Step 3: Implement brand and interface icon rendering**
Install the verified brand-data package:
```bash
npm install --save-exact simple-icons@16.29.0
```
Import named Simple Icons exports only in `brand-icons.ts`. Render package-provided paths through `BrandIcon.vue`; hide decorative marks from assistive technology and keep the visible technology or service name. Continue using Phosphor only for interface and diagram actions.
- [ ] **Step 4: Replace the four-box diagram with a flow**
@@ -828,7 +833,7 @@ Expected: PASS.
- [ ] **Step 6: Commit diagrams and iconography**
```bash
git add src/components/BrandIcon.vue src/icons/brand-icons.ts src/components/InfrastructureDiagram.vue src/components/ToolkitGrid.vue src/components/ContactDestination.vue src/styles/components.css tests/unit/brand-icons.test.ts tests/unit/components.test.ts tests/browser/accessibility-axe.spec.ts tests/browser/responsive-layout.spec.ts
git add package.json package-lock.json src/components/BrandIcon.vue src/icons/brand-icons.ts src/components/InfrastructureDiagram.vue src/components/ToolkitGrid.vue src/components/ContactDestination.vue src/styles/components.css tests/unit/brand-icons.test.ts tests/unit/components.test.ts tests/browser/accessibility-axe.spec.ts tests/browser/responsive-layout.spec.ts docs/third-party-notices.md
git commit -m "feat: add infrastructure flow and official iconography"
```