/* ── Self-hosted web fonts (AUT-366) ──────────────────────────────────────
   Newsreader, Figtree and IBM Plex Mono used to come from fonts.googleapis.com,
   which put a render-blocking round trip to a third-party host in front of every
   page. These are the same files, served from our own origin, latin and
   latin-ext subsets only. Generated from the css2 API; regenerate the same way
   if a weight is added. font-display: swap is preserved on every face. */
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/Figtree-400-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/Figtree-400-normal-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;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/Figtree-500-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/Figtree-500-normal-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;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/assets/fonts/Figtree-600-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/assets/fonts/Figtree-600-normal-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;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/Figtree-700-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/Figtree-700-normal-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;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/IBMPlexMono-400-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/IBMPlexMono-400-normal-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;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/IBMPlexMono-500-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/IBMPlexMono-500-normal-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;
}
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/Newsreader-500-italic-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/Newsreader-500-italic-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;
}
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/Newsreader-500-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/Newsreader-500-normal-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;
}
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/assets/fonts/Newsreader-600-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/assets/fonts/Newsreader-600-normal-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;
}

/* ──────────────────────────────────────────────────────────────────────────
   Tessera product site · your-tessera.com
   Type system: Newsreader (display) / Figtree (body) / IBM Plex Mono (proof
   lines). The mono "proof line" register carries the precise, verifiable
   claim under each plain-language headline (see Tessera_Target_Audience.md).
   ────────────────────────────────────────────────────────────────────────── */

:root {
  --paper: #f7f9fb;
  --paper-2: #edf2f7;
  --white: #ffffff;
  --ink-900: #10233b;
  --ink-600: #45566e;
  --ink-400: #7c8ba1;
  --navy: #16436e;
  --navy-hover: #0f3457;
  --tile-1: #bcd6e8;
  --tile-2: #8fb9da;
  --tile-3: #5e93be;
  --gold: #c99b3f;
  --gold-soft: #ead9b4;
  --line: #dce5ee;
  --good: #2e7d5b;
  --radius: 14px;
  --font-display: "Newsreader", Georgia, serif;
  --font-body: "Figtree", -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; font-size: 17px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  font-family: var(--font-body);
  background: var(--paper);
  color: var(--ink-900);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

::selection { background: var(--gold-soft); }

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

.wrap { max-width: 1320px; margin: 0 auto; padding: 0 32px; }

/* Text for screen readers only. Used where the visual carries meaning a reader
   cannot get: a redaction bar is a black rectangle to everything but an eye. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Type roles ─────────────────────────────────────────────────────────── */

h1, h2, .display {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.12;
  letter-spacing: -0.01em;
}

h1 { font-size: clamp(2.8rem, 6.5vw, 5rem); }
h2 { font-size: clamp(2rem, 4vw, 3.1rem); }
h3 { font-size: 1.2rem; font-weight: 600; }

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-400);
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 18px;
}
.eyebrow::before {
  content: "";
  width: 9px; height: 9px;
  background: var(--gold);
  border-radius: 2px;
  flex: none;
}

.proof {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.65;
  color: var(--ink-600);
}

.lede { font-size: 1.22rem; color: var(--ink-600); max-width: 36em; }

