Skip to content

feat(gallery+db): character page gallery UX overhaul + Sculpt/Classic estimated bodies - #29

Merged
kas1987 merged 10 commits into
mainfrom
feat/pdr-010-ceo-roi-analysis
Jun 6, 2026
Merged

feat(gallery+db): character page gallery UX overhaul + Sculpt/Classic estimated bodies#29
kas1987 merged 10 commits into
mainfrom
feat/pdr-010-ceo-roi-analysis

Conversation

@kas1987

@kas1987 kas1987 commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • Gallery UX (character.html): five improvements to the character page
    • Eyebrow shows series name only — "Slot N" removed
    • Info-panel backdrop uses gallery[1] (a different image from the hero) so the background and hero aren't identical
    • Image count badge derives from actual gallery[] array length, not the stale image_count field
    • Images auto-rotate every 4.5 s with a gold progress bar; rotation pauses on hover and resumes on mouse-leave
    • Lightbox overlay with prev/next/close, keyboard nav (←/→/Esc), and click-backdrop-to-close
  • DB entries (db/): estimated body profiles for two new SKUs
    • The Sculpt — ZS165D (Sculpt family, 165 cm D-cup, WHR 0.67)
    • The Classic — ZC165D (Classic family, 165 cm D-cup, WHR 0.70)
    • Entries added to family_taxonomy.json, body_profiles.json, body_measurements.json, character_profiles.json
    • All measurements flagged "estimated": true pending manufacture

Test plan

  • Open /character.html?id=<any-id-with-gallery> — verify eyebrow shows series only (no slot number)
  • Verify info-panel backdrop image differs from the main hero when gallery[1] exists
  • Verify image count badge matches gallery.length for characters with multiple images
  • Wait ~4.5 s — images should cycle automatically; gold progress bar animates across the bottom
  • Hover over gallery — rotation pauses; move away — rotation resumes
  • Click main image — lightbox opens; prev/next/close/keyboard/backdrop-click all work
  • Confirm ZS165D and ZC165D appear in the family taxonomy and body DB with estimated: true

🤖 Generated with Claude Code

kas1987 and others added 8 commits June 6, 2026 11:05
- 24 brands, 233 classified body profiles across 6 ZELEX families
- SQLite DB with competitor_rows, brand_summary, brand_geographic,
  market_tiers, market_regions, inventory_only tables
- Pricing, quality signals, geographic metadata per brand
- Irontech official + Tayu sitemap + Dollstudio multi-brand crawl
- RealDoll 13-model inventory captured (classification pending)
- Approved PDR-010 design spec added
Tayu is scraped via scrape_tayu() in main(); listing it as
pending-source in UNAVAILABLE_COMPETITORS made every generated
report mark Tayu as both covered and a gap simultaneously.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The two independent-catalog heatmap PNGs were force-added in e137d22
despite *.png being in .gitignore. The CI hygiene guard rejects image
files in the tree. Removing them from the index; local copies remain.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… estimated bodies

Gallery / character page (character.html):
- Remove "· Slot N" from series eyebrow — series name only
- Backdrop image now uses gallery[1] to differ from the hero
- Image count derived from gallery.length (not stale static field)
- Auto-rotate every 4.5 s with gold progress bar; pauses on hover
- Lightbox with prev/next buttons, keyboard nav (←/→/Esc), click-outside close

DB — estimated hero bodies for new families:
- db/family_taxonomy.json: ZS165D (Sculpt) + ZC165D (Classic) added; member_counts set to 1
- db/body_profiles.json: full profile entries for ZS165D + ZC165D
- db/body_measurements.json: estimated spec-cards (PDR-005/007 design targets)
- db/character_profiles.json: persona entries for The Athlete + The Standard

