/* LynxOffice — marketing site
 *
 * Brand tokens mirror the app's ColorHex.swift and the
 * "Color" section of DESIGN.md. If a value changes there, change it here:
 * those two places are the source of truth, this file is a copy for the web.
 *
 * The system is flat and two-tone, as the mark is. Mint is a FILL and never
 * text on paper (1.3:1); the light accent is the same hue darkened until it
 * holds AA. No gradients anywhere.
 */

/* ---------- tokens ---------- */

/* The five values below are the LynxOffice brand guidelines, verbatim:
 * docs/brand/lynxoffice-brand-guidelines.pdf, page 11 (Brand Colors) and
 * page 12 (Supporting Colors). Every other value in this block is DERIVED
 * from them, and each derivation was measured rather than eyeballed — the
 * ratio is written beside it.
 *
 * The spec assigns roles, so this file does not get to reinvent them:
 *   Mint Green      BRAND PRIMARY · LIGHT
 *   Midnight Navy   BRAND PRIMARY · DARK
 *   Graphite        BRAND NEUTRAL · INK
 *   Digital Indigo  ACCENT · FOCUS · ACTION   (emphasis, links, action cues)
 *   Cloud Gray      SURFACE · QUIET BACKGROUND
 * The spec also says the two supporting colours may not stand in for the
 * logo primaries, so indigo tints controls and never becomes the brand.
 */