/* ── Buttons ────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 600;
  padding: 13px 26px;
  border-radius: 10px;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
.btn-primary { background: var(--navy); color: var(--white); }
.btn-primary:hover { background: var(--navy-hover); transform: translateY(-1px); }
.btn-ghost { border-color: var(--line); color: var(--ink-900); background: var(--white); }
.btn-ghost:hover { border-color: var(--tile-3); }
.btn-lg { padding: 16px 32px; font-size: 1.02rem; }

/* ── Nav ────────────────────────────────────────────────────────────────── */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease;
}
.nav.scrolled { border-bottom-color: var(--line); }
.nav-inner {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 14px 32px;
  max-width: 1320px;
  margin: 0 auto;
}
.nav-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 1.05rem;
  text-decoration: none;
  letter-spacing: 0.01em;
}
.nav-logo img { width: 30px; height: 30px; border-radius: 7px; }
.nav-links {
  display: flex;
  gap: 24px;
  margin-left: 12px;
  flex: 1;
}
.nav-links a {
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--ink-600);
  text-decoration: none;
  transition: color 0.15s ease;
}
.nav-links a:hover { color: var(--ink-900); }
.nav-cta { display: flex; align-items: center; gap: 14px; }
/* Sign in.
 *
 * ⚠️ THIS USED TO BE `display: none` UNDER 760px, and that was the whole bug: on a
 * phone (and any narrow desktop window) the only control in the header was "Get
 * started", so an existing user had no way back into their account from the
 * marketing site at all. A returning customer is not a worse visitor than a new
 * one; do not hide their door again to save 70px.
 *
 * It reads as a bordered control rather than a bare text link so it is visibly a
 * button next to the primary CTA, while staying quiet enough not to compete with
 * it. */
.nav-cta .signin {
  font-size: 0.92rem; font-weight: 600;
  color: var(--ink-600); text-decoration: none;
  padding: 9px 16px;
  border: 1px solid var(--line);
  border-radius: 10px; /* matches .btn, so the pair reads as one control group */
  white-space: nowrap;
}
.nav-cta .signin:hover { color: var(--ink-900); border-color: var(--ink-400); }
.nav-cta .btn { padding: 10px 20px; font-size: 0.9rem; }

@media (max-width: 760px) {
  .nav-links { display: none; }
  /* Both controls stay, tightened so the pair still fits a narrow phone. */
  .nav-cta { gap: 8px; }
  .nav-cta .signin { padding: 8px 12px; font-size: 0.86rem; }
  .nav-cta .btn { padding: 8px 14px; font-size: 0.86rem; }
}

/* ── Hero ───────────────────────────────────────────────────────────────── */

.hero { padding: 72px 0 96px; }
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 64px;
  align-items: center;
}
.hero h1 em {
  font-style: italic;
  color: var(--navy);
}
/* Tagline under the H1: the old three-line hero headline, kept as the deck now
   that the H1 itself carries the search phrase (AUT-359). */
.hero-tagline {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.4vw, 1.9rem);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink-600);
  margin-top: 16px;
}
.hero-tagline em { font-style: italic; color: var(--navy); }
.hero .lede { margin: 26px 0 18px; }
.hero-crossmodel {
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--ink-600);
  max-width: 36em;
  margin: 0 0 34px;
  padding-left: 14px;
  border-left: 3px solid var(--line);
}
.hero-actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.hero-note {
  margin-top: 14px;
  font-size: 0.85rem;
  color: var(--ink-400);
}
.hero-proofrow {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
  margin-top: 44px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}
.hero-proofrow .proof { display: flex; align-items: center; gap: 8px; }
.hero-proofrow .proof::before {
  content: "✓";
  color: var(--good);
  font-weight: 600;
}

/* Living mosaic */
.mosaic-stage { position: relative; }
.mosaic {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 6px;
  aspect-ratio: 12 / 8;
}
.mosaic .tile {
  border-radius: 3px;
  background: var(--paper-2);
  transition: background 0.6s ease, transform 0.6s ease;
}
.mosaic .tile.on-1 { background: var(--tile-1); }
.mosaic .tile.on-2 { background: var(--tile-2); }
.mosaic .tile.on-3 { background: var(--tile-3); }
.mosaic .tile.on-g { background: var(--gold); }
/* Top right, not bottom left: the bottom of the stage now belongs to the handoff
   beat, and the two were drawing over each other. flex-end so the ragged chip
   widths align on the right edge, matching the captions below. */
.mosaic-chips {
  position: absolute;
  right: -12px;
  top: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-end;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--white);
  border: 1px solid var(--line);
  box-shadow: 0 6px 18px rgba(16, 35, 59, 0.07);
  border-radius: 999px;
  padding: 7px 14px;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--ink-600);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.chip.shown { opacity: 1; transform: none; }
.chip::before { content: "✓"; color: var(--good); font-weight: 700; font-size: 0.78rem; }
.mosaic-caption {
  margin-top: 18px;
  text-align: right;
  opacity: 0;
  transition: opacity 0.8s ease;
}
.mosaic-caption.shown { opacity: 1; }

/* Opening beat: the question that starts the sequence. In flow with an
   opacity-only reveal so it reserves its height at first paint and the
   mosaic never jumps when it appears. */
.mosaic-prompt {
  display: inline-flex;
  align-items: center;
  background: var(--ink-900);
  color: var(--white);
  border-radius: 999px 999px 999px 5px;
  padding: 9px 16px;
  margin-bottom: 14px;
  font-size: 0.85rem;
  font-weight: 500;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.mosaic-prompt.shown { opacity: 1; transform: none; }

/* Tail beat: the handoff. The facts travel; the identity does not. */
/* In flow so it reserves its space from first paint: the beat must not shift the hero. */
.mosaic-caption-2 { margin-top: 10px; font-weight: 600; color: var(--ink-900); }
.mosaic-handoff {
  margin-top: 16px;
  text-align: right;
  opacity: 0;
  transition: opacity 0.7s ease;
}
.mosaic-handoff.shown { opacity: 1; }
.mh-line {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  align-items: center;
  justify-content: flex-end;
}
.mh-line + .mh-line { margin-top: 9px; }
.mh-tag {
  font-size: 0.64rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-weight: 700;
}
.mh-tag-sent { color: var(--good); }
.mh-tag-held { color: var(--gold); }
.mh-note { font-size: 0.78rem; color: var(--ink-600); }
.id-pill {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 11px;
  background: var(--white);
  font-size: 0.75rem;
  color: var(--ink-600);
  transition: color 0.45s ease, background 0.45s ease, border-color 0.45s ease;
}
/* Blacked out rather than blurred: a redaction bar is unambiguous at this size. */
.id-pill.redacted {
  color: transparent;
  background: var(--ink-600);
  border-color: var(--ink-600);
}

@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; gap: 48px; }
  .mosaic-chips { right: 0; }
}

/* ── Sections ───────────────────────────────────────────────────────────── */

section { padding: 96px 0; }
section.tint { background: var(--white); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.section-head { max-width: 740px; margin-bottom: 56px; }
.section-head .lede { margin-top: 18px; }

/* Reveal on scroll */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.7s ease, transform 0.7s ease; }
.reveal.shown { opacity: 1; transform: none; }
.reveal:nth-child(2) { transition-delay: 0.08s; }
.reveal:nth-child(3) { transition-delay: 0.16s; }
.reveal:nth-child(4) { transition-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .chip, .mosaic-caption, .mosaic-handoff, .mosaic-prompt { opacity: 1 !important; transform: none !important; transition: none !important; }
  .id-pill { transition: none !important; }
  .mosaic .tile { transition: none !important; }
  .btn:hover { transform: none; }
}

/* ── Problem cards ──────────────────────────────────────────────────────── */

.cards-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
@media (max-width: 860px) { .cards-3 { grid-template-columns: 1fr; } }

.quote-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 30px 28px;
}
section.tint .quote-card { background: var(--paper); }
.quote-card .q {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.35rem;
  line-height: 1.3;
  margin-bottom: 14px;
}
.quote-card p { color: var(--ink-600); font-size: 0.95rem; }
.bridge {
  margin-top: 44px;
  font-size: 1.15rem;
  color: var(--ink-600);
  max-width: 40em;
}
.bridge strong { color: var(--ink-900); }

/* ── Demo ───────────────────────────────────────────────────────────────── */

/* Prose fallback for the second demo scene. Only ever seen without JS: main.js
   removes it on init (AUT-356). Styled so it does not look broken if it shows. */
.demo-static-alt {
  margin-top: 34px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
  max-width: 62em;
  color: var(--ink-600);
}
.demo-static-alt p { margin: 0 0 12px; }
.demo-static-label {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-400);
}