All four HTML pages (browse, contact, quiz, series) carry forward
minor polish edits from prior session.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 6, 2026 15:07

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces two new body profiles (ZS165D and ZC165D) with their corresponding measurements, taxonomy, and character profile details. It also adds interactive gallery features to character.html (including auto-rotation, a progress bar, and a lightbox modal), updates border-radius values to use CSS variables, refactors event listeners in series.html, and refines the quiz fallback logic in quiz.html. Feedback on these changes highlights two issues: a bug in quiz.html where fallback characters break the splitAt divider placement, and a race condition in character.html where the gallery progress bar can animate even when auto-rotation is paused.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread quiz.html
Comment thread character.html

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the character page browsing experience (gallery auto-rotation + lightbox + cleaner metadata) and extends the catalog database with two new estimated body SKUs for the Sculpt and Classic families.

Changes:

  • Refactors character.html gallery UX: series-only eyebrow, non-duplicate backdrop image, gallery-length-derived image counts, auto-rotate with progress bar, and a lightbox overlay with keyboard navigation.
  • Adds estimated DB entries for ZS165D (The Sculpt) and ZC165D (The Classic) across taxonomy, profiles, measurements, and character/persona copy.
  • Small UI/CSS consistency tweaks (button wiring in series.html, shared button styling in quiz.html, border-radius variables in browse.html/contact.html, and contact form error message structure).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
series.html Removes inline onclick and wires view toggle buttons via addEventListener.
quiz.html Makes “Begin” use shared .btn styling and tweaks match fallback logic.
db/family_taxonomy.json Adds ZS165D/ZC165D into family membership + body taxonomy list (estimated).
db/character_profiles.json Adds persona/positioning copy for ZS165D and ZC165D.
db/body_profiles.json Adds full estimated profile rows for ZS165D and ZC165D.
db/body_measurements.json Adds estimated measurement records for ZS165D and ZC165D.
contact.html Uses --r-md radius tokens; improves error message text update without clobbering the email link; hides chip area on success.
character.html Implements the character gallery UX overhaul (auto-rotate/progress + lightbox + metadata tweaks).
browse.html Uses --r-md for search input border radius consistency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread contact.html
Comment thread character.html
Comment thread character.html
- assets/site.css: add isolation:isolate to .btn.concierge to contain
  the z-index:-1 ::before pseudo-element within the button stacking context
- scripts/analyze_independent_groupings.py: use .as_posix() for
  generated_from so the path uses forward slashes on Windows
- scripts/scrape_competitors.js: wrap scraping loop in try…finally so
  browser.close() is guaranteed even on exception
- scripts/build_competitor_catalog_taxonomy.py:
  - use `or ""` (not default "") on body_html/title/handle to guard
    against explicit null values returned by the Shopify API
  - add height sanity check (50–250 cm) in scrape_supplier to drop
    mis-parsed values like 16 cm (Game Lady regression)
  - include "hybrid" material in tpe_share_pct calculation
  - wrap every network scrape call in main() with try/except so one
    supplier failure does not abort the entire run
- docs/pdr/PDR-010-competitor-family-coverage-roi-validation.md:
  - fix market concentration band table (90–100% header; correct
    WM/XT/SE/6YE/AS Doll to 60–69% band; move Game Lady/Tayu/Jiusheng
    out of <60% into 60–69%)
  - recalculate ROI composites using the stated weight formula
    (avail×2, conv×2, roadmap×1.5, others×1, total 10.5):
    Muse 3.5→3.7, Icon 4.0→3.9, Siren 3.8→3.7,
    Empress 2.3→2.0, Classic 3.4→3.1, Sculpt 2.3→2.0
- db/independent_catalog_groupings.json: fix Windows backslash in
  generated_from path
- docs/research/source-log.md: correct Irontech URL to
  https://www.irontechdoll.com/ (matches scraper endpoint)
- docs/research/competitor-family-coverage-matrix.md: fix Game Lady
  height range from 16-171 cm to 156-171 cm (scraper mis-parse)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@kas1987
kas1987 enabled auto-merge (squash) June 6, 2026 15:23

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9cc4536af3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread character.html
- quiz.html: recalculate fromSecond after fallback block so splitAt
  divider stays anchored to first runner-up character index