:root {
  /* the five brand values, exactly as published */
  --lynx-mint: #49F2BA;       /* Mint Green      — a FILL; 1.43:1 on paper, never text there */
  --lynx-navy: #00203F;       /* Midnight Navy   — 16.43:1 on paper */
  --graphite:  #252C33;       /* Graphite Charcoal — 14.12:1 on paper */
  --indigo:    #4A5CFE;       /* Digital Indigo  — 4.94:1 on paper */
  --cloud:     #F1F1F6;       /* Cloud Gray */

  /* The mark's lower face. Fixed navy is right on paper and on the ink hero,
   * but vanishes on the dark-mode footer ground, so dark mode lifts it. The
   * mint half is untouched either way. */
  --mark-shadow: #00203F;

  /* roles */
  --accent: #4A5CFE;          /* the spec's ACCENT · FOCUS · ACTION, unmodified */
  /* ⚠️ Digital Indigo is 4.94:1 on paper but only 4.39:1 on Cloud Gray — it
   * clears AA on white and MISSES it on the quiet surface. Indigo may carry
   * body text on --paper only; on --paper-2/--paper-3 it is limited to large
   * text and UI (≥3:1), and running text there uses --body or --muted. */
  /* Small accent TEXT uses this instead: Digital Indigo darkened 12%, which
   * is 6.04:1 on paper and 5.36:1 on Cloud Gray. The published indigo is
   * 4.39:1 on Cloud Gray — it misses AA on the brand's own quiet surface, so
   * an eyebrow or a link sitting on --paper-3 needs the darker value. Fills,
   * borders, focus rings and large text keep --accent exactly as published. */
  --accent-text: #4151E0;
  --accent-hover: #3D4BD0;    /* indigo darkened 18% — 6.74:1 on paper */
  /* The focus ring is a SEPARATE token from the accent. Indigo is 4.94:1 on
   * paper but 2.05:1 on the navy hero, so reusing --accent left the ring
   * invisible on every download button. Dark surfaces re-scope this to mint. */
  --focus: #4A5CFE;
  --ink: #00203F;             /* headings — Midnight Navy */
  --body: #252C33;            /* running text — Graphite, 14.12:1 */
  --muted: #666B70;           /* Graphite lightened 30% — 5.38:1 on paper, 4.78:1 on Cloud Gray */
  --paper: #FFFFFF;
  --paper-2: #F8F8FB;         /* Cloud Gray lightened, for the quiet band */
  --paper-3: #F1F1F6;         /* Cloud Gray, as published */
  --tint: #EDFEF8;            /* mint at 10% over paper — navy on it is 15.75:1 */
  --hairline: rgba(0, 32, 63, 0.14);
  --hairline-strong: rgba(0, 32, 63, 0.22);

  /* per-format hues, from FormatTint in ColorHex.swift */
    --word-bg: #DFEBFF;   --word-fg: #2164CA;   --word-ink: #183256;  --word-body: #3B4C6B;
  --sheet-bg: #EDFEF8;  --sheet-fg: #0B7A56;  --sheet-ink: #00203F; --sheet-body: #44605A;
  --deck-bg: #FFF0E1;   --deck-fg: #A25D1A;   --deck-ink: #513921;  --deck-body: #6A4E2C;
  --pdf-bg: #FDE4E4;    --pdf-fg: #CA2121;    --pdf-ink: #4D2426;   --pdf-body: #6B3A3C;
  --img-bg: #F1E4FE;    --img-fg: #7721CA;    --img-ink: #382554;   --img-body: #57407A;

  /* Markdown opens in the Word editor, so it carries Word's hue rather than
   * a sixth invented one. Agents carry the accent tint. Aliases, not new
   * values: nothing to keep in step with ColorHex.swift. */
  --md-bg: var(--word-bg);   --md-fg: var(--word-fg);
  --ai-bg: var(--tint);      --ai-fg: var(--accent);

  /* type */
  --display: "Encode Sans Expanded", "Helvetica Neue", Arial, sans-serif;
  --text: "Encode Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  /* rhythm — 8pt scale, as DESIGN.md sets for the app */
  --gutter: clamp(20px, 5vw, 72px);
  --wrap: 1296px;
  --radius-card: 16px;
  --radius-control: 8px;

  /* Product demos (assets/demos.css) draw the APP, not the page, so these are
   * the app's own chrome colours — OfficeColors in WordEditorView.swift and the
   * semantic tokens in DESIGN.md — not the site's. Dark values below, in both
   * dark blocks, so a demo turns dark exactly when the page does. */
  --demo-chrome: #F0F0F2;       /* statusBarBg: title bar, status bar */
  --demo-ribbon: #FAFAFC;       /* ribbonContentBg */
  --demo-canvas: #EBEDEF;       /* canvasBackground: the ground around a page */
  --demo-paper: #FFFFFF;        /* a page, a cell, a slide */
  --demo-control: #F2F2F5;      /* controlBg: ribbon tiles */
  --demo-panel: #F7F7FA;        /* sidePanelBg */
  --demo-text: #252C33;         /* textPrimary */
  --demo-text-2: #59636D;       /* textSecondary */
  --demo-text-3: #656E77;       /* textTertiary */
  --demo-line: #D9DDE2;         /* borderSubtle */
  --demo-accent: #00203F;       /* brandAccent: filled buttons, the active tab */
  --demo-accent-ink: #FFFFFF;
  --demo-focus: #4A5CFE;        /* actionFocus: selection */
  --demo-focus-soft: #EEF0FF;   /* actionFocusSoft */
  --demo-image-ground: #A6A6A6; /* the canvas behind an image (NSScrollView) */
  --demo-frame: rgba(0, 32, 63, 0.16);
  --demo-band: #F5F5F7;         /* ribbonBackground: the editor band behind the tabs */
  --demo-card: #FFFFFF;         /* cardBg / surfaceElevated */
  --demo-menu: #F6F6F8;         /* a pull-down menu */
  --demo-ground: #F1F1F6;       /* bgSubtle: the Home screen */
  --demo-elevated: #FFFFFF;     /* surfaceElevated: a Home card */
  --demo-textbg: #FFFFFF;       /* textBackgroundColor: the rendered Markdown page */
  --demo-label: rgba(0, 0, 0, 0.85); /* labelColor */
  --demo-mdink: #00203F;        /* brandInk: rendered Markdown headings */
  --demo-emph: #097E57;         /* brandEmphasis: the Home cards' icons */

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --accent: #49F2BA;          /* mint — 11.49:1 on the navy ground */
    --accent-text: #49F2BA;     /* mint clears AA on every dark ground here */
    --accent-hover: #7CF6CC;
    --focus: #49F2BA;
    --ink: #EBEDF0;             /* 14.01:1 on navy */
    --body: #C2C9D1;            /* 9.83:1 */
    --muted: #8F9DAB;           /* 5.93:1 */
    --paper: #00203F;           /* Midnight Navy is the dark ground */
    --paper-2: #11253A;
    --paper-3: #14324E;
    --tint: #09394E;
    --hairline: rgba(73, 242, 186, 0.16);
    --hairline-strong: rgba(73, 242, 186, 0.26);

    --mark-shadow: #2E6E7E;
    --word-bg: #183256;  --word-fg: #639CF2;  --word-ink: #DDE8FF; --word-body: #A8BEE0;
    --sheet-bg: #09394E; --sheet-fg: #49F2BA; --sheet-ink: #DDF5EC; --sheet-body: #9DBDB4;
    --deck-bg: #513921;  --deck-fg: #F09742;  --deck-ink: #FFE9D2; --deck-body: #D9B48C;
    --pdf-bg: #4D2426;   --pdf-fg: #F36D6D;   --pdf-ink: #FFE0E0; --pdf-body: #D9A3A3;
    --img-bg: #382554;   --img-fg: #B97BF4;   --img-ink: #EEE0FF; --img-body: #BCA6D6;

    /* Markdown opens in the Word editor, so it carries Word's hue rather than
     * a sixth invented one. Agents carry the accent tint. */
    --md-bg: var(--word-bg);   --md-fg: var(--word-fg);
    --ai-bg: var(--tint);      --ai-fg: var(--accent);

    --demo-chrome: #292929;  --demo-ribbon: #333336;  --demo-canvas: #383838;
    --demo-control: #3D3D40; --demo-panel: #2C2C2E;
    --demo-text: #FFFFFF;    --demo-text-2: #D0D7DD;  --demo-text-3: #9AA3AD;
    --demo-line: #3B464F;    --demo-accent: #49F2BA;  --demo-accent-ink: #00203F;
    --demo-focus: #7B88FF;   --demo-focus-soft: #1E2855;
    --demo-image-ground: #1E1E1E; --demo-frame: rgba(73, 242, 186, 0.22);
    --demo-band: #2E2E30;    --demo-card: #383838;    --demo-ground: #252C33;
    --demo-menu: #2C2C2E; --demo-elevated: #1C252D;
    --demo-textbg: #1E1E1E;  --demo-label: rgba(255, 255, 255, 0.85); --demo-mdink: #1C6473;
    --demo-emph: #49F2BA;

    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --accent: #49F2BA;          /* mint — 11.49:1 on the navy ground */
  --accent-text: #49F2BA;     /* mint clears AA on every dark ground here */
  --accent-hover: #7CF6CC;
  --focus: #49F2BA;
  --ink: #EBEDF0;             /* 14.01:1 on navy */
  --body: #C2C9D1;            /* 9.83:1 */
  --muted: #8F9DAB;           /* 5.93:1 */
  --paper: #00203F;           /* Midnight Navy is the dark ground */
  --paper-2: #11253A;
  --paper-3: #14324E;
  --tint: #09394E;
  --hairline: rgba(73, 242, 186, 0.16);
  --hairline-strong: rgba(73, 242, 186, 0.26);

  --mark-shadow: #2E6E7E;
  --word-bg: #183256;  --word-fg: #639CF2;  --word-ink: #DDE8FF; --word-body: #A8BEE0;
  --sheet-bg: #09394E; --sheet-fg: #49F2BA; --sheet-ink: #DDF5EC; --sheet-body: #9DBDB4;
  --deck-bg: #513921;  --deck-fg: #F09742;  --deck-ink: #FFE9D2; --deck-body: #D9B48C;
  --pdf-bg: #4D2426;   --pdf-fg: #F36D6D;   --pdf-ink: #FFE0E0; --pdf-body: #D9A3A3;
  --img-bg: #382554;   --img-fg: #B97BF4;   --img-ink: #EEE0FF; --img-body: #BCA6D6;

  /* Markdown opens in the Word editor, so it carries Word's hue rather than
   * a sixth invented one. Agents carry the accent tint. */
  --md-bg: var(--word-bg);   --md-fg: var(--word-fg);
  --ai-bg: var(--tint);      --ai-fg: var(--accent);

  --demo-chrome: #292929;  --demo-ribbon: #333336;  --demo-canvas: #383838;
  --demo-control: #3D3D40; --demo-panel: #2C2C2E;
  --demo-text: #FFFFFF;    --demo-text-2: #D0D7DD;  --demo-text-3: #9AA3AD;
  --demo-line: #3B464F;    --demo-accent: #49F2BA;  --demo-accent-ink: #00203F;
  --demo-focus: #7B88FF;   --demo-focus-soft: #1E2855;
  --demo-image-ground: #1E1E1E; --demo-frame: rgba(73, 242, 186, 0.22);
  --demo-band: #2E2E30;    --demo-card: #383838;    --demo-ground: #252C33;
  --demo-menu: #2C2C2E; --demo-elevated: #1C252D;
  --demo-textbg: #1E1E1E;  --demo-label: rgba(255, 255, 255, 0.85); --demo-mdink: #1C6473;
  --demo-emph: #49F2BA;

  color-scheme: dark;
}