.demo-tabs { display: flex; gap: 10px; margin-bottom: 26px; flex-wrap: wrap; }
.demo-tab {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink-600);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.demo-tab[aria-selected="true"] {
  border-color: var(--navy);
  color: var(--navy);
  background: var(--white);
}
.demo-prompt {
  font-family: var(--font-mono);
  font-size: 0.92rem;
  background: var(--ink-900);
  color: #dfe9f4;
  border-radius: 12px;
  padding: 18px 22px;
  margin-bottom: 26px;
  min-height: 58px;
}
.demo-prompt .cursor {
  display: inline-block;
  width: 8px; height: 1.05em;
  background: var(--gold);
  vertical-align: text-bottom;
  margin-left: 2px;
  animation: blink 1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .demo-prompt .cursor { animation: none; } }

.demo-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: start; }
@media (max-width: 860px) { .demo-cols { grid-template-columns: 1fr; } }

.demo-col {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px;
  min-height: 300px;
}
.demo-col.with { border-color: var(--tile-2); box-shadow: 0 14px 40px rgba(94, 147, 190, 0.14); }
.demo-col .label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: 18px;
  color: var(--ink-400);
}
.demo-col.with .label { color: var(--navy); }
.demo-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; min-height: 36px; }
.demo-chips .chip { font-size: 0.78rem; padding: 5px 12px; }
.demo-answer { color: var(--ink-600); font-size: 0.97rem; min-height: 120px; }
.demo-answer strong { color: var(--ink-900); }
.demo-replay {
  margin-top: 26px;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-400);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.demo-replay:hover { color: var(--ink-900); }

/* ── How it works ───────────────────────────────────────────────────────── */

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; counter-reset: step; }
@media (max-width: 860px) { .steps { grid-template-columns: 1fr; } }
.step {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 30px 28px;
  position: relative;
}
.step .num {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--gold);
  display: block;
  margin-bottom: 16px;
}
.step h3 { margin-bottom: 10px; }
.step p { color: var(--ink-600); font-size: 0.95rem; }

/* ── Pillars ────────────────────────────────────────────────────────────── */

.pillars { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
/* With an odd number of pillars the last one would sit alone in a half-width
   column. Let it span the full row instead, so the grid never ends ragged.
   No-op when the count is even. */
.pillars .pillar:last-child:nth-child(odd) { grid-column: 1 / -1; }
@media (max-width: 860px) { .pillars { grid-template-columns: 1fr; } }
.pillar {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 36px 32px;
}
.pillar .display { font-size: 1.9rem; margin-bottom: 14px; }
.pillar .proof { display: flex; gap: 10px; }
.pillar .proof::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 2px;
  background: var(--tile-3);
  flex: none;
  margin-top: 7px;
}
.footnote {
  margin-top: 30px;
  font-size: 0.78rem;
  color: var(--ink-400);
  max-width: 52em;
}

/* ── App screenshot carousel ────────────────────────────────────────────── */
/* Real captures, not mockups. The track scrolls natively with scroll-snap so
   the whole thing is usable with JS off; main.js adds arrows and dots. */

.shots { position: relative; }

.shots-track {
  list-style: none;
  display: flex;
  gap: 34px;
  overflow-x: auto;
  /* Explicitly hidden, not left to default: an auto/auto track swallows the
     wheel and the page stops scrolling when the pointer is over the phones. */
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Room for the phone's drop shadow above, which overflow would clip. Side
     padding stays at zero: with mandatory snap it would offset every resting
     position by its own width and throw the slide index off. */
  padding: 40px 0 8px;
  margin: -40px 0 -8px;
  scrollbar-width: none;
}
.shots-track::-webkit-scrollbar { display: none; }
.shots-track:focus-visible { outline: 2px solid var(--navy); outline-offset: 6px; border-radius: var(--radius); }
@media (prefers-reduced-motion: reduce) { .shots-track { scroll-behavior: auto; } }

.shot {
  flex: 0 0 calc((100% - 68px) / 3);
  scroll-snap-align: start;
  text-align: center;
}
.shot h3 { margin: 22px 0 6px; }
.shot p { color: var(--ink-600); font-size: 0.92rem; }