- character.html resetBar(): guard inner rAF callback against autoTimer
  being cleared during the two-frame delay
- character.html goTo(): set lbImgEl.alt dynamically using p.name and
  photo index for screen-reader accessibility
- character.html openLightbox/closeLightbox: save lightboxAutoWasRunning
  before stopAuto() so auto-rotation only restarts if it was running
- contact.html showError(): remove dead msgEl variable (assigned, never used)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kas1987
kas1987 merged commit 7a7cb82 into main Jun 6, 2026
1 check passed
@kas1987
kas1987 deleted the feat/pdr-010-ceo-roi-analysis branch June 6, 2026 15:29

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b432425baf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread db/body_measurements.json
"estimated": true,
"est_basis": "Interpolated from ZX172E / ZG175E (E-cup) slim build (no published spec card)"
},
"ZS165D": {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Teach the generators the new prefixes

When scripts/build_profiles.py is rerun (it is the documented generator for db/body_profiles.json), I checked that its prefix normalization only recognizes ZGX, ZX, ZK, and ZF, and otherwise falls back to ZG; adding this ZS165D source row therefore regenerates the profile as line ZG / series Inspiration instead of ZS / Sculpt (and the same happens to the new ZC165D row). Please update the generator’s prefix map/normalization before adding these generated DB entries so the new bodies round-trip correctly.

Useful? React with 👍 / 👎.

kas1987 added a commit that referenced this pull request Jun 16, 2026
…ke) (#34)

* research(pdr-010): competitor family taxonomy + apples-to-apples DB

- 24 brands, 233 classified body profiles across 6 ZELEX families
- SQLite DB with competitor_rows, brand_summary, brand_geographic,
  market_tiers, market_regions, inventory_only tables
- Pricing, quality signals, geographic metadata per brand
- Irontech official + Tayu sitemap + Dollstudio multi-brand crawl
- RealDoll 13-model inventory captured (classification pending)
- Approved PDR-010 design spec added

* PDR-010: expand competitor coverage and add independent grouping heatmaps

* PDR-010: add full-body heatmap and normalize ZELEX line grouping

* PDR-010: add PNG heatmaps, top10 matrices, and lineup brief

* PDR-010: track independent catalog heatmap PNG artifacts

* fix(taxonomy): remove Tayu from UNAVAILABLE_COMPETITORS

Tayu is scraped via scrape_tayu() in main(); listing it as
pending-source in UNAVAILABLE_COMPETITORS made every generated
report mark Tayu as both covered and a gap simultaneously.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): untrack PNG heatmap artifacts that trip the image guard

The two independent-catalog heatmap PNGs were force-added in e137d22
despite *.png being in .gitignore. The CI hygiene guard rejects image
files in the tree. Removing them from the index; local copies remain.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(gallery+db): character page gallery UX overhaul + Sculpt/Classic estimated bodies

Gallery / character page (character.html):
- Remove "· Slot N" from series eyebrow — series name only
- Backdrop image now uses gallery[1] to differ from the hero
- Image count derived from gallery.length (not stale static field)
- Auto-rotate every 4.5 s with gold progress bar; pauses on hover
- Lightbox with prev/next buttons, keyboard nav (←/→/Esc), click-outside close

DB — estimated hero bodies for new families:
- db/family_taxonomy.json: ZS165D (Sculpt) + ZC165D (Classic) added; member_counts set to 1
- db/body_profiles.json: full profile entries for ZS165D + ZC165D
- db/body_measurements.json: estimated spec-cards (PDR-005/007 design targets)
- db/character_profiles.json: persona entries for The Athlete + The Standard

All four HTML pages (browse, contact, quiz, series) carry forward
minor polish edits from prior session.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(pdr-010): address all PR #28 Copilot/Gemini review findings

- assets/site.css: add isolation:isolate to .btn.concierge to contain
  the z-index:-1 ::before pseudo-element within the button stacking context
- scripts/analyze_independent_groupings.py: use .as_posix() for
  generated_from so the path uses forward slashes on Windows
