/* skill-map landing — native styles.
   Ported section by section from docs/web-template.html.

   This file ships the design-system foundation:
   - Design tokens (color, type, spacing, radii, shadow, motion, layout)
   - Reset + base element styles
   - Semantic typography classes (.t-*)
   - Landing shell (.lp) — responsive, max-width 1440px
   - Focus + selection
*/

/* ============================================================
   TOKENS
   ============================================================ */
:root {
  /* ---------- COLOR — primitives ---------- */

  /* Pure neutrals (NOT cream) */
  --white:        #FFFFFF;
  --ink-50:       #F7F8FA;   /* page tint */
  --ink-100:      #EFF1F4;   /* hairline rows */
  --ink-200:      #E3E6EB;   /* borders */
  --ink-300:      #C9CED6;   /* disabled fg */
  --ink-400:      #8A93A1;   /* secondary text */
  --ink-500:      #5A6472;   /* tertiary text */
  --ink-600:      #2E3744;   /* body text */
  --ink-700:      #1B222C;   /* headings */
  --ink-800:      #0E131A;   /* near-black surfaces */
  --ink-900:      #06080C;   /* deepest */

  /* Saturated brand — GREEN is the secondary/normal workhorse.
     VIOLET is the accent — used sparingly for emphasis, CTAs, selection. */
  --green-50:     #E8FBEF;
  --green-100:    #C7F5D9;
  --green-200:    #8FE8B3;
  --green-300:    #4ED88A;
  --green-400:    #1ECF6B;
  --green-500:    #00C853;
  --green-600:    #00A847;
  --green-700:    #008538;
  --green-800:    #003D1C;

  --violet-50:    #F5F3FF;
  --violet-100:   #EDE9FE;
  --violet-200:   #DDD6FE;
  --violet-300:   #C4B5FD;
  --violet-400:   #A78BFA;
  --violet-500:   #8B5CF6;
  --violet-600:   #7C3AED;
  --violet-700:   #6D28D9;
  --violet-800:   #4C1D95;
  --violet-900:   #2E1065;

  /* Status */
  --success:      #2DB84F;
  --success-bg:   #E5FAEC;
  --warning:      #E8A100;
  --warning-bg:   #FFF6E0;
  --danger:       #E53935;
  --danger-bg:    #FDECEB;
  --info:         #2D7BFF;
  --info-bg:      #E6EFFF;

  /* ---------- COLOR — semantic ---------- */
  --bg:           var(--white);
  --bg-elev:      var(--white);
  --bg-subtle:    var(--ink-50);
  --bg-muted:     var(--ink-100);
  --bg-inverse:   var(--ink-800);

  --fg:           var(--ink-700);
  --fg-strong:    var(--ink-900);
  --fg-muted:     var(--ink-500);
  --fg-subtle:    var(--ink-400);
  --fg-on-brand:  var(--ink-900);
  --fg-on-dark:   var(--white);

  --border:       var(--ink-200);
  --border-strong:var(--ink-300);
  --border-focus: var(--violet-500);

  --brand:        var(--green-500);
  --brand-hover:  var(--green-600);
  --brand-press:  var(--green-700);
  --brand-soft:   var(--green-50);

  --accent:       var(--violet-600);
  --accent-hover: var(--violet-700);
  --accent-press: var(--violet-800);
  --accent-soft:  var(--violet-50);

  --link:         var(--ink-900);
  --link-accent:  var(--violet-700);

  /* Graph node-type colors */
  --node-skill:    #00C853;
  --node-agent:    #7C3AED;
  --node-command:  #4C1D95;
  --node-hook:     #A78BFA;
  --node-note:     var(--ink-400);
  --node-orphan:   var(--ink-500);

  /* Dark-surface pairings (bg / fg) */
  --skill-dark-bg:   #003D1C;  --skill-dark-fg:   #8FE8B3;
  --agent-dark-bg:   #4C1D95;  --agent-dark-fg:   #DDD6FE;
  --command-dark-bg: #2E1065;  --command-dark-fg: #C4B5FD;
  --hook-dark-bg:    #5B21B6;  --hook-dark-fg:    #EDE9FE;

  /* ---------- TYPOGRAPHY ---------- */
  --font-sans:    "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono:    "Geist Mono", ui-monospace, "JetBrains Mono", "SF Mono", Menlo, monospace;
  --font-display: "Geist", ui-sans-serif, system-ui, sans-serif;

  /* sizes (1.250 modular scale, anchored at 16px) */
  --text-2xs: 11px;
  --text-xs:  12px;
  --text-sm:  13px;
  --text-md:  15px;
  --text-lg:  17px;
  --text-xl:  20px;
  --text-2xl: 24px;
  --text-3xl: 32px;
  --text-4xl: 44px;
  --text-5xl: 60px;
  --text-6xl: 80px;

  /* weights */
  --w-regular:  400;
  --w-medium:   500;
  --w-semibold: 600;
  --w-bold:     700;
  --w-black:    800;

  /* leading */
  --lh-tight:   1.1;
  --lh-snug:    1.25;
  --lh-normal:  1.45;
  --lh-relaxed: 1.65;

  /* tracking */
  --tr-tighter: -0.03em;
  --tr-tight:   -0.015em;
  --tr-normal:   0em;
  --tr-wide:     0.04em;
  --tr-wider:    0.08em;

  /* ---------- SPACING ---------- */
  --s-0:  0;
  --s-1:  4px;
  --s-2:  8px;
  --s-3:  12px;
  --s-4:  16px;
  --s-5:  20px;
  --s-6:  24px;
  --s-8:  32px;
  --s-10: 40px;
  --s-12: 48px;
  --s-16: 64px;
  --s-20: 80px;
  --s-24: 96px;

  /* ---------- RADII ---------- */
  --r-xs:   4px;
  --r-sm:   6px;
  --r-md:   8px;
  --r-lg:  12px;
  --r-xl:  16px;
  --r-2xl: 22px;
  --r-pill: 999px;

  /* ---------- ELEVATION ---------- */
  --sh-0: 0 0 0 1px var(--border);
  --sh-1: 0 1px 0 rgba(14,19,26,.04), 0 1px 2px rgba(14,19,26,.06);
  --sh-2: 0 2px 4px rgba(14,19,26,.06), 0 4px 12px rgba(14,19,26,.06);
  --sh-3: 0 4px 8px rgba(14,19,26,.07), 0 12px 32px rgba(14,19,26,.10);
  --sh-4: 0 8px 16px rgba(14,19,26,.08), 0 24px 56px rgba(14,19,26,.14);
  --sh-focus: 0 0 0 3px rgba(0,200,83,.30);
  --sh-inset: inset 0 1px 0 rgba(255,255,255,.6), inset 0 -1px 0 rgba(14,19,26,.04);
  --sh-glow-brand: 0 0 0 1px var(--green-500), 0 0 28px rgba(0,200,83,.35);

  /* ---------- MOTION ---------- */
  --ease-out:    cubic-bezier(.2,.7,.2,1);
  --ease-in-out: cubic-bezier(.5,.0,.2,1);
  --ease-spring: cubic-bezier(.32,1.4,.4,1);
  --dur-fast:   120ms;
  --dur-base:   180ms;
  --dur-slow:   280ms;
  --dur-slower: 480ms;

  /* ---------- LAYOUT ---------- */
  --container:    1200px;
  --container-sm: 880px;
  --gutter:       24px;
  --header-h:     56px;
}

/* ============================================================
   RESET + BASE
   ============================================================ */
* { box-sizing: border-box; margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

html, body {
  background: var(--ink-900);
  color: var(--white);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "ss01", "cv01";
}

button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
a      { color: inherit; text-decoration: none; }
img,
svg    { display: block; max-width: 100%; }

@media (prefers-reduced-motion: reduce) {
  /* Baseline: collapse any animation/transition the user agent encounters. */
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }

  /* Hard-stop the always-on motion in the hero. These are the only
     `infinite` animations on the page and the main CPU/GPU draw when
     nothing else is happening. `animation: none` releases the compositor
     layer for them; collapsing duration to .01ms still keeps the layer
     and the work loop alive. */
  .hero__graph-svg .select-fx-pulse,
  .hero__graph-svg .hg-traveler {
    animation: none !important;
    opacity: 1 !important;
  }

  /* The canvas loop also self-suspends via JS, but hide the element so
     no leftover frame remains painted. */
  .hero__graph .hg-particles { display: none !important; }
}

/* ============================================================
   SEMANTIC TYPE STYLES
   Apply directly: <h1 class="t-display"> or attach to native tags.
   ============================================================ */
.t-display, h1.display {
  font-family: var(--font-display);
  font-size: var(--text-6xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-tighter);
  font-weight: var(--w-bold);
  color: var(--fg-strong);
}
.t-h1, h1 {
  font-family: var(--font-sans);
  font-size: var(--text-4xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-tight);
  font-weight: var(--w-semibold);
  color: var(--fg-strong);
}
.t-h2, h2 {
  font-size: var(--text-3xl);
  line-height: var(--lh-snug);
  letter-spacing: var(--tr-tight);
  font-weight: var(--w-semibold);
  color: var(--fg-strong);
}
.t-h3, h3 {
  font-size: var(--text-2xl);
  line-height: var(--lh-snug);
  letter-spacing: var(--tr-tight);
  font-weight: var(--w-semibold);
  color: var(--fg-strong);
}
.t-h4, h4 {
  font-size: var(--text-xl);
  line-height: var(--lh-snug);
  font-weight: var(--w-semibold);
  color: var(--fg-strong);
}
.t-eyebrow {
  font-size: var(--text-xs);
  font-weight: var(--w-semibold);
  letter-spacing: var(--tr-wider);
  text-transform: uppercase;
  color: var(--fg-muted);
}
.t-body, p {
  font-size: var(--text-md);
  line-height: var(--lh-relaxed);
  color: var(--fg);
}
.t-body-lg {
  font-size: var(--text-lg);
  line-height: var(--lh-relaxed);
  color: var(--fg);
}
.t-small {
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  color: var(--fg-muted);
}
.t-micro {
  font-size: var(--text-xs);
  line-height: var(--lh-normal);
  color: var(--fg-muted);
}
.t-mono, code, kbd, samp {
  font-family: var(--font-mono);
  font-size: 0.92em;
  font-feature-settings: "ss01", "cv01";
}
.t-code-block {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
}
.t-link, a {
  color: var(--link);
  text-decoration-line: underline;
  text-decoration-color: var(--ink-300);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color var(--dur-fast) var(--ease-out),
              text-decoration-color var(--dur-fast) var(--ease-out);
}
.t-link:hover, a:hover {
  color: var(--link-accent);
  text-decoration-color: var(--link-accent);
}

.tabular { font-variant-numeric: tabular-nums; }

/* ============================================================
   FOCUS + SELECTION
   ============================================================ */
