{ "schemaVersion": 2, "generatedAt": "2026-09-02T00:00:00Z", "title": "Design System: Movement", "extensions": { "colorMeta": { "stock": { "role": "neutral", "displayName": "Acid Stock", "canonical": "#f0e34a", "tonalRamp": ["#2b2707", "#4a4110", "#6b5f14", "#8d7d1c", "#b09c24", "#d0ba33", "#f0e34a", "#faf3ae"] }, "bone": { "role": "neutral", "displayName": "Bone", "canonical": "#f7f4e6", "tonalRamp": ["#2a281f", "#454236", "#615d4e", "#7f7a68", "#9e9884", "#c0baa4", "#dfd9c5", "#f7f4e6"] }, "ink": { "role": "neutral", "displayName": "Press Ink", "canonical": "#17140f", "tonalRamp": ["#17140f", "#2e291f", "#4a4437", "#6a6455", "#8b8574", "#aea896", "#d2ccba", "#f0ece0"] }, "blue": { "role": "primary", "displayName": "Ultramarine Ink", "canonical": "#1b2a8f", "tonalRamp": ["#0a0f36", "#101857", "#121d68", "#1b2a8f", "#2b3db5", "#5566d0", "#8f9ce5", "#ccd2f5"] }, "blue-strong": { "role": "primary", "displayName": "Ultramarine Deepened", "canonical": "#121d68", "tonalRamp": ["#080c2c", "#0c1244", "#121d68", "#1b2a8f", "#2b3db5", "#5566d0", "#8f9ce5", "#ccd2f5"] }, "cyan": { "role": "primary", "displayName": "Press Cyan (second ink, multiply only)", "canonical": "#14a0c8", "tonalRamp": ["#052a35", "#08414f", "#0a5a6f", "#0f7b96", "#14a0c8", "#3fbcdd", "#7fd4ea", "#c2ecf7"] }, "overprint": { "role": "secondary", "displayName": "Overprint Green (cyan multiplied into yellow stock)", "canonical": "#2f6b46", "tonalRamp": ["#0d2016", "#153322", "#1f5334", "#2f6b46", "#43895c", "#6dab82", "#a1cbaf", "#d5e8dc"] }, "dim-on-stock": { "role": "neutral", "displayName": "Thinned Ink on Stock", "canonical": "#6b5f14", "tonalRamp": ["#231f06", "#3b340a", "#524810", "#6b5f14", "#8d7d1c", "#b09c24", "#d0ba33", "#f0e34a"] }, "dim-on-bone": { "role": "neutral", "displayName": "Thinned Ink on Bone", "canonical": "#6a6455", "tonalRamp": ["#211f1a", "#37342c", "#4f4b3f", "#6a6455", "#8b8574", "#aea896", "#d2ccba", "#f0ece0"] }, "negative-fg": { "role": "tertiary", "displayName": "Refusal Red", "canonical": "#8e2417", "tonalRamp": ["#2c0b07", "#4a120c", "#6c1b11", "#8e2417", "#b23a2a", "#cf6d5e", "#e6a79c", "#f6dcd7"] } }, "typographyMeta": { "shout": { "displayName": "Shout", "purpose": "The first-viewport headline only. Uppercase, capped at 15ch, balanced wrap, crossed by the cyan overprint band." }, "headline": { "displayName": "Headline", "purpose": "Receipt marks, ledger title, tab words, the torn stub's word." }, "title": { "displayName": "Title", "purpose": "The slip heading above a form." }, "body": { "displayName": "Body", "purpose": "The bill's two-column argument." }, "reply": { "displayName": "Reply", "purpose": "The stance sheet's answer, max 68ch; first paragraph steps up to 1.15em." }, "label": { "displayName": "Label", "purpose": "Field labels, tab addresses, status lines, table column heads." }, "stamp": { "displayName": "Stamp", "purpose": "Button lettering only: uppercase, 0.14em tracking." } }, "shadows": [ { "name": "tab-lift", "value": "0 10px 30px rgba(23, 20, 15, 0.32)", "purpose": "The only shadow in the system: a tear-off tab lifting off the wall on hover/focus. Offset and blur, because that is what a real shadow has. Suppressed below 46rem and under prefers-reduced-motion." } ], "motion": [ { "name": "tab-lift-ease", "value": "260ms cubic-bezier(0.16, 1, 0.3, 1)", "purpose": "Transform and shadow on the tear-off tab. The only expressive motion in the build." }, { "name": "stamp-ease", "value": "160ms ease-out", "purpose": "Background deepening on the stamp button's hover." } ], "breakpoints": [ { "name": "stack", "value": "46rem", "purpose": "Below: the argument drops to one column and the tear strip stacks with horizontal dashed dividers; tab lift is replaced by a bone tint." }, { "name": "split", "value": "60rem", "purpose": "Below: the stance sheet's reply/slip grid stacks to one column." }, { "name": "full-bleed", "value": "46rem wide and 40rem tall", "purpose": "At or above both: the bill fills 100svh so the tear strip lands near the fold." } ], "textures": [ { "name": "halftone-stock", "value": "inline SVG dot screen, 6px tile, r=0.65, ink at 13% opacity", "purpose": "Paper grain on the acid stock. Authored dot screen, never a raster texture." }, { "name": "halftone-bone", "value": "inline SVG dot screen, 6px tile, r=0.6, ink at 7% opacity", "purpose": "Paper grain on the bone reading surface." } ] }, "components": [ { "name": "Stamp (primary button)", "kind": "button", "refersTo": "stamp", "description": "The primary action on every form surface: a blue block with the second ink struck across its face.", "html": "", "css": ".ds-stamp { position: relative; overflow: hidden; font-family: \"Public Sans\", ui-sans-serif, system-ui, sans-serif; font-weight: 700; font-size: 0.875rem; letter-spacing: 0.14em; text-transform: uppercase; color: #f0e34a; background: #1b2a8f; border: 0; border-radius: 0; padding: 0.85rem 1.75rem; cursor: pointer; transition: background 160ms ease-out; } .ds-stamp::after { content: \"\"; position: absolute; left: 1.15rem; right: 1.15rem; top: 56%; height: 7px; background: #14a0c8; mix-blend-mode: multiply; transform: translateY(1px); pointer-events: none; } .ds-stamp:hover:not(:disabled) { background: #121d68; } .ds-stamp:focus-visible { outline: 3px solid #1b2a8f; outline-offset: 2px; }" }, { "name": "Stamp, disabled", "kind": "button", "refersTo": "stamp-disabled", "description": "An unstruck stamp: the ground drops out to a dashed outline and the cyan strike is removed. Used until the proof-of-work module enables the form.", "html": "", "css": ".ds-stamp-disabled { font-family: \"Public Sans\", ui-sans-serif, system-ui, sans-serif; font-weight: 700; font-size: 0.875rem; letter-spacing: 0.14em; text-transform: uppercase; background: transparent; color: #6a6455; border: 2px dashed rgba(23, 20, 15, 0.55); border-radius: 0; padding: 0.85rem 1.75rem; cursor: not-allowed; }" }, { "name": "Tear-off Tab", "kind": "custom", "refersTo": "tab", "description": "The signature component and the primary action of the first surface: equal tabs hanging off a perforation, each carrying its own address. Never numbered.", "html": "
Scepticalmovement.bdj.oncarlos.com/scepticalCuriousmovement.bdj.oncarlos.com/curiousAll inmovement.bdj.oncarlos.com/all-in
", "css": ".ds-tear-perf { height: 2px; background-image: repeating-linear-gradient(to right, #17140f 0 7px, transparent 7px 14px); } .ds-tear-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; border-bottom: 2px solid #17140f; } .ds-tab { display: flex; flex-direction: column; gap: 0.5rem; min-height: 6.5rem; padding: 0.9rem 1.1rem 1rem; background: #f0e34a; color: #17140f; text-decoration: none; border-right: 2px dashed #17140f; transform-origin: top center; transition: transform 260ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow 260ms cubic-bezier(0.16, 1, 0.3, 1); } .ds-tab:last-child { border-right: 0; } .ds-tab:hover, .ds-tab:focus-visible { transform: translateY(-10px); box-shadow: 0 10px 30px rgba(23, 20, 15, 0.32); z-index: 1; } .ds-tab-word { font-family: \"Big Shoulders\", Haettenschweiler, \"Arial Narrow\", sans-serif; font-weight: 800; text-transform: uppercase; font-size: 2.75rem; line-height: 0.92; letter-spacing: -0.01em; } .ds-tab-addr { font-size: 0.8125rem; font-weight: 700; color: #1b2a8f; overflow-wrap: anywhere; }" }, { "name": "Ruled Field", "kind": "input", "refersTo": "field-input", "description": "A ruled line on paper, not a box on a screen. Label above in tracked bold; 2px ink underline; square focus registration mark.", "html": "", "css": ".ds-field { display: block; margin-bottom: 1.35rem; font-family: \"Public Sans\", ui-sans-serif, system-ui, sans-serif; } .ds-field > span { display: block; font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.06em; margin-bottom: 0.35rem; color: #17140f; } .ds-field input { width: 100%; box-sizing: border-box; font: inherit; color: #17140f; background: transparent; border: 0; border-bottom: 2px solid #17140f; border-radius: 0; padding: 0.45rem 0; } .ds-field input::placeholder { color: #6a6455; } .ds-field input:focus-visible { outline: 3px solid #1b2a8f; outline-offset: 2px; }" }, { "name": "Tinted Textarea", "kind": "input", "refersTo": "field-textarea", "description": "The one field variation: a faint ink tint that shows the field's extent. The tint is not a fill and never becomes a card.", "html": "", "css": ".ds-field-area { display: block; margin-bottom: 1.35rem; font-family: \"Public Sans\", ui-sans-serif, system-ui, sans-serif; } .ds-field-area > span { display: block; font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.06em; margin-bottom: 0.35rem; color: #17140f; } .ds-field-area textarea { width: 100%; box-sizing: border-box; font: inherit; line-height: 1.5; color: #17140f; background: rgba(23, 20, 15, 0.05); border: 0; border-bottom: 2px solid #17140f; border-radius: 0; padding: 0.55rem 0.7rem; min-height: 7.5rem; resize: vertical; } .ds-field-area textarea:focus-visible { outline: 3px solid #1b2a8f; outline-offset: 2px; }" }, { "name": "Shout with Overprint Band", "kind": "custom", "refersTo": "shout", "description": "The first-viewport headline in condensed caps, crossed by the second ink multiplied into the stock and offset 2px off true.", "html": "

Software is being handed to machines. Decide where you stand.

", "css": ".ds-stock { background-color: #f0e34a; background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Ccircle cx='1' cy='1' r='0.65' fill='%2317140f' fill-opacity='0.13'/%3E%3Ccircle cx='4' cy='4' r='0.65' fill='%2317140f' fill-opacity='0.13'/%3E%3C/svg%3E\"); padding: 2rem; overflow: hidden; } .ds-shout { position: relative; font-family: \"Big Shoulders\", Haettenschweiler, \"Arial Narrow\", sans-serif; font-weight: 800; text-transform: uppercase; color: #1b2a8f; font-size: clamp(2.5rem, 9vw, 6rem); line-height: 0.84; letter-spacing: -0.02em; margin: 0; max-width: 15ch; text-wrap: balance; } .ds-shout::after { content: \"\"; position: absolute; left: -100vw; right: -100vw; top: 46%; height: 0.26em; background: #14a0c8; mix-blend-mode: multiply; transform: translateY(2px); z-index: 1; pointer-events: none; }" }, { "name": "Torn Stub", "kind": "card", "refersTo": "tab", "description": "The tab you tore off, carried onto the stance sheet. Its lower edge is ragged because that is where the perforation gave. The word is the heading; nothing labels it.", "html": "

Sceptical

", "css": ".ds-torn { background: #f0e34a; width: fit-content; max-width: 100%; padding: 0.9rem 1.4rem 1.5rem; clip-path: polygon(0 0, 100% 0, 100% calc(100% - 9px), 96% 100%, 92% calc(100% - 7px), 88% 100%, 84% calc(100% - 8px), 80% 100%, 76% calc(100% - 6px), 72% 100%, 68% calc(100% - 9px), 64% 100%, 60% calc(100% - 7px), 56% 100%, 52% calc(100% - 8px), 48% 100%, 44% calc(100% - 6px), 40% 100%, 36% calc(100% - 9px), 32% 100%, 28% calc(100% - 7px), 24% 100%, 20% calc(100% - 8px), 16% 100%, 12% calc(100% - 6px), 8% 100%, 4% calc(100% - 9px), 0 100%); } .ds-torn-word { font-family: \"Big Shoulders\", Haettenschweiler, \"Arial Narrow\", sans-serif; font-weight: 800; text-transform: uppercase; font-size: 2.75rem; line-height: 0.9; color: #17140f; margin: 0; }" }, { "name": "Receipt", "kind": "card", "refersTo": "notice-negative", "description": "The terminal surface for every send, confirm, dead link and sign-in: a bone block between two ink rules with a cyan mark struck across the top rule.", "html": "

Check your inbox

We sent one message to the address you gave. Open it and confirm.

", "css": ".ds-receipt { position: relative; max-width: 46rem; margin: 0 auto; padding: 3rem 2.5rem; border-top: 2px solid #17140f; border-bottom: 2px solid #17140f; background: #f7f4e6; font-family: \"Public Sans\", ui-sans-serif, system-ui, sans-serif; color: #17140f; } .ds-receipt::before { content: \"\"; position: absolute; top: -3px; left: 2.5rem; width: 9rem; height: 8px; background: #14a0c8; mix-blend-mode: multiply; } .ds-receipt-mark { font-family: \"Big Shoulders\", Haettenschweiler, \"Arial Narrow\", sans-serif; font-weight: 800; text-transform: uppercase; font-size: 3rem; line-height: 0.92; color: #1b2a8f; margin: 0 0 0.85rem; } .ds-receipt p { margin: 0; font-size: 1.0625rem; line-height: 1.6; }" }, { "name": "Ledger Table", "kind": "custom", "refersTo": "body", "description": "The admin tally in the same hand: 2px ink head rule, 1px row rules, tracked uppercase column heads, tabular numerals.", "html": "
EmailStanceWhen
ada@example.comSceptical2026-09-01
grace@example.comCurious2026-09-02
", "css": ".ds-ledger { width: 100%; border-collapse: collapse; font-family: \"Public Sans\", ui-sans-serif, system-ui, sans-serif; font-size: 0.9375rem; font-variant-numeric: tabular-nums; color: #17140f; } .ds-ledger th { text-align: left; font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; border-bottom: 2px solid #17140f; padding: 0 0.75rem 0.5rem 0; } .ds-ledger td { border-bottom: 1px solid rgba(23, 20, 15, 0.22); padding: 0.7rem 0.75rem 0.7rem 0; vertical-align: top; }" }, { "name": "Refusal Notice", "kind": "custom", "refersTo": "notice-negative", "description": "Form error. Ruled along its top edge, never a left-border callout and never a rounded alert.", "html": "

That address could not be accepted.

", "css": ".ds-notice { border-left: 0; border-top: 2px solid #8e2417; background: rgba(158, 42, 26, 0.14); color: #8e2417; padding: 0.75rem 0.9rem; margin: 0 0 1.25rem; font-family: \"Public Sans\", ui-sans-serif, system-ui, sans-serif; font-weight: 700; border-radius: 0; }" } ], "narrative": { "northStar": "The Flyposted Bill", "overview": "This is a sheet pasted on a wall, photographed as it is: cheap coloured stock, two inks, a heavy impression, and the halftone dots of a job that was printed rather than rendered. Nothing here is a card floating on a canvas. The stock is the surface — full-bleed acid yellow on the bill itself — and the reading surfaces drop to bone because acid yellow is a shout and a shout cannot also be a paragraph. Depth is ink and perforation. The one exception is a tear-off tab lifting off the wall, which is a thing paper actually does.\n\nThe two inks are the whole colour theory. Ultramarine is the first ink; cyan is the second; the green is not a chosen colour at all but the consequence of cyan multiplied into yellow stock, offset a couple of pixels off true because a two-colour job never registers perfectly. That misregistration is the tell that the thing was printed, and it is load-bearing: remove the offset or swap the blend and the world stops being a press and becomes a gradient.\n\nTypographically it is a condensed display face shouting in caps against a plain grotesque doing the reading. The composition is hard: ruled columns, ruled underlines for fields, square dashes, zero radius anywhere. It refuses the centred single-field waitlist page — the page sorts you before it asks you for anything, and the primary action on the first surface is tearing off a tab, not pressing a button.", "keyCharacteristics": [ "Drenched stock, not accented white; two paper colours, never a screen white", "Two inks that build where they cross; green only as a product of overprint", "Zero radius everywhere — a printed sheet has corners", "Perforations, dashed rules and torn edges instead of borders and shadows", "Condensed uppercase display against a quiet body grotesque", "Self-hosted faces only; no third-party font origin exists in this world" ], "rules": [ { "name": "The Overprint Rule", "body": "Green is never picked from a swatch. Wherever ink crosses ink, the upper layer is mix-blend-mode: multiply so the inks build and darken. screen is a defect in this world, not an option; it lightens and turns a press into a light-box.", "section": "colors" }, { "name": "The Misregistration Rule", "body": "Every overprint band sits 1–2px off true (translateY(2px) on the shout, 1px on the stamp). The offset is the evidence of a two-colour job. It is not a rendering bug and must not be \"corrected\".", "section": "colors" }, { "name": "The Two-Stock Rule", "body": "There are exactly two grounds: acid stock for the bill and its tabs, bone for everything meant to be read. No third surface colour, and no white anywhere — white is a screen colour and this is a printed thing.", "section": "colors" }, { "name": "The Self-Hosted Faces Rule", "body": "Both families are served from static/fonts/*.woff2 with font-display: swap. This is a constraint, not a preference: the app ships default-src 'self', so a third-party font link is blocked at the browser. Never introduce a font CDN, and never add a face without vendoring the woff2.", "section": "typography" }, { "name": "The Display-Is-Caps Rule", "body": "The condensed face appears only uppercase, only at 800, and only for shouts, marks, titles and tab words. It is never used for running text, labels or numbers in prose — except the ledger's tally figures, where it sets the count as a struck number beside body-face copy.", "section": "typography" }, { "name": "The No-Costume-Mono Rule", "body": "A monospace stack is declared but is not used on any surface. Monospace here would be a costume for \"technical\" on pages that are not about machines. Tabular figures in the ledger come from font-variant-numeric: tabular-nums, not from a mono face.", "section": "typography" }, { "name": "The One Shadow Rule", "body": "A shadow exists in this world only to show paper leaving the wall. Nothing else is elevated: no panels, no menus, no hovering cards. A hard offset shadow with no blur belongs to a different world and is not this one.", "section": "elevation" }, { "name": "The Halftone Rule", "body": "Paper texture is the 6px inline-SVG dot screen at low opacity, multiplied into the stock. Never a raster texture, never a bevel, emboss, gradient or inner shadow.", "section": "elevation" }, { "name": "The Equal Tabs Rule", "body": "Tabs are never numbered, ranked, ordered by emphasis, or given a \"recommended\" treatment. Three positions numbered 1-2-3 imply a rank; these three are equal by design, and the only differences between them are the word and the address.", "section": "components" }, { "name": "The Tab Carries Its Address Rule", "body": "A tear-off tab exists to be the thing you walk away holding, so it prints its own destination. A separate \"take one\" call to action beside it says the same thing twice.", "section": "components" } ], "dos": [ "Do build every ink-over-ink crossing with mix-blend-mode: multiply and a 1–2px offset, so the colour is produced by the press rather than picked.", "Do keep radius at 0 on every new surface and control, including restating border-radius: 0 on native controls.", "Do put new reading surfaces on bone and reserve the acid stock for the bill, its tabs, and stubs torn from it.", "Do draw dividers as perforations, dashed 2px rules, or solid 2px ink rules, and fields as ruled underlines.", "Do vendor any new face into static/fonts/ as woff2; the CSP serves default-src 'self' and an external font link is blocked at the browser.", "Do keep tokens.css byte-identical to the framework's copy and make all visual changes in theme.css (palette, faces, shape, browser surfaces) or bill.css (composition). internal/movementtest/vendored_test.go records that divergence deliberately." ], "donts": [ "Don't use screen, overlay, lighten, or a flat green fill to make the overprint colour. Cyan on its own is never a surface colour.", "Don't \"fix\" the 2px band offset, the ragged clip-path edge, or the square perforation dashes — each is authored, and each is the evidence that this was printed.", "Don't add a second shadow, an elevated panel, or a card. Elevation exists only as a tab leaving the wall.", "Don't number, rank or otherwise differentiate the three tabs.", "Don't introduce white (#fff) as a surface, or a third stock colour.", "Don't set running text, labels or UI copy in the monospace stack, and don't set the display face in anything but uppercase 800.", "Don't replace the halftone with a raster texture, a gradient, or a bevel.", "Don't centre a single email field as a surface strategy; forms sit beside the argument they belong to, in the sheet's two-up grid." ] } }