- scripts/scrape_competitors.js: wrap scraping loop in try…finally so
  browser.close() is guaranteed even on exception
- scripts/build_competitor_catalog_taxonomy.py:
  - use `or ""` (not default "") on body_html/title/handle to guard
    against explicit null values returned by the Shopify API
  - add height sanity check (50–250 cm) in scrape_supplier to drop
    mis-parsed values like 16 cm (Game Lady regression)
  - include "hybrid" material in tpe_share_pct calculation
  - wrap every network scrape call in main() with try/except so one
    supplier failure does not abort the entire run
- docs/pdr/PDR-010-competitor-family-coverage-roi-validation.md:
  - fix market concentration band table (90–100% header; correct
    WM/XT/SE/6YE/AS Doll to 60–69% band; move Game Lady/Tayu/Jiusheng
    out of <60% into 60–69%)
  - recalculate ROI composites using the stated weight formula
    (avail×2, conv×2, roadmap×1.5, others×1, total 10.5):
    Muse 3.5→3.7, Icon 4.0→3.9, Siren 3.8→3.7,
    Empress 2.3→2.0, Classic 3.4→3.1, Sculpt 2.3→2.0
- db/independent_catalog_groupings.json: fix Windows backslash in
  generated_from path
- docs/research/source-log.md: correct Irontech URL to
  https://www.irontechdoll.com/ (matches scraper endpoint)
- docs/research/competitor-family-coverage-matrix.md: fix Game Lady
  height range from 16-171 cm to 156-171 cm (scraper mis-parse)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: apply PR #29 review comment fixes

- quiz.html: recalculate fromSecond after fallback block so splitAt
  divider stays anchored to first runner-up character index
- character.html resetBar(): guard inner rAF callback against autoTimer
  being cleared during the two-frame delay
- character.html goTo(): set lbImgEl.alt dynamically using p.name and
  photo index for screen-reader accessibility
- character.html openLightbox/closeLightbox: save lightboxAutoWasRunning
  before stopAuto() so auto-rotation only restarts if it was running
- contact.html showError(): remove dead msgEl variable (assigned, never used)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: ship compare funnel and analytics sanity guardrails

* feat(pdr-010): add Howie CEO package — strategic briefs + interactive dashboard

Adds the full CEO package for Howie's leadership review use:
- docs/howie-ceo-package/howie-ceo-dashboard.html — standalone interactive
  Family Activation Simulator: 6 family cards with live KPI recalculation,
  health pill (HEALTHY/AT RISK/CRITICAL), scenario ROI, and decision brief links.
  All data labeled as analyst estimates; no server dependency.
- docs/howie-ceo-package/00–05 — command brief, dedicated brief library,
  team execution guide, KPI scoreboard, deep-dive guide, decision log template.
  All files carry prominent ESTIMATES NOTICES (competitive research, not actuals).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(pdr-010): add like-kind manufacturing & cross-family tooling interdependency analyses

03-like-kind-manufacturing-scenarios.md: identifies ZE T168E (dist 0.96 to
Sculpt centroid) and ZG S155C/ZG162D as zero-to-minimal-tooling paths to seed
Classic and Sculpt families.

04-cross-family-tooling-interdependencies.md: maps bridge frames across all 6
families, defines the convergence frame concept (H160, W57 activates Classic +
Sculpt from one commission), identifies Sculpt/Icon bridge zone, and models the
~$200-350K cascade that eliminates both dead-end families while reinforcing Icon
and Empress.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(pdr-010): add manufacturing intelligence matrix brief for CEO package

Introduces the Build-to-Stage framework: Family × Component Layer × Demand
Confidence Tier matrix showing how market intelligence (family centroids,
dimensional distance scores, market gap coverage) feeds directly into
pre-staged work orders. Distinguishes what current data enables vs. what
requires customer/order data, and identifies Tier 1 pre-stage actions
(ZE T168E for Sculpt, ZG S155C for Classic) that can start immediately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(pdr-010): add full PDR with Mermaid path analysis across all epic phases