/* ---------- base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--body);
  font-family: var(--text);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; }
svg { flex-shrink: 0; }

h1, h2, h3, h4 {
  font-family: var(--display);
  color: var(--ink);
  margin: 0;
  line-height: 1.14;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
h1 { font-size: clamp(2rem, 1.2rem + 3.4vw, 3.375rem); line-height: 1.08; letter-spacing: -0.02em; }
h2 { font-size: clamp(1.625rem, 1.2rem + 1.9vw, 2.5rem); }
h3 { font-size: clamp(1rem, 0.94rem + 0.3vw, 1.0625rem); }
h4 { font-size: 0.8125rem; letter-spacing: 0; }

p { margin: 0; }
ul, ol { margin: 0; }

a { color: var(--accent); }
a:hover { color: var(--accent-hover); }

/* Surfaces that are dark in BOTH themes carry their own ring colour. */
.hero, .cta, .callout, .code, .card--dark, .band { --focus: var(--lynx-mint); }
.band { --focus: var(--lynx-navy); }

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 4px;
}

code, pre { font-family: var(--mono); }

/* Skip link — the first thing a keyboard reaches. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 20px;
  background: var(--lynx-mint);
  color: var(--lynx-navy);
  font-family: var(--display);
  font-weight: 700;
  text-decoration: none;
  border-radius: 0 0 var(--radius-control) 0;
}
.skip:focus { left: 0; }

/* ---------- layout ---------- */

.wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: clamp(48px, 7vw, 76px); }
.section--tight { padding-block: clamp(32px, 4vw, 44px); }
.section--paper2 { background: var(--paper-2); border-block: 1px solid var(--hairline); }
.section--paper3 { background: var(--paper-3); }

.eyebrow {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-text);
}

.lede { font-size: clamp(0.9375rem, 0.9rem + 0.2vw, 1rem); line-height: 1.62; color: var(--muted); }

/* A heading on the left, a paragraph on the right; stacks under 900px. */
.head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: clamp(18px, 3vw, 48px);
  margin-bottom: clamp(26px, 3vw, 38px);
}
.head-row__main { flex: 1 1 460px; display: flex; flex-direction: column; gap: 12px; }
.head-row__aside { flex: 0 1 420px; }

.grid { display: grid; gap: 20px; }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 24px; }