:focus-visible {
  outline: none;
  box-shadow: var(--sh-focus);
  border-radius: var(--r-sm);
}

::selection {
  background: var(--green-200);
  color: var(--ink-900);
}

/* ============================================================
   LANDING SHELL (.lp)
   Dark-surface wrapper. Responsive: full-width up to 1440px,
   centered above that. Internal sections handle their own
   container/padding rules.
   ============================================================ */
.lp {
  width: 100%;
  max-width: 1440px;
  margin-inline: auto;
  background: var(--ink-900);
  color: var(--white);
  position: relative;
  overflow: hidden;

  /* Override DS semantic type colors — DS assumes light surface; we're dark. */
  --fg:        rgba(255,255,255,.85);
  --fg-strong: #FFFFFF;
  --fg-muted:  rgba(255,255,255,.6);
  --fg-subtle: rgba(255,255,255,.45);
  --link:      #FFFFFF;
}
.lp h1, .lp h2, .lp h3, .lp h4, .lp h5, .lp h6,
.lp .t-display, .lp .t-h1, .lp .t-h2, .lp .t-h3, .lp .t-h4,
.lp .section-title { color: #FFFFFF !important; font-family: var(--font-sans) !important; }
.lp p,
.lp .t-body,
.lp .t-body-lg     { color: rgba(255,255,255,.78); }
.lp .t-small,
.lp .t-micro       { color: rgba(255,255,255,.55); }
.lp a              { color: inherit; text-decoration: none; }
.lp ::selection    { background: rgba(0,200,83,.35); color: #fff; }

.lp.theme-light {
  background: var(--white);
  color: var(--ink-700);
}

/* ============================================================
   CONTAINER
   Centers content up to 1280px with responsive lateral gutter.
   ============================================================ */
.lp-container {
  max-width: 1280px;
  margin: 0 auto;
  padding-inline: clamp(20px, 4vw, 64px);
  position: relative;
}

/* ============================================================
   NAV HEADER (.lp-nav)
   Desktop: logo left, links centered-right, CTA right.
   Mobile (≤768px): logo left, hamburger right, drawer overlay.
   ============================================================ */
.lp-nav {
  position: relative;
  z-index: 50;
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-inline: clamp(20px, 4vw, 64px);
  border-bottom: 1px solid rgba(255,255,255,.06);
  background: var(--ink-900);
}
.theme-light .lp-nav { border-bottom-color: var(--ink-100); background: var(--white); }

.lp-nav__logo {
  display: flex; align-items: center; gap: 10px;
  font-size: 17px; font-weight: 600; letter-spacing: -0.02em;
  color: #fff;
}
.lp-nav__logo-mark {
  width: 28px; height: 28px;
  display: grid; place-items: center;
}
.lp-nav__logo-mark img { width: 100%; height: 100%; }

/* Temporary "Beta" stamp — sits next to the wordmark.
   Stencil typography + thin red rule frame, slight tilt to read as a hand-stamped seal. */
.lp-nav__beta {
  font-family: "Stardos Stencil", "Geist", system-ui, sans-serif;
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #cf4640;
  border: 1.5px solid #cf4640;
  border-radius: 3px;
  padding: 3px 7px 2px;
  margin-left: 6px;
  transform: rotate(-4deg);
  transform-origin: center;
  opacity: 0.92;
  user-select: none;
}
.theme-light .lp-nav__beta { color: #ad322b; border-color: #ad322b; }

.lp-nav__links {
  display: flex; align-items: center; gap: 36px;
  font-size: 14px; color: rgba(255,255,255,.7);
  font-weight: 450;
}
.theme-light .lp-nav__links { color: var(--ink-500); }
.lp-nav__links a:hover { color: var(--white); }
.theme-light .lp-nav__links a:hover { color: var(--ink-900); }

.lp-nav__right {
  display: flex; align-items: center; gap: 14px;
}

/* Hamburger button — hidden on desktop, shown on mobile */
.lp-nav__toggle {
  display: none;
  width: 40px; height: 40px;
  align-items: center; justify-content: center;
  border-radius: var(--r-sm);
  color: var(--white);
  transition: background var(--dur-fast) var(--ease-out);
}
.lp-nav__toggle:hover { background: rgba(255,255,255,.06); }
.lp-nav__toggle svg { width: 22px; height: 22px; }
.lp-nav__toggle .icon-close { display: none; }
.lp-nav__toggle[aria-expanded="true"] .icon-open  { display: none; }
.lp-nav__toggle[aria-expanded="true"] .icon-close { display: block; }

/* Language toggle (EN / ES). Always visible. Each button is a plain <a>
   pointing to the rendered version of the page; the build script flags the
   active one with aria-current="page". */
.lp-lang {
  display: inline-flex;
  align-items: center;
  padding: 2px;
  border-radius: var(--r-sm);
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.08);
  gap: 1px;
}
.lp-lang__btn {
  padding: 4px 9px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  color: rgba(255,255,255,.55);
  border-radius: 4px;
  transition: color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
  text-decoration: none;
}
.lp-lang__btn:hover { color: rgba(255,255,255,.85); }
.lp-lang__btn[aria-current="page"] {
  color: #fff;
  background: rgba(255,255,255,.08);
}
.theme-light .lp-lang { background: rgba(14,19,26,.05); border-color: rgba(14,19,26,.1); }
.theme-light .lp-lang__btn { color: rgba(14,19,26,.6); }
.theme-light .lp-lang__btn:hover { color: var(--ink-900); }
.theme-light .lp-lang__btn[aria-current="page"] { color: var(--ink-900); background: #fff; }

/* Tiny inline GitHub CTA in the nav (matches .btn--mono spirit, smaller). */
.lp-nav__cta {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 0 14px; height: 36px;
  border-radius: var(--r-md);
  font-size: 13px; font-weight: 500;
  background: rgba(255,255,255,.06);
  color: var(--white);
  border: 1px solid rgba(255,255,255,.12);
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.lp-nav__cta:hover { background: rgba(255,255,255,.10); border-color: rgba(255,255,255,.22); }
.lp-nav__cta svg { width: 16px; height: 16px; }

/* ---------- Mobile (≤768px) ---------- */
@media (max-width: 768px) {
  .lp-nav { height: 64px; }
  .lp-nav__toggle { display: inline-flex; }

  /* Drawer: full panel, slides in from right. The drawer wraps both
     .lp-nav__links and .lp-nav__right so the same DOM works on both
     viewports — desktop just promotes its children via display:contents.
     overflow-y: auto so the migrated footer block (link cols + bottom
     strip injected by app.js) is reachable on short viewports without
     overflow being clipped. */
  .lp-nav__drawer {
    position: fixed;
    inset: 64px 0 0 0;
    background: var(--ink-900);
    padding: var(--s-8) var(--gutter);
    display: flex;
    flex-direction: column;
    gap: var(--s-4);
    overflow-y: auto;
    overscroll-behavior: contain;
    z-index: 40;
    transform: translateX(100%);
    transition: transform var(--dur-base) var(--ease-out);
    visibility: hidden;
  }
  .lp-nav__drawer[data-open="true"] {
    transform: translateX(0);
    visibility: visible;
  }
  .lp-nav__links {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }
  .lp-nav__links a {
    width: 100%;
    padding: var(--s-4) 0;
    font-size: var(--text-lg);
    color: rgba(255,255,255,.85);
    border-bottom: 1px solid rgba(255,255,255,.06);
  }
  /* Drawer right-cluster (lang + listen + star) stays as a single row,
     right-aligned, with compact chip-sized controls. The trio fits in
     ~250px so even at 360px viewport (≈312px usable) they don't crowd. */
  .lp-nav__right {
    align-self: flex-end;
    flex-direction: row;
    align-items: center;
    gap: 8px;
  }
  .lp-lang { padding: 3px; }
  .lp-lang__btn { min-height: 28px; padding: 4px 10px; font-size: 11px; }
  .lp-nav__listen { height: 32px; font-size: 12px; padding: 0 12px; }
  .lp-nav__cta { height: 32px; font-size: 12px; padding: 0 12px; }

  body.is-nav-open { overflow: hidden; }
}

/* ---------- Desktop: drawer is a noop wrapper, children promote up ---------- */
@media (min-width: 769px) {
  .lp-nav__drawer {
    display: contents;
  }
}

/* ============================================================
   BUTTONS (.btn)
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 0 18px; height: 40px;
  border-radius: var(--r-md);
  font-family: var(--font-sans);
  font-size: 14px; font-weight: 500;
  letter-spacing: -.005em;
  white-space: nowrap;
  /* Reset native button defaults so <button class="btn"> matches <a class="btn">. */
  border: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  color: inherit;
  transition: background var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.btn--lg { height: 48px; padding: 0 22px; font-size: 15px; }
.btn--xl { height: 56px; padding: 0 28px; font-size: 16px; border-radius: 10px; }
.btn svg { width: 18px; height: 18px; }

.btn--primary {
  background: var(--green-500);
  color: #fff;
  font-weight: 600;
}
.btn--primary:hover { background: var(--green-400); transform: translateY(-1px); }

.btn--accent {
  background: var(--violet-600);
  color: #fff;
  font-weight: 600;
}
.btn--accent:hover { background: var(--violet-500); transform: translateY(-1px); }

.btn--ghost {
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255,255,255,.14);
}
.btn--ghost:hover { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.24); }

.btn--mono {
  font-family: var(--font-mono);
  font-size: 13px;
  background: rgba(255,255,255,.06);
  color: #fff;
  border: 1px solid rgba(255,255,255,.10);
}
.btn--mono:hover { background: rgba(255,255,255,.10); border-color: rgba(255,255,255,.20); }

/* Pre-label inside a mono button: sans, smaller, muted, separated by a divider.
   The command stays as the visual primary element. */
.btn--mono .btn__label {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: rgba(255,255,255,.55);
  padding-right: 10px;
  border-right: 1px solid rgba(255,255,255,.14);
}

/* On narrow viewports, the full `npm i -g @skill-map/cli` command is wider
   than the available row (≥340px at btn--xl). Hide the command and keep the
   label — the click still copies the command via data-copy on the button. */
@media (max-width: 480px) {
  .btn--mono .btn__cmd { display: none; }
  .btn--mono .btn__label {
    border-right: 0;
    padding-right: 0;
    color: rgba(255,255,255,.85);
  }
}

/* ============================================================
   HERO (graph variant)
   ============================================================ */
/* ============================================================
   GLOBAL ANIMATION FPS CAP — scoped to .hero (experimental)
   ------------------------------------------------------------
   Replaces the timing-function of every animation inside .hero with
   `steps(N, end)`. Effective fps = N ÷ animation_duration_seconds.
   With N = 8 and our two infinite animations:
     - select-pulse  (1.6s) → 5.0fps
     - hg-travel     (1.4s) → 5.7fps
   To re-tune: edit the single number below.
     30fps ≈ 45  ·  20fps ≈ 30  ·  10fps ≈ 15  ·  5fps ≈ 8
   Caveat: easing curves (ease-out, etc.) defined per-animation are
   overridden — motion becomes uniform inside each step.
   ============================================================ */
.hero, .hero *,
.hero *::before, .hero *::after {
  animation-timing-function: steps(45, end) !important;
}

/* Selected-node ring pulse. Same compositor-only trick: animate transform on
   a <circle> centered at (0,0) inside a translated <g>. The previous SMIL
   <animate> approach modified the `r` attribute every frame, forcing SVG
   rasterization and pegging CPU when a backdrop-filter sat on top of it. */
@keyframes select-pulse {
  0%   { transform: scale(1);   opacity: .7; }
  100% { transform: scale(2.2); opacity: 0;  }
}
.hero__graph-svg .select-fx-pulse {
  animation: select-pulse 1.6s ease-out infinite;
  transform-origin: 0 0;
  will-change: transform, opacity;
}

/* Pan/zoom viewport — its `transform` is updated on wheel + bg drag.
   GPU layer hint so panning doesn't repaint the SVG below. */
.hero__graph-svg .hg-viewport {
  will-change: transform;
}
.hero__graph-svg .hg-bg {
  cursor: grab;
}
.hero__graph-svg.is-panning .hg-bg,
.hero__graph-svg.is-panning {
  cursor: grabbing;
}

/* Traveling pulse along a selected node's edge.
   Uses CSS `offset-path` (compositor-friendly path animation). */
@keyframes hg-travel {
  0%   { offset-distance: 0%;   opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0; }
}
.hero__graph-svg .hg-traveler {
  animation: hg-travel 1.4s linear infinite;
  pointer-events: none;
  will-change: offset-distance, opacity;
}

.hero {
  position: relative;
  overflow: hidden;
  padding-block:  clamp(40px, 6vw, 80px) clamp(60px, 8vw, 100px);
  padding-inline: clamp(20px, 4vw, 64px);
}

.hero__bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.hero__bg::before,
.hero__bg::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  filter: blur(20px);
}
.hero__bg::before {
  width: 600px; height: 600px;
  top: -100px; right: -100px;
  background: radial-gradient(circle, rgba(124,58,237,.4), transparent 60%);
}
.hero__bg::after {
  width: 500px; height: 500px;
  bottom: -200px; left: -100px;
  background: radial-gradient(circle, rgba(124,58,237,.3), transparent 60%);
}

.hero__inner {
  position: relative;
  max-width: 1280px;
  margin: 0 auto;
  padding-top: var(--s-8);
}

.hero__head {
  text-align: center;
  max-width: 880px;
  margin: 0 auto var(--s-12);
}

.hero__title {
  font-size: clamp(48px, 9vw, 92px);
  line-height: 1.05;
  letter-spacing: -.02em;
  font-weight: 600;
  color: #fff;
  margin-bottom: var(--s-6);
}
.hero__title-soft {
  font-size: .6em;
  font-style: italic;
  font-weight: 500;
  color: rgba(255,255,255,.75);
}

.hero__sub {
  font-size: clamp(18px, 2.1vw, 24px);
  line-height: 1.5;
  color: rgba(255,255,255,.85);
  font-weight: 400;
  max-width: 640px;
  margin: 0 auto var(--s-8);
}

.hero__ctas {
  display: flex;
  gap: var(--s-3);
  justify-content: center;
  flex-wrap: wrap;
}

/* ---------- Graph card ---------- */
.hero__graph {
  position: relative;
  border-radius: 20px;
  background: radial-gradient(ellipse at 50% 30%, rgba(14,19,26,.4) 0%, rgba(6,8,12,.95) 70%);
  border: 1px solid rgba(255,255,255,.08);
  box-shadow:
    0 40px 100px rgba(0,0,0,.5),
    0 0 80px -20px rgba(124,58,237,.25);
  overflow: hidden;
  height: clamp(360px, 60vh, 560px);
  /* Tell the browser nothing inside this card can affect layout/paint
     outside it — repaints from drag/hover stay scoped here. */
  contain: layout paint style;
}

.hero__graph-chrome {
  position: absolute;
  top: 0; left: 0; right: 0;
  padding: 16px 20px;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  border-bottom: 1px solid rgba(255,255,255,.05);
  background: rgba(14,19,26,.92);
  z-index: 5;
}
.hero__graph-path {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: rgba(255,255,255,.6);
}
.hero__graph-path svg { width: 14px; height: 14px; }

.hero__graph-counts {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: rgba(255,255,255,.45);
  align-items: center;
}
.hero__graph-counts strong { color: #fff; font-weight: 500; }
.hero__graph-counts .alert  { color: var(--violet-400); }
.hero__graph-counts .sep    { opacity: .4; }

.hero__graph-legend {
  position: absolute;
  top: 64px; left: 20px;
  display: flex; flex-direction: column;
  gap: 6px;
  z-index: 4;
  pointer-events: none;
}
.hero__graph-legend > div {
  display: flex; align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255,255,255,.5);
}
.hero__graph-legend i {
  width: 8px; height: 8px;
  border-radius: 50%;
  display: inline-block;
}

.hero__graph-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  cursor: grab;
  touch-action: none;
}

/* Particle field — sits below the SVG (z-index 1) and above the card bg.
   Visible through the SVG's translucent radial overlay. */
.hero__graph .hg-particles {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1;
}
.hero__graph-svg .edge {
  stroke: rgba(255,255,255,.12);
  stroke-width: 1;
  /* Only opacity is animated — it goes through the GPU compositor.
     stroke / stroke-width changes on selection are instant; the eye barely
     notices them since the dim/highlight read comes from the opacity fade. */
  transition: opacity var(--dur-base) var(--ease-out);
}
.hero__graph-svg .edge[data-hi="true"]  { stroke: rgba(124,58,237,.7); stroke-width: 1.5; }
.hero__graph-svg .edge[data-dim="true"] { opacity: .35; }

.hero__graph-svg .node {
  cursor: grab;
  transition: opacity var(--dur-base) var(--ease-out);
  /* Promote each node to its own GPU layer so drag updates the transform
     on the compositor thread instead of triggering main-thread paint.
     Memory cost: ~13 small layers, trivial. */
  will-change: transform;
}
.hero__graph-svg .node[data-dim="true"] { opacity: .3; }
.hero__graph-svg .node[data-selected="true"] circle:first-of-type {
  filter: drop-shadow(0 0 12px currentColor);
}
.hero__graph-svg .node[data-selected="true"] { color: var(--type-color, #fff); }
.hero__graph-svg .node[data-dragging="true"] { cursor: grabbing; }

.hero__graph-svg .node-label {
  font: 500 11px var(--font-mono);
  fill: rgba(255,255,255,.55);
  pointer-events: none;
  user-select: none;
  /* No transition: hover should feel instant. Animating fill on every
     pointerenter/leave is the main source of perceived latency. */
}
.hero__graph-svg .node[data-selected="true"] .node-label,
.hero__graph-svg .node[data-hover="true"]    .node-label { fill: #fff; }

/* ---------- Inspector panel ---------- */
.hero__inspector {
  position: absolute;
  top: 64px;
  right: 20px;
  width: 240px;
  padding: 18px 18px 16px;
  border-radius: 12px;
  background: #0E131A;
  border: 1px solid rgba(124,58,237,.35);
  box-shadow: 0 0 0 1px rgba(124,58,237,.15), 0 20px 50px rgba(0,0,0,.5);
  z-index: 6;
  color: #fff;
  font-family: var(--font-sans);
}
.hero__inspector__type {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 14px;
}
.hero__inspector__dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--type-color, #fff);
  box-shadow: 0 0 8px var(--type-color, #fff);
}
.hero__inspector__type-label {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: rgba(255,255,255,.5);
}
.hero__inspector__name {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: #fff;
  margin-bottom: 4px;
}
.hero__inspector__path {
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255,255,255,.45);
  margin-bottom: 18px;
  word-break: break-all;
}
.hero__inspector__rows {
  display: flex; flex-direction: column;
  gap: 10px;
  padding-top: 14px;
  border-top: 1px solid rgba(255,255,255,.08);
}
.hero__inspector__row {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
}
.hero__inspector__row .k {
  color: rgba(255,255,255,.5);
  font-family: var(--font-mono);
}
.hero__inspector__row .v {
  color: #fff;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.hero__inspector__warn {
  margin-top: 14px;
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(124,58,237,.12);
  border: 1px solid rgba(124,58,237,.28);
  font-size: 12px;
  color: var(--violet-200);
  display: flex; gap: 8px;
  align-items: flex-start;
}
.hero__inspector__warn svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 2px; }

/* On narrow viewports, dock the inspector at the bottom of the card so it
   doesn't overlap the legend or eat half the canvas. Phone breakpoint. */
@media (max-width: 480px) {
  .hero__inspector {
    top: auto;
    right: 12px;
    bottom: 56px;
    left: 12px;
    width: auto;
  }
  .hero__graph-legend { display: none; }
}

/* Hide hero__graph-legend / counts on tiny viewports to keep the card readable. */
@media (max-width: 480px) {
  .hero__graph-legend { display: none; }
  .hero__graph-counts { font-size: 10px; gap: 4px; }
  .hero__graph-counts .sep { display: none; }
}

/* On mobile, drop the interactive graph card entirely. The hero leans on
   title + sub + CTAs; the live graph belongs to /demo/. The drag/pan/particle
   JS is also short-circuited via matchMedia in app.js, so the cost is zero.
   Above 480px we already hide legend + collapse counts; below 768px we
   remove the whole card (768 inclusive shows the graph). */
@media (max-width: 767px) {
  .hero__graph { display: none; }
}

/* ============================================================
   GENERIC SECTION (used by Features, How, Cases, CLI, Quotes…)
   ============================================================ */
.section {
  max-width: 1280px;
  margin-inline: auto;
  padding-block:  clamp(60px, 8vw, 100px);
  padding-inline: clamp(20px, 4vw, 64px);
}

.section-header {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  margin-bottom: 80px;
  align-items: end;
}
.section-header--center {
  grid-template-columns: 1fr;
  text-align: center;
  max-width: 760px;
  margin-inline: auto;
  margin-bottom: 64px;
  gap: 16px;
}
@media (max-width: 768px) {
  .section-header { grid-template-columns: 1fr; gap: 24px; margin-bottom: 48px; }
}

.section-eyebrow {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--violet-400);
  margin-bottom: 16px;
}
.section-eyebrow--green { color: var(--green-400); }

.section-title {
  font-size: clamp(28px, 4vw, 44px);
  font-weight: 600;
  letter-spacing: -.025em;
  line-height: 1.15;
  color: #fff;
}
/* Softer second-line modifier for two-tone titles. */
.section-title-soft {
  color: rgba(255, 255, 255, .55);
  font-weight: 500;
}

.section-sub {
  font-size: clamp(15px, 1.5vw, 17px);
  line-height: 1.6;
  color: rgba(255,255,255,.6);
  max-width: 420px;
}
.section-header--center .section-sub { max-width: 580px; margin-inline: auto; }
.section-sub code {
  font-family: var(--font-mono);
  color: var(--green-400);
  background: rgba(0,200,83,.08);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: .9em;
}

/* ============================================================
   SECTION DIVIDER — soft horizontal glow + hairline accent
   A decorative break between major sections. The glow ellipse
   carries the brand's violet without imposing a hard rule.
   ============================================================ */
.section-divider {
  position: relative;
  width: 100%;
  max-width: 1280px;
  height: 0;
  margin: 0 auto;
  border: 0;
  overflow: visible;
  pointer-events: none;
}
.section-divider::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -50%);
  width: min(60%, 560px);
  height: 120px;
  background: radial-gradient(ellipse at center,
    rgba(124, 58, 237, 0.20) 0%,
    rgba(124, 58, 237, 0.08) 35%,
    transparent 70%);
  filter: blur(10px);
}
.section-divider::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  width: min(80%, 720px);
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(167, 139, 250, 0) 10%,
    rgba(167, 139, 250, 0.45) 50%,
    rgba(167, 139, 250, 0) 90%,
    transparent 100%);
}

/* ============================================================
   SCREENSHOTS — single hero shot, centered (16:9)
   The <img> uses object-fit: cover so the visible image crops to
   the cell instead of distorting it.
   Images are non-interactive on purpose (no click, no drag).
   ============================================================ */
.shots__grid {
  max-width: 1024px;
  margin-inline: auto;
}

.shots__main { aspect-ratio: 16 / 9; }

.shots figure {
  position: relative;
  margin: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .08);
  transition: transform 240ms cubic-bezier(0.2, 0, 0, 1),
              border-color 240ms cubic-bezier(0.2, 0, 0, 1),
              box-shadow 240ms cubic-bezier(0.2, 0, 0, 1);
}
.shots figure:hover {
  transform: scale(1.02);
  border-color: rgba(167, 139, 250, .35);
  box-shadow: 0 12px 40px -12px rgba(124, 58, 237, .35);
  z-index: 1;
}
@media (prefers-reduced-motion: reduce) {
  .shots figure { transition: none; }
  .shots figure:hover { transform: none; }
}
.shots figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
}

/* The image is wrapped in a button so click/Enter/Space open the lightbox.
   Use position: absolute fill rather than width/height: 100% — the parent
   figure has aspect-ratio: 16/9 and a child with `height: 100%` can resolve
   to 0 in some browsers when the parent's height is implicitly derived from
   aspect-ratio. Filling via inset: 0 sidesteps that quirk and guarantees a
   hit-testable area. */
.shots__zoom {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
  margin: 0;
  border: none;
  background: transparent;
  cursor: zoom-in;
  border-radius: inherit;
  overflow: hidden;
}
.shots__zoom:focus-visible {
  outline: 2px solid var(--violet-400);
  outline-offset: 4px;
}

/* Placeholder visual: dashed inset frame with a centered label. The
   author replaces the entire <span> with an <img> when real shots
   are ready, so no toggling logic is needed. */
.shots__placeholder {
  position: absolute;
  inset: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed rgba(255, 255, 255, .14);
  border-radius: var(--r-md);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .4);
}

/* ============================================================
   FEATURES — Two visual blocks share the section.
   `.features-grid`: two full cards in a 1px-gap hairline grid.
   The first is `feature--hero` and spans 2 columns (the dual-mode
   meta-architecture); the supporter on its right is the token-weight
   insight.
   `.features-list`: four compact list items in a 2×2 grid, no card
   chrome — leaner, supplementary register.
   ============================================================ */
.features-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: rgba(255,255,255,.06);
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.06);
}
@media (max-width: 1023px) { .features-grid { grid-template-columns: repeat(2, 1fr); } }
/* Single column threshold consolidated to 768 (was 560) so features-grid
   collapses at the same breakpoint as features-list and the rest of the
   site. One mental model instead of six. */
@media (max-width: 768px) { .features-grid { grid-template-columns: 1fr; } }

.feature {
  background: var(--ink-900);
  padding: 40px 36px;
  min-height: 260px;
  position: relative;
  transition: background var(--dur-base) var(--ease-out);
}
.feature:hover { background: var(--ink-800); }

/* Hero card: spans 2 columns at the top of the grid, larger title and
   icon, slightly more breathable padding. Carries the dual-mode story.
   At ≤960px the grid drops to 2 columns; the hero stops spanning so the
   row stays balanced (1 hero + 1 supporter still fits). At ≤560px the
   grid collapses to a single column and everything stacks naturally. */
.feature--hero {
  grid-column: span 2;
}
.feature--hero .feature__title { font-size: clamp(20px, 2.8vw, 26px); line-height: 1.2; }
.feature--hero .feature__body  { font-size: 15px; max-width: 560px; }
.feature--hero .feature__icon { width: 56px; height: 56px; border-radius: 12px; margin-bottom: 32px; }
.feature--hero .feature__icon svg { width: 26px; height: 26px; }
@media (max-width: 1023px) { .feature--hero { grid-column: auto; } }

/* ---------- Compact list (the 4 supplementary checks) ---------- */
.features-list {
  list-style: none;
  padding: 0;
  margin: 56px 0 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 32px 56px;
}
@media (max-width: 768px) {
  .features-list { grid-template-columns: 1fr; gap: 28px; }
}
.features-list__item {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}
.features-list__icon {
  flex: 0 0 36px;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  border: 1px solid;
  margin-top: 2px;
}
.features-list__icon svg { width: 18px; height: 18px; }
.features-list__item--green  .features-list__icon { background: rgba(0, 200, 83, .08);  border-color: rgba(0, 200, 83, .18);  color: var(--green-400); }
.features-list__item--violet .features-list__icon { background: rgba(124, 58, 237, .10); border-color: rgba(124, 58, 237, .22); color: var(--violet-400); }
.features-list__item--amber  .features-list__icon { background: rgba(232, 138, 0, .08); border-color: rgba(232, 138, 0, .20); color: #F5B850; }
.features-list__title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: #fff;
  margin: 0 0 4px;
}
.features-list__body {
  font-size: 13.5px;
  line-height: 1.55;
  color: rgba(255, 255, 255, .6);
  margin: 0;
}

.feature__icon {
  width: 44px; height: 44px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  border: 1px solid;
  margin-bottom: 28px;
}
.feature__icon svg { width: 20px; height: 20px; }

.feature--green  .feature__icon { background: rgba(0,200,83,.08);  border-color: rgba(0,200,83,.18);  color: var(--green-400); }
.feature--violet .feature__icon { background: rgba(124,58,237,.10); border-color: rgba(124,58,237,.22); color: var(--violet-400); }
.feature--amber  .feature__icon { background: rgba(232,138,0,.08); border-color: rgba(232,138,0,.20); color: #F5B850; }

.feature__head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.feature__title {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: #fff;
}
.feature__tag {
  font-family: var(--font-mono);
  font-size: 11px;
  opacity: .8;
}
.feature--green  .feature__tag { color: var(--green-400); }
.feature--violet .feature__tag { color: var(--violet-400); }
.feature--amber  .feature__tag { color: #F5B850; }

.feature__body {
  font-size: 14px;
  line-height: 1.6;
  color: rgba(255,255,255,.6);
}

/* ============================================================
   HOW IT WORKS — 3 numbered steps with code snippet
   ============================================================ */
.howit-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  list-style: none;
}
@media (max-width: 768px) { .howit-grid { grid-template-columns: 1fr; } }

.howit-step {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 32px;
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(255,255,255,.025), rgba(255,255,255,0));
}

.howit-step__num {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  color: var(--violet-400);
  margin-bottom: clamp(28px, 4vw, 56px);
}
.howit-step__num::after {
  content: '';
  flex: 1;
  height: 1px;
  background: rgba(124,58,237,.3);
}

.howit-step__title {
  font-size: clamp(20px, 2.5vw, 24px);
  font-weight: 600;
  letter-spacing: -.02em;
  color: #fff;
  margin-bottom: 14px;
}
.howit-step__body {
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255,255,255,.6);
  margin-bottom: 24px;
}

.howit-step__code {
  margin-top: auto;
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 12px 14px;
  border-radius: 8px;
  background: rgba(0,0,0,.4);
  border: 1px solid rgba(255,255,255,.06);
  color: var(--green-300);
  overflow-wrap: anywhere;
  word-break: break-word;
}
.howit-step__code .prompt { color: rgba(255,255,255,.3); }
.howit-step__code > span:not(.prompt) { display: block; }
@media (max-width: 768px) {
  .howit-step__code > span:not(.prompt) { display: inline; }
  .howit-step__code > span:not(.prompt) + span:not(.prompt)::before {
    content: ' · ';
    color: rgba(255,255,255,.3);
  }
}

/* Variant: stacked single-column header (used by Use cases). */
.section-header--stacked {
  grid-template-columns: 1fr;
  max-width: 720px;
  gap: 12px;
}

/* ============================================================
   USE CASES — 3 cards with tinted gradient + stat
   ============================================================ */
.cases-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}
@media (max-width: 1023px) { .cases-grid { grid-template-columns: 1fr; } }

.case {
  padding: 36px;
  border-radius: 18px;
  min-height: 320px;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
  border: 1px solid;
}
.case--green {
  background: linear-gradient(135deg, rgba(0,200,83,.12), rgba(0,200,83,.02));
  border-color: rgba(0,200,83,.18);
  --case-accent: var(--green-400);
}
.case--violet {
  background: linear-gradient(135deg, rgba(124,58,237,.14), rgba(124,58,237,.02));
  border-color: rgba(124,58,237,.22);
  --case-accent: var(--violet-400);
}
.case--amber {
  background: linear-gradient(135deg, rgba(245,184,80,.10), rgba(245,184,80,.02));
  border-color: rgba(245,184,80,.18);
  --case-accent: #F5B850;
}
.case--blue {
  background: linear-gradient(135deg, rgba(45,123,255,.12), rgba(45,123,255,.02));
  border-color: rgba(45,123,255,.20);
  --case-accent: var(--info);
}

.case__tag {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: -.005em;
  color: var(--case-accent);
  margin-bottom: 24px;
}
.case__title {
  font-size: clamp(20px, 3vw, 26px);
  font-weight: 600;
  letter-spacing: -.02em;
  color: #fff;
  margin-bottom: 14px;
}
.case__body {
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255,255,255,.65);
  margin-bottom: auto;
}
.case__stat {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid rgba(255,255,255,.08);
}
.case__stat-num {
  font-size: 36px;
  font-weight: 600;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
  color: var(--case-accent);
}
.case__stat-label {
  font-size: 13px;
  color: rgba(255,255,255,.55);
}

.code-tag {
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 6px 10px;
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.08);
  color: rgba(255,255,255,.65);
  border-radius: 6px;
}

/* ============================================================
   QUOTES / TESTIMONIALS — 3 cards with stars + initials avatar
   ============================================================ */
.quotes-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
@media (max-width: 1023px) { .quotes-grid { grid-template-columns: 1fr; } }

.quote {
  padding: 32px;
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 16px;
  background: rgba(255,255,255,.02);
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.quote__stars {
  display: flex;
  gap: 3px;
  color: var(--green-400);
}
.quote__stars svg { width: 14px; height: 14px; }

.quote__text {
  font-size: 17px;
  line-height: 1.55;
  letter-spacing: -.005em;
  color: rgba(255,255,255,.85);
}

.quote__person {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 20px;
  border-top: 1px solid rgba(255,255,255,.06);
}
.quote__avatar {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--violet-500), var(--green-500));
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 13px;
  color: var(--ink-900);
  flex-shrink: 0;
}
.quote__name {
  font-size: 14px;
  font-weight: 500;
  color: #fff;
}
.quote__role {
  font-size: 12px;
  color: rgba(255,255,255,.5);
}

/* ============================================================
   CTA BAR — final call to action with green glow
   ============================================================ */
.cta-bar {
  position: relative;
  overflow: hidden;
  padding-block:  clamp(80px, 12vw, 120px);
  padding-inline: clamp(20px, 4vw, 64px);
  text-align: center;
}
.cta-bar__bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.cta-bar__bg::before {
  content: '';
  position: absolute;
  width: 600px; height: 600px;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(0,200,83,.3), transparent 60%);
  filter: blur(20px);
}
.cta-bar__inner {
  position: relative;
  max-width: 880px;
  margin-inline: auto;
}
.cta-bar__title {
  font-size: clamp(36px, 7vw, 72px);
  line-height: .95;
  letter-spacing: -.04em;
  font-weight: 600;
  color: #fff;
  margin-bottom: 24px;
}
.cta-bar__sub {
  font-size: clamp(16px, 1.6vw, 19px);
  color: rgba(255,255,255,.65);
  max-width: 540px;
  margin: 0 auto 40px;
  line-height: 1.55;
}
.cta-bar__ctas {
  display: flex;
  gap: 14px;
  justify-content: center;
  margin-bottom: 32px;
  flex-wrap: wrap;
}
.cta-bar__fineprint {
  font-family: var(--font-mono);
  font-size: 13px;
  color: rgba(255,255,255,.4);
}

/* ============================================================
   FOOTER — 5-col grid + bottom bar
   ============================================================ */
.lp-footer {
  border-top: 1px solid rgba(255,255,255,.06);
  padding-block:  clamp(48px, 7vw, 80px) clamp(28px, 4vw, 40px);
  padding-inline: clamp(20px, 4vw, 64px);
  max-width: 1280px;
  margin-inline: auto;
}

.lp-footer__grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: clamp(24px, 4vw, 40px);
  margin-bottom: clamp(40px, 6vw, 64px);
}
/* Mid: brand spans full width, 4 link cols become 2×2. */
@media (max-width: 1023px) {
  .lp-footer__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 32px 24px;
  }
  .lp-footer__brand { grid-column: 1 / -1; }
  .lp-footer__tagline { max-width: 480px; }
}
/* Small: single column, generous spacing. */
@media (max-width: 480px) {
  .lp-footer__grid {
    grid-template-columns: 1fr;
    gap: 32px;
    margin-bottom: 40px;
  }
  .lp-footer__tagline { max-width: none; }
}

.lp-footer__logo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: #fff;
  margin-bottom: 16px;
}
.lp-footer__logo .lp-nav__logo-mark { width: 28px; height: 28px; display: grid; place-items: center; }
.lp-footer__logo img { width: 100%; height: 100%; }

.lp-footer__tagline {
  font-size: 14px;
  line-height: 1.6;
  color: rgba(255,255,255,.55);
  max-width: 280px;
  margin-bottom: 24px;
}
.lp-footer__tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.lp-footer__online {
  color: var(--green-400);
  border-color: rgba(0,200,83,.2);
}

.lp-footer__h {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: rgba(255,255,255,.45);
  margin-bottom: 18px;
}
.lp-footer__col ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.lp-footer__col a {
  font-size: 14px;
  color: rgba(255,255,255,.75);
  transition: color var(--dur-fast) var(--ease-out);
}
.lp-footer__col a:hover { color: #fff; }

.lp-footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  padding-top: 24px;
  border-top: 1px solid rgba(255,255,255,.06);
  font-size: 12px;
  color: rgba(255,255,255,.4);
}
.lp-footer__cmd {
  font-family: var(--font-mono);
  font-size: inherit;
  white-space: nowrap;
  /* Native button reset (it's now a click-to-copy trigger). */
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out);
}
.lp-footer__cmd:hover { color: #fff; }

.lp-footer__powered {
  font-size: 12px;
  color: rgba(255,255,255,.32);
  letter-spacing: .02em;
}
.lp-footer__powered a {
  color: rgba(255,255,255,.55);
  font-weight: 500;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}
.lp-footer__powered a:hover { color: #fff; }
@media (max-width: 480px) {
  .lp-footer__bottom {
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    gap: 12px;
  }
}

/* ============================================================
   PLUGIN ECOSYSTEM — kernel + 6 satellite plugin types
   The active plugin id lives on `.peco[data-active]`. Lines and
   satellites read that to decide their state; the brief panel
   shows only the matching `<article data-pe-id>`. The accent of
   the active plugin is exposed as `--pe-accent` so the panel can
   theme itself. Hover/focus/click all converge on `setActive(id)`.
   ============================================================ */
.peco__sub {
  font-size: 18px;
  line-height: 1.55;
  color: rgba(255, 255, 255, .65);
  max-width: 560px;
  margin: 18px auto 0;
  text-wrap: pretty;
}

.peco__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: 48px;
  align-items: center;
}
@media (max-width: 1023px) {
  .peco__grid { grid-template-columns: 1fr; gap: 32px; }
}

.peco__viz {
  position: relative;
  display: flex;
  justify-content: center;
}
.peco__svg {
  width: 100%;
  max-width: 720px;
  height: auto;
  overflow: visible;
}

/* ---------- Connection lines ---------- */
.peco__line line {
  stroke: rgba(255, 255, 255, .08);
  stroke-width: 1;
  transition: stroke .25s var(--ease-out), stroke-width .25s var(--ease-out);
}
.peco__line-traveler { opacity: 0; transition: opacity .2s var(--ease-out); }
.peco[data-active="provider"]  .peco__line[data-pe-id="provider"]  line,
.peco[data-active="extractor"] .peco__line[data-pe-id="extractor"] line,
.peco[data-active="rule"]     .peco__line[data-pe-id="rule"]     line,
.peco[data-active="action"]   .peco__line[data-pe-id="action"]   line,
.peco[data-active="hook"]    .peco__line[data-pe-id="hook"]    line,
.peco[data-active="formatter"] .peco__line[data-pe-id="formatter"] line {
  stroke: var(--pe-accent);
  stroke-width: 1.5;
  stroke-dasharray: 0;
}
.peco[data-active="provider"]  .peco__line[data-pe-id="provider"]  .peco__line-traveler,
.peco[data-active="extractor"] .peco__line[data-pe-id="extractor"] .peco__line-traveler,
.peco[data-active="rule"]     .peco__line[data-pe-id="rule"]     .peco__line-traveler,
.peco[data-active="action"]   .peco__line[data-pe-id="action"]   .peco__line-traveler,
.peco[data-active="hook"]    .peco__line[data-pe-id="hook"]    .peco__line-traveler,
.peco[data-active="formatter"] .peco__line[data-pe-id="formatter"] .peco__line-traveler {
  opacity: 1;
}

/* ---------- "Your plugin" placeholder ---------- */
.peco__placeholder-plus {
  font: 400 22px var(--font-mono);
  fill: rgba(167, 139, 250, .7);
}
.peco__placeholder-label {
  font: 500 11px var(--font-mono);
  fill: rgba(255, 255, 255, .5);
}

/* ---------- KERNEL center ---------- */
.peco__kernel-label {
  font: 600 13px var(--font-mono);
  fill: #fff;
  letter-spacing: .05em;
}
.peco__kernel-sub {
  font: 400 10px var(--font-mono);
  fill: rgba(255, 255, 255, .5);
  letter-spacing: .04em;
}

/* ---------- Satellites ---------- */
.peco__sat { cursor: pointer; outline: none; }
.peco__sat-pulse { opacity: 0; }
.peco__sat-glow  { opacity: 0; transition: opacity .25s var(--ease-out); }
.peco__sat-body  { transition: stroke-width .25s var(--ease-out), filter .25s var(--ease-out); }
.peco__sat-fill  { transition: opacity .25s var(--ease-out); }
.peco__sat-label   { font: 600 13px var(--font-mono); fill: rgba(255, 255, 255, .7); letter-spacing: .02em; transition: fill .2s var(--ease-out); }
.peco__sat-builtin { font: 400 10px var(--font-mono); fill: rgba(255, 255, 255, .4); letter-spacing: .02em; }

.peco__sat:hover .peco__sat-glow,
.peco__sat:focus-visible .peco__sat-glow,
.peco[data-active="provider"]  .peco__sat[data-pe-id="provider"]  .peco__sat-glow,
.peco[data-active="extractor"] .peco__sat[data-pe-id="extractor"] .peco__sat-glow,
.peco[data-active="rule"]     .peco__sat[data-pe-id="rule"]     .peco__sat-glow,
.peco[data-active="action"]   .peco__sat[data-pe-id="action"]   .peco__sat-glow,
.peco[data-active="hook"]    .peco__sat[data-pe-id="hook"]    .peco__sat-glow,
.peco[data-active="formatter"] .peco__sat[data-pe-id="formatter"] .peco__sat-glow {
  opacity: 1;
}
.peco__sat:hover .peco__sat-body,
.peco__sat:focus-visible .peco__sat-body,
.peco[data-active="provider"]  .peco__sat[data-pe-id="provider"]  .peco__sat-body,
.peco[data-active="extractor"] .peco__sat[data-pe-id="extractor"] .peco__sat-body,
.peco[data-active="rule"]     .peco__sat[data-pe-id="rule"]     .peco__sat-body,
.peco[data-active="action"]   .peco__sat[data-pe-id="action"]   .peco__sat-body,
.peco[data-active="hook"]    .peco__sat[data-pe-id="hook"]    .peco__sat-body,
.peco[data-active="formatter"] .peco__sat[data-pe-id="formatter"] .peco__sat-body {
  stroke-width: 2;
  filter: drop-shadow(0 0 14px var(--pe-accent));
}
.peco__sat:hover .peco__sat-fill,
.peco__sat:focus-visible .peco__sat-fill,
.peco[data-active="provider"]  .peco__sat[data-pe-id="provider"]  .peco__sat-fill,
.peco[data-active="extractor"] .peco__sat[data-pe-id="extractor"] .peco__sat-fill,
.peco[data-active="rule"]     .peco__sat[data-pe-id="rule"]     .peco__sat-fill,
.peco[data-active="action"]   .peco__sat[data-pe-id="action"]   .peco__sat-fill,
.peco[data-active="hook"]    .peco__sat[data-pe-id="hook"]    .peco__sat-fill,
.peco[data-active="formatter"] .peco__sat[data-pe-id="formatter"] .peco__sat-fill {
  opacity: .9;
}
.peco__sat:hover .peco__sat-label,
.peco__sat:focus-visible .peco__sat-label,
.peco[data-active="provider"]  .peco__sat[data-pe-id="provider"]  .peco__sat-label,
.peco[data-active="extractor"] .peco__sat[data-pe-id="extractor"] .peco__sat-label,
.peco[data-active="rule"]     .peco__sat[data-pe-id="rule"]     .peco__sat-label,
.peco[data-active="action"]   .peco__sat[data-pe-id="action"]   .peco__sat-label,
.peco[data-active="hook"]    .peco__sat[data-pe-id="hook"]    .peco__sat-label,
.peco[data-active="formatter"] .peco__sat[data-pe-id="formatter"] .peco__sat-label {
  fill: #fff;
}
/* Pulse ring only on the actively selected satellite (not on hover). */
.peco[data-active="provider"]  .peco__sat[data-pe-id="provider"]  .peco__sat-pulse,
.peco[data-active="extractor"] .peco__sat[data-pe-id="extractor"] .peco__sat-pulse,
.peco[data-active="rule"]     .peco__sat[data-pe-id="rule"]     .peco__sat-pulse,
.peco[data-active="action"]   .peco__sat[data-pe-id="action"]   .peco__sat-pulse,
.peco[data-active="hook"]    .peco__sat[data-pe-id="hook"]    .peco__sat-pulse,
.peco[data-active="formatter"] .peco__sat[data-pe-id="formatter"] .peco__sat-pulse {
  opacity: 1;
}

/* ---------- Brief panel ---------- */
.peco__panel {
  position: relative;
  padding: 32px 28px 28px;
  border-radius: var(--r-xl);
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--pe-accent) 12%, transparent),
    rgba(14, 19, 26, .9));
  border: 1px solid color-mix(in srgb, var(--pe-accent) 35%, transparent);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--pe-accent) 8%, transparent),
    0 30px 60px rgba(0, 0, 0, .4);
  overflow: hidden;
  transition: background .3s var(--ease-out), border-color .3s var(--ease-out);
}
.peco__panel::before {
  content: '';
  position: absolute;
  top: -50px; right: -50px;
  width: 200px; height: 200px;
  background: radial-gradient(circle, color-mix(in srgb, var(--pe-accent) 25%, transparent), transparent 60%);
  pointer-events: none;
}

.peco__brief { display: none; position: relative; }
.peco[data-active="provider"]  .peco__brief[data-pe-id="provider"],
.peco[data-active="extractor"] .peco__brief[data-pe-id="extractor"],
.peco[data-active="rule"]     .peco__brief[data-pe-id="rule"],
.peco[data-active="action"]   .peco__brief[data-pe-id="action"],
.peco[data-active="hook"]    .peco__brief[data-pe-id="hook"],
.peco[data-active="formatter"] .peco__brief[data-pe-id="formatter"] {
  display: block;
}

.peco__brief-tag {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255, 255, 255, .55);
  text-transform: uppercase;
  letter-spacing: .1em;
}
.peco__brief-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--pe-accent);
  box-shadow: 0 0 10px var(--pe-accent);
}
.peco__brief-builtin {
  margin-left: auto;
  padding: 2px 6px;
  background: rgba(255, 255, 255, .08);
  border-radius: 4px;
  color: rgba(255, 255, 255, .6);
  font-size: 9px;
}
.peco__brief-title {
  font-size: clamp(28px, 5vw, 38px);
  font-weight: 600;
  color: #fff;
  letter-spacing: -.025em;
  line-height: 1.05;
  margin-bottom: 6px;
}
.peco__brief-one {
  font-size: 14px;
  color: var(--pe-accent);
  margin-bottom: 18px;
  font-family: var(--font-mono);
}
.peco__brief-body {
  font-size: 14px;
  line-height: 1.6;
  color: rgba(255, 255, 255, .78);
  margin-bottom: 22px;
  text-wrap: pretty;
}
.peco__brief-code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.55;
  color: rgba(255, 255, 255, .78);
  background: rgba(0, 0, 0, .3);
  border: 1px solid rgba(255, 255, 255, .06);
  padding: 14px 16px;
  border-radius: 10px;
  margin: 0;
  overflow: auto;
}
.peco__brief-code code { font: inherit; color: inherit; background: none; padding: 0; }

/* ---------- Nav (prev / next) ---------- */
.peco__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 18px;
  position: relative;
}
.peco__nav-btn {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, .1);
  color: rgba(255, 255, 255, .65);
  padding: 7px 12px;
  border-radius: 8px;
  font: inherit;
  font-size: 11px;
  font-family: var(--font-mono);
  letter-spacing: .02em;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.peco__nav-btn:hover {
  background: rgba(255, 255, 255, .06);
  color: #fff;
  border-color: rgba(255, 255, 255, .2);
}
.peco__nav-count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255, 255, 255, .4);
}

/* ---------- CTA strip ---------- */
.peco__cta {
  margin-top: 56px;
  padding: 24px 32px;
  border-radius: 14px;
  background: linear-gradient(90deg, rgba(124, 58, 237, .10), rgba(124, 58, 237, .02));
  border: 1px solid rgba(124, 58, 237, .25);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.peco__cta-title {
  font-size: 18px;
  font-weight: 500;
  color: #fff;
  margin: 0 0 4px;
  letter-spacing: -.01em;
}
.peco__cta-cmd {
  font-size: 14px;
  color: rgba(255, 255, 255, .55);
  font-family: var(--font-mono);
  background: none;
  padding: 0;
}
.peco__cta-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* ============================================================
   ROADMAP TIMELINE — interactive milestones
   ============================================================ */
.roadmap {
  max-width: 1280px;
  margin-inline: auto;
  padding-block:  clamp(60px, 8vw, 80px);
  padding-inline: clamp(20px, 4vw, 64px);
  position: relative;
}

.roadmap__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 32px;
  margin-bottom: 36px;
}

.section-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  background: rgba(124,58,237,.12);
  border: 1px solid rgba(124,58,237,.25);
  margin-bottom: 18px;
  font-size: 12px;
  color: var(--violet-200);
  font-family: var(--font-mono);
  letter-spacing: .04em;
}
.section-badge::before {
  content: '';
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--violet-400);
}

.roadmap__title {
  font-size: clamp(24px, 3.6vw, 40px);
  line-height: 1.05;
  letter-spacing: -.03em;
  font-weight: 600;
  color: #fff;
  max-width: 1040px;
}
.roadmap__title-soft {
  display: inline-block;
  margin-top: 10px;
  color: rgba(255,255,255,.5);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(17px, 2vw, 22px);
  line-height: 1.4;
  letter-spacing: -.005em;
}

/* ---------- Phase strip (5 segments) ---------- */
.roadmap__strip {
  position: relative;
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(14,19,26,.4), rgba(6,8,12,.6));
  border: 1px solid rgba(255,255,255,.06);
  overflow: hidden;
}
.roadmap__segments {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  /* Hairline dividers between segments via the gap + parent background. */
  gap: 1px;
  background: rgba(255,255,255,.06);
}
.roadmap__seg {
  background: linear-gradient(180deg, rgba(14,19,26,.4), rgba(14,19,26,.6));
  border: none;
  padding: 20px 18px 16px;
  cursor: pointer;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font: inherit;
  color: inherit;
  transition: background var(--dur-fast) var(--ease-out);
  position: relative;
}
.roadmap__seg:hover {
  background: linear-gradient(180deg, rgba(20,26,36,.6), rgba(20,26,36,.8));
}
.roadmap__seg:focus-visible {
  outline: 2px solid var(--violet-400);
  outline-offset: -2px;
}
.roadmap__seg[aria-current="true"] {
  background: linear-gradient(180deg, rgba(124,58,237,.12), rgba(124,58,237,.04));
}
.roadmap__seg[aria-current="true"][data-status="done"] {
  background: linear-gradient(180deg, rgba(0,200,83,.10), rgba(0,200,83,.02));
}
.roadmap__seg[aria-current="true"][data-status="planned"],
.roadmap__seg[aria-current="true"][data-status="pending"],
.roadmap__seg[aria-current="true"][data-status="open"] {
  background: linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.01));
}

.roadmap__seg-id {
  font-family: var(--font-mono);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1;
  color: rgba(255,255,255,.35);
}
.roadmap__seg[data-status="done"]    .roadmap__seg-id { color: var(--green-400); }
.roadmap__seg[data-status="current"] .roadmap__seg-id { color: var(--violet-400); }
.roadmap__seg[data-status="open"]    .roadmap__seg-id { font-style: italic; }

.roadmap__seg-title {
  font-size: 13px;
  color: #fff;
  font-weight: 500;
  letter-spacing: -.005em;
  line-height: 1.3;
  min-height: 30px;
}

.roadmap__seg-bar {
  width: 100%;
  height: 4px;
  border-radius: 2px;
  background: rgba(255,255,255,.08);
  overflow: hidden;
}
.roadmap__seg-bar > span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--green-400), var(--violet-400));
  transition: width var(--dur-base) var(--ease-out);
}
.roadmap__seg[data-status="done"] .roadmap__seg-bar > span {
  width: 100% !important;
  background: var(--green-400);
}
.roadmap__seg-bar--empty {
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.10) 0 4px, transparent 4px 8px);
}
/* Phase-0 done state: render its bar fully filled even though there are no
   step items (the segment has the empty-bar class because progressOf returns
   null for highlights). */
.roadmap__seg[data-status="done"] .roadmap__seg-bar--empty {
  background: var(--green-400);
}

.roadmap__seg-prog {
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255,255,255,.5);
  letter-spacing: .02em;
}
.roadmap__seg[data-status="current"] .roadmap__seg-prog { color: var(--violet-200); }
.roadmap__seg[data-status="done"]    .roadmap__seg-prog { color: var(--green-400); }

.roadmap__seg-status {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: rgba(255,255,255,.35);
  margin-top: auto;
}
.roadmap__seg[data-status="done"]    .roadmap__seg-status { color: var(--green-400); }
.roadmap__seg[data-status="current"] .roadmap__seg-status { color: var(--violet-400); }
.roadmap__seg[data-status="planned"] .roadmap__seg-status { color: rgba(255,255,255,.45); }
.roadmap__seg[data-status="pending"] .roadmap__seg-status { color: rgba(255,255,255,.40); font-style: italic; }
.roadmap__seg[data-status="open"]    .roadmap__seg-status { color: rgba(255,255,255,.45); font-style: italic; }

/* Pulse on the current segment's id (CSS-only, GPU compositor). */
.roadmap__seg[data-status="current"] .roadmap__seg-id {
  text-shadow: 0 0 14px var(--violet-400);
  animation: rm-pulse 1.8s ease-in-out infinite;
}
@keyframes rm-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .65; }
}

/* ---------- Detail panel below the strip ---------- */
.roadmap__detail {
  margin-top: 20px;
  padding: 22px 26px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,.08);
  background: rgba(14,19,26,.5);
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 28px;
  align-items: flex-start;
  min-height: 160px;
  animation: rm-detail-in 240ms cubic-bezier(0.2, 0, 0, 1);
}
.roadmap__detail--hidden {
  display: none;
}
@keyframes rm-detail-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .roadmap__detail { animation: none; }
}
.roadmap__detail[data-status="done"] {
  background: linear-gradient(135deg, rgba(0,200,83,.08), rgba(0,200,83,.01));
  border-color: rgba(0,200,83,.18);
}
.roadmap__detail[data-status="current"] {
  background: linear-gradient(135deg, rgba(124,58,237,.10), rgba(124,58,237,.02));
  border-color: rgba(124,58,237,.25);
}
.roadmap__detail[data-status="pending"],
.roadmap__detail[data-status="open"] {
  border-style: dashed;
}

.roadmap__detail-meta {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.roadmap__detail-id {
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255,255,255,.45);
  letter-spacing: .12em;
  text-transform: uppercase;
}
.roadmap__detail-release {
  font-family: var(--font-mono);
  font-size: 13px;
  color: #fff;
  letter-spacing: -.005em;
}
.roadmap__detail-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: .12em;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  align-self: flex-start;
  border: 1px solid currentColor;
  color: rgba(255,255,255,.55);
}
.roadmap__detail[data-status="done"]    .roadmap__detail-status { color: var(--green-400); }
.roadmap__detail[data-status="current"] .roadmap__detail-status { color: var(--violet-400); }

.roadmap__detail-title {
  font-size: 22px;
  line-height: 1.2;
  font-weight: 600;
  color: #fff;
  letter-spacing: -.02em;
  margin-bottom: 4px;
}
.roadmap__detail-sub {
  font-size: 13px;
  color: rgba(255,255,255,.55);
  margin-bottom: 14px;
  font-family: var(--font-mono);
}
.roadmap__detail-brief {
  font-size: 14px;
  line-height: 1.55;
  color: rgba(255,255,255,.78);
  max-width: 760px;
  text-wrap: pretty;
  margin-bottom: 18px;
}
.roadmap__detail-list-h {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: rgba(255,255,255,.45);
  margin-bottom: 14px;
}
.roadmap__detail-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* All phase detail lists (Phase 0 / A / B / C / D) */
.roadmap__detail-list--steps li,
.roadmap__detail-list--highlights li,
.roadmap__detail-list--sketches li {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 12px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid rgba(255,255,255,.04);
}
.roadmap__step-mark {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,.25);
  position: relative;
  flex: 0 0 auto;
}
.roadmap__detail-list li[data-status="done"] .roadmap__step-mark {
  background: var(--green-400);
  border-color: var(--green-400);
}
.roadmap__detail-list li[data-status="done"] .roadmap__step-mark::after {
  content: '';
  position: absolute;
  left: 3px; top: 1px;
  width: 4px; height: 7px;
  border: solid #0a0d12;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.roadmap__detail-list li[data-status="current"] .roadmap__step-mark {
  background: var(--violet-400);
  border-color: var(--violet-400);
  box-shadow: 0 0 10px var(--violet-400);
}
.roadmap__step-text strong {
  font-weight: 500;
  color: #fff;
  font-size: 14px;
}


.roadmap__hint {
  margin-top: 14px;
  font-size: 11px;
  font-family: var(--font-mono);
  color: rgba(255,255,255,.38);
  text-align: center;
}

/* Responsive: stack segments and detail panel.
   Stacking threshold consolidated to the canonical 1024 desktop boundary so
   the roadmap collapses in line with cases-grid, quotes-grid, and peco-grid
   (see AGENTS.md § Web for the full breakpoint set).
   Accordion mode: app.js docks `.roadmap__detail` as a child of
   `.roadmap__segments` right after the clicked segment, so the brief reads
   inline. The strip drops `overflow: hidden` so the detail isn't clipped
   by its border-radius, and the detail itself loses its outer chrome
   (margin-top, rounded corners) since it's now flush with the segments. */
@media (max-width: 1023px) {
  .roadmap__strip { overflow: visible; }
  .roadmap__segments { grid-template-columns: 1fr; }
  .roadmap__segments > .roadmap__detail {
    margin-top: 0;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }
  .roadmap__seg {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px 16px;
    padding: 16px 18px;
  }
  .roadmap__seg-id { font-size: 22px; }
  .roadmap__seg-title { min-height: auto; flex: 1 1 auto; }
  .roadmap__seg-bar { flex: 1 1 100%; }
  .roadmap__seg-prog { flex: 0 0 auto; }
  .roadmap__seg-status { flex: 0 0 100%; margin-top: 0; }
}
@media (max-width: 768px) {
  .roadmap__detail {
    grid-template-columns: 1fr;
    gap: 16px;
    padding: 24px;
  }
  .roadmap__detail-title { font-size: 22px; }
  .roadmap__detail-list--steps li,
  .roadmap__detail-list--highlights li,
  .roadmap__detail-list--sketches li {
    grid-template-columns: 18px 1fr;
    gap: 10px;
  }
}

/* ============================================================
   COPY-TO-CLIPBOARD TOAST
   ------------------------------------------------------------
   Single floating pill, bottom-center. Fades in on copy, auto-
   dismisses after ~2s. No external library — vanilla CSS + the
   click handler in app.js.
   ============================================================ */
.copy-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  z-index: 9999;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  border-radius: var(--r-pill);
  background: rgba(8,12,18,.92);
  border: 1px solid rgba(0,200,83,.35);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: -.005em;
  box-shadow: 0 12px 28px rgba(0,0,0,.45);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms var(--ease-out), transform 220ms var(--ease-out);
}
.copy-toast.copy-toast--show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.copy-toast--err {
  border-color: rgba(255,170,80,.5);
}
.copy-toast__icon {
  width: 14px;
  height: 14px;
  color: var(--green-400);
  flex: 0 0 auto;
}
.copy-toast--err .copy-toast__icon {
  color: #ffaa50;
}

/* ============================================================
   Audio mini-player
   ------------------------------------------------------------
   Floating bottom-right card with a NotebookLM audio overview.
   Hidden by default; toggled from .lp-nav__listen. State is
   driven by `data-open` (visibility/animation) and `data-state`
   (play/pause icon swap).
   ============================================================ */

/* Nav trigger — sits between .lp-lang and .lp-nav__cta. Compact,
   matches .lp-nav__cta in shape but uses the violet accent so the
   "Listen" call to action reads as primary among the right-side
   controls. Keep the pill height + radius identical to .lp-nav__cta
   so they line up to the pixel. */
.lp-nav__listen {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 0 14px; height: 36px;
  border-radius: var(--r-md);
  font-size: 13px; font-weight: 500;
  background: rgba(124,58,237,.18);
  color: var(--white);
  border: 1px solid rgba(167,139,250,.40);
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.lp-nav__listen:hover {
  background: rgba(124,58,237,.28);
  border-color: rgba(167,139,250,.65);
}
.lp-nav__listen[aria-expanded="true"] {
  background: rgba(124,58,237,.35);
  border-color: rgba(167,139,250,.75);
}
.lp-nav__listen svg { width: 12px; height: 12px; }

@media (max-width: 768px) {
  .lp-nav__listen { height: 44px; font-size: 14px; }
}

/* Player root — fixed bottom-right, slides up + fades in via
   data-open. While `hidden` the element is removed from the layout
   entirely; once JS un-hides it, the data-open transition takes over.
   z-index sits below copy-toast (9999) but above nav (40) so a copy
   toast stacks on top if both are visible. */
.audio-player {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 90;
  width: 340px;
  padding: 14px 14px 12px;
  border-radius: var(--r-lg);
  background: rgba(8,12,18,.92);
  border: 1px solid rgba(167,139,250,.30);
  box-shadow: 0 18px 40px rgba(0,0,0,.55), 0 0 0 1px rgba(167,139,250,.08);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: rgba(255,255,255,.92);
  font-family: var(--font-mono);
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 200ms var(--ease-out), transform 240ms var(--ease-out);
}
.audio-player[data-open="true"] {
  opacity: 1;
  transform: translateY(0);
}

.audio-player__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.audio-player__title-group {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  letter-spacing: .01em;
  color: rgba(255,255,255,.85);
}
.audio-player__brand {
  width: 14px; height: 14px;
  color: var(--violet-400);
  flex: 0 0 auto;
}
.audio-player__title {
  font-weight: 600;
  letter-spacing: -.005em;
}
.audio-player__sep,
.audio-player__time-sep {
  color: rgba(255,255,255,.35);
}
.audio-player__duration-static {
  color: rgba(255,255,255,.55);
}

.audio-player__head-actions {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.audio-player__icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border-radius: 6px;
  color: rgba(255,255,255,.6);
  background: transparent;
  border: 0;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
  cursor: pointer;
}
.audio-player__icon-btn:hover {
  background: rgba(255,255,255,.08);
  color: var(--white);
}
.audio-player__icon-btn svg { width: 14px; height: 14px; }

/* Progress bar — full-width clickable button so it gets keyboard focus
   and a screen-reader-friendly label. The inner track is purely visual.
   Click and drag are wired in app.js (no native <input range> because
   styling it across browsers is a pit). */
.audio-player__progress {
  display: block;
  width: 100%;
  padding: 8px 0;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.audio-player__progress:focus-visible {
  outline: 2px solid var(--violet-400);
  outline-offset: 2px;
  border-radius: 4px;
}
.audio-player__progress-track {
  position: relative;
  height: 3px;
  background: rgba(255,255,255,.12);
  border-radius: 2px;
  overflow: hidden;
}
.audio-player__progress-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  background: linear-gradient(90deg, var(--violet-500), var(--violet-300));
  border-radius: 2px;
  transition: width 100ms linear;
}

.audio-player__controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 4px;
}
.audio-player__time {
  font-size: 11px;
  color: rgba(255,255,255,.55);
  letter-spacing: 0;
}
.audio-player__elapsed { color: rgba(255,255,255,.85); }