Covers 5 decision points — family activation paths, tooling investment options,
manufacturing model (MTO vs. Build-to-Stage), data signal maturity, and family
expansion sequence — each with Mermaid flowcharts showing pros/cons per path.
Includes investment summary across Immediate / Q3 / Q3-Q4 / 2027 horizons
and a single-table decision summary for Howie.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(pdr-010): embed Mermaid decision charts into CEO dashboard

Adds interactive PDR-010 decision path section to howie-ceo-dashboard.html:
- Mermaid v10.9.0 CDN + dark-theme initialization
- Phase Map (full-width): P0 done → P1 active → P2-P4 planned/future
- DP-1: Classic/Sculpt activation paths (A/B/C with verdicts)
- DP-2: Q3 tooling investment options (Convergence/Bridge/Both)
- DP-3: Make-to-Order → Build-to-Stage transition
- DP-4: Family expansion sequence (Zone A/B, Empress, Siren)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Import PDR recovery pack and enforce explicit PDR path gating

* Add CI PDR_PATH guard and complete recovery-task traceability

* Apply PDR-001 status primitives in shared card components

* Use shared status primitives on homepage family tiles

* Continue PDR-001 rollout and add PDR-002 homepage intent router

* Advance PDR-003 compare workflow with decision summaries

* Unify compare-entry UX and remove remaining homepage inline layout styles

* Implement PDR-004 ranked quiz funnel and handoff CTAs

* feat: add customization options guide with body/head tracks

* feat: add options deep-links, filter analytics, and noscript fallback

* chore: package latest root HTML set into v2 HTML

* feat: add community hub, SWOT gap review, and v2 packaging automation

* chore: harden validation and v2 packaging best practices

* feat: enforce v2 freshness in CI and data-drive community hub

* feat: tie community hub to KB with schema guard and events page

* chore: add community-events schema guard and KB sync utility

* chore: add check-mode sync guard and community data contract

* chore: refresh v2 package checksum artifact

* chore: add community provenance UI and event scaffold utility

* docs: finalize community data operations and CI sync policy guidance

* fix: repair validate-site metadata gate after main merge

* fix: resolve main merge conflicts and add required page metadata

* HZZ-FE-002: Refine luxury design system v2 (assets/site.css)

Distinct 5-state trust chips, consistent accessible focus rings, reusable
.panel / .field-* / .opt / .progress-* primitives, sticky compare-table,
unified mobile spacing rhythm, extended reduced-motion coverage.

PDR: docs/pdr/PDR-FE-002-luxury-design-system-v2.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add Claude Design frontend PDRs and tickets

Adds governed PDRs (PDR-FE-000..009), tickets (HZZ-FE-000..009),
Claude Design prompts, and Command Center frontend queue JSON for
the HowieZZ frontend rebuild.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* HZZ-FE-001: Redesign homepage as Concierge Atlas landing

Single clear primary action (Find your match), three parallel buyer paths,
canonical data-driven six-family rail (honest in-development for Classic/Sculpt),
compare-bodies preview at first decision block, concierge closing CTA.
Removed redundant .doors block and duplicate static family-chooser.

PDR: docs/pdr/PDR-FE-001-homepage-concierge-landing.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* HZZ-FE-003: Body compare UX

Non-dead-end empty state (quiz/browse CTAs), selected-body chip strip with
per-body remove + 0-4 counter, two-line plain-language buyer-read & handling
rows, softened gold to atelier-neutral. Reuses FE-002 compare-table primitives.

PDR: docs/pdr/PDR-FE-003-body-compare-ux.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* HZZ-FE-003: Align compare buyer-read & handling to real DB data

Replace hardcoded family/weight maps with lookups into the loaded model
(profiles + families): handling tiers derive from real weight_kg (28-39.9kg
spread, dead >42kg bucket removed), buyer-read cites each body's silhouette/
target_buyer + WHR/BWR vs its family range, surfaces family_confidence wording
(exact/near/loose) and "Estimated dimensions" note. Measurement-led per
docs/body-family-method.md and body-family-copy-guide.md.

PDR: docs/pdr/PDR-FE-003-body-compare-ux.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* HZZ-FE-005: Quiz match results funnel

Ranked top-3 family results with match %, measurement-led "why this matched"
panel citing the winning family's real WHR/BWR ranges + user axis leaning,
copy-guide voice, recommended character cards with per-body WHR/BWR, honest
in-development routing (no dead-ends; nearest active family via the method's
normalized-distance metric), concierge CTAs.

PDR: docs/pdr/PDR-FE-005-quiz-match-results.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* HZZ-FE-007: Browse and family UX

Explicit family/series/character taxonomy explainer; family availability
derived from real characters.json membership (Available / Limited / In
Development) rather than assumed; honest in-development cards for Classic &
Sculpt and a limited-release note for Empress (n=1) instead of empty/dimmed
grids; premium % + target buyer surfaced (measurement-led); concierge CTA
paths from both pages into compare/contact with ?family= context.

PDR: docs/pdr/PDR-FE-007-browse-family-ux.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* HZZ-FE-004: Character detail premium conversion

At-a-glance decision panel (silhouette, premium tier, match confidence, ratios
vs family band), best-for + worth-knowing modules, weight-based handling meter
(real weight_kg over 28-39.9kg), and compare/build-similar/ask-concierge routing
cluster. Self-fetches character_profiles.json; copy synthesized from real data
(positioning/energy/target_buyer); estimated + shoot-pending states stay honest.

PDR: docs/pdr/PDR-FE-004-character-detail-conversion.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* HZZ-FE-006: Concierge intake UX

Private-consultation framing; context summary card adapting to ?id=/?family=/
?b=/compare-handoff routes with WHR/BWR stats + family premium % from DB;
silhouette-family intent field auto-selected from context; trust/discretion
sidebar; made-to-order no-pressure copy; consultation-framed success/error.
18+ consent required, mailto fallback, and PII-free analytics all preserved.

PDR: docs/pdr/PDR-FE-006-concierge-intake.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs: add Claude Design premium intake & buyer-fit package (reference)

Guided intake + live configurator prototypes from Claude Design, with porting
plan into the ZX/site.css stack. Reference material for the contact.html intake
port and the new configurator page.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(intake): port Claude Design guided buyer-fit UX into contact.html

Audience switch (New buyer / Collector) re-tailoring copy depth; six interactive
buyer-fit fields (intended use, timeline, gradient realism scale, handling,
shipping/privacy, customization swatches) writing non-PII hidden inputs to the
existing submit payload; live "Your fit so far" sidebar. Reuses ZX prefill +
family-premium framing; 18+ consent, mailto fallback, and PII-free analytics
preserved. Prototype hex mapped to site.css variables.

PDR: docs/pdr/PDR-FE-006-concierge-intake.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(configurator): port Claude Design live configurator as new page

New configurator.html: parametric SVG silhouette redrawn live from each family's
published WHR/BWR ranges (clamped to the family envelope), realism scale, skin/
hair/eye tinting, concierge tip popouts, live build summary, and a concierge
handoff CTA to contact.html (?family= + non-PII config_summary). Classic & Sculpt
labelled in-development (derived from zero live bodies). Boots via ZX like the
other pages; site.js nav/footer gain a "Configure" link.

PDR: docs/pdr/PDR-FE-006-concierge-intake.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* HZZ-FE-008: Mobile navigation and CTA pass

Off-canvas hamburger drawer below 860px for the 9-link nav (desktop unchanged;
same .links markup so active/focus/scroll-elevation keep working; no-JS safe);
aria-expanded + Esc + scrim + scroll-lock. Hero and concierge/intent action
clusters stack full-width with primary on top; tap targets >=44px. Reduced-motion
disables drawer/scrim animation.

PDR: docs/pdr/PDR-FE-008-mobile-navigation-cta-pass.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* HZZ-FE-009: Visual QA review findings