@media (max-width: 1000px) {
  .grid--3, .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 660px) {
  .grid--3, .grid--4, .grid--2 { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- controls ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 26px;
  border-radius: var(--radius-control);
  font-family: var(--display);
  font-size: 0.9375rem;
  font-weight: 700;
  text-decoration: none;
  border: 1px solid transparent;
}
/* The mark's own pairing: mint fill, deep-teal text. 8.1:1, and fixed in both
 * appearances because it is the one loud surface on the page. */
.btn--primary { background: var(--lynx-mint); color: var(--lynx-navy); }
.btn--primary:hover { background: #A5F5D2; color: var(--lynx-navy); }
.btn--ghost { border-color: rgba(255, 255, 255, 0.46); color: #FFFFFF; }  /* 0.34 measured 2.94:1 on --kdan-ink */
.btn--ghost:hover { border-color: rgba(255, 255, 255, 0.6); color: #FFFFFF; }
.btn--sm { min-height: 44px; padding: 0 20px; font-size: 0.84375rem; }

/* ---------- header and hero ---------- */

.hero { background: var(--lynx-navy); color: #FFFFFF; }

.nav {
  position: relative;          /* the phone menu's panel hangs from it */
  display: flex;
  align-items: center;
  gap: clamp(16px, 3vw, 36px);
  padding-block: 20px;
  flex-wrap: wrap;
}
.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.brand__name { font-family: var(--display); font-size: 1.0625rem; font-weight: 700; color: #FFFFFF; letter-spacing: -0.01em; }
.nav__links { display: flex; gap: clamp(14px, 2vw, 28px); flex: 1 1 auto; flex-wrap: wrap; font-size: 0.875rem; }
.nav__links a { color: rgba(255, 255, 255, 0.78); text-decoration: none; padding-block: 6px; }
.nav__links a:hover { color: #FFFFFF; }
@media (max-width: 760px) { .nav__links { display: none; } }

/* The phone menu: a native <details>, shown only where the row of links is
 * hidden. Download stays beside it on the right. */
.nav__menu { display: none; }
@media (max-width: 760px) {
  .nav { gap: 12px; }
  .nav > .btn { margin-left: auto; }
  .nav__menu { display: block; }
}
/* The language menu (2026-10-03): kdan.com's globe, as a native <details>
 * like the phone menu. Its panel hangs right-aligned under the globe. On a
 * phone the globe takes the auto margin Download had, so the pair stays
 * together on the right. */
.nav__lang { position: relative; }
.nav__lang-btn {
  list-style: none;
  display: inline-flex; align-items: center; gap: 6px;
  color: rgba(255, 255, 255, 0.78);
  font-size: 0.875rem;
  padding-block: 6px;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}
.nav__lang-btn::-webkit-details-marker { display: none; }
.nav__lang-btn:hover, .nav__lang[open] .nav__lang-btn { color: #FFFFFF; }
.nav__lang-panel {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 21;
  display: grid; gap: 2px; min-width: 168px;
  padding: 8px;
  background: var(--lynx-navy);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 14px;
  box-shadow: 0 18px 40px rgba(0, 12, 28, 0.5);
}
.nav__lang-panel a {
  display: flex; align-items: center;
  min-height: 40px; padding: 0 12px;
  border-radius: 8px;
  font-size: 0.9375rem; font-weight: 600;
  color: #FFFFFF; text-decoration: none; white-space: nowrap;
}
.nav__lang-panel a:hover { background: rgba(255, 255, 255, 0.08); }
.nav__lang-panel a[aria-current="true"] { color: var(--lynx-mint); }
@media (max-width: 760px) {
  .nav__lang { margin-left: auto; }
  .nav__lang + .btn { margin-left: 0; }
  /* The globe alone: with the language's name, Download and the menu button
   * no longer fit one row at 375 px once Download is ダウンロード or
   * Descargar. The names are in the panel; the summary's aria-label says
   * what the button does. */
  .nav__lang-now { display: none; }
  .nav__lang-btn { min-height: 44px; min-width: 44px; justify-content: center; }
}
/* Six languages share one header row: ダウンロード and Descargar are wider
 * than Download, and at 360-375 px the row fits only with tighter spacing
 * (measured: ja needed 343 px of a 335 px row, es 327). */
@media (max-width: 420px) {
  .nav { gap: 8px; }
  .nav > .btn--sm { padding: 0 14px; }
  .nav__toggle { padding: 0 10px; gap: 6px; }
}
/* Below 380 px (ja needed 323 px of a 320 px row at 360) the menu button is
 * the icon alone. Its word stays for screen readers: clipped, not removed. */
@media (max-width: 380px) {
  .nav__toggle span {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
}
.nav__toggle {
  list-style: none;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 14px;
  border: 1px solid rgba(255, 255, 255, 0.46);
  border-radius: var(--radius-control);
  font-family: var(--display); font-size: 0.84375rem; font-weight: 700;
  color: #FFFFFF;
  cursor: pointer;
  user-select: none;
}
.nav__toggle::-webkit-details-marker { display: none; }
.nav__toggle:hover { border-color: rgba(255, 255, 255, 0.6); }
.nav__icon--close { display: none; }
.nav__menu[open] .nav__icon--open { display: none; }
.nav__menu[open] .nav__icon--close { display: block; }
.nav__panel {
  position: absolute; left: 0; right: 0; top: calc(100% - 8px); z-index: 20;
  display: grid; gap: 2px;
  padding: 8px;
  background: var(--lynx-navy);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 14px;
  box-shadow: 0 18px 40px rgba(0, 12, 28, 0.5);
}
.nav__panel a {
  display: flex; align-items: center;
  min-height: 44px; padding: 0 14px;
  border-radius: 8px;
  font-size: 1rem; font-weight: 600;
  color: #FFFFFF; text-decoration: none;
}
.nav__panel a:hover { background: rgba(255, 255, 255, 0.08); }
.nav__panel a[aria-current="page"] { color: var(--lynx-mint); }

.hero__body {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(28px, 4vw, 56px);
  align-items: flex-start;
  padding-block: clamp(32px, 5vw, 56px);
}
.hero__copy { flex: 1 1 480px; display: flex; flex-direction: column; gap: 22px; }
.hero__copy h1 { color: #FFFFFF; }
.hero__sub { font-size: clamp(0.9375rem, 0.9rem + 0.3vw, 1.0625rem); line-height: 1.62; color: rgba(255, 255, 255, 0.8); max-width: 34em; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; padding-top: 6px; }
.hero__meta { font-size: 0.8125rem; color: rgba(255, 255, 255, 0.52); }

.badge {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  padding: 0 14px;
  border-radius: 15px;
  background: rgba(127, 239, 190, 0.14);
  border: 1px solid rgba(127, 239, 190, 0.34);
  font-size: 0.78125rem;
  font-weight: 500;
  color: var(--lynx-mint);
}
.badge__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--lynx-mint); }

/* The screenshot well. A placeholder until real captures land; sized by
 * aspect-ratio so swapping in an <img> does not move the layout.
 *
 * min-width and max-width are load-bearing, not tidiness. An aspect-ratio box
 * derives the axis it is not given, so a min-height here computed a MINIMUM
 * WIDTH of height x 1.6 — 384px — and pushed the page into a sideways scroll on
 * any phone narrower than that. The height now follows the width, never the
 * other way round. */
/* This frame was drawn for an EMPTY well: a fixed 16/10 box with a dashed
 * placeholder inside. Now that it holds a real screenshot the ratio must come
 * from the image, not from the frame — forcing 16/10 on a 2400x1412 capture
 * squeezed it to 487x1412 and it rendered visibly stretched. The frame hugs
 * the image instead, and the image sets its own height.
 * The old fill (#0A3B44) and mint border were from the retired teal palette. */
.shot {
  flex: 1 1 420px;
  min-width: 0;
  max-width: 100%;
  border-radius: 14px 14px 0 0;
  background: rgba(73, 242, 186, 0.06);
  border: 1px solid rgba(73, 242, 186, 0.22);
  border-bottom: none;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.shot__chrome { display: flex; gap: 6px; padding: 2px 4px; }
.shot__chrome span { width: 9px; height: 9px; border-radius: 50%; background: rgba(255, 255, 255, 0.22); }
.shot__well {
  flex: 1;
  border-radius: 8px;
  background: #06222A;
  border: 1px dashed rgba(127, 239, 190, 0.3);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-align: center;
  padding: 16px;
  font-size: 0.78125rem;
  color: rgba(127, 239, 190, 0.75);
}

/* ---------- the mint privacy band ---------- */

.band {
  background: var(--lynx-mint);
  color: var(--lynx-navy);
}
.band__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(14px, 3vw, 44px);
  padding-block: 30px;
}
.band__claim {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--display);
  font-size: clamp(1rem, 0.9rem + 0.5vw, 1.25rem);
  font-weight: 700;
  flex: 0 1 auto;
}
.band__note { flex: 1 1 380px; font-size: 0.90625rem; line-height: 1.55; color: rgba(24, 63, 76, 0.84); }

/* ---------- cards ---------- */

.card {
  display: flex;
  flex-direction: column;
  gap: 13px;
  padding: 26px;
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
}
.card--quiet { background: var(--paper-3); border-color: transparent; }
.card--tint { background: var(--tint); border-color: rgba(15, 123, 76, 0.2); }
.card p { font-size: 0.86rem; line-height: 1.58; color: var(--body); }

/* AFTER .card p, deliberately. Both selectors are (0,1,1), so whichever is
 * written last wins — with these two the wrong way round the dark card's body
 * text rendered at 1.23:1 in light mode, which is invisible, not merely dim. */
.card--dark { background: var(--lynx-navy); border-color: var(--lynx-navy); }
.card--dark h3 { color: #FFFFFF; }
.card--dark p { color: rgba(255, 255, 255, 0.86); }

.card__icon {
  width: 42px; height: 42px;
  border-radius: 11px;
  background: var(--tint);
  display: flex; align-items: center; justify-content: center;
  color: var(--accent);
}
.card--dark .card__icon { background: rgba(127, 239, 190, 0.16); color: var(--lynx-mint); }

.equiv {
  margin-top: auto;
  padding: 7px 9px;
  border-radius: 6px;
  background: var(--paper-3);
  font-size: 0.6875rem;
  line-height: 1.5;
  color: var(--muted);
  overflow-wrap: anywhere;
}
.card--dark .equiv { background: rgba(127, 239, 190, 0.12); color: var(--lynx-mint); }

.step { display: flex; align-items: center; gap: 10px; }
.step__n {
  width: 26px; height: 26px;
  border-radius: 8px;
  background: var(--lynx-navy); color: var(--lynx-mint);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display); font-size: 0.8125rem; font-weight: 700;
  flex-shrink: 0;
}
.card--tint .step__n { background: var(--accent); color: var(--paper); }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  font-size: 0.71875rem;
  padding: 4px 9px;
  border-radius: 12px;
  background: var(--tint);
  color: var(--accent);
  font-weight: 500;
}
.chip--plain { background: var(--paper-3); color: var(--body); }
.card--tint .chip { background: var(--paper); }

.callout {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 20px 26px;
  border-radius: 14px;
  background: var(--lynx-navy);
  color: rgba(255, 255, 255, 0.88);
  font-size: 0.875rem;
  line-height: 1.55;
  margin-top: 28px;
}
.callout strong { color: #FFFFFF; }
.callout svg { color: var(--lynx-mint); margin-top: 1px; }

/* ---------- connect / code ---------- */

.split {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
}
.split__copy { flex: 1 1 420px; display: flex; flex-direction: column; gap: 18px; }
.split__aside { flex: 1 1 400px; min-width: 0; }

.ticks { list-style: none; padding: 0;  /* role="list" is on the element; Safari drops list semantics without it */ display: flex; flex-direction: column; gap: 10px; }
.ticks li { display: flex; align-items: flex-start; gap: 10px; font-size: 0.875rem; line-height: 1.5; }
.ticks svg { color: var(--accent); margin-top: 3px; }

.code {
  border-radius: 14px;
  background: var(--lynx-navy);
  padding: 22px 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.code__file { display: flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 0.71875rem; color: rgba(255, 255, 255, 0.55); }
.code__file span:first-child { width: 8px; height: 8px; border-radius: 50%; background: var(--lynx-mint); flex-shrink: 0; }
.code pre {
  margin: 0;
  font-size: 0.78125rem;
  line-height: 1.75;
  color: #D8F6E8;
  overflow-x: auto;
}
.code pre.dim { color: rgba(255, 255, 255, 0.62); }
.code .rule { height: 1px; background: rgba(255, 255, 255, 0.12); }
.code .prompt { color: var(--lynx-mint); }
.code .code__c { color: rgba(255, 255, 255, 0.5); }
/* An SDK page shows code where a product page shows its demo. The code block is
 * navy like the hero behind it, so there it needs an edge of its own. */
.hero__demo .code { background: rgba(255, 255, 255, 0.05); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14); }
/* A flex item will not shrink below its longest unbreakable line, so on a phone a
 * code column pushed the page 185px sideways. Let it shrink; the <pre> scrolls. */
.hero__demo--code { min-width: 0; }
.hero__demo--code .code pre { font-size: 0.74rem; }   /* 49 characters fit at 1024 px; phones scroll */

/* Numbered setup steps (/mcp/, /cli/): the hub's step badge, with the text
 * indented to sit under the step's title rather than under its number. */
.setup { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 20px; }
.setup h3 { font-size: 1rem; font-weight: 700; color: var(--ink); }
.setup p { margin-top: 8px; padding-left: 36px; font-size: 0.875rem; line-height: 1.6; color: var(--body); }

/* ---------- the five editors ---------- */

.editor {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(20px, 3vw, 44px);
  padding: clamp(24px, 3vw, 36px);
  border-radius: 18px;
  margin-bottom: 20px;
}
.editor__head { flex: 1 1 260px; max-width: 320px; display: flex; flex-direction: column; gap: 12px; }
.editor__head h3 { font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem); }
.editor__head p { font-size: 0.84375rem; line-height: 1.58; }
.editor__head code { font-size: 0.71875rem; }
.editor__icon {
  width: 46px; height: 46px;
  border-radius: 12px;
  background: var(--paper);
  display: flex; align-items: center; justify-content: center;
}
.editor__grid {
  flex: 3 1 460px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px 20px;
  align-content: start;
}
/* 1100, not 900: .editor is a wrapping flex row, and between roughly 920 and
 * 1000px the grid still shares the line with .editor__head, leaving three
 * columns about 140px wide. Measured: 960px viewport gave a 140px column while
 * 920px gave 227px — widening the window made the text narrower. */
@media (max-width: 1100px) { .editor__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .editor__grid { grid-template-columns: minmax(0, 1fr); } }
.editor__grid h4 { margin-bottom: 4px; font-weight: 600; }
.editor__grid p { font-size: 0.78125rem; line-height: 1.5; }

.editor--word  { background: var(--word-bg); }
.editor--word .editor__icon  { color: var(--word-fg); }
.editor--word h3, .editor--word h4 { color: var(--word-ink); }
.editor--word p, .editor--word code { color: var(--word-body); }

.editor--sheet { background: var(--sheet-bg); }
.editor--sheet .editor__icon { color: var(--sheet-fg); }
.editor--sheet h3, .editor--sheet h4 { color: var(--sheet-ink); }
.editor--sheet p, .editor--sheet code { color: var(--sheet-body); }

.editor--deck  { background: var(--deck-bg); }
.editor--deck .editor__icon  { color: var(--deck-fg); }
.editor--deck h3, .editor--deck h4 { color: var(--deck-ink); }
.editor--deck p, .editor--deck code { color: var(--deck-body); }

.editor--pdf   { background: var(--pdf-bg); }
.editor--pdf .editor__icon   { color: var(--pdf-fg); }
.editor--pdf h3, .editor--pdf h4 { color: var(--pdf-ink); }
.editor--pdf p, .editor--pdf code { color: var(--pdf-body); }

.editor--img   { background: var(--img-bg); }
.editor--img .editor__icon   { color: var(--img-fg); }
.editor--img h3, .editor--img h4 { color: var(--img-ink); }
.editor--img p, .editor--img code { color: var(--img-body); }

/* ---------- facts table ---------- */

.facts { display: flex; flex-wrap: wrap; gap: clamp(24px, 4vw, 52px); align-items: flex-start; }
.facts__copy { flex: 1 1 320px; max-width: 400px; display: flex; flex-direction: column; gap: 14px; }
.facts__table { flex: 2 1 480px; min-width: 0; overflow-x: auto; }

table.facts-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  background: var(--paper);
  border-radius: 14px;
  overflow: hidden;
}
table.facts-table caption {
  caption-side: top;
  text-align: left;
  padding-bottom: 10px;
  font-size: 0.78125rem;
  color: var(--muted);
}
table.facts-table th,
table.facts-table td { padding: 13px 20px; text-align: left; vertical-align: top; }
table.facts-table th { font-weight: 600; color: var(--ink); width: 210px; }
table.facts-table td { color: var(--body); }
table.facts-table tr + tr { border-top: 1px solid var(--hairline); }
@media (max-width: 520px) {
  table.facts-table th, table.facts-table td { display: block; }
  table.facts-table th { width: auto; padding-bottom: 2px; }
  table.facts-table td { padding-top: 0; }
}

/* ---------- faq ---------- */

.faq-item {
  padding: 22px 24px;
  border: 1px solid var(--hairline);
  border-radius: 14px;
}
.faq-item h3 { margin-bottom: 7px; font-size: 0.9375rem; font-weight: 700; }
.faq-item p { font-size: 0.84375rem; line-height: 1.6; color: var(--body); }

/* ---------- closing cta ---------- */

.cta {
  border-radius: 20px;
  background: var(--lynx-navy);
  padding: clamp(32px, 5vw, 58px) clamp(24px, 4vw, 64px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(24px, 4vw, 56px);
  margin-bottom: clamp(36px, 5vw, 56px);
}
.cta__copy { flex: 1 1 380px; display: flex; flex-direction: column; gap: 14px; }
.cta__copy h2 { color: #FFFFFF; }
.cta__copy p { color: rgba(255, 255, 255, 0.75); max-width: 34em; }
/* The panel is navy in both themes; the page's link colour (indigo) is not. */
.cta__copy a { color: var(--lynx-mint); }
.cta__copy a:hover { color: #FFFFFF; }
.cta__actions { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.cta__actions .hero__meta { color: rgba(255, 255, 255, 0.52); }

/* ---------- footer ----------
 * Laid out like the LynxPDF site's footer (2026-09-28): link columns under
 * title-case headings, contact cards beside them, and under a hairline a band
 * with the logo, the policy link and the copyright line. */

.foot { border-top: 1px solid var(--hairline); padding-block: 56px 40px; }
.foot .brand svg .mark-shadow { fill: var(--mark-shadow); }
.foot__top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(240px, 300px);
  gap: 40px 64px;
  align-items: start;
}
.foot__cols { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px 24px; }
.foot__col { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; }
.foot__h { margin-bottom: 10px; font-size: 1rem; font-weight: 700; color: var(--ink); }
.foot__col a { padding-block: 6px; font-size: 0.9375rem; color: var(--muted); text-decoration: none; }
.foot__col a:hover { color: var(--accent-text); }

/* A whole-card link. --paper-2 is a quiet surface, so the action is small
 * accent TEXT and takes --accent-text (see the note on --accent). */
.foot__cards { display: grid; gap: 16px; }
.foot__card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 22px 24px;
  border: 1px solid var(--hairline);
  border-radius: 16px;
  background: var(--paper-2);
  color: var(--ink);
  text-decoration: none;
  transition: border-color 160ms ease;
}
.foot__card:hover { border-color: var(--accent); }
.foot__card-title { font-size: 1.0625rem; font-weight: 700; line-height: 1.3; }
.foot__card-action { display: inline-flex; align-items: center; gap: 6px; font-size: 0.9375rem; font-weight: 600; color: var(--accent-text); }

.foot__bottom {
  margin-top: 48px;
  padding-top: 32px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}
/* Three links since 2026-09-28; they wrap as a row, never as one run of text. */
.foot__policies { display: flex; flex-wrap: wrap; gap: 6px 20px; font-size: 0.875rem; }
.foot__policies a { color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.foot__policies a:hover { color: var(--accent-text); }
/* Cookie Settings is a button that reads as the policy links beside it. */
.foot__cookies {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.foot__cookies:hover { color: var(--accent-text); }

/* ---------- cookie consent (2026-10-03) ----------
 * One banner for every visitor, from build_site.ANALYTICS: shown until the
 * visitor answers, and again from Cookie Settings. Accept and Reject share one
 * style on purpose, because refusing must be as easy as agreeing. The tokens
 * carry it into both appearances. */
.consent {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 90;
  max-width: 40rem;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  padding: 16px 20px;
  background: var(--paper);
  color: var(--body);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-card);
  box-shadow: 0 12px 32px rgba(0, 32, 63, 0.18);
  font-size: 0.875rem;
  line-height: 1.5;
}
.consent[hidden] { display: none; }
.consent__text { flex: 1 1 18rem; margin: 0; }
.consent__text a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
.consent__actions { display: flex; flex: 0 0 auto; gap: 10px; }
.foot__legal { font-size: 0.875rem; color: var(--muted); }

@media (max-width: 1080px) {
  .foot__top { grid-template-columns: minmax(0, 1fr); }
  .foot__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) { .foot__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .foot__cards { grid-template-columns: minmax(0, 1fr); } }

/* Placeholders are meant to be obvious in review and impossible to ship by
 * accident. Remove this rule when every bracket is filled. */
.todo {
  font-family: var(--mono);
  font-size: 0.9em;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 3px;
  background: #FFE3E3;
  color: #8E1111;          /* 7.4:1 on its own background */
  outline: 1px dashed #CA2121;
}
/* Both dark paths, or the guard is unreachable from the explicit toggle. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .todo { background: #4D1616; color: #FFC9C9; outline-color: #F36D6D; }
}
:root[data-theme="dark"] .todo { background: #4D1616; color: #FFC9C9; outline-color: #F36D6D; }

/* ==========================================================================
   Spoke pages and the hub's new sections (2026-09-22)

   Appended deliberately at the END of the file. Two selectors of equal
   specificity are decided by source order, and that has already produced one
   invisible-text bug here (.card p beating .card--dark p, 1.23:1). Everything
   below introduces NEW class names rather than re-stating an existing one, so
   nothing above changes meaning — keep it that way when editing.
   ========================================================================== */

/* ---------- sub-page hero ---------- */

.hero--sub { padding-bottom: clamp(28px, 4vw, 44px); }
.hero--sub h1 {
  font-size: clamp(1.75rem, 1.35rem + 2vw, 2.75rem);
  max-width: 18ch;
}
.hero__body--sub { padding-top: clamp(26px, 4vw, 48px); padding-bottom: 0; }
.hero__body--sub .hero__copy { max-width: 62ch; }
.hero--sub .chips .chip {
  background: rgba(127, 239, 190, 0.14);
  color: var(--lynx-mint);
}

/* ---------- breadcrumb ---------- */

.crumbs {
  border-bottom: 1px solid var(--hairline);
  background: var(--paper);
  font-size: 0.78125rem;
}
.crumbs .wrap { display: flex; align-items: center; gap: 9px; padding-block: 11px; flex-wrap: wrap; }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--accent); text-decoration: underline; }
.crumbs span[aria-current] { color: var(--ink); font-weight: 600; }
.crumbs__sep { color: var(--muted); opacity: 0.55; }

/* ---------- feature groups ---------- */

.feats {
  margin-top: 30px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  overflow: hidden;
}
.feat { background: var(--paper); padding: 22px 24px 24px; }
.feat h3 {
  font-size: 0.9375rem;
  font-weight: 700;
  margin-bottom: 7px;
  color: var(--ink);
}
.feat p { font-size: 0.84375rem; line-height: 1.62; color: var(--body); }
.feat code {
  font-family: var(--mono);
  font-size: 0.78em;
  background: var(--paper-3);
  padding: 1px 5px;
  border-radius: 4px;
}

/* ---------- the verification numbers ---------- */

.stats {
  margin-top: 32px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 18px;
}
.stat {
  padding: 24px 26px;
  border-radius: var(--radius-card);
  background: var(--paper);
  border: 1px solid var(--hairline);
}
.stat__n {
  font-family: var(--display);
  font-size: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
  font-weight: 700;
  line-height: 1.05;
  color: var(--accent);
  letter-spacing: -0.02em;
}
.stat__l {
  margin-top: 9px;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--muted);
}

/* ---------- workflow rows ---------- */

.flows { margin-top: 30px; display: flex; flex-direction: column; gap: 1px; background: var(--hairline); border-radius: var(--radius-card); overflow: hidden; border: 1px solid var(--hairline); }
.flow {
  background: var(--paper);
  padding: 24px clamp(22px, 3vw, 34px);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
}
@media (min-width: 860px) {
  .flow { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.35fr); gap: clamp(24px, 4vw, 56px); align-items: start; }
}
.flow h3 {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--ink);
}
.flow p { font-size: 0.875rem; line-height: 1.65; color: var(--body); }

/* ---------- a card that is a link ---------- */

.card--link { text-decoration: none; display: flex; flex-direction: column; }
.card--link:hover { border-color: var(--hairline-strong); }
.card__more {
  margin-top: auto;
  padding-top: 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--accent-text);
}
.card--link:hover .card__more { gap: 10px; }
.card__more svg { transition: transform 160ms ease; }
@media (prefers-reduced-motion: reduce) { .card__more svg { transition: none; } }

/* ---------- comparison + tool tables ---------- */

table.facts-table thead th {
  text-align: left;
  font-size: 0.78125rem;
  font-weight: 700;
  color: var(--ink);
  padding: 13px 16px;
  background: var(--paper-3);
  border-bottom: 1px solid var(--hairline-strong);
  vertical-align: bottom;
}
table.compare td { font-size: 0.8125rem; line-height: 1.5; }
/* The tick is a text mark, not colour alone: a cell that differs only by hue
 * says nothing to a screen reader or to anyone who cannot separate the two. */
table.compare td.yes { color: var(--ink); font-weight: 600; }
table.compare td.yes::before {
  content: "\2713\00a0";
  color: var(--accent);
  font-weight: 700;
}
th.tool-group {
  background: var(--paper-3);
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 12px 16px;
}
table.facts-table th[scope="row"] code {
  font-family: var(--mono);
  font-size: 0.78125rem;
  color: var(--accent);
  font-weight: 600;
}

/* ---------- product screenshots ---------- */

/* Every <img> here carries width/height so the box is reserved before the file
 * arrives — a screenshot that pushes the page down as it loads is the same
 * class of bug as the aspect-ratio hero well, just later in the load. */
.figure { margin: clamp(26px, 4vw, 44px) 0 0; }
.figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 14px;
  border: 1px solid var(--hairline-strong);
  background: var(--paper-3);
}
.figure figcaption {
  margin-top: 12px;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--muted);
  max-width: 76ch;
}
.figure figcaption b { color: var(--ink); font-weight: 600; }