@media (max-width: 900px) { .shot { flex-basis: calc((100% - 34px) / 2); } }
@media (max-width: 620px) { .shot { flex-basis: 100%; } }

.phone {
  background: var(--ink-900);
  border-radius: 34px;
  padding: 10px;
  box-shadow: 0 24px 60px rgba(16, 35, 59, 0.18);
  max-width: 320px;
  margin: 0 auto;
}
.phone img {
  border-radius: 26px;
  width: 100%;
  height: auto;
  background: var(--paper);
}

/* Controls are injected by main.js, so nothing here renders without it. */
.shots-nav {
  position: absolute;
  top: calc(50% - 60px);
  transform: translateY(-50%);
  width: 40px; height: 40px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink-900);
  box-shadow: 0 6px 20px rgba(16, 35, 59, 0.12);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.1rem; line-height: 1;
  transition: opacity 0.2s ease, background 0.2s ease;
  z-index: 2;
}
.shots-nav:hover { background: var(--paper-2); }
.shots-nav.prev { left: -20px; }
.shots-nav.next { right: -20px; }
.shots-nav[disabled] { opacity: 0.3; cursor: default; }
@media (max-width: 1100px) {
  .shots-nav.prev { left: 2px; }
  .shots-nav.next { right: 2px; }
}

.shots-dots {
  display: flex; justify-content: center; gap: 9px;
  margin-top: 30px;
}
.shots-dots button {
  width: 9px; height: 9px; padding: 0;
  border: 0; border-radius: 3px;
  background: var(--line);
  cursor: pointer;
  transition: background 0.2s ease, width 0.2s ease;
}
.shots-dots button[aria-current="true"] { background: var(--tile-3); width: 22px; }

/* Browser mockup */
.browser-band { margin-top: 84px; }
.browser-band .band-inner {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: 56px;
  align-items: center;
}
@media (max-width: 900px) { .browser-band .band-inner { grid-template-columns: 1fr; } }
.browser {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(16, 35, 59, 0.12);
}
.browser-bar {
  display: flex; align-items: center; gap: 10px;
  background: var(--paper-2);
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
}
.browser-bar .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--line); }
.browser-bar .url {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-600);
  background: var(--white);
  border-radius: 6px;
  padding: 4px 12px;
  flex: 1;
  text-align: center;
}
.browser-body { padding: 26px; font-size: 0.85rem; }
.browser-body .msg {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 16px;
  margin-bottom: 10px;
  color: var(--ink-600);
  max-width: 85%;
}
.browser-body .msg.user {
  background: var(--paper-2);
  margin-left: auto;
  color: var(--ink-900);
}

/* ── Clips (See it in action) ───────────────────────────────────────────── */

.clips { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px; }
@media (max-width: 860px) { .clips { grid-template-columns: 1fr; } }
.clip { margin: 0; }
.clip img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: center 30%;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  box-shadow: 0 14px 40px rgba(16, 35, 59, 0.1);
}
.clip video {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  box-shadow: 0 14px 40px rgba(16, 35, 59, 0.1);
  background: var(--paper-2);
}
.clip figcaption {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-600);
  margin-top: 12px;
}

/* ── Privacy ────────────────────────────────────────────────────────────── */