Auditor pass over all funnel pages (desktop + mobile Chrome screenshots).
Verdict: PASS - 0 blockers, 0 major, 5 minor. Verified missing-image
.monotile fallback, honest Classic/Sculpt in-development states, estimated-
dimension disclosure, 18+/privacy, and the FE-008 mobile drawer. Minor issues
logged as follow-up tickets HZZ-FE-010..013. Screenshots kept local
(gitignored) to avoid the repo image guard.

PDR: docs/pdr/PDR-FE-009-visual-qa-screenshot-review.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(qa): resolve FE-009 minor findings (HZZ-FE-010..013)

- M-1/FE-010: verified browse renders 76 cards (headless screenshot artifact,
  not a bug); add html[data-zx-loaded] CI readiness signal in ZX.load().
- M-2/FE-011: body overflow-x:hidden guard + quiz h1 mobile floor 36->28px.
- M-3/FE-012: footer reconciled to "six silhouette families across four series".
- M-4/FE-013: --muted #9a9a9a -> #ababab for small-label contrast comfort.

PDR: docs/pdr/PDR-FE-009-visual-qa-screenshot-review.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(qa): add reconciliation analysis + live interaction QA evidence

Reconciliation: worktree-agent branches (782b510) are stale ancestors;
fe-design vs feat/pdr-010 merges clean (0 conflicts); only PR #27
(pdr-001-design-system-v2) genuinely diverges. Recommends landing #34 as
canonical design, salvaging #27's competitor-analysis data only.

Live QA (real Chrome CDP @390px): overflow PASS all pages (canScrollX=no),
mobile nav drawer PASS (open/Esc/scrim/close + active link), navToggle 44px.
Closes FE-009 M-2 and M-5 with evidence.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ci): community-data validator tolerates gitignored _local/ provenance refs

The required "Validate site + data + scripts" check hard-failed because
db/community_channels.json cites _local/reference/zelexdoll-theme as a
source_ref, but _local/ is gitignored (machine-local reference material) and
never exists in CI -- so the check blocked every PR off this base. Validate
shape only (not on-disk existence) for _local/ provenance refs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(v2): refresh v2 HTML package after frontend redesign

Regenerate the v2 HTML bundle + manifest/checksums from the updated source
pages (includes new configurator.html). Satisfies the CI "v2 HTML package is
refreshed" guard.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ci): make v2 HTML package deterministic across environments

Remove volatile fields (generated_utc, source_root, destination,
per-file modified_utc) from manifest.json and write all output files
with explicit LF line endings via [IO.File]::WriteAllText. The guard
runs the script and checks git diff — this ensures the committed
artifacts are byte-identical to what CI regenerates on Linux.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): set ErrorActionPreference=Continue in analytics suite script

GitHub Actions pwsh steps default to Stop, which turns Write-Error into
a terminating throw (exit 1) before the explicit exit 2 can run. This
broke the analytics config guardrail check that expects exit code 2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): add ErrorActionPreference=Continue to guardrail steps

GitHub Actions pwsh steps run as pwsh -command ". '{0}'" with
ErrorActionPreference=Stop in the outer context. When the analytics
script subprocess exits with code 2 (non-zero), the outer step throws
before $LASTEXITCODE can be checked. Setting Continue at the top of
the inline run script prevents the non-zero exit code from being
treated as a fatal error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): use [Environment]::Exit(2) for config validation failures

Replace Write-Error+exit 2 with Write-Host+[Environment]::Exit(2) for
all config-validation early-exits. [Environment]::Exit() calls the OS
exit function directly via .NET, bypassing all PowerShell error-handling
machinery and guaranteeing the subprocess reports exit code 2 regardless
of the runner environment. Also adds a diagnostic Write-Host to confirm
the attribute values being compared.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): add exit 0 after successful guardrail checks

Without explicit exit 0, the step ends with $LASTEXITCODE=2 still set
from the subprocess. GitHub Actions' pwsh wrapper treats any non-zero
$LASTEXITCODE at step end as failure and exits with code 1, even though
the check passed. Adding exit 0 explicitly signals success.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants