Skip to content

site(style): design-token layer and shared components — palette roles, type/spacing scales, capsule buttons, chips, cards, unified H1/H2, zh/ja hero phrase breaks - #349

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/pm-dispatch-objectos-ju9td1-issue-345
Nov 2, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/pm-dispatch-objectos-ju9td1-issue-345

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Closes #345

Style-audit phase 1 under the visual-style ruling on #340 (comment 6570301123, maintainer 2026-11-02): direction A "Governed editorial", system fonts, palette roles, capsule buttons. Blocked-by #342 has landed; this is on top of 4e37285 (#341, #347, #348 included).

What changed

  1. Token layer in src/layouts/Base.astro. Every colour, type size, line height, measure, radius and shadow a component uses is now a named token; a component declares layout and picks tokens.
    • Colour roles, 17 named per theme (13 re-declared for dark; the four --on-panel*/--panel-ink values are the same in both): --bg --surface --surface-sunk --line, --ink --ink-soft --muted, --brand (indigo: logo, links, focus, selected state, topic chips, card hover), --brand-soft, --green (emphasis: eyebrows, the hero's second line, indexes, marks), --amber / --red (status only), --panel-ink with --on-panel --on-panel-soft --on-panel-accent, --status-archived. --accent/--accent-soft/--ring are gone (--ring is derived from --brand); --surface-glass is derived from --surface.
    • Existing colours map onto the roles, no new hues: #3d58f0/#91a3ff is --brand; the two greens (#057a58 home/blog/404, #087f5b elsewhere) are one --green: #087f5b; the three blues (--home-blue #3157d8, --sec-blue #2563eb, #8fa3ff) fold into --brand; the three ambers (#93600f, #b45309, #b7791f) into --amber: #93600f; the two reds into --red: #bd4b4b; the dark panel greens (#172b26, #12352c→#183f35, rgba(23,43,38,.96)) into --panel-ink: #172b26. The Tailwind defaults site(style): phase-0 quick wins — font-stack order, dark CTA, dark cover dimming, prose measure, CJK title line-height, tabular numerals, hamburger at 1024 #341 could not move (#10b981 live dot, #292524 media note, #0f172a / #111827-family video frames, #6ee7b7 / #34d399 poster accents) now take --green, --ink, --panel-ink and --on-panel-accent. The body's paper wash is color-mix of the grounds and accents (two stops move by 1-3 units of 255). The only literals left outside the :root blocks are the #000 alpha masks of the scroll-edge fades and the logo's own #4F46E5 (logo colour is a phase-2 decision on site(style): phase-0 quick wins from the visual-style audit — font-stack order, dark-mode CTA contrast, dark-mode cover dimming, prose measure, CJK title line-height, tabular numerals #340).
    • Type scale: twelve fixed steps --fs-12 … --fs-44 (12 13 14 15 16 17 18 20 24 30 36 44 px) plus three fluid display steps --fs-h2 (28-40), --fs-h1 (36-56) and --fs-hero (40-64). The two h1 steps keep the evidence pages' vh term, so a 1366×625 laptop still holds the primary CTA in its first screen.
    • Five line heights --lh-display 1.05 / heading 1.25 / ui 1.45 / body 1.65 / prose 1.8, with --lh-display: 1.2 on zh/ja/ko page roots.
    • Spacing --sp-1 … --sp-10 on a 4px base and one --space-section: clamp(3.5rem, 8vw, 7rem) shared by home, evidence and security sections.
    • Four measures --measure-lead 36rem / prose 44rem / wide 54rem / media 60rem (plus --maxw); three radii --r-control 6px / card 8px / pill 999px; three shadows --shadow-sm / md / lg.
  2. Shared components (Base.astro, global). .btn with .btn-primary (ink capsule, inverts on .on-dark panels and in the dark theme), .btn-secondary (surface + line), .btn-ghost (underlined text link), .btn-sm for the header bar; .chip and .chip-brand; .card / .card-link and .card-grid; .pill-nav; .eyebrow / .section-kicker; .panel-dark. The five templates are migrated: home, evidence pages, pricing, security, cluster — plus the header CTA and drawer CTA, blog cards, post header, glossary, legal and 404. The five primary-button styles (header capsule, home 6px gradient, evidence capsule, pricing 10px indigo, security 6px white) are one. The pricing recommended card is the primary ink button with a 2px --brand outline and a 2px --brand card edge; the recommended badge stays.
  3. Type scale applied. H1 at 1440 is 55.5px on every page template (was 52 / 52.8 / 53.6 / 54.4 / 55.5 / 60 / 80 / 89.6); the home and security heroes are 60px at 1440 and cap at 64 (were 60 and 80, 75.6 / 80 at 1920). Marketing H2 is 40px (was 51-57), so the home H1:H2 is 1.5 (was 1.06). Display/mono weights 650-800 are 700; 500 is 400; the scale is 400 / 600 / 700.
  4. zh/ja hero phrase breaks. .hero-lead and .hero-editions render through phraseHtml and take keep-all, like the headings: the zh lead now breaks …AI 编写它,/ 运行时运行它,…, the ja lead …をひとつ。/ AI が書き、ランタイムが動かし、/ エージェントが… at 390 (was 运/行时, ひと/つ).
  5. Decorative tri-colour bars (home positioning, blog hero, 404) are a single --green rule. The decorative tones on home solution/AI cards, evidence loop steps and card labels, and the security deployment titles (blue/amber) are gone: marks and indexes are --green, hover edges and arrows --brand, titles ink.

Out of scope and untouched: the nav structure and labels (#348), the cover spec in AGENTS.md and the cover scripts, inline scripts (the CSP digests are unchanged; seo:smoke checks them), the logo colour, webfonts. AGENTS.md is untouched (a governed surface; a note naming the token layer can go in a separate small PR).

Token inventory (component <style> blocks, scripts-free count of distinct declared values)

before after
font-size 78 21 (15 tokens + em/cqw relatives in the hero strong, card arrow, inline code and the video poster)
line-height 31 6 (5 tokens + 1 on mono indexes)
font-weight 7 (400 500 600 700 750 760 800) 4 (400 600 700 inherit)
box-shadow 31 5 (3 tokens + the header's inset hairline + the live dot's halo)
border-radius 9 5 (3 tokens + 0 + the blockquote's one-sided card radius)
literal colours outside the token blocks 83 (hex/rgba, incl. 17 token definitions) 0 (+ #000 alpha masks, logo #4F46E5)
named colour tokens per theme 13 17
max-width 22 10 (4 measures + --maxw + 100%/none/two phone min() floors/one 320px caption)
letter-spacing 10 4 (0, 0.08em, -0.01em on display, 0.02em on phone table heads)

Computed-style diff

8 pages (home, pricing, compare, security, glossary, blog index, a post, a cluster page) × 6 viewports × light/dark × en and zh-Hans = 192 snapshots before (4e37285) and after; every element keyed by DOM path, 23 properties. Colour syntax is normalised, so a token that resolves to the same bytes is not a change. No element is missing after, no page's scroll width changed. 868 distinct (element, property, before → after) changes, all in the families below; the full table is scratchpad/tok-345/diff-final.md.

property distinct what it is
lineHeight 199 follows fontSize × the five --lh-* steps (31 values → 5; CJK display 1.2)
fontSize 102 the scale: 0.6-0.78rem labels → 12px; 0.82-0.9 → 13/14; h1 52-89.6 → 46-56 (hero 50-64); marketing h2 51-57 → 40; prose h2 28 → 30; metric figures 32/28.8 → 30; pricing amount 40 → 36
borderTopColor / borderLeftColor 69 each currentColor edges following color, plus card edges on --line and the pricing/brand edges
boxShadow 70 31 hand-written shadows → --shadow-sm/md/lg; green-tinted and inset shadows removed; cards that had none take --shadow-sm
color / outlineColor 63 each role mapping: greens → #087f5b; blues/ambers on marks, indexes, labels, step titles → --green or ink; links/arrows/hover → --brand; blog kicker brand → green; panel text white → --on-panel; Tailwind greys/greens → tokens; non-topic post chips brand → --ink-soft (two chip styles)
paddingTop 51 --space-section (home 112 → 109-112, evidence 80 → 112, security 96 → 112 at desktop; phones 51-60 → 56-64) and button/chip boxes
backgroundColor 32 buttons (gradient → solid ink / inverted), panels (--panel-ink), chips (sunk / brand-soft), video frame
maxWidth 28 21 widths → the four measures (±16-40px)
letterSpacing 26 display h1 -0.01em; 0.03-0.07em small caps → 0.08em
borderTopLeftRadius 24 buttons → pill; 6/10/16px cards → 8; drawer/nav controls 8 → 6
fontWeight 22 650-800 → 700; chips 400 → 600; poster note 500 → 400
minHeight 15 .btn 44 (header 36), chips 24, pill-nav 32
paddingLeft 13 button/chip boxes
fontFamily 7 the video poster's Inter, … stack → --font-sans
backgroundImage 6 body wash via color-mix (±3/255), button and panel gradients → solid tokens, cluster-link tint on the new green
wordBreak / textWrap 5 / 4 hero lead/editions and eyebrows keep-all; chips nowrap

Contrast and axe

  • AA: every text element on 11 pages × 2 viewports × 2 themes (9,492 elements) measured against its nearest opaque ground: 0 below 4.5:1 (3:1 large), before and after. The one regression axe caught in the first build (the home outcome cells, --green on an 8% green tint, 4.48) is fixed: the text leans 10% toward ink on a 6% tint, 5.0:1.
  • axe-core (wcag2a/aa, 2.1, 2.2aa, best-practice) over 15 pages, 1366 and 390, light and dark, with the Why/Resources menus and the drawer open and the footer in view: 80 runs, 4 violations before, 4 after, the same four — target-size on two footer links at 390 (a[href$="approvals/"], the Why-ObjectOS column's seventh link), present on main since site(nav): phase 2 — Why ObjectOS top level, GitHub into Developers, Guides column, four-column footer, ruled 8-locale labels #348 and not touched here. Nothing new.

Locales and viewports

Screenshots in scratchpad/www/shots-tok-345/ (174 + 64 element crops, and header/ with the bar at 1100/1366/390 light and dark for en, de, fr, zh-Hans, the drawer open at 390, and the hero at 1366/390 in en and zh-Hans after the 13px bar labels): en on all ten page types × six viewports × light/dark; zh-Hans on home/security/post/blog/pricing/cluster at 1366 and 390 light/dark; zh-Hant, ja, ko, de, es, fr home at 1366 and 390, security and blog at 390, a post at 1366 dark. No page overflows its viewport (checked on every shot). Header fit: the bar labels take the 13px step (at 14px French had 6px to spare at 1100); .bar scrollWidth = clientWidth in all eight locales at 1100 and 1366, the gap between the nav and the right-hand group is 41px (fr), 54 (es), 106 (de), 135 (en) at 1100, and the logo keeps its width.

Gates

  • pnpm content:lint — passed (399 files, 46 glossary terms).
  • pnpm check — 0 errors, 0 warnings, 0 hints (167 files).
  • pnpm build — passed, including the cover gates, og:images and the three --dist lints (964 pages, 0 CJK segment breaks, 109,909 links).
  • pnpm seo:smoke — passed (954 pages; 4 inline script digests CSP-checked, unchanged).
  • node scripts/post-deploy-probe.mjs --base-url <local dist> — PASS 6/6.

Acceptance notes

🤖 Generated with Claude Code

https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr

…scale (#345)

Phase 1 of the style audit under the visual-style ruling on #340: direction A
"Governed editorial", system fonts, palette roles, capsule buttons.

Base.astro carries the token layer: 17 named colour roles per theme (--brand
for identity and interaction, --green for emphasis, --ink for action, amber
and red for status only, --panel-ink with its on-panel trio), twelve fixed
type steps plus three fluid display steps, five line heights, 4px spacing
with one --space-section, four measures, three radii and three shadows. The
shared .btn (primary / secondary / ghost), .chip / .chip-brand, .card /
.card-grid, .pill-nav, .eyebrow and .panel-dark classes replace the five
templates' own buttons, chips and cards; home, the evidence pages, pricing,
security and the cluster pages are migrated, with the header, blog, post,
glossary, legal and 404 surfaces. H1 is one step on every page template
(hero 40-64px, page 36-56px), marketing H2 is 28-40px, weights are 400 / 600
/ 700. The zh/ja hero lead and edition paragraph take the headings' phrase
<wbr> and keep-all. The decorative tri-colour bars are a single green rule.
No palette hue is new: the existing colours map onto the roles.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 2, 2026 07:41
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

Verdict: ACCEPT. Reviewed against GitHub, not the report. This implements style-audit phase 1 under the ruling on #340 (comment 6570301123): direction A, system fonts, palette roles, capsule buttons.

Item Reading
Shape get_files: 16 files, +993 −1234 (2,227 lines). Base.astro adds the token layer; 13 components/layouts are migrated; scripts/lib/cover-colors.mjs gets 4 lines so the dark-cover map follows the renamed tokens. No governed path: the AGENTS.md bullet the dev drafted was removed before push. Nav structure and labels, cover spec, CSP digests and the post-deploy probe are untouched.
Inventory Distinct values in component styles, before → after: font-size 78 → 21, line-height 31 → 6, weight 7 → 4, box-shadow 31 → 5, radius 9 → 5, max-width 22 → 10, literal colours 83 → 0 (logo #4F46E5 left for the phase-2 palette decision). Named colour roles per theme: 17 (--brand / --green / --ink / amber / red).
Computed-style diff 192 snapshots: 8 pages × 6 viewports × light/dark × en + zh-Hans. 868 distinct intentional changes, 0 elements missing, 0 scroll-width changes. The full table is in the PR body.
Checks AA contrast: 0 of 9,492 text elements below AA, before and after. One regression (home outcome cells at 4.48:1) was found and fixed before commit. axe: 4 → 4, identical; these are the pre-existing footer target-size findings from #348. Header fit after the 14 → 13px bar labels: .bar scrollWidth = clientWidth in all 8 locales at 1100/1200/1366. Post-deploy probe against the local dist: PASS 6/6. Seat viewed the en 1366 pricing (capsule buttons, unified H1), the zh-Hans 390 home hero (phrase breaks at 编写它,/ 运行时) and the fr 1100 header.
Gate check-runs Build and deploy = success on head 31be334; mergeable clean. Local: content:lint 0, check 0, build 0 (cover gates and check-positioning included), seo:smoke 0.
Accepted deviations Evidence pages' section spacing grows from 5rem to 7rem and security's from 6rem to 7rem under the shared --space-section. Decorative blue/amber accents on cards and steps are removed under the status-only rule. Both are listed in the PR body.
Out-of-scope dispositions Logo colour vs --brand, webfonts, imagery language, and a style-lint against literal values: carrier #340 phase 2, recorded in Acceptance notes. A token-layer note for AGENTS.md: Acceptance notes, as an optional separate governed PR. Footer target-size findings at 390: carrier #348 follow-up, Acceptance notes.
Landing Relay automerge_enable → merge queue → confirm the push deploy and the post-deploy probe. #345 closes via Closes #345.

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants