/* Self-hosted JetBrains Mono (latin subset, variable weight 100-800, ~31 KB) --
   the brand display face (DESIGN.md §3). font-display: swap so text renders
   in the fallback mono stack while it loads. */
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url("fonts/jetbrains-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --ink-950: #0f1012;
  --ink-900: #17181b;
  --ink-800: #202226;
  --ink-700: #2a2c30;
  --ink-600: #5a5d63;
  --ink-500: #8a8d93;
  --ink-300: #c9cbce;
  --paper: #f7f6f3;
  --paper-raised: #ffffff;
  --accent: #e6a03c; /* hex fallback; oklch override in @supports below */
  --accent-on-light: oklch(0.66 0.14 75);
  --mono: "JetBrains Mono", "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Dither vocabulary (SITE-PLAN §1) --- raw RGB channels for the two dither
     inks, so consumers set only --dither-alpha to pick a step. */
  --dither-amber: 230, 160, 60;   /* amber ink, matches mock rgba(230,160,60) */
  --dither-paper: 247, 246, 243;  /* paper ink, matches mock rgba(247,246,243) */

  /* Dither-alpha steps (subtle -> dense). Consumers pick one via --dither-alpha. */
  --dither-a1: 0.08;   /* faint paper wash (mock line 42) */
  --dither-a2: 0.18;   /* halftone tail (mock line 177) */
  --dither-a3: 0.2;    /* amber halo base (mock line 41) */
  --dither-a4: 0.28;   /* amber wedges (mock lines 44-45) */
  --dither-a5: 0.35;   /* mock line 110 glow */
  --dither-a6: 0.5;    /* dense window glow (mock line 109) */

  /* Hard offset shadow --- never blurred (SITE-PLAN §1, mock line 111). */
  --hard-shadow: 8px 8px 0 rgba(0, 0, 0, 0.55);

  /* Product-window mock hairline (mock lines 113, 125, 134, 146, 149): a hair
     lighter than --ink-700 (window border). Scoped to the mock rather than
     reusing --ink-800, which the header also relies on. */
  --mock-hairline: #24262a;
}

/* Wide-gamut accent where oklch is supported (DESIGN.md's canonical value);
   older browsers keep the hex fallback declared in :root. */
@supports (color: oklch(0.78 0.15 75)) {
  :root {
    --accent: oklch(0.78 0.15 75);
  }
}

* {
  box-sizing: border-box;
}

/* Hard geometry baseline (SITE-PLAN §1): squared corners everywhere. Individual
   components opt back into rounding only where a real macOS widget needs it
   (traffic lights below). */
*,
*::before,
*::after {
  border-radius: 0;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  color: var(--paper);
  background: var(--ink-950);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
}

a {
  color: inherit;
}

.site-header {
  align-items: center;
  background: var(--ink-950);
  border-bottom: 1px solid var(--ink-800);
  color: var(--paper);
  display: flex;
  gap: 24px;
  justify-content: space-between;
  padding: 18px 48px;
}

.brand {
  align-items: center;
  display: inline-flex;
  gap: 12px;
  min-width: max-content;
  text-decoration: none;
}

.brand-mark {
  display: inline-flex;
  gap: 4px;
}

.brand-mark span {
  display: block;
  height: 9px;
  width: 9px;
}

.brand-mark span:first-child {
  background: var(--accent);
}

.brand-mark span:last-child {
  background: var(--paper);
}

.wordmark {
  color: var(--paper);
  font-family: var(--mono);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* Pixel-umlaut o (mock lines 79-88): a hidden "ö" reserves the slot width, a
   positioned "o" sits under two 3px squares — left amber, right paper. */
.wm-o {
  display: inline-block;
  position: relative;
}
.wm-o-space {
  visibility: hidden;
}
.wm-o-body {
  bottom: 0;
  left: 0;
  position: absolute;
}
.wm-dot {
  height: 3px;
  position: absolute;
  top: 4px;
  width: 3px;
}
.wm-dot-l {
  background: var(--accent);
  left: 2px;
}
.wm-dot-r {
  background: var(--paper);
  left: 7px;
}

.nav-links {
  align-items: center;
  display: flex;
  gap: 28px;
  font-size: 13px;
  font-weight: 600;
}

.nav-links a {
  color: var(--ink-300);
  isolation: isolate; /* keep the z-index:-1 hover underlay inside the link */
  position: relative;
  text-decoration: none;
}

/* Nav-link hover: a subtle amber-dither underlay fades the text to paper --
   dither texture on hover, never a smooth color wash (SITE-PLAN §1). */
.nav-links a:not(.nav-cta)::before {
  background: conic-gradient(
    rgba(var(--dither-amber), 0.5) 25%,
    transparent 0 50%,
    rgba(var(--dither-amber), 0.5) 0 75%,
    transparent 0
  );
  background-size: 2px 2px;
  bottom: -3px;
  content: "";
  left: -3px;
  opacity: 0;
  pointer-events: none;
  position: absolute;
  right: -3px;
  top: -3px;
  z-index: -1;
}
.nav-links a:not(.nav-cta):hover {
  color: var(--paper);
}
.nav-links a:not(.nav-cta):hover::before {
  opacity: 1;
}

.nav-links .nav-cta {
  background: var(--accent);
  color: var(--ink-950);
  overflow: hidden;
  padding: 8px 16px;
  position: relative;
}
/* CTA hover: a paper-dither texture sweeps over the amber (no smooth fade). */
.cta-dither {
  overflow: hidden;
  position: relative; /* containing block for the ::after overlay */
}
.cta-dither::after {
  background: conic-gradient(
    rgba(var(--dither-paper), 0.55) 25%,
    transparent 0 50%,
    rgba(var(--dither-paper), 0.55) 0 75%,
    transparent 0
  );
  background-size: 3px 3px;
  content: "";
  inset: 0;
  opacity: 0;
  pointer-events: none;
  position: absolute;
}
.cta-dither:hover::after {
  opacity: 1;
}

/* Keyboard focus. The clip-path on .pixel-clip eats outlines drawn outside
   the shape, so the CTA focus ring sits inset, inside the clip. */
.pixel-clip:focus-visible {
  outline: 2px solid var(--ink-950);
  outline-offset: -6px;
}
.nav-links a:not(.nav-cta):focus-visible {
  color: var(--paper);
}
.nav-links a:not(.nav-cta):focus-visible::before {
  opacity: 1;
}

.hero {
  background: var(--ink-950);
  color: var(--paper);
  overflow: hidden;
  padding: 58px 48px 34px;
  position: relative;
}

/* Decorative layer holding halos, wedges, and stair ornaments. Spans the top
   of the hero; every child is pointer-events:none via its utility class. */
.hero-fx {
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  position: absolute;
}

/* Dither halo behind the headline -- three stacked layers, denser than the
   mock so the texture reads at arm's length (SITE-PLAN §1 "denser fields").
   All anchored to the top of the hero. */
.hero-halo-amber,
.hero-halo-paper,
.hero-halo-coarse {
  left: 0;
  right: 0;
  top: 0;
}
.hero-halo-amber {
  --dither-cell: 5px;
  --dither-rgb: var(--dither-amber);
  --dither-alpha: 0.24; /* raised above mock's .20 */
  --dither-mask: radial-gradient(ellipse 72% 74% at 50% 0%, #000, transparent 74%);
  height: 560px;
}
.hero-halo-paper {
  --dither-cell: 3px;
  --dither-rgb: var(--dither-paper);
  --dither-alpha: 0.1; /* slightly above mock's .08 */
  --dither-mask: radial-gradient(ellipse 45% 50% at 50% 0%, #000, transparent 70%);
  height: 560px;
}
/* New coarse 8px amber layer -- low alpha, wide spread; carries the texture
   at distance without muddying the headline. */
.hero-halo-coarse {
  --dither-cell: 8px;
  --dither-rgb: var(--dither-amber);
  --dither-alpha: 0.12;
  --dither-mask: radial-gradient(ellipse 82% 66% at 50% 6%, #000, transparent 78%);
  height: 520px;
}

/* Amber corner wedges, left + right of the hero (mock lines 44-45). */
.hero-wedge-l,
.hero-wedge-r {
  --dither-cell: 6px;
  --dither-rgb: var(--dither-amber);
  --dither-alpha: 0.28;
  height: 420px;
}
.hero-wedge-l {
  --dither-mask: radial-gradient(ellipse 100% 70% at 0% 50%, #000, transparent 75%);
  left: 0;
  top: 120px;
  width: 300px;
}
.hero-wedge-r {
  --dither-mask: radial-gradient(ellipse 100% 70% at 100% 40%, #000, transparent 75%);
  height: 460px;
  right: 0;
  top: 60px;
  width: 340px;
}

/* Pixel stair scatter ornaments (mock lines 47-70). */
.stair-tr {
  position: absolute;
  right: 56px;
  top: 80px;
}
.stair-ml {
  left: 44px;
  position: absolute;
  top: 280px;
}

.hero-copy {
  margin: 0 auto 42px;
  max-width: 820px;
  position: relative; /* lift copy above .hero-fx */
  text-align: center;
  z-index: 1;
}

/* Screen-reader-only text (keeps the accessible "döts" word for the aria-hidden
   decorative treatment). */
.visually-hidden {
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* Treatment B -- dither-textured accent word "döts": real JetBrains Mono bold
   filled with an amber Bayer checker via background-clip:text. Umlaut dots are
   the natural glyph dots, so the word reads instantly at any size. */
.dots-accent {
  background-image: conic-gradient(
    rgba(var(--dither-amber), 1) 25%,
    rgba(var(--dither-amber), 0.4) 0 50%,
    rgba(var(--dither-amber), 1) 0 75%,
    rgba(var(--dither-amber), 0.4) 0
  );
  background-size: 4px 4px;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* Fallback: where background-clip:text is unsupported, show a solid amber word. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .dots-accent {
    background: none;
    color: var(--accent);
  }
}

.eyebrow,
.section-kicker {
  color: var(--accent);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  margin: 0 0 12px;
  text-transform: lowercase;
}

h1,
h2,
p {
  margin-top: 0;
}

h1 {
  font-family: var(--mono);
  font-size: clamp(34px, 8vw, 58px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.12;
  margin-bottom: 20px;
}

.lede {
  color: var(--ink-300);
  font-size: 17px;
  line-height: 1.6;
  margin: 0 auto;
  max-width: 610px;
}

.hero-actions {
  align-items: center;
  display: flex;
  gap: 16px;
  justify-content: center;
  margin-top: 28px;
}

.button-primary {
  background: var(--accent);
  color: var(--ink-950);
  display: inline-flex;
  font-weight: 700;
  justify-content: center;
  min-height: 46px;
  min-width: 190px;
  padding: 12px 22px;
  text-decoration: none;
}

.button-primary:hover {
  filter: brightness(1.04);
}

.download-disabled {
  cursor: default;
  opacity: 0.6; /* visibly inert until a real build ships */
}

.meta-line {
  color: var(--ink-500); /* ink-600 fails 4.5:1 on ink-950 */
  font-family: var(--mono);
  font-size: 12px;
}

/* Wrapper positions the dither glow behind the window; the window itself is
   the positioned, opaque layer on top (mock lines 108-111). */
.product-shell-wrap {
  margin: 0 auto;
  /* Reserve room in the hero's (overflow:hidden) flow for the glow's bottom
     overhang (-90px, see .mock-glow-wide) so it isn't clipped. */
  margin-bottom: 90px;
  max-width: 1060px;
  position: relative;
}

/* Double dither glow (mock lines 109-110): wide 6px field with heavy overhang
   top/bottom + a tighter, shorter-reach 3px field. Both center-masked
   ellipses so the glow blooms from the middle and fades at the edges. */
.mock-glow {
  bottom: 0;
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
  top: 0;
}
/* Glow layers behind the window (mock lines 109-110). */
.mock-glow-wide {
  --dither-cell: 6px;
  --dither-rgb: var(--dither-amber);
  --dither-alpha: var(--dither-a6);
  --dither-mask: radial-gradient(ellipse 60% 58% at 50% 50%, #000, transparent 72%);
  bottom: -90px;
  left: 0;
  position: absolute;
  right: 0;
  top: -70px;
}
.mock-glow-tight {
  --dither-cell: 3px;
  --dither-rgb: var(--dither-amber);
  --dither-alpha: var(--dither-a5);
  --dither-mask: radial-gradient(ellipse 50% 50% at 50% 50%, #000, transparent 65%);
  bottom: -50px;
  left: 40px;
  position: absolute;
  right: 40px;
  top: -30px;
}

.product-shell {
  background: var(--ink-900);
  border: 1px solid var(--ink-700);
  box-shadow: var(--hard-shadow);
  overflow: hidden;
  position: relative;
}

.window-bar {
  align-items: center;
  border-bottom: 1px solid var(--mock-hairline);
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(3, 11px) 1fr;
  padding: 11px 14px;
}

.traffic {
  border-radius: 50%;
  display: block;
  height: 11px;
  width: 11px;
}

.traffic-red {
  background: #ff5f57;
}

.traffic-yellow {
  background: #febc2e;
}

.traffic-green {
  background: #28c840;
}

.window-title {
  color: var(--ink-600);
  font-size: 12px;
  font-weight: 600;
  text-align: center;
}

.workspace-preview {
  display: grid;
  font-family: var(--mono);
  font-size: 12px;
  grid-template-columns: 180px 1fr 190px 1.1fr;
  height: 360px;
}

.project-rail,
.file-rail,
.terminal-pane,
.editor-pane {
  border-right: 1px solid var(--mock-hairline);
  min-width: 0;
  overflow: hidden;
}

.editor-pane {
  border-right: 0;
}

.project-rail,
.file-rail {
  color: var(--ink-300);
  font-family: var(--sans);
  padding: 14px 0;
}

.rail-label {
  color: var(--ink-600);
  font-size: 10px;
  font-weight: 700;
  margin: 0;
  padding: 0 14px 8px;
}

.rail-row,
.file-row {
  align-items: center;
  display: flex;
  gap: 7px;
  min-height: 27px;
  padding: 4px 14px;
  white-space: nowrap;
}

.rail-row.nested {
  padding-left: 26px;
}

.rail-row span {
  background: var(--ink-700);
  display: inline-block;
  height: 6px;
  width: 6px;
}

.rail-row.running span {
  background: var(--accent);
}

.rail-row.active,
.file-row.active {
  background: var(--mock-hairline);
  color: var(--paper);
}

.file-row.active span {
  color: var(--accent);
}

.terminal-pane,
.editor-pane {
  color: var(--ink-300);
  line-height: 1.75;
  padding: 14px 16px;
}

.terminal-pane p,
.editor-pane p {
  margin: 0;
  white-space: nowrap;
}

/* .muted covers both the terminal's boxed CLI banner (mock ink-600) and the
   editor's keyword tokens (mock ink-500) -- ink-500 wins since keywords are
   the dominant use; the one banner/comment line that needs ink-600 is
   corrected per-pane below. */
.muted {
  color: var(--ink-500);
}

.terminal-pane .muted,
.editor-pane p:first-child .muted {
  color: var(--ink-600);
}

.dim {
  color: var(--ink-500);
}

.prompt {
  color: var(--ink-600);
}

.accent-text {
  color: var(--accent);
}

.bright-text {
  color: var(--paper);
}

.cursor {
  background: var(--accent);
  display: inline-block;
  height: 14px;
  vertical-align: middle;
  width: 7px;
}

/* Halftone ramp seam out of the hero/mock region (SITE-PLAN §2.4). Negative
   margin pulls it up under the mock's glow overhang so the seam reads as the
   hero's own fade-out rather than a gap before the proof grid. */
.seam-out-of-hero {
  margin-top: -32px;
  position: relative;
  z-index: 1;
}

.agent-strip {
  align-items: center;
  background: var(--ink-950);
  color: var(--paper);
  display: grid;
  gap: 28px;
  grid-template-columns: minmax(220px, 0.7fr) 1fr;
  padding: 48px 48px 56px;
}

.agent-strip h2,
.download h2 {
  color: var(--paper);
  font-family: var(--mono);
  font-size: 26px;
  letter-spacing: 0;
  line-height: 1.25;
  margin-bottom: 0;
}

.agent-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: flex-end;
  list-style: none;
  margin: 0;
  padding: 0;
}

.agent-list li {
  background: var(--ink-900);
  border: 1px solid var(--mock-hairline);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
  padding: 10px 12px;
}

/* Proof grid (mock lines 180-194): 1px #24262A gutters via the grid-gap trick
   -- the grid background paints the gutter color, each cell paints ink-950
   over it, so only the 1px seams between/around cells show the gutter. */
.proof {
  background: var(--mock-hairline);
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(3, 1fr);
}

.proof article {
  background: var(--ink-950);
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 190px;
  padding: 36px 48px;
}

.proof h2 {
  color: var(--paper);
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
  margin-bottom: 0;
}

.proof p,
.download p {
  color: var(--ink-500);
  font-size: 13px;
  line-height: 1.55;
  margin-bottom: 0;
}

/* Pixel-stair seam before the download section (SITE-PLAN §2.7): sparse,
   decorative, low-opacity scatter -- a quiet seam, not a stripe. */
.stair-seam {
  overflow: hidden;
  padding: 18px 0;
}

.download {
  background: var(--ink-950);
  color: var(--paper);
  overflow: hidden;
  padding: 54px 48px 64px;
  position: relative;
  text-align: center;
}

/* Very low-alpha amber field behind the download copy for depth (SITE-PLAN
   §2.5) -- a1/a2 steps only, legibility comes first. */
.download-dither {
  --dither-cell: 6px;
  --dither-rgb: var(--dither-amber);
  --dither-alpha: var(--dither-a2);
  --dither-mask: radial-gradient(ellipse 70% 80% at 50% 30%, #000, transparent 75%);
  inset: 0;
  position: absolute;
}

.download > :not(.download-dither) {
  position: relative;
  z-index: 1;
}

.download p {
  color: var(--ink-500);
  margin: 16px auto 26px;
  max-width: 560px;
}

.download-actions {
  justify-content: center;
}

.site-footer {
  align-items: center;
  background: var(--ink-950);
  border-top: 1px solid var(--mock-hairline);
  color: var(--ink-500); /* ink-600 fails 4.5:1 on ink-950 */
  display: flex;
  font-family: var(--mono);
  font-size: 12px;
  gap: 10px;
  justify-content: center;
  padding: 22px 48px;
}

.site-footer p {
  margin: 0;
}

/* ==========================================================================
   DITHER / PIXEL VOCABULARY (SITE-PLAN §1) --- pure-CSS textures, zero images.
   All fields degrade to nothing where mask-image is unsupported (see @supports
   guard at the bottom of this block).
   ========================================================================== */

/* --- Bayer dither field ---------------------------------------------------
   The 2x2 conic checker from the mock (lines 40-45), parameterized. Drop a
   positioned div with .dither-field and override the custom properties:
     --dither-cell   cell size: 3px | 5px | 6px | 8px
     --dither-rgb    var(--dither-amber) or var(--dither-paper)
     --dither-alpha  one of --dither-a1..a6 (or a raw 0-1 number)
     --dither-mask   a radial-gradient() that shapes the field to a soft blob
   Consumer is responsible for position/size (absolute, width/height, insets).
   Defaults live in var() fallbacks (not declarations) so consumer overrides
   win regardless of where they sit in the cascade. */
.dither-field {
  pointer-events: none;
  background: conic-gradient(
    rgba(var(--dither-rgb, var(--dither-amber)), var(--dither-alpha, var(--dither-a3))) 25%,
    transparent 0 50%,
    rgba(var(--dither-rgb, var(--dither-amber)), var(--dither-alpha, var(--dither-a3))) 0 75%,
    transparent 0
  );
  background-size: var(--dither-cell, 5px) var(--dither-cell, 5px);
  -webkit-mask: var(--dither-mask, radial-gradient(ellipse 70% 72% at 50% 0%, #000, transparent 74%));
  mask: var(--dither-mask, radial-gradient(ellipse 70% 72% at 50% 0%, #000, transparent 74%));
}

/* --- Halftone ramp --------------------------------------------------------
   The 4-row shrinking-dot seam from the mock (lines 172-178), as one element
   with four stacked radial-gradient layers. Amber by default; override
   --halftone-rgb to var(--dither-paper) for a paper seam. Each row is 8px tall
   with a smaller/fainter dot than the one above, so the texture fades out. */
.halftone-ramp {
  --halftone-rgb: var(--dither-amber);
  pointer-events: none;
  height: 32px;
  background-image:
    radial-gradient(circle at 50% 50%, rgba(var(--halftone-rgb), 0.55) 44%, transparent 48%),
    radial-gradient(circle at 50% 50%, rgba(var(--halftone-rgb), 0.42) 36%, transparent 40%),
    radial-gradient(circle at 50% 50%, rgba(var(--halftone-rgb), 0.3) 28%, transparent 32%),
    radial-gradient(circle at 50% 50%, rgba(var(--halftone-rgb), 0.18) 20%, transparent 24%);
  background-size: 8px 8px;
  background-position:
    0 0,      /* row 1: densest, top */
    4px 8px,  /* row 2: offset half-cell, staggered */
    0 16px,   /* row 3 */
    4px 24px; /* row 4: faintest, bottom */
  background-repeat: repeat-x;
}

/* --- Pixel stair ornament -------------------------------------------------
   CSS-grid scatter from the mock (lines 47-70). This class is just the grid
   container; each ornament's cells are placed per-instance (inline grid-column/
   grid-row + amber/paper background + opacity), because every scatter is unique.
   Default cell 14px; override --stair-cell (mock uses 13px and 14px). */
.pixel-stair {
  --stair-cell: 14px;
  display: grid;
  grid-template-columns: repeat(var(--stair-cols, 6), var(--stair-cell));
  grid-auto-rows: var(--stair-cell);
  pointer-events: none;
}
/* Convenience cell colors so instances can use classes instead of inline bg. */
.pixel-stair .cell-amber { background: var(--accent); }
.pixel-stair .cell-paper { background: var(--paper); }

/* --- Stair-stepped corner clip -------------------------------------------
   Subtle 2-3 step pixel corner for buttons/cards (SITE-PLAN §1 "pixel-clipped
   edges"). --clip-step is the pixel depth of each stair (default 4px). Applied
   via clip-path polygon: all four corners get a 2-step notch. */
.pixel-clip {
  --clip-step: 4px;
  clip-path: polygon(
    var(--clip-step) 0,
    calc(100% - var(--clip-step)) 0,
    calc(100% - var(--clip-step)) var(--clip-step),
    100% var(--clip-step),
    100% calc(100% - var(--clip-step)),
    calc(100% - var(--clip-step)) calc(100% - var(--clip-step)),
    calc(100% - var(--clip-step)) 100%,
    var(--clip-step) 100%,
    var(--clip-step) calc(100% - var(--clip-step)),
    0 calc(100% - var(--clip-step)),
    0 var(--clip-step),
    var(--clip-step) var(--clip-step)
  );
}

/* --- Hard offset shadow ---------------------------------------------------
   The offset-never-blurred shadow (mock line 111). Utility for cards/mock. */
.hard-shadow {
  box-shadow: var(--hard-shadow);
}

/* --- Graceful degradation -------------------------------------------------
   Dither fields rely on mask-image to be shaped; without it they would paint as
   full-bleed checkerboards over the whole page. Default the field to hidden and
   only reveal it where masks are supported, so unmasked browsers get the clean
   dark layout. (Halftone ramp and pixel stairs need no mask and always show.) */
.dither-field { display: none; }
@supports (mask-image: radial-gradient(#000, transparent)) or
          (-webkit-mask-image: radial-gradient(#000, transparent)) {
  .dither-field { display: block; }
}

@media (max-width: 920px) {
  .site-header {
    align-items: flex-start;
    flex-direction: column;
    padding: 16px 22px;
  }

  .nav-links {
    gap: 16px;
    overflow-x: auto;
    width: 100%;
  }

  .hero {
    padding: 42px 22px 26px;
  }

  .lede {
    font-size: 16px;
  }

  .hero-actions {
    align-items: stretch;
    flex-direction: column;
  }

  .meta-line {
    text-align: center;
  }

  .product-shell {
    box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.5);
  }

  .workspace-preview {
    grid-template-columns: 150px minmax(360px, 1fr);
    height: 300px;
    overflow-x: auto;
  }

  .file-rail,
  .editor-pane {
    display: none;
  }

  .agent-strip,
  .proof {
    grid-template-columns: 1fr;
  }

  .agent-strip {
    padding: 34px 22px;
  }

  .agent-list {
    justify-content: flex-start;
  }

  .proof article {
    border-right: 0;
    min-height: 0;
    padding: 30px 22px;
  }

  .download {
    padding: 44px 22px 54px;
  }
}

/* Below ~700px: hide the stair ornaments and corner wedges, and soften the
   halo so texture never crowds the copy at small sizes (SITE-PLAN §4). */
@media (max-width: 700px) {
  .stair-tr,
  .stair-ml,
  .hero-wedge-l,
  .hero-wedge-r {
    display: none;
  }

  .hero-halo-amber {
    --dither-alpha: 0.18;
    height: 380px;
  }
  .hero-halo-paper {
    height: 380px;
  }
  .hero-halo-coarse {
    --dither-alpha: 0.09;
    height: 360px;
  }
}

@media (max-width: 560px) {
  .nav-links {
    font-size: 12px;
  }

  .nav-links .nav-cta {
    padding: 7px 10px;
  }

  .button-primary {
    width: 100%;
  }

  .product-shell {
    margin-left: -8px;
    margin-right: -8px;
  }

  .workspace-preview {
    grid-template-columns: 128px 330px;
  }

  .project-rail,
  .terminal-pane {
    font-size: 11px;
  }
}

/* ==========================================================================
   Motion pass (SITE-PLAN §3) -- cursor blink, session-dot pulse, dither
   shimmer. Compositor-cheap only: opacity + background-position, nothing
   layout/paint-heavy. Entirely gated behind prefers-reduced-motion so the
   no-preference branch is the only place motion exists; the default (no
   media query matched) state above is the fully-static, reduced-motion page.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  /* Block cursor blink -- 1s step-end, on/off like a real terminal caret. */
  .cursor {
    animation: cursor-blink 1s step-end infinite;
  }

  @keyframes cursor-blink {
    0%, 50% { opacity: 1; }
    50.01%, 100% { opacity: 0; }
  }

  /* Session dot pulse -- "claude · main" running indicator (DESIGN.md §4.6:
     state is visible, quiet). Slow ease-in-out breathing between full and
     dim, never a hard blink -- reads as alive, not as an alert. */
  .rail-row.running span {
    animation: session-pulse 2.8s ease-in-out infinite;
  }

  @keyframes session-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
  }

  /* Dither shimmer -- one halo layer only (the coarse 8px field; it has the
     most visible cells so the drift reads at all without calling attention
     to itself). The checker moves to an oversized ::before animated with
     transform (compositor-friendly) instead of background-position (which
     would repaint the masked layer every frame); the parent keeps the mask
     and clips the child. Drifting exactly one whole 8px cell over 32s makes
     the loop point invisible. */
  .hero-halo-coarse {
    background: none;
    overflow: hidden;
  }
  .hero-halo-coarse::before {
    animation: dither-shimmer 32s linear infinite;
    background: conic-gradient(
      rgba(var(--dither-rgb, var(--dither-amber)), var(--dither-alpha, var(--dither-a3))) 25%,
      transparent 0 50%,
      rgba(var(--dither-rgb, var(--dither-amber)), var(--dither-alpha, var(--dither-a3))) 0 75%,
      transparent 0
    );
    background-size: var(--dither-cell, 8px) var(--dither-cell, 8px);
    content: "";
    inset: -8px 0 0 -8px;
    position: absolute;
    will-change: transform;
  }

  @keyframes dither-shimmer {
    from { transform: translate(0, 0); }
    to { transform: translate(8px, 8px); }
  }
}