.privacy { background: var(--ink-900); color: #e6edf5; }
.privacy .eyebrow { color: var(--tile-1); }
.privacy .lede { color: #a9bcd2; }
.privacy-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
@media (max-width: 860px) { .privacy-grid { grid-template-columns: 1fr; } }
.privacy-card {
  border: 1px solid rgba(230, 237, 245, 0.16);
  border-radius: var(--radius);
  padding: 30px 28px;
  background: rgba(255, 255, 255, 0.03);
}
.privacy-card h3 { margin-bottom: 10px; color: var(--white); }
.privacy-card p { color: #a9bcd2; font-size: 0.95rem; }
.privacy-card .proof { color: var(--tile-1); margin-top: 14px; font-size: 0.75rem; }
.privacy-link { margin-top: 44px; }
.privacy-link a { color: var(--tile-1); font-weight: 600; text-decoration: none; border-bottom: 1px solid rgba(188, 214, 232, 0.4); padding-bottom: 2px; }
.privacy-link a:hover { border-bottom-color: var(--tile-1); }

/* ── Testimonials, redacted ─────────────────────────────────────────────── */
/*
 * Two rendering modes on purpose:
 *
 *   default   every voice is in normal flow, fully painted. This is what runs
 *             with no JS at all and with prefers-reduced-motion, and it is a
 *             perfectly good section: the redaction still reads.
 *   .is-live  main.js opts in. Voices stack in one grid cell so the container
 *             never changes height, and the choreography below plays.
 *
 * The resting state carries NO transition, so resetting a voice after it exits
 * snaps back instantly instead of un-drawing itself on a two second delay.
 */

/* The only section head on the page that centres, because everything under it
   is centred on the record card. */
#voices .section-head { margin-left: auto; margin-right: auto; text-align: center; }
#voices .eyebrow { justify-content: center; }

.voices { display: grid; gap: 40px; justify-items: center; }
.voice { max-width: 760px; width: 100%; text-align: center; }

.voice-q {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.5rem, 2.9vw, 2.15rem);
  line-height: 1.32;
  color: var(--ink-900);
  margin: 0 auto 40px;
  max-width: 22em;
}
.voice-q::before { content: "\201C"; }
.voice-q::after { content: "\201D"; }

/* The attribution. Sits where a name normally sits under a pull quote, bottom
   right after a dash, and every other line it holds is simply more of the same
   attribution. No card and no table on purpose: the moment it looks like a
   database readout it stops reading as "this is the person who said it". */
.voice-by {
  margin: 34px 0 0 auto;
  width: max-content;
  max-width: 100%;
  text-align: right;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.06rem;
  color: var(--ink-600);
}
.by-line { margin: 0 0 7px; line-height: 1.9; white-space: nowrap; }
.by-line:last-child { margin-bottom: 0; }
.by-name { font-size: 1.2rem; color: var(--ink-900); margin-bottom: 14px; }

/* The redaction itself: a soft pill, not a censor's rectangle. Sized in em so
   it scales with the line it is standing in for. */
.rd {
  display: inline-block;
  height: 0.78em;
  max-width: 100%;
  background: var(--navy);
  border-radius: 999px;
  vertical-align: -0.02em;
  transform-origin: left center;
}
.by-name .rd { background: var(--ink-900); height: 0.72em; }

.voices-note {
  margin-top: 56px;
  text-align: center;
  color: var(--ink-400);
  font-size: 0.95rem;
}
.voices-note a {
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid rgba(22, 67, 110, 0.3);
  padding-bottom: 2px;
}
.voices-note a:hover { border-bottom-color: var(--navy); }

/* Animated mode ---------------------------------------------------------- */

.voices.is-live { gap: 0; }
.voices.is-live > .voice { grid-area: 1 / 1; visibility: hidden; }
.voices.is-live .voice-q { opacity: 0; transform: translateY(16px); }
.voices.is-live .by-line { opacity: 0; transform: translateY(8px); }
.voices.is-live .rd { transform: scaleX(0); }

.voices.is-live > .voice.is-on { visibility: visible; }
.voice.is-on .voice-q {
  opacity: 1; transform: none;
  transition: opacity 0.9s ease, transform 0.9s ease;
  transition-delay: 0.1s;
}
.voice.is-on .by-line {
  opacity: 1; transform: none;
  transition: opacity 0.45s ease, transform 0.45s ease;
  transition-delay: calc(1.75s + var(--i) * 0.22s);
}
.voice.is-on .rd {
  transform: scaleX(1);
  transition: transform 0.42s cubic-bezier(0.2, 0.7, 0.3, 1);
  transition-delay: calc(1.9s + var(--i) * 0.22s);
}

/* Leaving: quote and attribution fade as one. The pills are pinned painted so
   the lines do not empty themselves out on the way off. */
.voices.is-live > .voice.is-exiting { visibility: visible; }
.voice.is-exiting .voice-q,
.voice.is-exiting .by-line { opacity: 0; transform: none; transition: opacity 0.45s ease; transition-delay: 0s; }
.voice.is-exiting .rd { transform: scaleX(1); }

/* Dots are built by main.js, so they never appear without the rotation they
   control, and never for a single voice. */
.voice-dots { display: flex; justify-content: center; gap: 10px; margin-top: 36px; }
.voice-dots:empty { display: none; }
.voice-dot {
  width: 9px; height: 9px; padding: 0;
  border: 1px solid var(--ink-400);
  background: transparent;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.25s ease, border-color 0.25s ease;
}
.voice-dot[aria-selected="true"] { background: var(--gold); border-color: var(--gold); }
.voice-dot:hover { border-color: var(--navy); }

/* Narrow screens: a right-hung attribution has nothing to hang off, and the
   longest label plus its pill is wider than the column. Left align and let the
   pills shrink instead of pushing the page sideways. */
@media (max-width: 620px) {
  .voice { text-align: left; }
  .voice-q { text-align: center; }
  .voice-by { margin-right: auto; width: auto; font-size: 1rem; }
  .by-line { white-space: normal; }
  .rd { max-width: 55vw; }
}

@media (prefers-reduced-motion: reduce) {
  .voice-q, .by-line { opacity: 1 !important; transform: none !important; }
  .rd { transform: scaleX(1) !important; transition: none !important; }
}

/* ── Pricing (teaser + page) ────────────────────────────────────────────── */

.tiers { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; align-items: stretch; }
@media (max-width: 1000px) { .tiers { grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px) { .tiers { grid-template-columns: 1fr; } }
.tier {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 30px 26px;
  display: flex;
  flex-direction: column;
}
.tier.featured {
  border-color: var(--navy);
  box-shadow: 0 18px 48px rgba(22, 67, 110, 0.14);
  position: relative;
}
.tier .flag {
  position: absolute;
  top: -12px; left: 26px;
  background: var(--navy);
  color: var(--white);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 4px 12px;
}
.tier h3 { font-size: 1.05rem; }
.tier .price { font-family: var(--font-display); font-size: 2.1rem; margin: 10px 0 2px; }
.tier .price span { font-family: var(--font-body); font-size: 0.85rem; color: var(--ink-400); }
.tier .for { font-size: 0.85rem; color: var(--ink-400); margin-bottom: 20px; }
.tier ul { list-style: none; margin-bottom: 26px; flex: 1; }
.tier li {
  font-size: 0.9rem;
  color: var(--ink-600);
  padding: 6px 0 6px 24px;
  position: relative;
}
.tier li::before {
  content: "✓";
  position: absolute; left: 0;
  color: var(--good);
  font-weight: 600;
}
.tier .btn { width: 100%; }

.compare { margin-top: 72px; overflow-x: auto; }
.compare table {
  width: 100%;
  border-collapse: collapse;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  min-width: 640px;
}
.compare th, .compare td {
  padding: 14px 18px;
  text-align: left;
  font-size: 0.9rem;
  border-bottom: 1px solid var(--line);
}
.compare th {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-400);
  background: var(--paper-2);
}
.compare td:first-child { color: var(--ink-600); }
.compare tr:last-child td { border-bottom: none; }

.pricing-notes { margin-top: 44px; }
.pricing-notes p { font-size: 0.85rem; color: var(--ink-400); max-width: 56em; }
.pricing-notes a { color: var(--ink-600); }

/* Teaser band on index */
.teaser-row {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin: 34px 0;
}
.teaser-chip {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 10px 20px;
  color: var(--ink-600);
}
.teaser-chip strong { color: var(--ink-900); font-weight: 600; }

/* ── FAQ ────────────────────────────────────────────────────────────────── */

.faq-list { max-width: 880px; }
.faq-list details {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  margin-bottom: 12px;
  overflow: hidden;
}
.faq-list summary {
  cursor: pointer;
  list-style: none;
  padding: 20px 24px;
  font-weight: 600;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::after {
  content: "+";
  font-family: var(--font-mono);
  color: var(--ink-400);
  font-size: 1.1rem;
  transition: transform 0.2s ease;
}
.faq-list details[open] summary::after { transform: rotate(45deg); }
.faq-list details p {
  padding: 0 24px 20px;
  color: var(--ink-600);
  font-size: 0.95rem;
  max-width: 60em;
}
.faq-list details a { color: var(--navy); }

/* ── Final CTA ──────────────────────────────────────────────────────────── */

.final { text-align: center; padding: 120px 0; }
.final h2 { font-size: clamp(2.2rem, 4.5vw, 3.4rem); }
.final .lede { margin: 20px auto 40px; }
.final .hero-actions { justify-content: center; }

/* ── Footer ─────────────────────────────────────────────────────────────── */

footer {
  background: var(--white);
  border-top: 1px solid var(--line);
  padding: 64px 0 40px;
  font-size: 0.9rem;
}
.foot-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 40px;
  margin-bottom: 48px;
}
@media (max-width: 760px) { .foot-grid { grid-template-columns: 1fr 1fr; } }
.foot-brand p { color: var(--ink-400); margin-top: 12px; max-width: 26em; }
.foot-col h4 {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-400);
  margin-bottom: 16px;
}
.foot-col a {
  display: block;
  color: var(--ink-600);
  text-decoration: none;
  padding: 4px 0;
}
.foot-col a:hover { color: var(--ink-900); }
.foot-legal {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  color: var(--ink-400);
  font-size: 0.82rem;
}
.foot-legal .links { display: flex; gap: 20px; }
.foot-legal a { color: var(--ink-400); text-decoration: none; }
.foot-legal a:hover { color: var(--ink-900); }

/* ── Page-hero (pricing) ────────────────────────────────────────────────── */

.page-hero { padding: 80px 0 56px; }
.page-hero .lede { margin-top: 20px; }

/* ── Long-form content pages (AUT-360/361/362/363) ────────────────────────
   /privacy, /faq, /about, /what-is-ai-memory, the use-case pages and the
   guides all share this. Reading measure is deliberately narrower than the
   marketing sections: these pages are read, not scanned. */
.prose { max-width: 42em; }
.prose > * + * { margin-top: 18px; }
.prose h2 {
  font-size: clamp(1.5rem, 2.8vw, 2.05rem);
  margin-top: 52px;
}
.prose h3 { margin-top: 34px; }
.prose p, .prose li { color: var(--ink-600); font-size: 1.05rem; line-height: 1.72; }
.prose strong { color: var(--ink-900); }
.prose ul, .prose ol { padding-left: 1.15em; }
.prose li + li { margin-top: 10px; }
.prose a { color: var(--navy); font-weight: 500; }
.prose h2 + p, .prose h3 + p { margin-top: 12px; }

.prose .callout {
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 10px;
  padding: 22px 26px;
  margin-top: 30px;
}
.prose .callout p { margin: 0; }
.prose .callout p + p { margin-top: 12px; }

/* Definition sentence, repeated across pages so retrievers see it often. */
.definition {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2vw, 1.4rem);
  line-height: 1.45;
  color: var(--ink-900);
  border-left: 3px solid var(--gold);
  padding-left: 22px;
  margin: 34px 0;
  max-width: 34em;
}

/* Card grid used by /faq topic links and the use-case index. */
.link-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 40px; }
@media (max-width: 900px) { .link-cards { grid-template-columns: 1fr; } }
.link-card {
  display: block;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px 26px 28px;
  text-decoration: none;
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.link-card:hover { border-color: var(--tile-3); transform: translateY(-2px); }
.link-card h3 { margin-bottom: 8px; }
.link-card p { color: var(--ink-600); font-size: 0.95rem; }
.link-card .more { display: inline-block; margin-top: 14px; font-size: 0.85rem; font-weight: 600; color: var(--navy); }