/* The window chrome is drawn by the app, so the shot needs no fake titlebar —
 * but it does need a ground that is not the same value as the page, or a light
 * screenshot bleeds into light paper and a dark one into the dark band. */
.shot-frame {
  padding: clamp(10px, 1.4vw, 18px);
  border-radius: 20px;
  background: var(--paper-3);
  border: 1px solid var(--hairline);
}
.shot-frame .figure { margin-top: 0; }
.shot-frame .figure img { border-color: var(--hairline); }

/* card thumbnails on the hub's editor grid */
.card__shot {
  display: block;
  width: 100%;
  height: auto;
  margin: 2px 0 14px;
  border-radius: 9px;
  border: 1px solid var(--hairline);
  background: var(--paper-3);
}


/* ---------- accent text on the navy ground (2026-09-22, brand palette) ----------
 *
 * Digital Indigo is the spec's ACCENT · FOCUS · ACTION colour and it is right
 * on paper (4.94:1). On Midnight Navy it is 3.33:1 — fine for a border or a
 * large label, not for the 12px uppercase eyebrow. Mint is 11.49:1 there and
 * is the brand primary for dark surfaces, so accent TEXT flips to mint on
 * every navy ground. Measured, not assumed.
 */
.hero .eyebrow,
.callout .eyebrow,
.card--dark .eyebrow { color: var(--lynx-mint); }

