Repository navigation
Design system: the phone-first scanner (spec 080, #343) - #360
Draft
plainprogrammer wants to merge 21 commits into
Draft
plainprogrammer wants to merge 21 commits into
plainprogrammer wants to merge 21 commits into
Conversation
Plan section: Phase 0: Preflight (T0.2). Spec 080 at 1.2.2 (approved with the plan), the plan, and the index row. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
T1.1 The three tokens and the band text's contrast Spec 080 FR-1, AC-1.1, AC-1.2 (decisions 3 and 4). Each of tokens.css's three colour blocks gains on-success and on-warning beside their fills and scrim (#66) after danger; tokens.json lists all three. The token spec checks the values and 4.5:1 for each on- token on its fill in every block, and that white on the dark success fill would fail. Red: the six new examples failed (values_at gave [nil, nil], scrim nil, KeyError "on-success"); the can-fail example passed, as planned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T2.1 One home for the probe helpers (a refactor; no behaviour changes) Spec 080 is about to need a third copy of the helpers the two deck specs each define, so they move to DesignSystemProbe (spec/support), which both deck specs now include: theme, add_to_main, evaluate, computed, token and box. Every deleted local body matched the module's, so no local definition was kept. blank_host and the rest stay where they were. A refactor: the two deck specs ran 71 examples, 0 failures before the move and 71 examples, 0 failures after it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…educed motion (#343) T2.2 The reduced-motion helper, the block and AC-6.4 Spec 080 FR-7, AC-6.4 (decision 14). additions.css ends with one block under prefers-reduced-motion: reduce that removes transitions and animations from every element, ::before, ::after and ::backdrop, with !important (the stylesheets' only use, said in the block's comment). The .c-scanner * rule stays as it is. ReducedMotion (spec/support, included in system specs) applies the stylesheets' reduced-motion rules to the page as an adopted sheet, since headless Firefox reports no preference. The new system spec file proves a c-btn's 120ms and a c-tile__media's 150ms transitions run without the rules and stop with them; it also holds the in_viewport helper the later phases use. The files spec checks that !important is used only in the last spec 080 block and that the block is last. Red: the system example raised `no reduced-motion rule matches ["::backdrop"] (found [".c-scanner *"])` after its two pre-preference expectations (0.12s; 0.15s, 0.15s) had passed; the files example got 0 for the !important count and nil for blocks.last. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T3.1 ScanMarkup The markup of the status band, the sheet, the one-screen shell and the selection pane, written once for the examples, the previews and Scanner.md (spec 080 decision 8). It is test-support markup with no view behind it, so no example drives it red: as the plan says, the examples of T3.2 on are its proof. Verified here by `ruby -c` (Syntax OK), RuboCop (no offenses), YARD on the file alone (100% documented, no warnings), the comment ratchet (all added public objects commented), and a plain-Ruby script that called band, pane (three panels, all but the centred one hidden, a relabelled foil button), shell with a result, sheet (open) and bottom_bar (reading, no torch) and checked their output. Taken from the plan's block as written; no deviation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T3.2 c-band c-band with c-band--success and c-band--warning (spec 080 FR-2, AC-1.3 to AC-1.5), inserted above the reduced-motion block, which stays last. The examples and the CSS are the plan's blocks as written. Red, before the CSS: 4 of 6 examples failed for the missing rules (a transparent ground and the ink colour in both themes, 16px/normal/400 with no padding, the svg at its intrinsic size with stroke 1.5, the 360px band unwrapped by any grid: 409px high). "tells the three forms apart" passed on arrival: it reads ScanMarkup's markup, not the CSS, so it is a characterisation of the three forms' icons and words. The reduced-motion example was already green. Green: the scanner components spec, design_system_files_spec and design_system_tokens_spec, 27 examples, 0 failures. RuboCop clean. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ly the screen (#343) T4.1 `c-shell--focused` (Phase 4: The focused shell and the sheet). Red before the rule: inside a 390 x 844 frame the document was [375, 844] (a classic scrollbar), the body's margin-top, margin-left and min-height were 8px 8px 844px, and the document scrolled. The class removes the margin and the minimum height; every later in_viewport example relies on it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
T4.2 `c-sheet` (Phase 4: The focused shell and the sheet). Red before the block, all 9 sheet examples: the browser's own dialog (bottom at 568px, 3px border, no radius, Close 50 x 36 with a 16px icon, title 24px/700, body not scrolling, overscroll auto, animation none 0s), no `.c-sheet::backdrop` rule (rule_value nil), no `.c-sheet__foot a:hover` rule, the foot at 16px/normal in black, the link at the browser's blue with an auto outline, and the sheet overflowing sideways at 360px. Green with the plan's CSS unchanged. Headless Firefox reports the backdrop's computed colour, rgba(0, 0, 0, 0.4) in both themes, so the AC-2.1 example also expects `getComputedStyle(dialog, "::backdrop")` to equal the scrim token (as the plan's Risks note asks); with the backdrop rule removed it reads the browser's rgba(0, 0, 0, 0.1) and fails. Ruling: added the computed `::backdrop` expectation beside the rule read — the plan says to add it when the browser reports it — if another browser reports none, only the rule read is portable and the expectation is Firefox-specific. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
T5.1 `c-scan` (Phase 5: The shell). Adds the Scan shell block to additions.css, directly above the app-wide reduced-motion block: a size container named `scan`, as tall as the dynamic viewport, with a 56px top bar (Back, the destination, Done), the stage in surface-sunken with the covering video, the guide and the two lines over the camera, and a 96px bottom bar (count, main button, torch). Thirteen system examples prove AC-3.1 to AC-3.9. Red: all 13 examples failed against the missing CSS (the unstyled shell scrolled the frame, so in_viewport's size check read 375 and 345 wide; the bars' controls were 36px, the main button 14px, the torch icon 16px at stroke 2, the count in Plex Sans). "Scrolls by the body's margin without c-shell--focused" failed on arrival too, as the plan allowed; it passes with the rule. Ruling: two exact edges compared within 0.5px (Done's right edge at 352, Undo's 1px inset from the after-add line's right) — the rows hold text of fractional width, so Firefox lays them out at 352.0000153 and 1.0000153 — cost if wrong: a sub-pixel drift would pass, which no criterion cares about. The CSS is the plan's draft, unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…creen rule (#343) T6.1 `c-scanpane` and the capture strip (plan, Phase 6: The selection pane; spec 080 FR-5, AC-4.1 to AC-4.11). Adds the Scan pane block above the reduced-motion block: the capture strip, the pane with its band, image row, Previous and Next, one details block and the add buttons, its own `[hidden]` rule (decision 8), the two 200ms keyframes and the short-screen container query. The reduced-motion block now holds `.c-scanpane__row { scroll-behavior:auto; }` (FR-7), so its comment is true; no new `!important`. Red: 18 of the 19 new examples failed against the missing CSS (no strip or pane displayed; `apply_reduced_motion_rules` raised `no reduced-motion rule matches [".c-scanpane__row"]`; the hidden-button example failed for the pane only). "shows only the centred card's panel" passed on arrival, a characterisation: the browser's own `[hidden]` rule and the shell's hide the other panels. Green: 19 of 19, the files spec still passes. Measured (headless Firefox): 390 x 844 pane 548, band 40, image 288, addsGap 16, no scroll; row image 206.2 wide, padding 91.9, 79.9 of each neighbour, gap 12, no scrollbar, first and last centre at 195. 390 x 664 strip 96, picture 76, image 184. 360 x 640 image 160, no scroll; with the two-line band 56, image 160, scrolls. 360 x 560 scrolls. AC-4.11: two 160 x 52 buttons, the long label on 2 lines, fits. No deviation from the plan's draft: no Risks fallback was needed (the row's end padding counts as scrollable, the container-query units in the grid item resolve against the track, the AC-4.9 heights are 56 and 44 as drafted). The fractional row sizes were already `be_within` in the plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tay in blocks of their own (#343) T6.2 The blocks' guard (AC-6.2) (plan, Phase 6: The selection pane). A guard over what Phases 2 to 6 wrote: the six spec 080 blocks are StatusBand, Focused shell, Sheet, Scan shell, Scan pane and Reduced motion, app-wide, in that order; with comments stripped, none holds a colour literal, and every font declaration uses a `--font-` token (or `font:inherit`). It passed on arrival, so it was shown to fail by three mutations of the committed additions.css in the working tree, each restored with `git checkout -- app/assets/stylesheets/collector/additions.css`: - `color:#fff;` added to `.c-band`: FAIL (the StatusBand block listed); - `font-family:serif;` added to `.c-scanpane__name`: FAIL (`["font-family:serif"]`); - the heading "Scan pane (spec 080)" renamed "Pane (spec 080)": FAIL (the block names differ). Runs: the scanner components, files, tokens and both deck design-system specs, 141 examples, 0 failures; spec/system/scanner*_spec.rb, 51 examples, 0 failures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…atus band in the README (#343) Plan task: T7.1 README (Phase 7: The documents). Satisfies AC-5.1 to AC-5.4 and AC-5.11 by reading. - Color: the status band, the one filled use of a status colour, with on-success and on-warning; danger is never a fill; scrim is a sheet's backdrop and nothing else. - Motion: a new section after States (200ms at most, instant under reduced motion, one app-wide block, the browser's smooth scroll). - Mobile and Hotwire: focused pages and c-shell--focused, the content notice in a one-screen focused page's sheets (not used by a page yet), sheets as the one exception to "Nothing needs JavaScript", swipes. - Components: StatusBand and Sheet in the current set; the spec 080 App additions line with the classes and the three tokens. - Iconography: the band's 16px icons, the star at 14px, the 20px icons at stroke 1.5. Ruling: the Sheets bullet adds "which keeps that state" — AC-5.1 asks that a sheet keeps the page's state where a navigation would lose it, and the plan's draft only implied it — cost if wrong: four words to drop. Ruling: the Touch bullet's list says "and the rules drawn for the phone-first scanner's shell and pane and a sheet's Close (spec 080; no page uses them yet)" in place of the plan's bare list entry — the list names pages, and FR-6 forbids describing these parts as live — cost if wrong: the wording is longer than it needs to be. Ruling: the App additions line also names the sub-parts the CSS has (__dest-label, __dest-value, __dest-text, __line--status, __line--added, __line-text, __read-label, __read-name, __read-line, __nav--prev, __nav--next) — the line lists the classes that were built, and the plan's list stopped at the elements — cost if wrong: a longer line. Ruling: Iconography says the 20px icons sit "inside controls, where the component sets the 1.5 (back from the 2 a c-btn gives its icons, for those in a c-btn)" in place of "inside buttons" — the back arrow and the destination are not c-btn, and their CSS sets the 1.5 itself — cost if wrong: none; the sizes and strokes are the plan's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plan task: T7.2 StatusBand.md and Sheet.md (Phase 7: The documents).
Satisfies AC-1.6 and AC-2.6 by reading.
Collectible check: `grep -niwE "cards?|magic|mtg|foil|printings?|set|mana|
scryfall|gathering|deck|collector line|artwork"` over both files finds
nothing in Sheet.md but the CSS word "set" ("never set display"), and in
StatusBand.md only the scanner's sentences: in the first-use bullet and in
the Markup example, which says it is shown with its first use's sentences.
Ruling: StatusBand.md's Markup shows the three icons in full from
ScanMarkup.icon in place of the plan's "…the alert triangle…" and "…a
question mark in a circle…" — the brief takes the documents' markup from
ScanMarkup, so the document, the examples and the previews agree — cost
if wrong: two long lines.
Ruling: StatusBand.md's Markup line adds "Shown with sentences of its
first use (the scanner's, below)." — the example's sentences say "card"
and "Printing", and decision 9 allows a scanner part only as "first used
by" — cost if wrong: one sentence to drop.
Ruling: StatusBand.md says the markup keeps stroke-width="1.5" and the
band's CSS sets the 2 — the markup and the stated stroke would otherwise
look contradictory (README Iconography) — cost if wrong: none.
Ruling: the first-use bullets of both documents add "no view renders a
band yet" / "no view renders a sheet yet", and StatusBand's names its
preview — FR-6 Must not (nothing described as live before #344/#345) —
cost if wrong: none.
Ruling: Sheet.md's foot bullet adds the foot's place ("the last thing in
its body"), the 16px line height, the link's hover underline and focus
ring, and decision 13's "such a page has a sheet or keeps the footer, and
a focused page that scrolls keeps the footer"; the backdrop bullet adds
decision 4's "no dimming" fallback; the Close bullet adds stroke 1.5 and
44 × 44px; the scroll and inset are named by their CSS — each matches
AC-2.6/AC-2.7 and the built CSS — cost if wrong: longer bullets.
Ruling: the backdrop tap is phrased "the tap on the backdrop is closed by
the page's script, which is #344's and not built yet" — AC-2.6's clause
in its own words — cost if wrong: none.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e scanner as built (#343) Plan task: T7.3 Scanner.md (Phase 7: The documents). Satisfies AC-5.5 to AC-5.7 by reading (decision 1). The as-built text is unchanged: the section after "## As built, until #344 and #345" and its blank line was diffed against `git show HEAD~:docs/design-system/components/Scanner.md | tail -n +3` (the old body from "The card scanner (spec 007): …" to its last bullet, 38 lines) with `diff`, which printed nothing; `git diff` of the file has 106 insertions and no deletion. Ruling: the first section's summary adds "Nothing here is live yet: no view renders these parts, and the scanner works as the second section says until #344 and #345 merge." — FR-6 Must not — cost if wrong: one sentence. Ruling: a second, short Markup block shows the two lines over the camera while aiming and after an add (from ScanMarkup.lines), with a sentence on the shell without a result — AC-5.5 asks for the status line's and the after-add line's markup, and in the result-state block both are hidden and empty — cost if wrong: a few lines. Ruling: the capture is `<canvas class="c-scan__capture">` and an image an `<img>` inside the `li`, as the plan directs for a document, where ScanMarkup writes a `div` and an empty `li` for the previews' captions; the CSS (object-fit on both) serves either — cost if wrong: #344 picks the element it draws into. Ruling: the strip's short form answers to "the shell (on a phone, the screen)" being under 720px high, in place of "the screen" — the CSS is a container query on c-scan (decision 7) — cost if wrong: none. Ruling: the row's bullet cites "(design decision 17)" and the band's "(design decision 14)"; the state bullet names `.c-scan [hidden]` and `.c-scanpane [hidden]`; the strip's name "ending in an ellipsis" — AC-5.7 names those design decisions, and the rest matches the built CSS — cost if wrong: none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, the sheets and the status band (#343) T8.1 Write the four files from ScanMarkup (spec 080 Phase 8; AC-5.8, AC-5.10). Written by the plan's drafted generator, unchanged, from spec/support/scan_markup.rb; the generator stays in the session scratchpad as the plan says. Each file links preview-fonts.css, tokens.css, components.css and additions.css and nothing else, its own <style> holds only .pv frames and captions, it honours ?theme=dark, and it has no <img>, no set symbol and no mana symbol. Ruling: the commit subject is the plan's T8.2 subject, given to the previews' own commit, and the shots take a commit of their own — one commit per task — cost if wrong: one subject to reword. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…343) T8.2 Open them, look, and keep the shots (spec 080 Phase 8; AC-5.9). Each preview was served over a local static server and opened in headless Firefox (classic scrollbars) at a window wide enough for its frames (2200, 1400, 1000, 1400 px), in light (data-theme set explicitly) and dark (?theme=dark, read as "dark" on load). For all eight loads: the four stylesheets' rule counts are 4, 15, 185 and 395; a second run of the inline script returned no error; every frame has scrollWidth <= clientWidth; every .c-scan is 844px and every capture strip 144px; each centred card sits 0px off the row's centre. The unsure sentence's band is 40px (one line) at 390px and 56px (two lines) at 360px. Ruling: the shots are full-page screenshots at 1x, shrunk only when wider than 1600px ("-resize 1600x>" rather than the plan's "1600x"), so the narrower pages are not enlarged — cost if wrong: re-run magick. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Phase 9: Verification, checks, review (T9.1, T9.2). The record of spec 080 (1.2.2): the bin/ci run at bc21f9c (passed in 8m36.12s; RSpec 4671 examples, 0 failures, 1 pending, against a baseline of 4614), the scanner components spec's describes against the criteria, the red runs and measurements as the implementers reported them, the token and document criteria with their quotations, the previews and their shots, the unchanged scanner's diffs, every ruling with its commit, and the observations. The implementation review (T9.3) and the final visual review (T9.4) are pending. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ks (#343) Phase 9: Verification, checks, review (T9.3, review fixes). Answers the implementation review's finding that decision 15 ("each new rule that sets a size sets box-sizing:border-box") did not hold on eight rules, and that nothing guarded it. A new example in spec/design_system_files_spec.rb reads each rule of the spec 080 blocks on its own and fails when it sets width, height or a min-/max- of either to a value with a digit (not a bare 0) without box-sizing:border-box. Red before the CSS change, on twelve rules: .c-band svg | .c-sheet__close svg | .c-scan__back svg, .c-scan__dest svg, .c-scan__torch svg | .c-scan__dest-value | .c-scan__video | .c-scan__line--status | .c-scanpane__item img | .c-scanpane__nav svg | .c-scanpane__meta | .c-scanpane__add .c-btn svg | .c-scan__strip and .c-scan__capture (the short-screen container query). Ruling: no exemption for a rule that gets border-box from another rule on the same element (.c-scan__line--status, the container query's two) — adding the declaration is one word and makes the decision hold literally, so the guard stays simple — cost if wrong: a redundant declaration on three rules. Ruling: min-/max-width count as sizes, which adds .c-scan__dest-value (max-width:100%) to the review's list — decision 15 says "a size", not which property — cost if wrong: one redundant declaration. None of the twelve has padding or a border, or already had border-box, so no rendered size changes: the four spec 080 previews, screenshotted at 1280px and 390px in both themes before and after, differ by 0 pixels (ImageMagick compare -metric AE). No pre-spec-080 rule changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#343) Phase 9: Verification, checks, review (T9.3, review fixes). Answers the implementation review's two comment findings. - spec/support/design_system_probe.rb: the header told its history ("Written twice before it was moved here, with a third copy due"), which .claude/rules/code-documentation.md forbids. It now says why the module exists: the one home of the probes that example groups proving the design system's CSS include. - spec/support/scan_markup.rb: the header said the previews "are written from these strings" and that "a script can require this file by path", but no script is committed. It now says the four previews were generated once from these strings and are edited by hand, so a change here doesn't reach them, and names the one by-path use that exists (`ruby -r ./spec/support/scan_markup.rb`, plan Phase 7, the documents' markup). Ruling: the preview generator stays uncommitted — the plan (T8.1, "The script below is a scratchpad file, not committed") decided it, no other preview under docs/design-system/previews has a generator in script/, and the plan keeps the script's text — cost if wrong: a later change to the markup is copied into the previews by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#343) Phase 9: Verification, checks, review (T9.3, review fixes). Answers the implementation review's finding that AC-1.3, AC-2.1, AC-2.4, AC-3.3, AC-3.4, AC-3.7, AC-4.1, AC-4.4 and AC-4.6 were only partly proved in spec/system/design_system_scanner_components_spec.rb. Added, to existing examples or in four new ones (52 examples, was 48): - AC-1.3: the band's font-family is --font-sans; the warning band's icon is --on-warning (both themes). - AC-2.1: the sheet's four corners (--radius-md, --radius-md, 0, 0) and position fixed (both themes). - AC-2.4 (new): a sheet read straight after close() has display none, no animation name, a 0s transition and no running animation. - AC-3.3 (new): Done is as wide with a long value as with a short one, and the chevron starts where the value's text ends or later. - AC-3.4: the count's number is 13px/18px and sits above "added". - AC-3.7 (new, both themes): the after-add line's four corners are --radius-md and its text is --ink. - AC-4.1: the name read is --ink. - AC-4.4: every side of Previous and Next is 1px solid --line-strong. - AC-4.6: the star starts left of the foil button's words. Each held on arrival. Mutations, each applied to the working tree and then restored with git checkout (additions.css; components.css for M11): - M1 .c-band font --font-sans -> --font-mono: AC-1.3 got "IBM Plex Mono, ui-monospace, monospace" (light and dark). - M2 added `.c-band--warning svg { color:var(--ink) }`: AC-1.3 got rgb(31, 29, 26) for the warning icon (light), rgb(239, 233, 222) (dark). - M3 sheet radius on all four corners, M4 position absolute: AC-2.1 got ["8px", "8px", "8px", "8px", "absolute"] (both themes). - M5 added `.c-sheet:not([open]) { animation:c-sheet-rise .2s reverse }`: AC-2.4 got ["none", "c-sheet-rise", "0s", 0]. - M6 dropped Done's flex:none: AC-3.3 got width 52.4 against 67.6. - M7 row-reverse on .c-scan__dest-value: AC-3.3 chevron check false. - M8 count number 15px and the count's flex-direction row: AC-3.4 got ["15px", "18px"], and the number's bottom 805.5 against 788.5. - M9 .c-scan__line radius-sm and ink-muted: the new AC-3.7 examples got 4px corners and rgb(95, 90, 82) / rgb(170, 162, 152). - M10 read name ink-muted: AC-4.1 got rgb(95, 90, 82). - M11 .c-btn--secondary border-color --line: AC-4.4 got rgb(212, 203, 186) against rgb(140, 131, 116). - M12 row-reverse on the add button: AC-4.6 star check false. Ruling: AC-2.4's "instant" is read straight after close() in the same script (display, animation name, transition duration, running animations), not by waiting — a close animation or a display transition with allow-discrete changes one of the four at that moment, and no sleep is needed — cost if wrong: a close effect done by script, not CSS, would pass; this spec draws CSS only. Ruling: radii are compared with --radius-md as the root declares it (custom helper), not a literal 8px — the criterion names the token — cost if wrong: none beyond one more script call per example. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plan section: Phase 9: Verification, checks, review (T9.2, T9.3). Two Mode B rounds: round 1 DRIFT DETECTED (box-sizing, two comments, nine partly proved criteria), fixed in c68d3bc, 20947c3 and f1dad84; round 2 SPEC-ALIGNED. bin/ci green at f1dad84: 4676 examples, 0 failures, 1 pending. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #343.
Spec 080 adds the design system's parts for the phone-first scanner before any view is built:
on-success,on-warningandscrimc-bandc-sheet, a native<dialog>opened as a modalc-scan, withc-shell--focusedon the page's<body>c-scanpane, with the capture strip and the short-screen ruleadditions.cssThe README rules,
StatusBand.md,Sheet.mdandScanner.mddocument them, and four previews draw them at 390 × 844 in both themes.What a shipped page sees. No view, script, controller, model or helper changes, and the scanner as built is untouched. The one change a shipped page sees: under
prefers-reduced-motion: reduce, transitions and animations stop across the app (decision 14).How it is proved. Every CSS and layout criterion has an example in headless Firefox (
spec/system/design_system_scanner_components_spec.rb, 52 examples). Each example failed before its rule existed, or was shown to fail by breaking the CSS on purpose. The tokens' contrast and the new blocks' rules each have a guard: no colour literal, no!importantoutside the reduced-motion block, andbox-sizingon every sized rule. The document criteria are verified by reading and quoted inverification.md.verification.mdare all indocs/specs/080-phone-first-scanner-components/.bin/cipassed atf1dad843: 4676 examples, 0 failures, 1 pending (the baseline was 4614).c68d3bc9,20947c32andf1dad843.For #344 to consider: in the dark theme, the guide's inner dashed line can't be seen against an empty stage. It is the shipped guide's rule, and over a real camera picture it shows.
Previews
The previews use blank placeholder images and static markup, with no card art and no catalog data. The sample copy is the mock-ups'.
ScannerFlow: the five steps
ScannerConfidence: the three confidence states
Sheet: the destination sheet and the sitting's list, with the content notice in their foot. These are drawn with the
openattribute, so there is no backdrop.StatusBand: every form and sentence, at 390px and 360px
🤖 Generated with Claude Code