.audio-player__speed {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  color: rgba(255,255,255,.7);
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.1);
  padding: 4px 8px;
  border-radius: 6px;
  margin-left: auto;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
  cursor: pointer;
}
.audio-player__speed:hover {
  background: rgba(255,255,255,.10);
  color: var(--white);
}

.audio-player__playpause {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--violet-600);
  color: var(--white);
  border: 0;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              transform 120ms var(--ease-out);
}
.audio-player__playpause:hover { background: var(--violet-500); }
.audio-player__playpause:active { transform: scale(0.94); }
.audio-player__playpause svg { width: 16px; height: 16px; }

/* Icon swap on play/pause — driven by data-state on the player root.
   Default (paused) shows the play triangle; playing shows the pause bars. */
.audio-player__icon--pause { display: none; }
.audio-player[data-state="playing"] .audio-player__icon--play  { display: none; }
.audio-player[data-state="playing"] .audio-player__icon--pause { display: inline-block; }

/* Mobile: pin to bottom, full-width with safe insets so it doesn't
   overlap the home-indicator on iOS. Aligned to the canonical 480 phone
   breakpoint (see AGENTS.md § Web). Above 480 the floating-right card
   sits at 340px which fits comfortably on phablets and small tablets. */
@media (max-width: 480px) {
  .audio-player {
    left: 12px;
    right: 12px;
    bottom: 12px;
    width: auto;
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  }
}

/* Touch targets ≥36px (ideally 44) on mobile for the player + lightbox +
   peco nav controls. WCAG 2.5.5 recommends 44×44 — we hit the bar on the
   primary actions (play/pause, lightbox close) and bring the rest closer. */
@media (max-width: 768px) {
  .audio-player__icon-btn { width: 36px; height: 36px; }
  .audio-player__icon-btn svg { width: 16px; height: 16px; }
  .audio-player__playpause { width: 44px; height: 44px; }
  .audio-player__playpause svg { width: 18px; height: 18px; }
  .lightbox__close { width: 44px; height: 44px; top: 16px; right: 16px; }
  .lightbox__close svg { width: 20px; height: 20px; }
  .peco__nav-btn { padding: 10px 14px; min-height: 36px; }
}

/* ============================================================
   UTILITIES
   ============================================================ */
/* Visually hidden but available to assistive tech. Standard a11y pattern. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   LIGHTBOX — native <dialog> for full-size screenshot view
   ============================================================
   Opens via showModal() from app.js when the user clicks the
   shots__zoom button. Native <dialog> gives:
   - Focus trap inside the dialog
   - Escape closes
   - ::backdrop styled overlay
   - Top-layer stacking (above everything)
   We close on backdrop-click via a JS handler (target === dialog). */
/* IMPORTANT: scope to `[open]` — without it, `display: flex` would override
   the UA's default `display: none` for closed <dialog>, leaving an invisible
   fullscreen overlay that swallows every click below it (including the
   shots__zoom button). With `[open]`, the rules apply only while the dialog
   is shown via showModal(). */
.lightbox[open] {
  /* Fullscreen transparent stage; the image inside is centered via flex.
     The image fills the full viewport width on phones (`max-width: 100%`
     against the 100vw dialog) and is capped at 1600px on big desktops by
     the rule on `.lightbox__img` below. */
  position: fixed;
  inset: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  max-width: 100vw;
  max-height: 100vh;
  border: none;
  padding: 0;
  background: transparent;
  overflow: visible;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, .9);
}
.lightbox::backdrop {
  background: rgba(6, 8, 12, .85);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.lightbox__img {
  display: block;
  width: auto;
  height: auto;
  /* Phones: fill the full viewport width (max-width: 100% of the 100vw
     dialog). Big desktops: cap at 1600px so the image doesn't stretch
     edge-to-edge on 4K monitors. Aspect ratio is preserved by the browser
     because we only constrain one explicit dimension at a time. */
  max-width: min(100%, 1600px);
  max-height: 100%;
  border-radius: var(--r-lg);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .6);
  user-select: none;
  -webkit-user-drag: none;
  /* Block the browser's native gestures (page-zoom, scroll) on the image
     so our touch handlers can implement local pinch-zoom and pan without
     fighting the UA. transform-origin: center keeps the zoom focal point
     in the visual center; we adjust position via translate() instead.
     will-change hints the compositor to promote this to its own layer. */
  touch-action: none;
  transform-origin: center center;
  will-change: transform;
}
.lightbox__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: rgba(0, 0, 0, .55);
  color: rgba(255, 255, 255, .9);
  border-radius: 50%;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
  z-index: 1;
}
.lightbox__close:hover { background: rgba(0, 0, 0, .8); }
.lightbox__close:focus-visible {
  outline: 2px solid var(--violet-400);
  outline-offset: 2px;
}
.lightbox__close svg { width: 18px; height: 18px; }

/* ============================================================
   COOKIE CONSENT MODAL
   ------------------------------------------------------------
   Native <dialog> for focus trap + Escape close. The dialog is
   the modal box itself (centered, max-width 480px); ::backdrop
   blurs the whole page behind it.
   Accept = green brand chip, prominent. Decline = unstyled link
   in muted gray, deliberately low visual weight so the path of
   least resistance is consent rather than rejection.
   ============================================================ */
.cookie-consent { display: none; }
.cookie-consent[open] {
  display: block;
  position: fixed;
  inset: 0;
  margin: auto;
  width: calc(100% - 32px);
  max-width: 480px;
  height: max-content;
  max-height: calc(100vh - 32px);
  border: 1px solid rgba(167, 139, 250, .35);
  border-radius: var(--r-xl);
  background: rgba(8, 12, 18, .96);
  color: rgba(255, 255, 255, .9);
  padding: 28px 28px 22px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .6),
              0 0 0 1px rgba(167, 139, 250, .12);
  font-family: var(--font-sans);
  z-index: 200;
}
.cookie-consent::backdrop {
  background: rgba(6, 8, 12, .55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.cookie-consent__title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: #fff;
  margin: 0 0 10px;
}
.cookie-consent__body {
  font-size: 14px;
  line-height: 1.55;
  color: rgba(255, 255, 255, .72);
  margin: 0 0 22px;
}

.cookie-consent__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 18px;
}

/* Accept: violet accent pill, the visual primary. */
.cookie-consent__accept {
  height: 42px;
  padding: 0 22px;
  border-radius: var(--r-md);
  border: 0;
  background: var(--violet-600);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -.005em;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.cookie-consent__accept:hover {
  background: var(--violet-500);
  transform: translateY(-1px);
}
.cookie-consent__accept:active { transform: translateY(0); }
/* Override the site-wide green focus ring (`--sh-focus`) on the modal's
   accept button so the focus halo matches the violet pill instead of
   clashing with it. */
.cookie-consent__accept:focus-visible {
  box-shadow: 0 0 0 3px rgba(124, 58, 237, .45);
}

/* Decline: low-contrast text link. No background, no border, small font.
   The button is reachable by tab + click but the visual ranking puts it
   below the accept pill — deliberate dark-pattern-adjacent. */
.cookie-consent__decline {
  background: transparent;
  border: 0;
  padding: 4px 8px;
  color: rgba(255, 255, 255, .35);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 400;
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, .15);
  text-underline-offset: 3px;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out),
              text-decoration-color var(--dur-fast) var(--ease-out);
}
.cookie-consent__decline:hover {
  color: rgba(255, 255, 255, .55);
  text-decoration-color: rgba(255, 255, 255, .35);
}
.cookie-consent__decline:focus-visible {
  outline: 2px solid var(--violet-400);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (max-width: 480px) {
  .cookie-consent[open] {
    padding: 22px 20px 18px;
  }
  .cookie-consent__actions {
    flex-direction: column-reverse;
    align-items: stretch;
    gap: 12px;
  }
  .cookie-consent__decline {
    align-self: center;
  }
}

/* ============================================================
   MOBILE TITLE SCALE — uniform reduction on phones (≤767px)
   ------------------------------------------------------------
   Every title in the site shrinks on phones so the hierarchy
   stays compact and readable on 360–430px viewports. Tablet
   portrait (≥768) keeps the desktop scale via the existing
   clamp() floors.
   ============================================================ */

/* Footer-in-drawer slot — populated by app.js on phones, empty on
   desktop. Defined OUTSIDE the @media so the cascade order is
   `display: none` (default) → `display: flex` (mobile override).
   If the override sat after this rule the desktop default would win
   on every viewport. */
.lp-nav__footer-mobile { display: none; }

@media (max-width: 767px) {
  .hero__title              { font-size: 36px; line-height: 1.1; }
  .cta-bar__title           { font-size: 30px; line-height: 1.05; }
  .section-title            { font-size: 24px; }
  .roadmap__title           { font-size: 22px; }
  .peco__brief-title        { font-size: 22px; }
  .roadmap__detail-title    { font-size: 20px; }
  .case__title              { font-size: 18px; }
  .howit-step__title        { font-size: 18px; }
  .feature--hero .feature__title { font-size: 18px; }
  .feature__title           { font-size: 18px; }
  .peco__cta-title          { font-size: 16px; }
  .features-list__title     { font-size: 15px; }

  /* Plugin definitions panel (.peco__brief) — body, subtitle, code snippet
     and tag all step down so the card reads compact on phones. */
  .peco__brief-tag    { font-size: 10px; margin-bottom: 12px; }
  .peco__brief-one    { font-size: 12px; margin-bottom: 14px; }
  .peco__brief-body   { font-size: 13px; line-height: 1.55; margin-bottom: 18px; }
  .peco__brief-code   { font-size: 10.5px; padding: 12px 14px; }
  .peco__panel        { padding: 24px 20px 20px; }

  /* Hide the "A plugin is ~30 lines of code" CTA strip on phones — the
     panel above already carries the message and the strip just adds noise. */
  .peco__cta          { display: none; }

  /* Footer link columns migrate into the nav drawer on phones (see app.js
     "Footer → mobile drawer migration"). The grid + brand block hide
     because their content is either redundant (logo already in the nav)
     or moved (link cols). The .lp-footer__bottom strip stays visible —
     it carries the copyright + author + Makersia attribution and must
     read on the page itself, not behind a hamburger menu. */
  .lp-footer__grid    { display: none; }
  .lp-footer          { padding-block: 0 24px; }
  .lp-footer__bottom  { margin-top: 0; padding-top: 24px; }
  .lp-nav__footer-mobile {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    text-align: right;
    gap: 28px;
    margin-top: 32px;
    padding-top: 24px;
    border-top: 1px solid rgba(255, 255, 255, .08);
  }
  .lp-nav__footer-mobile .lp-footer__col ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 10px;
  }
  .lp-nav__footer-mobile .lp-footer__col a { font-size: 15px; }
}