/* A quiet-surface button. .btn--ghost is white-on-navy and belongs to the hero;
 * using it on a light section rendered white text on Cloud Gray at 1.13:1 —
 * invisible, and introduced by this change rather than by the palette. */
.btn--quiet {
  border-color: rgba(74, 92, 254, 0.38);
  color: var(--accent-text);
  background: var(--paper);
}
.btn--quiet:hover { border-color: var(--accent); background: var(--tint); }

/* ---------- the official mark (2026-09-22) ----------
 * Replaces a hand-drawn hexagon that approximated the logo. Page 14 of the
 * brand guidelines prohibits redrawing it, and page 10 sets 32px as the
 * minimum for the mark alone — the old SVG rendered at 26px, so it broke both
 * rules at once. The wordmark beside it stays HTML text in the brand's own
 * display face; the official lockup artwork should replace the pair when its
 * SVG is exported.
 */
/* No width here: the HTML width attribute sizes it (150px in the header, 146px
 * in the footer — both at or above the spec's minimum for this lockup). Setting
 * width:auto collapsed it to 0x0 inside the flex row, which rendered as a
 * missing logo while the file itself loaded perfectly. */
.brand__lockup { display: block; height: auto; flex: 0 0 auto; }
@media (max-width: 520px) {
  /* The spec's 146px minimum is for the horizontal lockup. Below the width
   * where 146px stops fitting comfortably the mark alone takes over, which has
   * its own 32px minimum and clears it easily at 34px. */
  .brand__lockup { content: url("/assets/logo/mark-reversed.svg"); max-width: 34px; }
}

