← back to Quadrille Showroom
Add AGE-VIEWS-SPEC.md — overseer plan for 10 age-adaptive avatar showroom views (12-85)
bdcbe78c43b716fe6d7559fe5028f2212c7bc813 · 2026-06-29 07:01:17 -0700 · Steve
Files touched
Diff
commit bdcbe78c43b716fe6d7559fe5028f2212c7bc813
Author: Steve <steve@designerwallcoverings.com>
Date: Mon Jun 29 07:01:17 2026 -0700
Add AGE-VIEWS-SPEC.md — overseer plan for 10 age-adaptive avatar showroom views (12-85)
---
AGE-VIEWS-SPEC.md | 281 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 281 insertions(+)
diff --git a/AGE-VIEWS-SPEC.md b/AGE-VIEWS-SPEC.md
new file mode 100644
index 0000000..8a2da43
--- /dev/null
+++ b/AGE-VIEWS-SPEC.md
@@ -0,0 +1,281 @@
+# AGE-ADAPTIVE AVATAR SHOWROOM VIEWS — Authoritative Plan & Spec
+
+**Initiative:** "Age-Adaptive Avatar Showroom Views" — 10 first-person showroom views spanning ages 12 → 85.
+**Overseer:** vp-research-content (this doc is the overseer deliverable; build fans out under it).
+**Date:** 2026-06-29 · **Status:** PLAN — gated to /contrarian before any build. No engine edits this pass.
+**Constraints:** local only · $0 · no deploy · no customer-facing change · avatar from THREE primitives only.
+
+---
+
+## 0. DTD verdict adopted — Verdict A (BOTH adapt)
+
+The running panel leans strongly **A: both (1) the AVATAR figure ages 12→85 AND (2) the UI/UX adapts per age.**
+**This overseer concurs with A**, and refines it:
+
+- The whole point of an *age-adaptive avatar showroom* is that a 12-year-old and an 85-year-old are
+ *embodied differently AND served differently*. Adapting only the avatar (A-without-UI) is a costume
+ change with no usability payoff; adapting only the UI (the existing age-adaptive-theme skill already
+ does that, decoupled from any avatar) ignores Steve's explicit ask to "create versions based on age...
+ for the avatar." A is the only reading that satisfies the literal commission.
+- **One sharpening of A:** the avatar and the UI must move on the *same age axis but not on identical
+ curves*. The avatar morphs *continuously* (proportions interpolate smoothly with age); the UI snaps to
+ the nearest of the validated age-adaptive-theme bands (typography research only validates discrete
+ bands, not a continuum — claiming a smoothly-interpolated WCAG value at age 58.3 would be the exact
+ "false APCA confidence" failure the validation-loop skill exists to prevent). So: **avatar = continuous
+ lerp; UI = banded snap.** Both driven by one `age` value.
+
+No dissent strong enough to override. Proceeding on A.
+
+---
+
+## 1. THE 10 AGE BANDS (12 → 85)
+
+Bands chosen on **life-stage meaning** (how a person of that age relates to a luxury interiors showroom +
+how their vision/motor/cognition + taste profile differ), not arithmetic spacing. Each maps to exactly one
+age-adaptive-theme UI band (the skill's `bandFor()` covers 3–95; we use the 12–85 slice).
+
+| # | Age | Band name | Life stage / showroom relationship | UI band (age-adaptive-theme) |
+|---|-----|-----------|-------------------------------------|------------------------------|
+| 1 | **12** | **Tween** | Curious kid "designing my room"; play-mode, low stakes | `tween` (10–12) |
+| 2 | **16** | **Teen** | Self-expression, bold taste, fluent/fast UI, dense OK | `teen` (13–19) |
+| 3 | **21** | **Emerging Adult** | First apartment, budget-aware, mobile-native | `adult` (low end) |
+| 4 | **28** | **Young Pro** | First real design budget, decisive, modern dashboard | `adult` |
+| 5 | **35** | **Established** | Family home, refined taste, dense info wanted | `adult` (high end) |
+| 6 | **45** | **Connoisseur** | Peak buying power, calm refined pacing, serif | `mature` (45–59) |
+| 7 | **55** | **Tastemaker** | Mature eye, early presbyopia onset, larger type creeping in | `mature` (high end) |
+| 8 | **65** | **Senior** | ★ Senior-usability HARD bar begins — hi-contrast, large, big targets | `senior` (60–79) |
+| 9 | **75** | **Elder** | ★ Deeper senior bar — one decision at a time, max legibility | `senior` (high end) |
+| 10 | **85** | **Legacy** | ★ Hardest accessibility bar — yellow-on-black, 28px+, single action | `elder` (80+) |
+
+**The 65+ HARD bar** (bands 8–10) is non-negotiable: each MUST clear senior-usability —
+large type (≥20px body, ≥28px at 85), high contrast (APCA Lc ≥ 60 body / ≥ 75 for any
+call-to-action), big hit targets (≥48px at 65, ≥56px at 85). See §7 verification.
+
+---
+
+## 2. PER-BAND AVATAR (first-person, all from THREE primitives — $0)
+
+First-person camera = the avatar's eyes. On look-straight the forward wing-bank view stays clean; on
+**look-down** the viewer sees their own torso / clasped hands / lap / legs / feet. So the avatar morph is
+felt primarily through **what your own body looks like when you glance down** + **eye height** + **posture
+sway**. All driven from the existing `buildAvatar()` primitive rig in `public/js/showroom.js` (~L989) — we
+only re-parameterize its existing constants (`AVATAR_EYE_Y`, `hipY`, `chestTopY`, `shoulderHalf`,
+`BODY_BACK`, arm/forearm/hand dims, leg length, foot size) + swap the 4 clothing materials. **No new
+geometry types, no GLTF, no model-gen.**
+
+### 2a. The four primitive levers that carry "age"
+
+1. **EYE HEIGHT (`AVATAR_EYE_Y`)** — the single most legible age cue. A 12-yr-old's eyes sit lower; growth
+ peaks ~late teens; a slight decline + stoop in the 80s lowers it again.
+2. **PROPORTIONS** — head-to-body ratio (kids = larger head fraction → at 12 the neck stub sits higher /
+ torso shorter), shoulder width (`shoulderHalf` narrow at 12 → broad at 28–45 → slightly narrowed at 85),
+ torso length, limb length. Pure scalar tweaks to existing constants.
+3. **POSTURE** — implemented as a small forward lean of the whole rig + a forward-tilt of the neck/upper
+ torso. Upright through midlife; a measured **kyphotic stoop** at 75–85 (rig leans forward ~6–12°, eye
+ drops, hands rest higher/closer). Posture is a rotation on the rig + neck group — no new meshes.
+4. **CLOTHING (material swap only)** — recolor the existing `sweater / jeans / skin / shoe` materials per
+ age. Skin roughness/tone shifts subtly older (cooler, higher roughness) at 65+. No new clothing meshes;
+ "age-appropriate" = palette + roughness on the 4 existing materials.
+
+### 2b. Per-band avatar parameters (relative to the current adult rig: EYE 1.62m, shoulderHalf 0.20)
+
+| # | Age | Eye Y (m) | Shoulder½ | Posture lean | Clothing palette (sweater / jeans / skin / shoe) |
+|---|-----|-----------|-----------|--------------|---------------------------------------------------|
+| 1 | 12 | **1.40** | 0.145 | upright, light bounce | bright hoodie (teal) / lighter jeans / youthful warm skin / canvas sneaker (white) |
+| 2 | 16 | 1.55 | 0.175 | upright, relaxed | graphic crew (charcoal+accent) / slim dark denim / warm skin / dark sneaker |
+| 3 | 21 | 1.60 | 0.195 | upright | casual knit (olive) / mid denim / warm skin / low boot |
+| 4 | 28 | **1.62** | 0.205 | upright (baseline) | charcoal sweater (current) / indigo denim / warm skin / dark leather (baseline rig) |
+| 5 | 35 | 1.62 | 0.215 | upright, settled | fine-gauge merino (slate) / dark trouser-denim / warm skin / leather derby |
+| 6 | 45 | 1.61 | 0.215 | upright, composed | cashmere (camel/greige) / wool trouser (charcoal) / mature skin / suede loafer |
+| 7 | 55 | 1.60 | 0.210 | very slight forward | quarter-zip (heather) / tailored trouser / cooler skin / leather loafer |
+| 8 | 65 | 1.58 | 0.205 | slight stoop ~4° | soft cardigan (navy) / relaxed trouser / cooler higher-roughness skin / comfort shoe |
+| 9 | 75 | 1.54 | 0.195 | stoop ~8°, hands higher | knit vest+shirt (warm grey) / easy trouser / elder skin / cushioned shoe |
+| 10 | 85 | **1.48** | 0.185 | stoop ~12°, hands clasped high/close | thick cardigan (oat) / soft trouser / elder skin (cool, matte) / orthopedic-style shoe |
+
+> Implementation note for the engine officer: these are **interpolation anchors**, not 10 hardcoded bodies.
+> `buildAvatar(age)` reads an `ageRigParams(age)` lerp function (anchors above) so the slider morphs the body
+> continuously. Hands/forearm rest position rises and pulls inward with stoop so the look-down framing stays
+> natural at every age. Contact shadow + grounding unchanged. All shadows/PBR inherited from the rig.
+
+---
+
+## 3. PER-BAND UI/UX ADAPTATION (leverage age-adaptive-theme bands)
+
+The HUD chrome over the 3D canvas — masthead, board caption, spec panel, CTA, version rail, FPS toggle —
+re-themes per age by rewriting CSS vars exactly as the age-adaptive-theme skill prescribes. We consume that
+skill's `bands.json` + `bandFor()` + the `--btn-min-height` / `--font-line-height` baselines verbatim
+(do NOT re-derive APCA values — use the skill's validated tokens; that's the validation-loop lesson).
+
+| # | Age | Base body / heading | Palette | Density / spacing | Info-complexity (spec detail shown) | Copy tone | Hit target |
+|---|-----|---------------------|---------|-------------------|-------------------------------------|-----------|------------|
+| 1 | 12 | 15 / 22 px | amber bg + **indigo-700** | playful, roomy cards | name + 1 fun fact ("looks like candy stripes!") | friendly, simple | 44px |
+| 2 | 16 | 16 / 22 px | dark navy + magenta/cyan neon | dense, tight (scan-line accent) | full pattern + colorway + scale, power-user | confident, punchy | 44px |
+| 3 | 21 | 15 / 18 px | dark indigo (DW default) | modern dashboard | pattern, colorway, repeat, price-aware | clear, modern | 44px |
+| 4 | 28 | 15 / 18 px | dark indigo | modern dashboard, full Hermes panel | full spec table | professional | 44px |
+| 5 | 35 | 15 / 18 px | dark indigo | dense, all info | full spec + "pairs well with" | professional, assured | 44px |
+| 6 | 45 | 15 / 22 px | cream / burgundy serif | calmer pacing, 16px gap | full spec, refined hierarchy | refined editorial | 44px |
+| 7 | 55 | 16 / 24 px | cream / burgundy serif | calmer, larger | full spec, slightly larger labels | refined, unhurried | 48px |
+| 8 | **65** | **20 / 30 px** | **pure black-on-white** | single-column, 20px gap | **reduced** — pattern + colorway + 1 key spec; details behind a clear "More" | plain, direct | **48px** |
+| 9 | **75** | **22 / 32 px** | black-on-white | single-column, larger padding | **minimal** — name + colorway + one CTA | one idea per screen | **52px** |
+| 10 | **85** | **28 / 44 px** | **yellow-on-black** (cataract-scatter correct) | single action at a time | **essentials only** — name + the action verb | just the verb ("See it on the wall") | **56px** |
+
+**65+ HARD bar enforced here:** bands 8–10 use the skill's `senior`/`elder` tokens which are APCA-validated
+(black-on-white / yellow-on-black, Atkinson Hyperlegible, ≥20px body, ≥48px targets). FPS toggle, version
+rail, and any decorative chrome are **simplified or hidden** in these bands so the path is unobstructed.
+
+---
+
+## 4. PER-BAND SHOWROOM ENVIRONMENT TWEAK (light touch)
+
+Environment morph is *subtle* — the room is still the v1 gallery wing-bank; only mood/lighting/calm shifts.
+This rides on the existing PBR/PMREM lighting rig; one or two scalar/colour tweaks per band, FPS-safe.
+
+| # | Age | Environment tweak |
+|---|-----|-------------------|
+| 1 | 12 | Brightest, most saturated key; warm playful bounce; faint extra board spacing so it feels open/fun |
+| 2 | 16 | Cooler, higher-contrast, slight neon rim accent on frames (matches teen UI) |
+| 3 | 21 | Neutral bright gallery (baseline) |
+| 4 | 28 | Neutral bright gallery (baseline) |
+| 5 | 35 | Neutral, slightly warmer key |
+| 6 | 45 | Warmer, softer key; gentle exposure lift; calmer |
+| 7 | 55 | Warmer still, softened shadows, reduced glare |
+| 8 | 65 | **Brighter overall ambient + reduced harsh speculars** (glare control for aging lens); calm, even light |
+| 9 | 75 | Even, high-ambient, very low glare; slowest any animation; maximal contrast on the focused board |
+| 10 | 85 | Calmest: high even ambient, no bloom/haze, focused board maximally lit vs a quiet surround; zero visual noise |
+
+> Senior bands (65+) deliberately *raise* ambient + *kill glare/bloom* — high contrast on content,
+> low contrast in the periphery. The opposite of the teen band's deep-contrast drama.
+
+---
+
+## 5. IMPLEMENTATION DECISION — **RECOMMEND (b): ONE age-SLIDER on the core build**
+
+**Recommendation: build the 10 as a single live AGE SLIDER on the core (V1) build** that morphs the avatar
+(continuous) + UI (banded snap) + environment (banded) across 12→85 — **not** 10 standalone V22–V31 overlays.
+
+### Why (b) wins
+
+1. **Matches the source-of-truth models.** The avatar rig (`buildAvatar`) and the age-adaptive-theme skill
+ are *both* already slider/parameter shaped. age-adaptive-theme's entire reference implementation IS a
+ slider. Fighting that to freeze 10 static overlays throws away the morph that makes the feature
+ impressive — the *continuous transformation* is the demo.
+2. **One engine change, not ten files to keep in sync.** 10 overlays = 10 copies of avatar + UI + env code
+ that drift independently (we've seen this exact drift cost with the hero/proto fleet). One slider on V1 =
+ one `ageRigParams(age)` + one `applyAgeBand(age)` + one env tweak table. DRY, auditable, one place to fix.
+3. **The avatar lives ONLY in the core build.** The V12–V21 protos are camera-only first-person with NO
+ avatar rig. To do "age the avatar" as overlays we'd have to *port the whole primitive rig into 10 proto
+ files* — exactly the duplication (b) avoids. The avatar already exists in V1; the slider extends V1.
+4. **Senior-usability is testable once.** One slider → run the APCA + target-size checks at the 65/75/85
+ stops once, against one codebase. Ten overlays = ten audits.
+5. **Impressive + investor-legible.** "Drag one slider, watch the showroom-goer age from 12 to 85 — body,
+ eyes, type, contrast, calm all shift together" is a far stronger demo than clicking through 10 near-
+ identical static rooms.
+
+### Tradeoffs / what (b) costs (honest)
+
+- **(b) touches the core engine** (`showroom.js` `buildAvatar`, plus a new HUD-theming layer). That's the
+ one real cost: the engine is "owned elsewhere" per HIGH-END-VERSIONS-SPEC. **Mitigation:** the slider is
+ *additive and gated behind a new V-entry / mode flag* ("Age View"), default OFF; `buildAvatar()` keeps its
+ current zero-arg behavior (defaults to age 28 = today's exact rig), so V1 is byte-identical when the slider
+ isn't engaged. No regression to existing versions. The engine officer makes ONE careful, reviewed change.
+- **(a) 10 overlays** would be isolated + parallel-buildable (its only real advantage) — but at the price of
+ 10× avatar-rig duplication, 10× drift, 10× audit, and a *worse* demo. The isolation advantage is moot here
+ because the thing being adapted (the avatar) doesn't exist in the overlay layer at all.
+- **Hybrid considered + rejected:** "slider on core + also snapshot 10 static overlays for the V-picker."
+ Rejected for this pass — it reintroduces the duplication/drift we're avoiding. If Steve later wants the 10
+ as discrete pickable chips, generate them as *thin presets that call the same slider engine at a fixed age*
+ (one line each), never as forked copies.
+
+**Net: (b) — one age slider on the core build, additive, default-off, age-28 == today's rig.**
+If /contrarian or Steve overrules toward (a), the §2/§3/§4 tables are overlay-ready as-is.
+
+---
+
+## 6. FOUR-HORSEMEN DESIGN FRAMES NEEDED (orchestrator main-thread runs these)
+
+The MCP design tools (Figma / 21st / Paper / Canva) run in the orchestrator's main thread, not in this
+overseer thread. Requesting **exactly these frames** — 3 representative age bands spanning the range + the
+slider chrome itself:
+
+1. **HUD frame — Age 12 (Tween):** playful amber/indigo-700 masthead + board caption + "fun fact" line +
+ big friendly CTA. Show the roomy/playful density. *(Figma layout + Canva visual pass.)*
+2. **HUD frame — Age 45 (Connoisseur):** the refined serif cream/burgundy `mature` HUD — full spec table,
+ editorial hierarchy, calm pacing. The "peak buyer" frame. *(Figma + Canva.)*
+3. **HUD frame — Age 85 (Legacy):** the `elder` senior-usability HUD — yellow-on-black, 28/44px Atkinson
+ Hyperlegible, single action verb, 56px target, all decorative chrome stripped. **This is the frame the
+ senior-usability bar is judged against.** *(Figma + 21st live preview to confirm contrast renders.)*
+4. **The AGE SLIDER control itself** (the persistent chrome): age readout + band label + tagline + the
+ 12→85 track, in a treatment that reads at every band (it must remain legible in the elder band too).
+ *(21st Dev component + Paper spec for behavior/states.)*
+5. **(Optional, if budget) A 3-up "morph strip"** — avatar+HUD thumbnails at 12 / 45 / 85 side by side — for
+ the pitch deck / VC debrief. *(Canva.)*
+
+> Deliberately only 3 HUD age-frames (12 / 45 / 85), not 10 — the other 7 bands interpolate/snap between
+> these anchors and don't need bespoke design comps. 3 anchors + slider chrome is the minimum that fully
+> specifies the visual range.
+
+---
+
+## 7. PHASED BUILD PLAN + GATES + VERIFICATION
+
+Recommended execution = **single engine officer (vp-engineering), not an N-agent fan-out** — because (b) is
+*one coordinated change to one core file* (avatar rig + HUD theming on V1). Fan-out shines for N isolated
+files; this is the opposite shape. (If Steve overrules to (a) 10 overlays, THEN fan out 10 agents via
+abramstasks, one proto each, using §2/§3/§4 as the per-file spec.)
+
+### Phase 0 — Gate this plan (NOW)
+- /contrarian tears this spec apart → revise → only then build. **No engine edits until contrarian clears.**
+
+### Phase 1 — Design anchors (orchestrator)
+- Orchestrator runs the §6 four-horsemen frames (3 HUD anchors + slider chrome). Engine officer waits on
+ these so the HUD theming matches approved comps, not invented styling.
+
+### Phase 2 — Avatar age-morph (engine officer, vp-engineering)
+- Add `ageRigParams(age)` lerp (anchors from §2b) + extend `buildAvatar(age=28)` to consume it.
+ **Default zero-arg call == today's rig (age 28) byte-for-byte** (regression guard).
+- Continuous: eye height, proportions, posture lean, clothing material swap. Primitives only, $0.
+- Verify with the **a11y-check** + **avatar-dance**/screenshot at each anchor age that look-down shows a
+ plausible body and forward view stays clean.
+
+### Phase 3 — UI age-band theming (engine officer)
+- Drop in age-adaptive-theme's `bands.json` tokens + `bandFor()` + the `--btn-min-height`/`--font-line-height`
+ baselines onto the HUD chrome (masthead, caption, spec panel, CTA, rail). Banded snap, not interpolation.
+- Wire the §3 info-complexity shaping (`renderFor(band)` — fewer spec rows + simpler copy in 65+).
+
+### Phase 4 — Environment tweaks + the slider control (engine officer)
+- Add the §4 per-band light-touch env table (scalar/colour lerps on the existing PBR/PMREM rig, FPS-safe).
+- Add the persistent **Age slider** (matches the §6.4 approved chrome), default OFF behind an "Age View"
+ mode flag; persists `age` to `localStorage`.
+
+### Phase 5 — Verification (HARD gates)
+1. **FPS gate** — slider must hold ≥55fps at every age (HIGH-END-VERSIONS-SPEC budget). Prove with the FPS
+ readout; pause-on-hidden intact.
+2. **Senior-usability gate (65/75/85) — HARD, blocking:**
+ - **APCA contrast** via age-adaptive-theme's `lib/apca.js` (do NOT self-calculate): body text **Lc ≥ 60**,
+ any CTA **Lc ≥ 75**, at ages 65, 75, 85. Verify in `colour-contrast.com/apca` for the elder band.
+ - **Target size**: every interactive control **≥48px (65/75)** / **≥56px (85)** — measured, not asserted.
+ - **Type size**: body ≥20px (65) → ≥28px (85); headings ≥30px (65) → ≥44px (85).
+ - **Info-complexity**: 65+ shows reduced spec detail + single-action copy (no full spec table dumped on an
+ 85-yr-old).
+ - Run **a11y-check** skill against the 65/75/85 stops.
+3. **Cross-engine render** — /3x (Chrome/Safari/Firefox) on the slider at the 3 anchor ages (12/45/85), 0
+ console errors, real China Seas textures intact, Back/picker postMessage still works.
+4. **validation-loop** — after applying any contrarian/a11y fixes, RE-RUN the same APCA + target + FPS checks
+ on the post-edit build before declaring done (the codified "don't claim done after one edit cycle" rule).
+5. **/contrarian final pass** on the built slider before it's called complete.
+
+### Gates summary
+- **/contrarian** — gates the PLAN (Phase 0) AND the final BUILD (Phase 5.5).
+- **HARD senior-usability + APCA gate** — blocking at 65/75/85; build is NOT done until these pass measured.
+- **Engine change is additive + default-off + age-28-identical** — the regression guard that lets us touch
+ "owned-elsewhere" core code safely.
+- **$0 throughout** — primitives + local APCA/a11y/FPS checks; the only paid step is the four-horsemen design
+ frames in the orchestrator (estimate: design-MCP calls, a few cents to low-$; orchestrator surfaces actual).
+
+---
+
+## Appendix — file/asset touchpoints (for the build, not this pass)
+- `public/js/showroom.js` — `buildAvatar()` ~L989 → add `age` param + `ageRigParams(age)` lerp; `updateAvatarRig()` unchanged.
+- `public/js/versions.js` — add ONE "Age View" entry/mode flag (default off); `VERSION_ORDER` append.
+- HUD/CSS — consume `~/.claude/skills/age-adaptive-theme/bands.json` + `lib/apca.js` (reference, don't fork).
+- No new geometry, no GLTF, no model-gen, no stock images, no deploy.
← f94d966 High-end versions batch 3: V18 Infinity Mirror + V19 Conserv
·
back to Quadrille Showroom
·
AGE-VIEWS-SPEC: apply /contrarian plan-gate fixes (opaque HU 3048f97 →