diff --git a/.gitignore b/.gitignore index 9fbdc7f..e3e8a42 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,7 @@ pnpm-debug.log* # the public sources task reference:public fetches .sources/ + +# ui-hill-climb: the captures and the council sets are evidence, not source +ui-hill-climb/rounds/ +_output/ diff --git a/astro.config.mjs b/astro.config.mjs index 6199be3..ebc1725 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -22,8 +22,9 @@ export default defineConfig({ title: 'Spinbox', description: 'Self-hosted sandboxes in your own AWS account: a virtual machine per workspace, snapshots with memory, rollback, and a diff of what changed.', - // The organization's own mark (spin-stack/brand): the tile on its navy in dark, and clear in light, - // where the tile would read as a sticker. No alt: the name is written beside it. + // The organization's own mark (spin-stack/brand), clear in both: in dark with its shadow drawn + // for the navy page (mark-dark), where the tile read as a box on the header. No alt: the name is + // written beside it. logo: { dark: './src/assets/logo.png', light: './src/assets/logo-light.png', alt: '' }, favicon: '/favicon.png', social: [{ icon: 'github', label: 'GitHub', href: 'https://github.com/spin-stack' }], diff --git a/src/assets/logo.png b/src/assets/logo.png index e74d626..581d93e 100644 Binary files a/src/assets/logo.png and b/src/assets/logo.png differ diff --git a/src/components/Answers.astro b/src/components/Answers.astro index 6d1fd7b..45bb3f3 100644 --- a/src/components/Answers.astro +++ b/src/components/Answers.astro @@ -45,7 +45,7 @@ const drawn = html.replace(/
  • /g, () => `
  • ${iconSVG(icon .answers :global(li strong) { display: block; color: var(--sl-color-white); - font-family: var(--sl-font-mono); + font-family: var(--spin-font-display); font-size: var(--sl-text-base); margin-bottom: 0.2rem; } diff --git a/src/components/Cta.astro b/src/components/Cta.astro index f07b45d..025d30a 100644 --- a/src/components/Cta.astro +++ b/src/components/Cta.astro @@ -40,10 +40,11 @@ const { title, links } = Astro.props; h2 { margin: 0 auto; max-width: 22ch; - font-family: var(--sl-font-mono); - font-size: clamp(1.8rem, 1.2rem + 2.4vw, 3rem); + font-family: var(--spin-font-display); + font-size: var(--spin-text-h1); line-height: 1.1; - letter-spacing: var(--spin-heading-tracking); + letter-spacing: var(--spin-display-tracking); + word-spacing: -0.12em; color: var(--spin-brand-frost); } p { diff --git a/src/components/Hero.astro b/src/components/Hero.astro index cd4ebb4..d6a24fb 100644 --- a/src/components/Hero.astro +++ b/src/components/Hero.astro @@ -1,7 +1,7 @@ --- // The landing page's hero: Starlight's, with a workspace's disk to work under it and the // project's name above the title. The title's second sentence - what Spinbox does, after what it -// is - is in the accent: one color, flat, as the console sets what matters. +// is - is in the accent's text colour: one colour, flat, as the console sets what matters. import { LinkButton } from '@astrojs/starlight/components'; import Disk from './Disk.astro'; @@ -59,10 +59,9 @@ const rest = cut < 0 ? '' : title.slice(cut + 2); display: inline-flex; align-items: center; gap: 0.6rem; - font-family: var(--sl-font-mono); font-size: var(--sl-text-sm); + font-weight: 600; color: var(--spin-label); - letter-spacing: 0.04em; } .dot { width: 0.5rem; @@ -71,10 +70,12 @@ const rest = cut < 0 ? '' : title.slice(cut + 2); background: var(--spin-label); } h1 { - font-family: var(--sl-font-mono); - font-size: clamp(2.3rem, 1rem + 3.6vw, 3.9rem); + font-family: var(--spin-font-display); + font-size: var(--spin-text-display); + text-wrap: balance; line-height: 1.08; - letter-spacing: var(--spin-heading-tracking); + letter-spacing: var(--spin-display-tracking); + word-spacing: -0.12em; font-weight: 600; color: var(--sl-color-white); margin: 0; diff --git a/src/components/Stats.astro b/src/components/Stats.astro index 58aaf56..04fcaef 100644 --- a/src/components/Stats.astro +++ b/src/components/Stats.astro @@ -55,7 +55,7 @@ const stats = [ background: var(--sl-color-black); } .n { - font-family: var(--sl-font-mono); + font-family: var(--spin-font-display); font-size: clamp(2.4rem, 1.5rem + 2.5vw, 3.6rem); font-weight: 600; line-height: 1; diff --git a/src/components/Story.astro b/src/components/Story.astro index 32e020b..8804604 100644 --- a/src/components/Story.astro +++ b/src/components/Story.astro @@ -293,11 +293,9 @@ const plain = esc(steps.map((s) => [...s.commands.map((c) => `$ ${c}`), ...stepO gap: 0.2rem; } .label { - font-family: var(--sl-font-mono); - font-size: 0.75rem; - letter-spacing: 0.12em; - text-transform: uppercase; - color: var(--spin-muted); + font-size: 0.8125rem; + font-weight: 500; + color: var(--spin-label); } .title { font-size: 1.125rem; diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx index 3513a30..a85f53e 100644 --- a/src/content/docs/index.mdx +++ b/src/content/docs/index.mdx @@ -8,10 +8,9 @@ hero: actions: - text: Evaluate Spinbox link: overview/evaluate/ - icon: right-arrow - text: Install on AWS link: aws/overview/ - variant: minimal + variant: secondary --- import Answers from '../../components/Answers.astro'; diff --git a/src/data/reference.json b/src/data/reference.json index a05ba8e..3e016bb 100644 --- a/src/data/reference.json +++ b/src/data/reference.json @@ -10,7 +10,7 @@ "release": "v20261027.02" }, "brand": { - "commit": "7e17029f6a087f386a4798af03df6e9623ecfe12" + "commit": "b7e4afcc3f5def534915077a2f4fc79a867f0924" }, "counts": { "built": 85, diff --git a/src/styles/brand-starlight.css b/src/styles/brand-starlight.css index 922c601..0d6e334 100644 --- a/src/styles/brand-starlight.css +++ b/src/styles/brand-starlight.css @@ -1,36 +1,42 @@ /* Written by `task palette` from palette.toml (spin-stack/brand). Edit palette.toml, not this file. */ :root { - --sl-color-accent-low: #163D51; - --sl-color-accent: #27BFE8; - --sl-color-accent-high: #87D6EF; - --sl-color-white: #F5F8FB; - --sl-color-gray-1: #EEF2F9; - --sl-color-gray-2: #E6EDF6; - --sl-color-gray-3: #9AA9C2; - --sl-color-gray-4: #6A7EA0; - --sl-color-gray-5: #33435F; - --sl-color-gray-6: #172035; - --sl-color-black: #111827; - --sl-color-banner-bg: #1B435C; - --sl-color-banner-text: #E6EDF6; + --sl-color-accent-low: #123049; + --sl-color-accent: #1B7DB4; + --sl-color-accent-high: #A9D9F0; + --sl-color-white: #F5F7FA; + --sl-color-gray-1: #EEF1F6; + --sl-color-gray-2: #E6EBF2; + --sl-color-gray-3: #9AA5B8; + --sl-color-gray-4: #6B7894; + --sl-color-gray-5: #34405A; + --sl-color-gray-6: #161E2F; + --sl-color-black: #0E1421; + --sl-color-banner-bg: #17334C; + --sl-color-banner-text: #E6EBF2; } :root[data-theme='light'] { - --sl-color-accent-low: #C9DFEB; + --sl-color-accent-low: #BDD8E6; --sl-color-accent: #0A6FA3; - --sl-color-accent-high: #0D3B5A; + --sl-color-accent-high: #0C3957; --sl-color-white: #0A0E17; --sl-color-gray-1: #0E131F; --sl-color-gray-2: #111827; - --sl-color-gray-3: #4A5871; - --sl-color-gray-4: #6E7D96; - --sl-color-gray-5: #B9C6D8; - --sl-color-gray-6: #DEE6F1; + --sl-color-gray-3: #525D72; + --sl-color-gray-4: #77829A; + --sl-color-gray-5: #C4CCD8; + --sl-color-gray-6: #E1E7F0; --sl-color-black: #FFFFFF; - --sl-color-banner-bg: #BDD7E6; + --sl-color-banner-bg: #BED7E6; --sl-color-banner-text: #111827; - --sl-color-gray-7: #F0F4F9; + --sl-color-gray-7: #F1F4F9; } :root { --sl-font: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif; --sl-font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace; } +:root { + --sl-text-h1: clamp(1.75rem, 1.421rem + 1.348vw, 2.5rem); + --sl-text-h2: clamp(1.375rem, 1.156rem + 0.8989vw, 1.875rem); + --sl-text-h3: clamp(1.125rem, 1.015rem + 0.4494vw, 1.375rem); + --sl-text-h4: clamp(1rem, 0.9452rem + 0.2247vw, 1.125rem); +} diff --git a/src/styles/brand-tokens.css b/src/styles/brand-tokens.css index da312ec..d44eb9b 100644 --- a/src/styles/brand-tokens.css +++ b/src/styles/brand-tokens.css @@ -1,43 +1,65 @@ /* Written by `task palette` from palette.toml (spin-stack/brand). Edit palette.toml, not this file. */ :root, .spin-dark { - --spin-accent: #27BFE8; - --spin-accent-text: #27BFE8; - --spin-border: #33435F; - --spin-border-strong: #6A7EA0; - --spin-destructive: #C2304F; - --spin-error: #F57AB4; - --spin-label: #5FE3D6; - --spin-muted: #9AA9C2; - --spin-on-accent: #111827; - --spin-overlay: #273552; - --spin-page: #111827; - --spin-raised: #202C47; - --spin-success: #3DDC97; - --spin-surface: #172035; - --spin-text: #E6EDF6; - --spin-warning: #FFC857; - --spin-accent-hover: #13293A; - --spin-accent-selected: #163D51; + --spin-accent: #1B7DB4; + --spin-accent-text: #6CC6EE; + --spin-border: #34405A; + --spin-border-strong: #6B7894; + --spin-destructive: #C4384F; + --spin-error: #EE7BB0; + --spin-label: #8FB3C6; + --spin-muted: #9AA5B8; + --spin-on-accent: #FFFFFF; + --spin-overlay: #2A3550; + --spin-page: #0E1421; + --spin-raised: #1F2940; + --spin-success: #4CC38A; + --spin-surface: #161E2F; + --spin-text: #E6EBF2; + --spin-warning: #E3B04B; + --spin-accent-fill-hover: #186E9E; + --spin-accent-fill-active: #155F89; + --spin-destructive-hover: #AC3146; + --spin-destructive-active: #952B3C; + --spin-control: #1F2940; + --spin-control-hover: #2A3550; + --spin-shadow-overlay: 0 0 0 1px rgb(0 0 0 / 0.4); + --spin-success-badge: color-mix(in srgb, var(--spin-success) 12%, transparent); + --spin-warning-badge: color-mix(in srgb, var(--spin-warning) 12%, transparent); + --spin-error-badge: color-mix(in srgb, var(--spin-error) 12%, transparent); + --spin-accent-text-badge: color-mix(in srgb, var(--spin-accent-text) 12%, transparent); + --spin-accent-hover: #0F1E30; + --spin-accent-selected: #123049; } :root[data-theme='light'] { --spin-accent: #0A6FA3; - --spin-accent-text: #085E8C; - --spin-border: #B9C6D8; - --spin-border-strong: #6E7D96; - --spin-destructive: #B4234A; - --spin-error: #9B1B73; - --spin-label: #0C3C84; - --spin-muted: #4A5871; + --spin-accent-text: #075A86; + --spin-border: #C4CCD8; + --spin-border-strong: #77829A; + --spin-destructive: #C0303F; + --spin-error: #9A1F60; + --spin-label: #33586E; + --spin-muted: #525D72; --spin-on-accent: #FFFFFF; --spin-overlay: #FFFFFF; --spin-page: #FFFFFF; - --spin-raised: #DEE6F1; - --spin-success: #1E7046; - --spin-surface: #F0F4F9; + --spin-raised: #E1E7F0; + --spin-success: #0F6844; + --spin-surface: #F1F4F9; --spin-text: #111827; - --spin-warning: #8A5A00; + --spin-warning: #845000; + --spin-accent-fill-hover: #09628F; + --spin-accent-fill-active: #08547C; + --spin-destructive-hover: #A92A37; + --spin-destructive-active: #922430; + --spin-control: #F1F4F9; + --spin-control-hover: #E1E7F0; + --spin-shadow-overlay: 0 12px 32px rgb(16 19 24 / 0.14), 0 2px 6px rgb(16 19 24 / 0.08); + --spin-success-badge: color-mix(in srgb, var(--spin-success) 12%, transparent); + --spin-warning-badge: color-mix(in srgb, var(--spin-warning) 12%, transparent); + --spin-error-badge: color-mix(in srgb, var(--spin-error) 12%, transparent); + --spin-accent-text-badge: color-mix(in srgb, var(--spin-accent-text) 12%, transparent); --spin-accent-hover: #E7F1F6; - --spin-accent-selected: #C9DFEB; + --spin-accent-selected: #BDD8E6; } :root { --spin-brand-blue: #2F6BE3; @@ -54,13 +76,27 @@ --spin-line-height: 1.6; --spin-heading-weight: 600; --spin-heading-tracking: -0.02em; + --spin-font-heading: var(--spin-font-sans); + --spin-font-display: var(--spin-font-mono); + --spin-display-tracking: -0.035em; + --spin-numeric: tabular-nums; + --spin-text-display: clamp(2rem, 1.452rem + 2.247vw, 3.25rem); + --spin-text-h1: clamp(1.75rem, 1.421rem + 1.348vw, 2.5rem); + --spin-text-h2: clamp(1.375rem, 1.156rem + 0.8989vw, 1.875rem); + --spin-text-h3: clamp(1.125rem, 1.015rem + 0.4494vw, 1.375rem); + --spin-text-h4: clamp(1rem, 0.9452rem + 0.2247vw, 1.125rem); --spin-measure: 72ch; --spin-sidebar: 17rem; - --spin-radius-sm: 4px; + --spin-radius-sm: 6px; --spin-radius: 8px; --spin-radius-lg: 12px; --spin-target: 24px; --spin-target-touch: 44px; + --spin-control-sm: 28px; + --spin-control-md: 32px; + --spin-control-lg: 36px; + --spin-control-icon: 16px; + --spin-control-gap: 6px; --spin-width-contained: 1200px; --spin-width-detail: 1152px; --spin-width-wide: 1600px; diff --git a/src/styles/custom.css b/src/styles/custom.css index 8a27d6e..5b98c2d 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -8,10 +8,15 @@ @import '@fontsource/ibm-plex-mono/500.css'; @import '@fontsource/ibm-plex-mono/600.css'; -/* Headings in the mono face: a site about machines, set like their consoles. One tracking for all - of them, the palette's: five values had grown here and in the landing's parts. */ +/* Headings in the mono (spin-stack/brand's type.display): a site about machines, set like their + consoles, at the display's tight tracking and with its word gaps closed - a mono's own spacing + is what made a large heading read as a terminal. */ .sl-markdown-content :is(h1, h2, h3, h4), -h1#_top, +h1#_top { + font-family: var(--spin-font-display); + letter-spacing: var(--spin-display-tracking); + word-spacing: -0.12em; +} .site-title { font-family: var(--sl-font-mono); letter-spacing: var(--spin-heading-tracking); @@ -40,9 +45,46 @@ a[data-feature='built'] { [data-has-hero] .sl-markdown-content .sl-heading-wrapper > a { display: none; } -/* Buttons at the brand's corner, not Starlight's pill: a control, sized to its label. */ +/* Buttons are spin-stack/brand's (its laboratory's Buttons): the control's height and small + corner, the accent solid with a white label for the one primary action, a quiet fill and a + hairline for the rest, and the hover and pressed fills brand derives and checks. Starlight's + primary was the accent's light tint with dark text: the loudest thing on every page. */ .sl-link-button { - border-radius: var(--spin-radius); + border-radius: var(--spin-radius-sm); + min-height: var(--spin-control-lg); + padding: 0 1rem; + gap: var(--spin-control-gap); + font-size: var(--sl-text-sm); + font-weight: 500; + line-height: 1; + transition: background-color var(--spin-duration-fast) var(--spin-ease); +} +.sl-link-button.primary { + background: var(--spin-accent); + border-color: var(--spin-accent); + color: var(--spin-on-accent); +} +.sl-link-button.primary:hover { + background: var(--spin-accent-fill-hover); + border-color: var(--spin-accent-fill-hover); + color: var(--spin-on-accent); +} +.sl-link-button.primary:active { + background: var(--spin-accent-fill-active); +} +.sl-link-button.secondary { + background: var(--spin-control); + border-color: var(--spin-border); + color: var(--spin-text); +} +.sl-link-button.secondary:hover { + background: var(--spin-control-hover); + color: var(--spin-text); +} +@media (pointer: coarse) { + .sl-link-button { + min-height: var(--spin-target-touch); + } } .status-counts { font-family: var(--sl-font-mono); @@ -62,10 +104,6 @@ a[data-feature='built'] { color: var(--sl-color-accent-high); font-weight: 600; } -.sl-markdown-content :is(h1, h2, h3), -h1#_top { - word-spacing: -0.12em; -} /* The columns. The table of contents is the bar under the header at every width (PageSidebar.astro), so the right column Starlight keeps for it goes, and the text is centered in all that is right @@ -122,7 +160,7 @@ h1#_top { } /* The section headings, not a part's own (a .not-content block sets its heading itself). */ [data-has-hero] .sl-markdown-content h2:not(.not-content *) { - font-size: clamp(1.8rem, 1.1rem + 2.6vw, 3rem); + font-size: var(--spin-text-h1); text-transform: none; line-height: 1.08; color: var(--sl-color-white); @@ -157,7 +195,15 @@ h1#_top { } } -/* In dark the mark is a tile of its own ground, rounded; in light it is clear. */ -.site-title img { - border-radius: 22%; + +/* Text that is not a command - a command's --help, output - wraps in its block rather than running + past its edge, where the CLI's reference cut its flags' descriptions off. A command does not: a + wrap would break it at a flag's dash; it scrolls, as a terminal's line does. Expressive Code's + own wrap rule, set here for plain text alone. */ +.sl-markdown-content .expressive-code pre[data-language='plaintext'] .ec-line .code { + white-space: pre-wrap; + overflow-wrap: break-word; +} +.sl-markdown-content .expressive-code pre[data-language='plaintext'] .ec-line .code span.indent { + white-space: pre; } diff --git a/tools/refgen/brand.go b/tools/refgen/brand.go index b30337e..0e601c0 100644 --- a/tools/refgen/brand.go +++ b/tools/refgen/brand.go @@ -12,7 +12,7 @@ import ( var brandFiles = []struct{ from, to string }{ {"dist/tokens.css", "src/styles/brand-tokens.css"}, {"dist/starlight.css", "src/styles/brand-starlight.css"}, - {"logos/mark-256.png", "src/assets/logo.png"}, + {"logos/mark-dark-256.png", "src/assets/logo.png"}, {"logos/mark-clear-256.png", "src/assets/logo-light.png"}, {"logos/mark-512.png", "public/mark.png"}, {"logos/favicon-64.png", "public/favicon.png"}, diff --git a/ui-hill-climb/ROUNDS.md b/ui-hill-climb/ROUNDS.md new file mode 100644 index 0000000..4c74985 --- /dev/null +++ b/ui-hill-climb/ROUNDS.md @@ -0,0 +1,23 @@ +# Rounds - the website on spin-stack/brand#21 + +The screen set is `screens.json`: the landing, a concept, the cost page, evaluate, how it works, a +release page and a CLI reference, in dark and light, desktop and phone. Captured from +`astro build` + `astro preview` (the dev server draws its toolbar into a capture). Reviewers: +Claude and Codex, blind, pairs against round 00 in random order (Gemini was out of quota). + +## 00 - main at eba842a +Navy at #111827, mono headings, the hero's second sentence in the neon cyan, Starlight's primary +button the accent's light tint with dark text, uppercase mono labels. + +## 01 - brand at da8df63: navy ink, sans headings +Claude 0/10, Codex 4/10. Both, on every screen: the ink (#0A0E16) read as near-black and lost the +navy; the sans headings read as a template; the grey second sentence as disabled. The identity was +the navy and the mono, not their contrast. + +## 02 - brand at e2cc7f7: the navy at its own chroma, the site's headings in the mono (type.display) +Claude 5-5, Codex 3-6 (1 tie). What was left: a page's title at the display's size (to 52 px) +towered over its sections. + +## 03 - brand at b7e4afc: a page's title is h1 (28-40); plain text wraps in its block +Claude 10/10, Codex 5-1 (4 ties). A command still scrolls rather than wrap at a flag's dash; its +--help and output wrap (the CLI reference cut its flags' descriptions off). diff --git a/ui-hill-climb/ledger.jsonl b/ui-hill-climb/ledger.jsonl new file mode 100644 index 0000000..149d787 --- /dev/null +++ b/ui-hill-climb/ledger.jsonl @@ -0,0 +1,6 @@ +{"round": 1, "reviewer": "claude/sonnet", "kind": "full", "scores": {"hierarchy": 7, "typography": 7, "spacing": 7, "color": 7, "consistency": 7, "density": 7, "usability": 7, "polish": 6, "responsive": 6, "identity": 8}, "control": {"hierarchy": 7, "typography": 7, "spacing": 7, "color": 7, "consistency": 7, "density": 7, "usability": 7, "polish": 6, "responsive": 6, "identity": 8}, "pairs": [{"screen": "home.desktop.dark", "winner": "baseline", "reason": "Navy surface with a cyan second hero line and monospace display type carries the brand; the other version is near-black neutral with a grey half-headline that reads as disabled."}, {"screen": "home.desktop.light", "winner": "baseline", "reason": "Light mode keeps the brand blue in the hero, with a strong primary CTA and a legible second line; the other has a grey second line and no brand colour."}, {"screen": "home.mobile.dark", "winner": "baseline", "reason": "Mobile hero keeps the navy and cyan identity with a clear, high-contrast hierarchy; the other is greyer and its secondary line is faint."}, {"screen": "snapshots.desktop.dark", "winner": "baseline", "reason": "Navy docs surface and monospace headings suit an infrastructure product, and the cyan active nav is clearer; the other is flat near-black."}, {"screen": "snapshots.desktop.light", "winner": "baseline", "reason": "The monospace heading voice matches the CLI-centric product and the code blocks, and the blue-tinted light palette is consistent."}, {"screen": "snapshots.mobile.light", "winner": "baseline", "reason": "Monospace headings stay legible on a phone and keep identity, though the title wraps; the sans version is only marginally calmer."}, {"screen": "cost.desktop.dark", "winner": "baseline", "reason": "Navy surface gives the tables and inline code better tonal separation, and the monospace headings tie the page to the product; the other blends into near-black."}, {"screen": "evaluate.desktop.light", "winner": "baseline", "reason": "Distinctive monospace headings keep a clear hierarchy, with a consistent blue link and active-nav treatment."}, {"screen": "cli-exec.desktop.dark", "winner": "baseline", "reason": "The CLI reference in navy with a cyan active item and a mono title feels native, and its code block separates from the page better."}, {"screen": "how-it-works.mobile.dark", "winner": "baseline", "reason": "Mobile prose on a navy ground with the brand mark and mono headings has clearer identity, and the diagram sits comfortably in the layout."}], "findings": [{"screen": "home.desktop.dark", "location": "Hero h1", "severity": "structural", "problem": "Wide monospace display type wraps the headline to three lines and the cyan second sentence is as heavy as the first, so the hero is tall and the emphasis is unclear.", "fix": "Reduce the h1 size or tighten the tracking so it fits two lines. Keep cyan only on the key phrase."}, {"screen": "home.desktop.dark", "location": "Break it. See it. Undo it. section", "severity": "structural", "problem": "The four steps in the left column are tall and sparse, and the demo terminal on the right ends early, leaving an empty block below it. Step 4 is boxed as active while the others are not, with no clear active-state logic.", "fix": "Make the steps a compact list that sticks beside the terminal. Highlight the active step in sync with the demo."}, {"screen": "home.desktop.dark", "location": "Diagram panel", "severity": "cosmetic", "problem": "The diagram labels are about 10px monospace and low-contrast, and the panel is mostly empty space, so the layers and the A/M/D chips are hard to read.", "fix": "Scale the diagram up, bring labels to at least 12px with higher-contrast text, and trim the padding."}, {"screen": "home.mobile.dark", "location": "Mobile hero demo and diagram", "severity": "structural", "problem": "The diagram shrinks until its labels are illegible, and the demo terminal's first line is clipped under the header (the \"--wait\" fragment).", "fix": "Show a simplified diagram on mobile and scroll the terminal body from the top. Alternatively, stack the labels beside the layers."}, {"screen": "snapshots.mobile.light", "location": "Code blocks on mobile", "severity": "structural", "problem": "Commands and comments are cut off at the right edge with no visible scroll cue or wrap, so `--description` strings and flags can't be read or copied with confidence.", "fix": "Soft-wrap code on narrow widths or add a fade and scrollbar cue, and add a copy button to the frame."}, {"screen": "snapshots.desktop.light", "location": "Code block frame", "severity": "systemic", "problem": "The decorative three-dot title bar is empty and adds height, and the block has no visible copy button or language label. The tinted background is also close to the page surface.", "fix": "Replace the dots with a label such as 'shell' plus a copy button. Strengthen the border or contrast against the page."}, {"screen": "cli-exec.desktop.dark", "location": "Reference page code block", "severity": "systemic", "problem": "The CLI help is a single unstyled pre block. The long flag descriptions are clipped on the right (the --timeout and --output lines), and there is no section anchor, so users can't scan Flags or Examples or link to them.", "fix": "Parse the sections into headings and a flag table with wrapping. Give the examples their own copyable blocks."}, {"screen": "cost.desktop.dark", "location": "Cost tables", "severity": "structural", "problem": "The price table sets the two region columns in monospace beside a proportional heading, and the section tables have different widths (the 1040px and 1193px tables against the full-width one), so the right edges don't align.", "fix": "Use one table width for all tables. Put the numeric columns in tabular figures and the units in a caption."}, {"screen": "snapshots.desktop.dark", "location": "Sidebar", "severity": "structural", "problem": "The sidebar ends abruptly at about 900px, leaving a mismatched dark block beside the longer page, and the reference list is cut off mid-item ('spin trust') with no scroll indication.", "fix": "Make the sidebar sticky and full height with its own scroll and a fade at the clipping edge."}, {"screen": "snapshots.desktop.dark", "location": "Top banner", "severity": "cosmetic", "problem": "The experimental banner sits in a bright teal band on every page, directly under the 'On this page' bar, and competes with the page title. The 'On this page' toggle and the banner are also stacked, which eats vertical space.", "fix": "Make it a slimmer neutral strip with a warning icon, or dismissible, and merge the toggle row into the header on desktop."}, {"screen": "evaluate.desktop.light", "location": "Body links and inline code", "severity": "cosmetic", "problem": "Bright blue underlined links appear in every paragraph beside tinted inline-code chips. In the Linux requirements list the chips are dense, with uneven padding and heavy visual noise.", "fix": "Tone down the link underline and use one chip style with consistent padding and a lower-contrast fill."}, {"screen": "home.desktop.light", "location": "Light-mode primary CTA and secondary button", "severity": "cosmetic", "problem": "Evaluate Spinbox is a small solid button with a barely visible outline secondary beside it. Both are small for a landing CTA, and the secondary lacks an affordance.", "fix": "Increase the button size and padding and give the secondary a clear border. Use the same CTA treatment on dark and light."}]} +{"round": 1, "reviewer": "codex/gpt", "kind": "full", "scores": {"hierarchy": 8, "typography": 8, "spacing": 8, "color": 8, "consistency": 8, "density": 8, "usability": 8, "polish": 8, "responsive": 8, "identity": 9}, "control": {"hierarchy": 8, "typography": 7, "spacing": 8, "color": 8, "consistency": 8, "density": 7, "usability": 7, "polish": 8, "responsive": 6, "identity": 8}, "pairs": [{"screen": "home.desktop.dark", "winner": "candidate", "reason": "More disciplined type scale and denser lower-page composition make the landing page easier to scan while retaining the infrastructure-product character."}, {"screen": "home.desktop.light", "winner": "baseline", "reason": "The stronger mono display treatment and higher-contrast terminal create a more distinctive, credible technical landing page."}, {"screen": "home.mobile.dark", "winner": "baseline", "reason": "On mobile, the cyan emphasis makes the central product promise materially clearer than the low-contrast secondary headline in b."}, {"screen": "snapshots.desktop.dark", "winner": "baseline", "reason": "Mono headings establish a clearer documentation identity without compromising the readable prose and code structure."}, {"screen": "snapshots.desktop.light", "winner": "candidate", "reason": "The branded heading treatment gives the light documentation page stronger hierarchy and parity with dark mode."}, {"screen": "snapshots.mobile.light", "winner": "candidate", "reason": "The compact single-line title preserves valuable narrow-screen space and improves document scanning."}, {"screen": "cost.desktop.dark", "winner": "candidate", "reason": "The sans-serif headings and tighter vertical rhythm make a data-heavy cost page easier to read."}, {"screen": "evaluate.desktop.light", "winner": "baseline", "reason": "Mono section headings make this overview feel purpose-built for operators rather than like generic documentation."}, {"screen": "cli-exec.desktop.dark", "winner": "baseline", "reason": "The wider, more consistently framed command-reference content improves scanning of the long CLI output."}, {"screen": "how-it-works.mobile.dark", "winner": "baseline", "reason": "The mono heading system better connects the mobile documentation page to Spinbox\u2019s technical identity."}], "findings": [{"screen": "home.desktop.dark", "location": "Hero headline, desktop", "severity": "structural", "problem": "The muted gray \u201cKeep control of what it changes\u201d is part of the primary promise but recedes too far relative to the white first clause.", "fix": "Use the cyan brand emphasis or a higher-contrast blue-white tone for the second clause; reserve muted text for supporting copy."}, {"screen": "home.desktop.dark", "location": "Hero-to-demo and demo-to-feature-section gaps", "severity": "structural", "problem": "The large vertical gaps weaken continuity from the value proposition into proof and then into the workflow.", "fix": "Reduce both section gaps and use a consistent section rhythm so the interactive demo reads as direct evidence for the headline."}, {"screen": "home.desktop.light", "location": "Light-theme code terminal", "severity": "systemic", "problem": "Command text is rendered in very pale blue on a pale surface, making commands less legible than surrounding prose.", "fix": "Increase code foreground contrast substantially and keep syntax color only for semantic tokens, not the entire command."}, {"screen": "home.mobile.dark", "location": "Mobile \u201cBreak it. See it. Undo it.\u201d section", "severity": "structural", "problem": "The terminal demo is shown before the explanatory steps, reversing the learning sequence on the narrow layout.", "fix": "Show the step list first, or interleave each step with the relevant terminal state before presenting the full transcript."}, {"screen": "snapshots.desktop.dark", "location": "Dark documentation body column", "severity": "systemic", "problem": "Several prose paragraphs and tables approach an overly wide reading measure for dense operational material.", "fix": "Constrain prose and standard tables to a narrower content measure; let wide code examples opt into a wider overflow container."}, {"screen": "snapshots.desktop.light", "location": "Light documentation code examples", "severity": "systemic", "problem": "Long commands visibly clip at the right edge, with no apparent horizontal-scroll affordance.", "fix": "Provide an obvious horizontal scrolling treatment with a fade/scroll cue and a copy control; preserve command text without destructive wrapping."}, {"screen": "snapshots.mobile.light", "location": "Mobile code examples", "severity": "broken", "problem": "The command lines are clipped horizontally, so essential arguments cannot be read or copied reliably.", "fix": "Make code blocks horizontally scrollable with visible affordance, or provide per-line copy and carefully wrap explanatory\u2014not executable\u2014content."}, {"screen": "cost.desktop.dark", "location": "\u201cThree months, priced\u201d table", "severity": "structural", "problem": "The scenario table relies on desktop width without a visible small-screen treatment, making its four-column comparison fragile.", "fix": "Define a responsive table pattern: retain scenario and price, stack or disclose the descriptive column, and preserve column headers."}, {"screen": "cli-exec.desktop.dark", "location": "CLI reference output panel", "severity": "broken", "problem": "The preformatted reference text runs beyond the visible right edge, hiding flag descriptions.", "fix": "Use a horizontally scrollable code/reference container with an explicit scroll cue and copy affordance; avoid clipping overflow."}, {"screen": "how-it-works.mobile.dark", "location": "Architecture diagram on mobile", "severity": "structural", "problem": "The diagram is scaled down until labels and relationships are not usable, despite being central to the page\u2019s explanation.", "fix": "Use a responsive diagram with a legible mobile composition, or supply a tap-to-expand full-resolution view and concise adjacent legend."}]} +{"round": 2, "reviewer": "claude/sonnet", "kind": "full", "scores": {"hierarchy": 7, "typography": 7, "spacing": 7, "color": 7, "consistency": 7, "density": 7, "usability": 7, "polish": 6, "responsive": 7, "identity": 7}, "control": {"hierarchy": 7, "typography": 6, "spacing": 7, "color": 7, "consistency": 7, "density": 6, "usability": 7, "polish": 6, "responsive": 7, "identity": 7}, "pairs": [{"screen": "home.desktop.dark", "winner": "candidate", "reason": "The smaller two-line headline puts the diagram and demo higher on the screen. The primary and secondary buttons both read as buttons, and the blue primary has stronger contrast."}, {"screen": "home.desktop.light", "winner": "candidate", "reason": "In the light theme the compact hero keeps the headline and CTAs in proportion. Both CTAs are clear buttons, and the diagram sits closer to the fold."}, {"screen": "home.mobile.dark", "winner": "candidate", "reason": "On the phone the headline takes three lines instead of five, and the full-width button pair is easier to tap. The diagram is visible sooner."}, {"screen": "snapshots.desktop.dark", "winner": "baseline", "reason": "The code blocks sit on a lighter navy surface that separates them from the page. The page title is in better proportion to the h2s, and the syntax colours are more varied."}, {"screen": "snapshots.desktop.light", "winner": "baseline", "reason": "The page title is better proportioned to the h2s, and the layout is tighter. The prose measure and code styling are otherwise the same as in a."}, {"screen": "snapshots.mobile.light", "winner": "candidate", "reason": "The smaller title and tighter header spacing show more content above the fold. Everything else is the same as a."}, {"screen": "cost.desktop.dark", "winner": "baseline", "reason": "The title is in better proportion to the section headings, and the logo sits on a tile that keeps it visible against the dark navy. The cost table is easier to scan."}, {"screen": "evaluate.desktop.light", "winner": "baseline", "reason": "The h1 and h2 scale is more restrained, so more of the prose and the nav cards fit on screen. The reading rhythm is the same as in a."}, {"screen": "cli-exec.desktop.dark", "winner": "baseline", "reason": "The CLI help block is on a more distinct navy surface, and the title is in better proportion. Both versions clip long lines at the right edge."}, {"screen": "how-it-works.mobile.dark", "winner": "candidate", "reason": "The h1 and h2 sizes are better matched to the body text on a narrow screen. Everything else is the same as in a."}], "findings": [{"screen": "cli-exec.desktop.dark", "location": "CLI reference pre block, the --timeout and --output flag rows", "severity": "structural", "problem": "Long flag descriptions run off the right edge of the block and are clipped, with no wrapping or scroll indicator. Descriptions are lost in the reference the audience relies on most.", "fix": "Wrap long lines in the generated help block with a hanging indent, or add a visible horizontal scroll affordance."}, {"screen": "snapshots.mobile.light", "location": "Code blocks on mobile ('Taking one', 'Going back')", "severity": "structural", "problem": "Commands are cut at the right edge (`--description \"bei`, `--wa`). They can only be read by horizontal scrolling, and nothing signals that. The window-chrome dots take space and add no meaning.", "fix": "Add a fade or scroll shadow on the overflow edge, and a copy button on every block. Drop the dots, or let long commands wrap with a continuation indent."}, {"screen": "snapshots.desktop.dark", "location": "Left sidebar, background panel", "severity": "cosmetic", "problem": "The sidebar surface ends abruptly at about y=900, while the page continues. This leaves a visible seam at the bottom of the nav column on long pages.", "fix": "Make the sidebar background extend the full viewport height, or remove its distinct background."}, {"screen": "snapshots.desktop.light", "location": "Light theme, code blocks and active nav item", "severity": "systemic", "problem": "The code surface is a cool grey-blue slab. The active sidebar item uses a saturated pale-blue fill with weak label contrast. Both blend with the banner colour and make the light theme feel washed out next to the dark theme.", "fix": "Use a near-white code surface with a 1px border. Switch the active nav item to a thin cyan or navy marker with a navy label."}, {"screen": "home.desktop.light", "location": "Dark terminal inside the light hero", "severity": "systemic", "problem": "A heavy near-black demo panel in the light theme overpowers the headline and breaks the light/dark parity. The light hero also carries two tinted bands (banner and diagram panel) at similar weight.", "fix": "Give the light theme a light terminal surface, or keep the terminal dark and tone down the banner. Make both themes use one token for code surfaces."}, {"screen": "home.desktop.dark", "location": "Hero diagram panel", "severity": "structural", "problem": "The diagram has large empty margins and tiny mono labels, about 10px. Its right half repeats the diff command and result, which the demo panel below shows again, and a gap sits between the diff text and the step chips.", "fix": "Scale the diagram and its labels up, or crop the panel to its content. Remove the duplicated diff text, or show one demo in one place."}, {"screen": "home.mobile.dark", "location": "Mobile hero diagram", "severity": "structural", "problem": "The diagram labels shrink to illegible size (about 6px) on the phone, so the diagram reads as decoration.", "fix": "Show a simplified vertical stack on narrow screens with labels at 12px or larger, or put the labels beneath the diagram."}, {"screen": "home.desktop.dark", "location": "'Break it. See it. Undo it.' section", "severity": "structural", "problem": "Four steps sit in a narrow left column against a demo panel with dead space beneath it. The step headings wrap badly ('Take a snapshot, memory and / all'), and only step 04 is boxed.", "fix": "Make the steps one even row or a stacked list with consistent boxing. Fix the heading widths. Put the demo panel in a sticky column or shorten it to match."}, {"screen": "home.mobile.dark", "location": "Mobile demo terminal", "severity": "broken", "problem": "The first lines of the terminal are clipped at the top (`--wait` is visible alone). The block cuts content without a scroll cue, and commands wrap mid-flag, which makes them hard to copy and read.", "fix": "Size the container to its content, or start the scroll at the top. Wrap with a hanging indent at flag boundaries."}, {"screen": "cost.desktop.dark", "location": "'All the time' and 'Settings' tables", "severity": "systemic", "problem": "The first table spans the full measure, but the next two stop at about 65 to 75% of it, each at a different width. Column widths and row heights are inconsistent across the page. The inline code chips in the settings table sit tight against the row rules.", "fix": "Give all tables the same width and the same first-column treatment. Add vertical padding to code chips in table cells."}, {"screen": "evaluate.desktop.light", "location": "Footer metadata line and pagination", "severity": "cosmetic", "problem": "The mono 'Installations run Spinbox\u2026' provenance line is small, low in contrast and has the same weight as the links inside it. The pagination cards use a large title face compared with the body text.", "fix": "Set the provenance line in the muted text token at 12px with a stronger link colour. Reduce the pagination title to the h4 size."}, {"screen": "snapshots.desktop.light", "location": "h1 and h2 headings in the monospace display face", "severity": "systemic", "problem": "Wide mono headings at a large size wrap quickly and eat vertical space in prose pages. On mobile, 'Snapshots and rollback' breaks into two lines. Headings look the same as code, which weakens the distinction between prose and commands.", "fix": "Use a proportional face for h1 to h3 and keep mono for code, ids and eyebrows. Otherwise cut the h2 size by about 15% and use tighter tracking."}, {"screen": "home.desktop.dark", "location": "Experimental banner under the header", "severity": "cosmetic", "problem": "The banner sits on every page, takes about 40px of fixed header space, and uses a bold teal-tinted fill that competes with the cyan CTA. On mobile it takes two lines.", "fix": "Make the banner a thin muted strip with a single line, or let it be dismissed. Use a neutral surface so cyan stays reserved for actions."}]} +{"round": 2, "reviewer": "codex/gpt", "kind": "full", "scores": {"hierarchy": 8, "typography": 8, "spacing": 8, "color": 8, "consistency": 8, "density": 8, "usability": 7, "polish": 8, "responsive": 7, "identity": 9}, "control": {"hierarchy": 8, "typography": 8, "spacing": 8, "color": 8, "consistency": 8, "density": 8, "usability": 7, "polish": 8, "responsive": 7, "identity": 9}, "pairs": [{"screen": "home.desktop.dark", "winner": "baseline", "reason": "The three-line hero preserves a clearer reading rhythm and gives the primary action more deliberate emphasis."}, {"screen": "home.desktop.light", "winner": "baseline", "reason": "The headline wraps naturally rather than forcing the cyan clause into a visually crowded two-line lockup."}, {"screen": "home.mobile.dark", "winner": "baseline", "reason": "The mobile hero has more consistent CTA hierarchy and breathing room."}, {"screen": "snapshots.desktop.dark", "winner": "candidate", "reason": "The larger page title creates a more legible documentation hierarchy without compromising the content column."}, {"screen": "snapshots.desktop.light", "winner": "candidate", "reason": "The title and section hierarchy are clearer while retaining a calm, documentation-first density."}, {"screen": "snapshots.mobile.light", "winner": "baseline", "reason": "The mobile heading scale is more distinct from body prose and section headings."}, {"screen": "cost.desktop.dark", "winner": "baseline", "reason": "It better balances the page title against the substantive table and reading content."}, {"screen": "evaluate.desktop.light", "winner": "baseline", "reason": "The page title is less oversized, keeping the long evaluation document focused on its content."}, {"screen": "cli-exec.desktop.dark", "winner": "candidate", "reason": "The stronger command-page title makes the reference hierarchy easier to scan."}, {"screen": "how-it-works.mobile.dark", "winner": "tie", "reason": "Both versions provide effectively the same clear mobile reading structure and visual hierarchy."}], "findings": [{"screen": "home.mobile.dark", "location": "Mobile landing-page terminal demo", "severity": "broken", "problem": "The first visible terminal line begins with \u201c--wait\u201d, making the command sequence look vertically clipped and breaking the demo narrative.", "fix": "Ensure the terminal transcript starts at its first command on narrow layouts; allow its height to expand or use an intentional scroll container with a visible overflow cue."}, {"screen": "snapshots.mobile.light", "location": "Mobile documentation code blocks", "severity": "structural", "problem": "Long commands are visibly cut off at the right edge with no horizontal-scroll affordance or wrapping strategy.", "fix": "Make code blocks horizontally scrollable with a persistent fade/scroll cue, or selectively wrap command examples while retaining copyable unwrapped source."}, {"screen": "home.mobile.dark", "location": "Mobile landing-page \u201cBreak it. See it. Undo it.\u201d section", "severity": "structural", "problem": "The terminal precedes the explanatory step cards, so the command output arrives before users understand the workflow it demonstrates.", "fix": "On narrow screens, place the compact step explanation before the terminal, or add a clearly labeled workflow summary immediately above it."}, {"screen": "snapshots.desktop.dark", "location": "Documentation prose column", "severity": "structural", "problem": "Desktop body copy spans a broad content area, producing lines that are long for sustained technical reading.", "fix": "Constrain prose to roughly 68\u201375ch while allowing tables and code samples to use a wider overflow-capable container."}, {"screen": "how-it-works.mobile.dark", "location": "Mobile documentation navigation", "severity": "structural", "problem": "The hamburger exposes navigation but there is no visible current-section or in-page progress signal once the sidebar is collapsed.", "fix": "Retain a compact current-page/current-heading indicator beneath the top bar, linked to the expanded navigation."}, {"screen": "cost.desktop.dark", "location": "Cost tables on dark documentation pages", "severity": "systemic", "problem": "Table rules and secondary labels are muted enough that scanning rows and associating region prices requires more effort than necessary.", "fix": "Increase row-divider and muted-label contrast slightly, while preserving cyan only for links and active states."}, {"screen": "home.desktop.dark", "location": "Landing-page lower workflow panel", "severity": "cosmetic", "problem": "The fourth \u201cRoll back\u201d card is visually isolated below the three-step list, weakening the intended sequence.", "fix": "Use a four-step grid at wide widths or connect the final card to the prior steps with an explicit continuation treatment."}]} +{"round": 3, "reviewer": "claude/sonnet", "kind": "full", "scores": {"hierarchy": 7, "typography": 7, "spacing": 7, "color": 7, "consistency": 8, "density": 7, "usability": 7, "polish": 7, "responsive": 7, "identity": 8}, "control": {"hierarchy": 7, "typography": 6, "spacing": 6, "color": 7, "consistency": 7, "density": 6, "usability": 7, "polish": 7, "responsive": 6, "identity": 8}, "pairs": [{"screen": "home.desktop.dark", "winner": "candidate", "reason": "Headline sets in two lines without the orphaned 'changes.', and the solid primary plus bordered secondary button read as a clear pair. The hero is shorter, so the demo shows sooner."}, {"screen": "home.desktop.light", "winner": "candidate", "reason": "The headline breaks cleanly in two lines and the solid blue primary beside a bordered secondary reads as two buttons. The hero is more restrained, and the mono eyebrow is not needed."}, {"screen": "home.mobile.dark", "winner": "candidate", "reason": "On a phone the headline takes three lines and not four, and both CTAs sit side by side as real buttons. The demo terminal comes sooner and there is less scrolling."}, {"screen": "snapshots.desktop.dark", "winner": "candidate", "reason": "Smaller h1 and h2 with tighter gaps give more prose per screen, and the headings still stand out from the body. The oversized mono h2s in the other version crowd the 960px measure."}, {"screen": "snapshots.desktop.light", "winner": "candidate", "reason": "The calmer heading scale suits documentation better. More content is visible per screen, and the code blocks and the prose around them keep a steadier rhythm."}, {"screen": "snapshots.mobile.light", "winner": "candidate", "reason": "The title fits on one line at 390px and the section headings are proportionate. The other version wraps the h1 to two lines and spends vertical space on oversized headings."}, {"screen": "cost.desktop.dark", "winner": "candidate", "reason": "The scenario and settings tables sit closer to their headings, so the cost data reads sooner. The heading scale is proportionate to the table text."}, {"screen": "evaluate.desktop.light", "winner": "candidate", "reason": "Moderate headings keep the page prose-led and let it fit on fewer screens. The oversized mono h2s in the other version compete with the body text."}, {"screen": "cli-exec.desktop.dark", "winner": "candidate", "reason": "Long flag descriptions wrap, so no text is clipped and no horizontal scroll is needed. The other version cuts off 'control plane gives\u2026' and the default values at the right edge."}, {"screen": "how-it-works.mobile.dark", "winner": "candidate", "reason": "The h1 stays on one line and the h2s are proportionate. The prose measure is unchanged and more of the architecture text fits on screen."}], "findings": [{"screen": "snapshots.desktop.dark", "location": "Starlight sidebar, left column", "severity": "structural", "problem": "The sidebar background ends at about 900px, and its nav list is clipped mid-item ('spin trust') on the CLI pages. Below that the page shows a different surface, so the column looks cut off. This appears on s04, s07 and s09, in dark and in light.", "fix": "Make the sidebar full viewport height with sticky positioning and the page background. Let the nav scroll inside it."}, {"screen": "cli-exec.desktop.dark", "location": "CLI reference
     block", "severity": "structural", "problem": "The help text is one big preformatted block with flag columns aligned by spaces. Long descriptions wrap back to column 0 and break the alignment. There is no copy button, and flags and examples are not separate elements.", "fix": "Render examples in normal code blocks with copy buttons. Render flags as a two-column table or definition list with a hanging indent, and keep the usage line as its own block."}, {"screen": "snapshots.mobile.light", "location": "Code blocks on mobile (Taking one, Going back)", "severity": "structural", "problem": "Commands are clipped at the right edge (the description string, '--wait', '--with-memory'). Nothing signals that the block scrolls, and the blocks have no copy button.", "fix": "Add a visible scroll affordance (edge fade) and a copy button in the frame. Consider wrapping with a hanging indent below 480px."}, {"screen": "home.mobile.dark", "location": "Hero demo terminal on mobile", "severity": "structural", "problem": "The terminal's first line is cut off at the top ('--wait' alone) and the box has no title context. The diagram labels (running \u00b7 writes here, snapshot \u00b7 after) are tiny and unreadable at 390px.", "fix": "Start the terminal at the first command, or size it to its content. Enlarge the labels or move them below the stack in a legend. Raise the minimum SVG text size to about 11\u201312px."}, {"screen": "home.desktop.dark", "location": "Hero demo panel", "severity": "systemic", "problem": "The right column leaves a large empty gap between the diff output and the step chips. The diagram and the code are different sizes and do not align on a baseline. The tiny 10px mono labels have weak contrast on the dark panel.", "fix": "Use a grid with aligned top and bottom edges. Fill or remove the gap. Raise the label size to 12px and the colour to the secondary text token."}, {"screen": "home.desktop.dark", "location": "Feature list '01 Snapshot \u2026 04 Roll back' beside terminal", "severity": "systemic", "problem": "Card 04 has a box and 01\u201303 do not, so the selected state looks arbitrary. Titles orphan a word ('memory and / all', 'never / happened'). The 'How we know' links are about 11px underlined and stand out too little. The terminal column ends well short of the list.", "fix": "Show the box only as an active-step state tied to the demo, or give all items one treatment. Set titles with text-wrap: balance. Make the links 13px and use a neutral colour until hover."}, {"screen": "cost.desktop.dark", "location": "Cost scenario table", "severity": "systemic", "problem": "The us-east-1 and us-west-2 columns carry identical figures ($50, $418, $1,575). The table has no emphasis on the totals, and the numbers are not set in a tabular mono face. The 'All the time' and 'Settings' tables use a different width, so the page has three table widths.", "fix": "Show one price column with a region note, or show the difference. Use tabular-nums and mono for figures. Give the tables one width and a consistent first-column weight."}, {"screen": "snapshots.desktop.light", "location": "Light-mode code frames", "severity": "systemic", "problem": "The code frame has an empty chrome bar with three faint dots and a flat pale-blue body. Comment text and the --flag tokens are low-contrast, below AA on the pale blue. The dots carry no function and a language or filename label would be more useful. The dark hero terminal is a different treatment from the docs code blocks.", "fix": "Drop the dots, or replace them with a shell label plus a copy button. Darken the comment and option tokens to at least 4.5:1. Use one code-block surface across hero and docs."}, {"screen": "snapshots.desktop.dark", "location": "Top banner 'Spinbox is experimental'", "severity": "systemic", "problem": "The full-width teal/blue band is the most saturated surface on every page, in both themes, and competes with the page title. It repeats on every screen. It is a status message but uses the brand cyan colour, so it does not read as a warning.", "fix": "Make it a thin, dismissible neutral strip with an amber or status-coloured marker. Keep the brand cyan for interactive elements."}, {"screen": "snapshots.desktop.dark", "location": "Sidebar top-level tabs and 'On this page' bar", "severity": "cosmetic", "problem": "The icon tiles for Docs, Install, Security and Reference carry icons in coloured squares, and the active one is a bright cyan tile. They are heavier than the page links below. The 'On this page' bar and the breadcrumb 'Overview' have small, unaligned controls.", "fix": "Use plain monoline icons and mark the active tab with a left rule and text colour. Align the TOC trigger height with the search field."}, {"screen": "evaluate.desktop.light", "location": "Inline code and body links", "severity": "cosmetic", "problem": "Inline code chips on the pale grey-blue sit close to the link colour. Links inside lists are underlined at weight equal to body, so many underlined phrases per paragraph make dense runs hard to scan.", "fix": "Give inline code a clear surface and a 1px border. Use a slightly heavier link colour with a thin underline offset."}, {"screen": "home.desktop.light", "location": "Hero headline and eyebrow", "severity": "cosmetic", "problem": "The two-colour mono headline ('Keep control of what it changes.') runs in cyan over a large block of the hero. The eyebrow 'spin-stack \u00b7 self-hosted sandboxes' is a small low-contrast line. Together the hero says little about AWS or the product name.", "fix": "Colour only 'what it changes' in cyan. Strengthen the eyebrow with the product name or a version, and keep it at least 13px."}, {"screen": "how-it-works.mobile.dark", "location": "Architecture diagram on mobile", "severity": "systemic", "problem": "The AWS diagram is shrunk to full width at 390px and every label is illegible. It is a white image on a dark page, so it is glaring and not in the theme. It has no tap-to-zoom.", "fix": "Link the image to a full-size view (lightbox or open in new tab). Offer a dark variant or a muted frame, and add a text list of the parts as an alternative."}]}
    +{"round": 3, "reviewer": "codex/gpt", "kind": "full", "scores": {"hierarchy": 8, "typography": 8, "spacing": 8, "color": 8, "consistency": 9, "density": 8, "usability": 8, "polish": 8, "responsive": 8, "identity": 9}, "control": {"hierarchy": 8, "typography": 8, "spacing": 7, "color": 8, "consistency": 8, "density": 7, "usability": 7, "polish": 8, "responsive": 6, "identity": 9}, "pairs": [{"screen": "home.desktop.dark", "winner": "baseline", "reason": "The headline\u2019s line breaks preserve the two-part message: the cyan promise reads as one deliberate unit."}, {"screen": "home.desktop.light", "winner": "candidate", "reason": "The two-line desktop headline is materially more compact while retaining a clear reading order."}, {"screen": "home.mobile.dark", "winner": "candidate", "reason": "It uses the narrow viewport more efficiently: the main statement stays to three lines rather than fragmenting the first sentence."}, {"screen": "snapshots.desktop.dark", "winner": "tie", "reason": "No meaningful visible difference in hierarchy, readability, or layout."}, {"screen": "snapshots.desktop.light", "winner": "tie", "reason": "No meaningful visible difference in hierarchy, readability, or layout."}, {"screen": "snapshots.mobile.light", "winner": "candidate", "reason": "The single-line page title creates a cleaner, more efficient mobile document header without sacrificing legibility."}, {"screen": "cost.desktop.dark", "winner": "candidate", "reason": "The slightly tighter vertical rhythm makes the long operational cost document easier to scan."}, {"screen": "evaluate.desktop.light", "winner": "tie", "reason": "Both establish the same strong documentation hierarchy and readable measure."}, {"screen": "cli-exec.desktop.dark", "winner": "candidate", "reason": "The reference content is set in a marginally more contained reading column, which better suits a very wide CLI output block."}, {"screen": "how-it-works.mobile.dark", "winner": "tie", "reason": "Both provide the same clear, mobile-first technical-document layout."}], "findings": [{"screen": "home.desktop.dark", "location": "Desktop hero, secondary CTA", "severity": "structural", "problem": "\u201cInstall on AWS\u201d is visually too close to plain supporting text in the preferred dark variant, despite being a primary evaluation path.", "fix": "Use a quiet outlined secondary button with the same height, padding, and focus treatment as the primary CTA."}, {"screen": "home.desktop.light", "location": "Hero-to-demo transition", "severity": "structural", "problem": "The large gap after the demo panel makes the first explanatory workflow feel detached from the product demonstration.", "fix": "Reduce the section spacing one step or introduce a short transition label that links the demo to the workflow."}, {"screen": "home.mobile.dark", "location": "Mobile workflow section", "severity": "structural", "problem": "The terminal appears before the explanatory steps, unlike the desktop split layout; users encounter dense commands before the task context.", "fix": "On narrow screens, place the selected step summary above the terminal or add a persistent step indicator immediately above it."}, {"screen": "snapshots.mobile.light", "location": "Mobile code examples", "severity": "broken", "problem": "Long command lines are horizontally clipped with no visible wrapping, scrolling affordance, or copy control.", "fix": "Provide a horizontally scrollable code region with a visible edge/fade affordance and a copy button; preserve unwrapped commands."}, {"screen": "cost.desktop.dark", "location": "Cost comparison table", "severity": "structural", "problem": "The table relies on dense prose in the \u201cWhat runs\u201d column and weakly separated monetary columns, making cross-region comparison slow.", "fix": "Strengthen header/column alignment and use a narrower scenario description or responsive stacked row treatment before the table becomes cramped."}, {"screen": "evaluate.desktop.light", "location": "Documentation article body", "severity": "systemic", "problem": "The article\u2019s wide desktop measure approaches the upper comfortable limit for dense prose, especially in the opening explanatory paragraphs.", "fix": "Cap prose content closer to 70\u201375ch while allowing tables and code blocks to use a wider overflow container."}, {"screen": "cli-exec.desktop.dark", "location": "CLI reference command panel", "severity": "broken", "problem": "The long generated reference lines visibly run into or beyond the panel edge, impairing command and flag readability.", "fix": "Make the command reference block horizontally scrollable, retain full monospace lines, and expose a clear horizontal-scroll affordance."}, {"screen": "how-it-works.mobile.dark", "location": "Mobile architecture diagram", "severity": "cosmetic", "problem": "The diagram is technically visible but too small to convey the relationships described in the adjacent text.", "fix": "Open the image in a zoomable lightbox or provide a simplified mobile-specific diagram with readable labels."}]}
    diff --git a/ui-hill-climb/product.md b/ui-hill-climb/product.md
    new file mode 100644
    index 0000000..345f443
    --- /dev/null
    +++ b/ui-hill-climb/product.md
    @@ -0,0 +1,9 @@
    +Product: Spinbox, a self-hosted platform (in the customer's own AWS account) for running isolated sandboxes, development workspaces and AI agents, each a virtual machine with snapshots and diffs. This is its WEBSITE: a landing page and the documentation (Astro Starlight) - concepts, AWS setup and cost, the CLI reference - read by infrastructure and platform engineers evaluating and operating it.
    +
    +Direction constraints:
    +- Readable documentation first: comfortable prose at a measure, clear heading hierarchy, code blocks and commands easy to copy and read.
    +- The brand: navy and the mark's cyan; restrained colour with semantic meaning; contrast WCAG AA at least.
    +- Commands, ids and output in a monospace face; prose and headings legible at every screen size.
    +- Light and dark both first-class; works on a phone.
    +- Not a generic SaaS template: purpose-built for a serious infrastructure product.
    +References (ref-*.png) are infrastructure consoles, a bar for colour, contrast and restraint, not for layout.
    \ No newline at end of file
    diff --git a/ui-hill-climb/prompt-pairs.md b/ui-hill-climb/prompt-pairs.md
    new file mode 100644
    index 0000000..5793002
    --- /dev/null
    +++ b/ui-hill-climb/prompt-pairs.md
    @@ -0,0 +1,35 @@
    +You are reviewing the UI of a real product. You cannot and must not modify any file.
    +
    +Product: Spinbox, a self-hosted platform (in the customer's own AWS account) for running isolated sandboxes, development workspaces and AI agents, each a virtual machine with snapshots and diffs. This is its WEBSITE: a landing page and the documentation (Astro Starlight) - concepts, AWS setup and cost, the CLI reference - read by infrastructure and platform engineers evaluating and operating it.
    +
    +Direction constraints:
    +- Readable documentation first: comfortable prose at a measure, clear heading hierarchy, code blocks and commands easy to copy and read.
    +- The brand: navy and the mark's cyan; restrained colour with semantic meaning; contrast WCAG AA at least.
    +- Commands, ids and output in a monospace face; prose and headings legible at every screen size.
    +- Light and dark both first-class; works on a phone.
    +- Not a generic SaaS template: purpose-built for a serious infrastructure product.
    +References (ref-*.png) are infrastructure consoles, a bar for colour, contrast and restraint, not for layout.
    +
    +Attached:
    +- Reference products in the same category (ref-*.png): the bar for a 10.
    +- Pairs of the same screen in two versions (sNN-a.png, sNN-b.png), in no particular order.
    +- Single screens (cNN.png) to score on their own, if any.
    +
    +Tasks:
    +1. For each pair, say which version is better for this product and audience, or "tie", and the
    +   single most important reason.
    +2. For the version you preferred overall, score each rubric category 1-10 ("scores"); and score the
    +   cNN screens together on the same rubric ("control"). If there are no cNN screens, repeat
    +   "scores" in "control".
    +Rubric, each 1-10 where 10 is the best reference product in the set, not perfection:
    +hierarchy (what matters is seen first), typography (scale, weights, legibility of data and ids),
    +spacing (consistent scale, alignment), color (semantic roles, contrast, restraint; tones that are
    +too saturated or surfaces that blend count against it), consistency, density, usability
    +(navigation, affordances, state feedback), polish (edges, corners, borders, details),
    +responsive (narrow layouts designed), identity (purpose-built for this product and audience).
    +3. List concrete findings about the version you preferred: screen id, location, the problem, and
    +   the fix. Prefer structural and systemic problems over cosmetic ones. No generic advice. At most
    +   12 findings.
    +
    +Judge only what is visible. Do not assume either version is newer. Answer with JSON matching the
    +attached schema and nothing else.
    diff --git a/ui-hill-climb/review.schema.json b/ui-hill-climb/review.schema.json
    new file mode 100644
    index 0000000..bd0b30c
    --- /dev/null
    +++ b/ui-hill-climb/review.schema.json
    @@ -0,0 +1,58 @@
    +{
    +  "title": "ui-hill-climb review",
    +  "type": "object",
    +  "additionalProperties": false,
    +  "required": ["pairs", "scores", "control", "findings"],
    +  "$defs": {
    +    "score": { "type": "integer", "minimum": 1, "maximum": 10 },
    +    "scores": {
    +      "type": "object",
    +      "additionalProperties": false,
    +      "required": ["hierarchy", "typography", "spacing", "color", "consistency", "density", "usability", "polish", "responsive", "identity"],
    +      "properties": {
    +        "hierarchy": { "$ref": "#/$defs/score" },
    +        "typography": { "$ref": "#/$defs/score" },
    +        "spacing": { "$ref": "#/$defs/score" },
    +        "color": { "$ref": "#/$defs/score" },
    +        "consistency": { "$ref": "#/$defs/score" },
    +        "density": { "$ref": "#/$defs/score" },
    +        "usability": { "$ref": "#/$defs/score" },
    +        "polish": { "$ref": "#/$defs/score" },
    +        "responsive": { "$ref": "#/$defs/score" },
    +        "identity": { "$ref": "#/$defs/score" }
    +      }
    +    }
    +  },
    +  "properties": {
    +    "pairs": {
    +      "type": "array",
    +      "items": {
    +        "type": "object",
    +        "additionalProperties": false,
    +        "required": ["screen", "winner", "reason"],
    +        "properties": {
    +          "screen": { "type": "string", "description": "Pair id, e.g. s01" },
    +          "winner": { "type": "string", "enum": ["a", "b", "tie"] },
    +          "reason": { "type": "string" }
    +        }
    +      }
    +    },
    +    "scores": { "$ref": "#/$defs/scores", "description": "Scores of the version preferred overall" },
    +    "control": { "$ref": "#/$defs/scores", "description": "Scores of the single cNN screens" },
    +    "findings": {
    +      "type": "array",
    +      "items": {
    +        "type": "object",
    +        "additionalProperties": false,
    +        "required": ["screen", "location", "severity", "problem", "fix"],
    +        "properties": {
    +          "screen": { "type": "string" },
    +          "location": { "type": "string" },
    +          "severity": { "type": "string", "enum": ["broken", "structural", "systemic", "cosmetic"] },
    +          "problem": { "type": "string" },
    +          "fix": { "type": "string" }
    +        }
    +      }
    +    }
    +  }
    +}
    diff --git a/ui-hill-climb/screens.json b/ui-hill-climb/screens.json
    new file mode 100644
    index 0000000..5db61f2
    --- /dev/null
    +++ b/ui-hill-climb/screens.json
    @@ -0,0 +1,104 @@
    +{
    + "viewports": {
    +  "desktop": [
    +   1440,
    +   900
    +  ],
    +  "mobile": [
    +   390,
    +   844
    +  ]
    + },
    + "themes": [
    +  "dark",
    +  "light"
    + ],
    + "screens": [
    +  {
    +   "id": "home",
    +   "path": "/website/",
    +   "viewports": [
    +    "desktop",
    +    "mobile"
    +   ],
    +   "steps": [
    +    {
    +     "wait": 600
    +    }
    +   ]
    +  },
    +  {
    +   "id": "how-it-works",
    +   "path": "/website/overview/how-it-works/",
    +   "steps": [
    +    {
    +     "wait": 400
    +    }
    +   ]
    +  },
    +  {
    +   "id": "snapshots",
    +   "path": "/website/concepts/snapshots/",
    +   "steps": [
    +    {
    +     "wait": 400
    +    }
    +   ]
    +  },
    +  {
    +   "id": "cost",
    +   "path": "/website/aws/cost/",
    +   "viewports": [
    +    "desktop"
    +   ],
    +   "steps": [
    +    {
    +     "wait": 400
    +    }
    +   ]
    +  },
    +  {
    +   "id": "evaluate",
    +   "path": "/website/overview/evaluate/",
    +   "viewports": [
    +    "desktop"
    +   ],
    +   "steps": [
    +    {
    +     "wait": 400
    +    }
    +   ]
    +  },
    +  {
    +   "id": "release",
    +   "path": "/website/reference/release/",
    +   "viewports": [
    +    "desktop"
    +   ],
    +   "themes": [
    +    "dark"
    +   ],
    +   "steps": [
    +    {
    +     "wait": 400
    +    }
    +   ]
    +  },
    +  {
    +   "id": "cli-exec",
    +   "path": "/website/reference/cli/exec/",
    +   "viewports": [
    +    "desktop",
    +    "mobile"
    +   ],
    +   "themes": [
    +    "dark"
    +   ],
    +   "steps": [
    +    {
    +     "wait": 400
    +    }
    +   ]
    +  }
    + ]
    +}
    \ No newline at end of file
    diff --git a/versions.yaml b/versions.yaml
    index ed975cf..accae12 100644
    --- a/versions.yaml
    +++ b/versions.yaml
    @@ -29,7 +29,7 @@
       kind: git
       source: https://github.com/spin-stack/brand
       version: main
    -  pin: 7e17029f6a087f386a4798af03df6e9623ecfe12
    +  pin: b7e4afcc3f5def534915077a2f4fc79a867f0924
       track: branch
       note: >-
         The palette and the logos. brand cuts no releases, so its main is what it has to say. The