/* The footer's two lockups. The header is navy in both themes, so it always
 * takes the reversed artwork; the footer sits on the page's ground, which is
 * white in light mode, so it shows the ink colourway there and the reversed
 * one in dark. Written for BOTH dark paths, like every dark rule here. Before
 * this the footer used the reversed artwork everywhere: white on white. */
.foot .brand__lockup--rev { display: none; }
/* The footer's lockup has a row to itself, where 146px fits on any phone, so
 * it keeps the full lockup and skips the header's mark-only swap above. */
@media (max-width: 520px) {
  .foot .brand__lockup { content: normal; max-width: none; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .foot .brand__lockup--ink { display: none; }
  :root:not([data-theme="light"]) .foot .brand__lockup--rev { display: block; }
}
:root[data-theme="dark"] .foot .brand__lockup--ink { display: none; }
:root[data-theme="dark"] .foot .brand__lockup--rev { display: block; }


/* The hero screenshot. width:100% + height:auto is what keeps the aspect ratio
 * the file's own; the HTML width/height attributes stay on the element so the
 * box is reserved before the file arrives. */
.shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
}

/* ---------- policy pages (_authoring/legal_run.py) ----------
 * Long legal prose: a 72ch column set flush with the hero's left edge rather
 * than centred, headings a step down from the marketing h2 (which is sized for
 * a section title, not for "4. Purchase Cancellation"), and the site's small
 * indigo for links, since they sit in 16px running text. Each heading opens a
 * <section>, so spacing comes from gap, not from margins that collapse. */
.legal,
.legal section { display: flex; flex-direction: column; gap: 16px; }
.legal { color: var(--body); line-height: 1.7; }
.legal :is(h2, h3, p, ul) { max-width: 72ch; }
.legal h2 { margin-top: 28px; font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem); }
.legal h3 { margin-top: 8px; font-size: 1.0625rem; }
.legal > section:first-child > h2:first-child { margin-top: 0; }
.legal ul { display: flex; flex-direction: column; gap: 8px; padding-left: 1.4em; }
.legal a { color: var(--accent-text); text-underline-offset: 3px; overflow-wrap: anywhere; }
.legal a:hover { color: var(--accent-hover); }
