diff --git a/.impeccable/surfaces/crates-context-src-question-page-rs.md b/.impeccable/surfaces/crates-context-src-question-page-rs.md new file mode 100644 index 000000000..d9748b641 --- /dev/null +++ b/.impeccable/surfaces/crates-context-src-question-page-rs.md @@ -0,0 +1,68 @@ +--- +version: 1 +slug: "crates-context-src-question-page-rs" +primary_target: "crates/context/src/question_page.rs" +related_targets: ["crates/context/src/serve_question.rs"] +--- + +## Scope + +Operate mode: the existing local question picker. Help builders compare the +current hand, choose, steer, or re-roll. Preserve payloads, copy, choices, +confirmation, loading, error handling, and responsive deck behavior. + +## Direction contract + +THESIS: Quiet picker chrome lets the offered directions carry the character. +OWN-WORLD: Inherit impeccable-site's paper-and-instruments proposal: neutral paper, +ink type, patina state text, small gold marks, tactile controls. Use system fonts +and the existing outlined SVG logo; no font files or external font requests. +STORY: Compare the options, inspect details, choose or request another hand. +FIRST VIEWPORT: Small brand at top; readable heading and build-path switch above +the existing card deck; steering and re-roll actions remain reachable below. +FORM: Existing picker structure, user-pinned site theme; no concept roll required. +FINISH: unreviewed and undocumented is unfinished; this build ends with the finish review, the verdict, DESIGN.md, and every shipping raster carrying its provenance + +## Authority + +The user confirmed impeccable-site #34 (head eb5348e48fcd94d0d74895488b985988a401a2e2) +as the light-theme authority, with system fonts for the picker. This is a scoped adaptation, +not a rewrite of the repository's global DESIGN.md. No new raster assets. + +## Built surface + +Recorded from `crates/context/src/question_page.rs`, rendered +`.impeccable/review/after.html`, and the desktop/mobile captures alongside it. +Finish reviewer disposition: **ship**, with no requested fixes. + +- **Paper and ink:** light-only chrome uses neutral paper (`oklch(97.8% 0 0)`), + raised paper (`oklch(99.5% 0 0)`), ink headings (`oklch(13% 0 0)`), and body + text (`oklch(22% 0 0)`). Dark instrument fills carry primary actions and image + controls; gold appears in the logo, lead-card border, and active switch dot. +- **Local palette adaptations:** patina is the site's text-safe deep value + (`oklch(49% 0.11 190)`); faint metadata shares muted ink (`oklch(46% 0 0)`). + Dividers and the build-path switch boundary use ink at 12% opacity; other + control boundaries use 45%. The lead-card outline (including hover) and + active switch dot use default Kinpaku (`oklch(84% 0.19 80.46)`), not deep gold. +- **Explicit font override:** headings, body, and controls use `system-ui, + -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`; metadata uses + `ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace`. Body is 15px/1.55; + headings are 2rem at weight 600, reduced to 1.5rem in portrait; card titles + are 1.125rem at weight 600. The existing wordmark is inline SVG path outlines + with a tight viewBox, displayed at 164 × 30px. No font files are required. +- **Comparison layout:** a 90rem maximum content width shares its inset with + the deck and footer. Landscape uses a horizontal snapping deck; portrait + uses a vertical deck capped at `min(68dvh, 44rem)` with Back/More controls. + The build-path switch moves below the heading in portrait. Footer controls + are sticky in landscape and remain in document flow in portrait. +- **Tactile controls:** cards and dialogs use 8px corners and layered soft + shadows. Actions and the steering field use 6px corners. The build-path + switch has a recessed gray track, a raised active cap, and a gold dot; + re-roll controls share the cap shadow and inset pressed state. Keyboard + focus uses a 2px patina outline. Image zoom, card flips, loading placeholders, + confirmation, and completion/error surfaces retain their existing roles. + +These are picker-local facts, not a replacement global design system. Existing +card badges and dense uppercase metadata are preserved content treatments, +not new typography rules for other surfaces. The user-authorized system fonts +are an intentional local override. No raster assets were created or added. diff --git a/crates/cli/tests/serve_question_security.rs b/crates/cli/tests/serve_question_security.rs index 1a82731da..76eed23bc 100644 --- a/crates/cli/tests/serve_question_security.rs +++ b/crates/cli/tests/serve_question_security.rs @@ -106,6 +106,16 @@ fn detached_posts_require_key_and_loopback_host_origin() { assert!(page.contains("/heartbeat' + keyQ")); assert!(page.contains("/build-path' + keyQ")); + // The picker is self-contained: system fonts and an outlined SVG + // wordmark, with no bundled font routes or external stylesheet. + assert!(!page.contains("@font-face")); + assert!(page.contains("--ks-font: system-ui,")); + assert!(page.contains("aria-label=\"Impeccable\"")); + for path in ["/fonts/albert-sans.woff2", "/fonts/alumni-sans.ttf", "/fonts/%2e%2e/q.json"] { + let (st, _) = raw_request(port, "GET", path, &[], None); + assert_eq!(st, 404, "no font asset routes"); + } + // The build-path flip takes the same gate as /answer. let flip = r#"{"value":"comp"}"#; let (st, _) = raw_request(port, "POST", "/build-path", &[json], Some(flip)); diff --git a/crates/context/src/question_page.rs b/crates/context/src/question_page.rs index 7e1511a96..62199cbd1 100644 --- a/crates/context/src/question_page.rs +++ b/crates/context/src/question_page.rs @@ -1,7 +1,11 @@ //! Generated from skill/scripts/serve-question.mjs `page()` template by scratchpad/gen-page.mjs. //! `@@N@@` marks the N-th `${...}` interpolation (see PAGE_EXPRS), filled by serve_question.rs. +//! Picker theme follows impeccable-site's paper-and-instruments system. +//! Inline logo outlines reuse site/public/assets/brand/impeccable-logo-on-light.svg +//! from impeccable-site at eb5348e48fcd94d0d74895488b985988a401a2e2, with a tight +//! viewBox and theme-aware fills. All remaining typography uses system fonts. -pub const PAGE: &str = "\n\n