/* ============================================================
   Lunamux landing page — "Lunamux Dark" terminal aesthetic:
   deep navy with a cyan glow and a mint-white lift.
   Pure CSS, no external fonts or assets.

   NOTE: the --green* custom-property names are historical — they
   now hold the Lunamux Dark navy/cyan palette, not green. Names
   kept so every existing usage picks up the new colours untouched.
   ============================================================ */

:root {
  --bg:        #04090f;   /* near-black navy ground (from Lunamux Dark theme) */
  --panel:     #070f1a;   /* surface (from Lunamux Dark theme) */
  --panel-2:   #0b1626;   /* raised surface (from Lunamux Dark theme) */
  --green:     #4dc8f5;   /* primary text — cyan glow */
  --green-hi:  #66d9ff;   /* bright accent — vivid cyan (clearly blue vs. the white headings) */
  --green-dim: #5f7590;   /* secondary / comments */
  --green-dimmer: #24384f;
  --border:    rgba(77, 200, 245, .20);
  --border-hi: rgba(77, 200, 245, .45);
  --glow:      rgba(77, 200, 245, .35);
  --red:       #ff5f57;
  --yellow:    #febc2e;
  --traffic-g: #28c840;
  --blue:      #5fa8ff;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", "Fira Code", Menlo, Consolas, monospace;

  --maxw: 1120px;
  /* The left nav's width, and the width below which it stops being furniture
     and becomes a drawer behind the hamburger.

     1024px is not where the content stops fitting beside it — that is
     --maxw + --sidebar-w ≈ 1336px. Between the two the page column just
     narrows from its 1120px maximum, which costs nothing: the two-column
     layouts inside it hold until their own 820/900px breakpoints. Cutting
     over at 1336 instead would take the sidebar away from every 1280px
     laptop, which is the width this thing is mostly read at. Below 1024 the
     column would start losing real estate to the nav, so there the nav
     leaves. */
  --sidebar-w: 216px;
  --nav-break: 1024px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  /* the fixed left nav is out of flow, so the page makes its own room for
     it. Dropped at --nav-break, where the nav becomes a drawer over the
     page instead of furniture beside it. */
  padding-left: var(--sidebar-w);
  background: var(--bg);
  color: var(--green);
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* faint radial vignette in the page background */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background:
    radial-gradient(120% 80% at 70% -10%, rgba(77,200,245,.06), transparent 60%),
    radial-gradient(90% 60% at 0% 110%, rgba(77,200,245,.05), transparent 55%);
  pointer-events: none;
  z-index: -1;            /* behind all page content, incl. screenshots */
}

a { color: inherit; text-decoration: none; }
code, em { font-style: normal; color: var(--green-hi); }

/* ---------- decorative CRT scanline overlay ---------- */
/* The standalone .overlay div is no longer painted — see the note below.
   We keep the rule as a no-op so the leftover markup stays harmless. */
.overlay { display: none; }

/* The scanlines are rendered as a pseudo-element of the ACTIVE page rather
   than a viewport-fixed div. Each page forms its own stacking context (via
   its fade-in animation), so painting the scanlines here lets them sit
   ABOVE the page text for the CRT look but BELOW the framed screenshots
   (z-index 3) — otherwise multiply blending bands ugly horizontal lines
   across them, most visible on light-themed shots. The nav (1000),
   progress bar (10000) and lightbox (10001) all stay above this. */
.page.is-active::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0,0,0,0) 0px,
    rgba(0,0,0,0) 2px,
    rgba(0,0,0,.18) 3px,
    rgba(0,0,0,0) 4px
  );
  mix-blend-mode: multiply;
  opacity: .35;
}
/* Over the embedded live demo the scanlines read as a rendering artifact,
   so drop them while the demo page is active (script.js toggles the class).
   Same for the embedded issue tracker. */
body.demo-active .page.is-active::after,
body.issues-active .page.is-active::after { content: none; }

/* ---------- scroll progress bar ---------- */
.progress {
  position: fixed;
  top: 0;
  /* fixed, so body's padding does not move it: it starts where the page
     does, at the sidebar's edge */
  left: var(--sidebar-w);
  height: 2px;
  width: 0%;
  background: linear-gradient(90deg, var(--green-dim), var(--green-hi));
  box-shadow: 0 0 8px var(--glow);
  z-index: 10000;
  transition: width .08s linear;
}

/* ---------- NAV (left sidebar) ----------
   The nav is a column down the left rather than a bar across the top: the
   page is a centred 1120px column, so the space beside it was going spare
   anyway, and a sidebar buys every tab a full row — room for an icon and a
   label without the bar's width budget deciding what fits.

   It is fixed, not sticky: out of flow, so it survives body.demo-active's
   flex-column full-height layout (see the bottom of this file) without
   taking a row from it, and the page scrolls under it. `body` carries the
   matching padding-left. Below --nav-break it slides off-canvas — see the
   media query at the end of this section. */
.nav {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--sidebar-w);
  z-index: 1000;
  background: rgba(4, 9, 15, .82);
  backdrop-filter: blur(10px);
  /* No edge against the page: the gap and the rows' own alignment already
     say where the nav ends, and a rule down the full height competes with
     the active row's outline. The drawer at narrow widths does need an edge,
     but it floats over the page and its shadow gives it one. */
  /* the groups are short, but a long one (or a small laptop) still has to
     reach the bottom rows */
  overflow-y: auto;
  overscroll-behavior: contain;
}
.nav-inner {
  min-height: 100%;
  padding: 22px 12px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  /* the one number that sets the groups apart. Each group is a <nav>, so
     this gap is the whole grouping mechanism: no dividers, no per-group
     margins to keep in sync. */
  gap: 30px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  /* 10px matches the tab rows' own padding, so the dot's left edge starts on
     the same rail as the column of icons under it */
  padding: 0 10px;
  margin-bottom: 2px;
  font-weight: 600;
  color: var(--green-hi);
  letter-spacing: .5px;
  white-space: nowrap;
}
.brand .dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--green-hi);
  box-shadow: 0 0 10px var(--green-hi);
  animation: dotGlow 2.2s ease-in-out infinite;
}
@keyframes dotGlow {
  0%, 100% {
    background: var(--green-dim);
    box-shadow: 0 0 2px rgba(102,217,255,.25);
    opacity: .35;
  }
  50% {
    background: var(--green-hi);
    box-shadow: 0 0 14px var(--green-hi), 0 0 28px rgba(102,217,255,1),
                0 0 46px rgba(102,217,255,.6);
    opacity: 1;
  }
}
/* One run of tabs — one row per item. There are three runs (the product, the
   project's activity, the site around it) plus the Legal disclosure, and
   .nav-inner's gap is what sets them apart. Inside a run the rows sit tight
   against each other, so the groups read as blocks. */
.tabs {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* The overflow menu's trigger is a <button>, not a link — it opens a panel
   rather than going anywhere — and it sits outside all three <nav>s. It is
   still a row to look at, so it borrows the row rules by name. */
.tabs a,
.nav-menu-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 10px;
  border: 1px solid transparent;
  border-radius: 7px;
  color: var(--green-dim);
  font-size: 13px;
  text-align: left;
  transition: color .2s, border-color .2s, background .2s;
}
.tabs a:hover,
.nav-menu-btn:hover { color: var(--green); border-color: var(--border); }
.tabs a.active {
  color: var(--green-hi);
  border-color: var(--border-hi);
  background: rgba(77,200,245,.06);
}
/* The icons: hand-drawn in chrome.js, stroked in currentColor, so they take
   the row's colour in every state and need nothing here but a box. `flex:
   none` keeps them square while the label takes the slack. */
.nav-icon {
  width: 16px;
  height: 16px;
  flex: none;
  color: inherit;
}
.nav-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---------- nav overflow menu ---------- */
/* The "Legal" button and its panel: Privacy / Terms, one row for the two of
   them until asked. A plain disclosure — see wireMenu() in chrome.js for the
   open/close behaviour. It is the sidebar's last group, so the panel opens
   downwards in flow and pushes nothing around. */
.nav-menu { display: flex; flex-direction: column; gap: 2px; }
/* A word, not a glyph — so it wants the tabs' own type. Everything else it
   looks like comes from the row rules above. */
.nav-menu-btn {
  font-family: var(--mono);
  background: none;
  cursor: pointer;
}
.nav-menu-btn[aria-expanded="true"] {
  color: var(--green-hi);
  border-color: var(--border-hi);
  background: rgba(77,200,245,.06);
}
/* A chevron built from a rotated square's two visible sides: it points down
   when shut and up when open, so the row says which way it goes. `margin-left:
   auto` parks it at the row's right edge. */
.nav-menu-chev {
  width: 6px;
  height: 6px;
  flex: none;
  margin: -3px 2px 0 auto;
  border-right: 1.4px solid currentColor;
  border-bottom: 1.4px solid currentColor;
  transform: rotate(45deg);
  transition: transform .2s;
}
.nav-menu-btn[aria-expanded="true"] .nav-menu-chev {
  margin-top: 1px;
  transform: rotate(-135deg);
}
/* The panel indents to the labels' rail (10px row padding + the 16px icon +
   its 10px gap), so the small print reads as hanging off Legal rather than
   as two more tabs. */
.nav-menu-panel {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-left: 36px;
}
.nav-menu-panel[hidden] { display: none; }
.nav-menu-panel a {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--green-dim);
  font-size: 12px;
  white-space: nowrap;
}
.nav-menu-panel a:hover { color: var(--green-hi); background: rgba(77,200,245,.06); }
.nav-menu-panel a.active { color: var(--green-hi); }
/* the small print's icons ride a size down, with the type */
.nav-menu-panel .nav-icon { width: 14px; height: 14px; }

/* ---------- nav: the drawer, and the button that opens it ----------
   Both exist only below --nav-break; above it the sidebar is always there and
   there is nothing to open. chrome.js toggles `nav-open` on <body> either way
   and lets these rules decide whether it means anything. Both controls live
   on <body> rather than in the nav — see the note in chrome.js: the nav is
   what slides away. */
.nav-toggle,
.nav-scrim { display: none; }

@media (max-width: 1024px) {
  /* the page takes its width back and the nav leaves the flow entirely */
  body { padding-left: 0; padding-top: 52px; }
  .progress { left: 0; }

  .nav {
    width: min(268px, 82vw);
    transform: translateX(-100%);
    transition: transform .22s cubic-bezier(.2,.7,.2,1);
    box-shadow: 0 0 60px rgba(0,0,0,.6);
  }
  body.nav-open .nav { transform: none; }
  /* The toggle stays put and on top when the drawer slides out from under
     it — it is the close button too. So the drawer starts its content below
     the toggle strip rather than behind it. */
  .nav-inner { padding-top: 56px; }

  /* The strip the toggle sits in: the drawer is gone, so without this the
     button would sit on top of the first line of the page. Same height as
     the padding-top above. */
  .nav-toggle {
    position: fixed;
    top: 8px; left: 10px;
    z-index: 1001;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px; height: 36px;
    padding: 0;
    background: rgba(4, 9, 15, .82);
    backdrop-filter: blur(10px);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--green-dim);
    cursor: pointer;
    transition: color .2s, border-color .2s;
  }
  .nav-toggle:hover { color: var(--green); border-color: var(--border-hi); }
  .nav-toggle svg { width: 16px; height: 16px; }
  .nav-toggle[aria-expanded="true"] {
    color: var(--green-hi);
    border-color: var(--border-hi);
  }

  /* Dims the page behind an open drawer and swallows the click that closes
     it. Below .nav's z-index, above everything else. */
  .nav-scrim {
    position: fixed;
    inset: 0;
    z-index: 999;
    display: block;
    background: rgba(2, 5, 9, .6);
    opacity: 0;
    pointer-events: none;
    transition: opacity .22s;
  }
  body.nav-open .nav-scrim { opacity: 1; pointer-events: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .nav, .nav-scrim { transition: none; }
}
/* ---------- buttons ---------- */
.btn {
  display: inline-block;
  padding: 11px 20px;
  border-radius: 9px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .3px;
  border: 1px solid var(--border-hi);
  transition: transform .15s, box-shadow .2s, background .2s, color .2s;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn-primary {
  background: var(--green-hi);
  color: #062033;
  box-shadow: 0 0 0 rgba(77,200,245,0);
}
.btn-primary:hover { box-shadow: 0 6px 26px var(--glow); }
.btn-ghost { color: var(--green); background: transparent; }
.btn-ghost:hover { background: rgba(77,200,245,.08); box-shadow: 0 0 18px rgba(77,200,245,.12); }

/* ---------- layout sections ---------- */
section { position: relative; }

/* ---------- page views (single-file router) ---------- */
.page { display: none; }
.page.is-active {
  display: block;
  animation: pageFade .4s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes pageFade {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- HERO ---------- */
.hero {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 80px 20px 60px;
}
.hero-grid {
  display: grid;
  grid-template-columns: 1fr 1.25fr;
  gap: 48px;
  align-items: center;
}
.kicker {
  color: var(--green-dim);
  font-size: 13px;
  letter-spacing: 1px;
  margin-bottom: 16px;
}
h1 {
  font-size: clamp(34px, 5vw, 56px);
  line-height: 1.08;
  margin: 0 0 20px;
  font-weight: 700;
  letter-spacing: -.5px;
  color: #eaf3fb;
}
.glow {
  color: var(--green-hi);
  text-shadow: 0 0 24px var(--glow), 0 0 4px var(--glow);
}
.lede {
  color: var(--green);
  font-size: 16px;
  max-width: 46ch;
  margin: 0 0 28px;
}
.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; }
.hero-meta {
  margin-top: 22px;
  color: var(--green-dim);
  font-size: 13px;
}

/* ---------- terminal window component ---------- */
.term {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(0,0,0,.55);
}
.term-focused {
  border-color: var(--border-hi);
  box-shadow: 0 0 0 1px var(--border-hi), 0 24px 70px rgba(0,0,0,.6),
              0 0 50px rgba(77,200,245,.12);
}
.term-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--border);
}
.lights { display: flex; gap: 7px; }
.lights i { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
.lights .r { background: var(--red); }
.lights .y { background: var(--yellow); }
.lights .g { background: var(--traffic-g); }
.term-title {
  color: var(--green-dim);
  font-size: 12px;
  letter-spacing: 1px;
}
@keyframes blink { 50% { opacity: 0; } }

/* ---------- FEATURES ---------- */
.features {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 40px 20px 30px;
  display: flex;
  flex-direction: column;
  gap: 96px;
}
.feature {
  display: grid;
  /* shot lives in the wider column so it matches the hero screenshot's size */
  grid-template-columns: 1fr 1.25fr;
  gap: 48px;
  align-items: center;
}
.feature[data-side="right"] { grid-template-columns: 1.25fr 1fr; }
.feature[data-side="right"] .feature-copy { order: 2; }
.feature[data-side="right"] .shot { order: 1; }

/* Labeled divider between feature groups — marks where the experimental
   sections begin. Fading rules on either side of a centered pill. */
.feature-sep {
  display: flex;
  align-items: center;
  gap: 18px;
  /* pull in against the 96px .features gap so the rule reads as a divider
     that belongs with the section below it, not a free-floating row */
  margin: -24px 0;
}
.feature-sep::before,
.feature-sep::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--border-hi), transparent);
}
.feature-sep-label {
  flex: none;
  font-family: var(--mono, monospace);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--green-dim);
  white-space: nowrap;
}

/* A screenshot-free feature: one centered column instead of the two-up grid. */
.feature.feature-noshot {
  grid-template-columns: 1fr;
  justify-items: center;
  text-align: center;
  padding: 8px 0;
}
.feature-noshot .feature-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* fixed width so typing never reflows / re-centers the block */
  width: min(640px, 100%);
}
.feature-noshot .feature-index { margin-bottom: 10px; }
.feature-noshot h3 { font-size: clamp(26px, 3.6vw, 38px); }
/* The index and heading stay centered (they're static). The typed text is
   left-aligned inside the fixed-width block so its left edge stays put as
   characters appear — centering each line would make it jitter sideways. */
.feature.feature-noshot p { width: 100%; max-width: none; text-align: left; }
.feature-noshot .kv { width: 100%; text-align: left; margin-top: 6px; }

.feature-index {
  color: var(--green-dimmer);
  font-size: 56px;
  font-weight: 700;
  line-height: 1;
  margin-bottom: 4px;
}
.feature h3 {
  font-size: clamp(24px, 3vw, 32px);
  margin: 0 0 14px;
  color: #eaf3fb;
  letter-spacing: -.3px;
}

/* "experimental" badge */
.badge-exp {
  display: inline-block;
  vertical-align: middle;
  margin-left: 10px;
  padding: 3px 9px;
  border: 1px solid var(--yellow);
  border-radius: 999px;
  color: var(--yellow);
  background: rgba(254, 188, 46, .08);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .8px;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 0 12px rgba(254, 188, 46, .12);
}
/* inline variant used inside list items */
.badge-exp.sm { margin-left: 6px; padding: 1px 7px; font-size: 10px; }
/* version badge next to a download card's platform name */
.badge-ver {
  display: inline-block;
  vertical-align: middle;
  margin-left: 10px;
  padding: 2px 8px;
  border: 1px solid var(--green-dim);
  border-radius: 999px;
  color: var(--green);
  background: rgba(77, 200, 245, .08);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .5px;
  white-space: nowrap;
}
.feature p {
  color: var(--green);
  max-width: 48ch;
  margin: 0 0 22px;
  min-height: 4.8em;   /* reserve space so typing doesn't reflow the layout */
}
/* blinking caret shown to the right of text while it types in */
.type-caret {
  display: inline-block;
  color: var(--green-hi);
  margin-left: 2px;
  text-shadow: 0 0 8px var(--glow);
  transform: scaleX(1.5);          /* 50% wider block cursor */
  transform-origin: left center;
  animation: blink 1.05s steps(1) infinite;
}
.kv { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.kv li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  color: var(--green);
  font-size: 14px;
}
.kv li span:first-child:not(.led):not(.tt-ind) {
  flex: none;
  min-width: 64px;
  color: var(--green-hi);
  font-weight: 600;
}
.kv em { color: var(--green-dim); }

/* status LEDs used in feature lists */
.led {
  width: 9px; height: 9px; border-radius: 50%;
  display: inline-block; flex: none;
  transform: translateY(1px);
}
.led-r { background: var(--red);    box-shadow: 0 0 8px var(--red); }
.led-b { background: var(--blue);   box-shadow: 0 0 8px var(--blue); }
.led-g { background: var(--traffic-g); box-shadow: 0 0 8px var(--traffic-g); }
.led-y { background: var(--yellow); box-shadow: 0 0 8px var(--yellow); }

/* agent-state indicators — mirror the real Lunamux app: a rotating
   spinner while an agent is working, a pulsating warning triangle while
   it waits for input (fades opacity 1 → 0.3 → 1 over 2.5s, like the app's
   `fade-warning` keyframes). */
/* reserve the same 64px label column as the key rows so the text after
   the icon aligns with the other feature lists; the icon sits left. */
.tt-ind {
  min-width: 64px; height: 13px; flex: none;
  display: inline-flex; align-items: center; justify-content: flex-start;
  transform: translateY(2px);
}
.tt-working::before {
  content: ""; width: 13px; height: 13px; box-sizing: border-box;
  border-radius: 50%;
  border: 1.5px solid var(--green-dimmer);
  border-top-color: var(--green);
  box-shadow: 0 0 6px rgba(77, 200, 245, .5);
  animation: tt-spin .7s linear infinite;
}
@keyframes tt-spin { to { transform: rotate(360deg); } }
.tt-waiting {
  color: var(--yellow);
  filter: drop-shadow(0 0 4px rgba(254, 188, 46, .6));
  animation: tt-fade-warning 2.5s ease-in-out infinite;
}
.tt-waiting svg { display: block; }
@keyframes tt-fade-warning { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) {
  .tt-working { animation: none; }
  .tt-waiting { animation: none; opacity: 1; }
}

/* ---------- screenshot placeholder ---------- */
.shot { margin: 0; }
.shot-canvas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  aspect-ratio: 16 / 10;          /* same box as a real screenshot slot */
  margin: 0;
  border: 1px dashed var(--border-hi);
  border-radius: 14px;
  color: var(--green-dim);
  font-size: 13px;
  letter-spacing: .5px;
  background:
    repeating-linear-gradient(45deg,
      rgba(77,200,245,.03) 0, rgba(77,200,245,.03) 10px,
      transparent 10px, transparent 20px);
}
.shot-glyph { font-size: 22px; color: var(--green-dim); }
/* Real screenshots render frameless (no fake window chrome) and are
   clickable to open full size in the lightbox modal. */
.shot-zoom {
  display: block;
  position: relative;
  z-index: 3;                     /* above the scanline overlay (2) so it doesn't band the shot */
  width: 100%;
  aspect-ratio: 16 / 10;          /* same proportions as the hero screenshot */
  padding: 14px;
  border: 1px solid var(--green-dim);
  border-radius: 14px;
  overflow: hidden;
  background: var(--panel);
  cursor: zoom-in;
  box-shadow: 0 24px 60px rgba(0,0,0,.45), 0 0 24px rgba(77,200,245,.10);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.shot-zoom:hover,
.shot-zoom:focus-visible {
  border-color: var(--green);
  box-shadow: 0 24px 60px rgba(0,0,0,.5), 0 0 30px rgba(77,200,245,.14);
  outline: none;
}
.shot-zoom img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 6px;
}

/* Cross-fading hero slideshow: images stack inside the frame and fade
   between one another. Only .is-active is visible at full opacity. */
.shot-slideshow .shot-stack {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
}
.shot-slideshow .hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1s ease-in-out;
}
.shot-slideshow .hero-slide.is-active { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .shot-slideshow .hero-slide { transition: none; }
}

/* A thin, wide screenshot (e.g. a status-bar strip) shouldn't float in a
   tall 16/10 box. The short variant drops the fixed ratio so the slot hugs
   the image's natural height, and centers it vertically in the feature row. */
.shot--short { align-self: center; }
.shot-zoom--short {
  aspect-ratio: auto;
  padding: 10px 14px;
}
.shot-zoom--short img {
  height: auto;
  object-fit: fill;
}

/* A candid photo paired with a single bezeled phone beside it. The photo is
   portrait (≈7:8), not 16/10, so it gets its own portrait box instead of the
   default landscape one — otherwise it floats letterboxed with dead side
   margins. Width is vw-driven so its height tracks the phone bezel beside it,
   making the two read as a balanced pair; it may shrink on narrow screens. */
.shot-companion {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(14px, 2vw, 32px);
}
.shot-companion .shot-zoom {
  flex: 0 1 auto;
  width: clamp(240px, 34vw, 390px);
  height: auto;
  aspect-ratio: 1274 / 1466;   /* match the photo's real proportions */
  min-width: 0;
}
.shot-companion .phone { flex: 0 0 auto; }

/* ---------- phone device frames (devices section) ----------
   Two phone screenshots in CSS-drawn bezels instead of one 16/10 shot.
   Each .phone is a click-to-zoom trigger (data-full) like .shot-zoom. */
.shot-phones { align-self: center; }
.phones {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: clamp(18px, 3vw, 44px);
}
.phone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  cursor: zoom-in;
}
.phone-bezel {
  position: relative;
  z-index: 3;                       /* above the scanline overlay (2) */
  display: block;
  width: clamp(142px, 19vw, 210px);
  padding: 9px;
  border-radius: 34px;
  background: linear-gradient(155deg, #1e273300, #161d27) , #0c141d;
  border: 1px solid var(--border-hi);
  box-shadow:
    0 26px 60px rgba(0,0,0,.55),
    0 0 26px rgba(77,200,245,.08),
    inset 0 0 0 2px rgba(0,0,0,.6);
  transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.phone-bezel img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 26px;
  background: #000;
}
/* iOS dynamic island — sits in the empty gap at the top of the shot */
.phone--ios .phone-bezel::after {
  content: "";
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  width: 30%;
  height: 19px;
  border-radius: 12px;
  background: #000;
  z-index: 2;
}
/* Android punch-hole camera */
.phone--android .phone-bezel::after {
  content: "";
  position: absolute;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #000;
  box-shadow: inset 0 0 0 1px rgba(77,200,245,.18);
  z-index: 2;
}
.phone-label {
  font-size: 12px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--green-dim);
  transition: color .18s ease;
}
.phone:hover .phone-bezel,
.phone:focus-visible .phone-bezel {
  border-color: var(--green);
  box-shadow:
    0 30px 70px rgba(0,0,0,.6),
    0 0 34px rgba(77,200,245,.16),
    inset 0 0 0 2px rgba(0,0,0,.6);
  transform: translateY(-4px);
}
.phone:hover .phone-label,
.phone:focus-visible .phone-label { color: var(--green); }
.phone:focus-visible { outline: none; }

/* ============================================================
   ABOUT — two-column split (experiment)
   ------------------------------------------------------------
   The About page splits into two columns: the existing hero +
   feature stack on the LEFT (.about-main) and the experimental 3D
   world showcase on the RIGHT (.about-3d). The .about-split wrapper
   also reshapes the left column — it hides the big hero screenshot
   and collapses every feature to a single column with its screenshot
   BELOW the copy, each section divided by a hairline rule.
   ============================================================ */
.about-split {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 64px 20px 60px;
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: clamp(32px, 4.5vw, 72px);
  align-items: start;
}
.about-split--solo { grid-template-columns: minmax(0, 1fr); }
.about-main { min-width: 0; }

/* --- left column: hero without its screenshot --- */
.about-split .hero {
  max-width: none;
  margin: 0;
  padding: 0;
}
.about-split .hero-grid {
  grid-template-columns: 1fr;
  gap: 0;
}
.about-split .hero-shot { display: none; }
.about-split .hero .lede { max-width: none; }

/* --- left column: features stacked, screenshot below copy, ruled --- */
.about-split .features {
  max-width: none;
  margin: 0;
  padding: 0;
  gap: 0;
}
.about-split .feature,
.about-split .feature[data-side="right"] {
  grid-template-columns: 1fr;
  gap: 22px;
  padding: 44px 0;
  border-top: 1px solid var(--border);
  align-items: start;
}
/* copy always sits above the shot, regardless of the feature's side */
.about-split .feature .feature-copy { order: 0; }
.about-split .feature .shot,
.about-split .feature .shot-phones,
.about-split .feature .shot-companion { order: 1; }
.about-split .feature p { max-width: none; }
.about-split .feature .kv { max-width: none; }
/* the experimental divider already reads as a section break here */
.about-split .feature-sep { margin: 0; padding: 30px 0 2px; }
/* slide reveals straight up in the narrow column (no sideways shift) */
.about-split .feature[data-side="left"].reveal,
.about-split .feature[data-side="right"].reveal { transform: translateY(26px); }
.about-split .feature.reveal.visible { transform: none; }

/* --- right column: the 3D world showcase --- */
.about-3d { min-width: 0; }
.w3-head {
  padding-bottom: 26px;
  border-bottom: 1px solid var(--border-hi);
}
.w3-head h2 {
  font-size: clamp(24px, 3vw, 32px);
  line-height: 1.1;
  margin: 0 0 14px;
  color: #eaf3fb;
  letter-spacing: -.3px;
}
.w3-head .lede { max-width: none; margin: 0; }

.w3-list { display: flex; flex-direction: column; }
.w3-sec {
  padding: 34px 0;
  border-top: 1px solid var(--border);
}
.w3-list .w3-sec:first-child { border-top: none; padding-top: 30px; }
.w3-index {
  color: var(--green-dimmer);
  font-size: 40px;
  font-weight: 700;
  line-height: 1;
  margin-bottom: 8px;
}
.w3-sec h3 {
  font-size: clamp(19px, 2.2vw, 23px);
  margin: 0 0 10px;
  color: #eaf3fb;
  letter-spacing: -.2px;
}
.w3-sec p {
  color: var(--green);
  font-size: 14px;
  margin: 0 0 16px;
}
/* inline links in the 3D copy read clearly as links (the global reset strips
   underlines): bright accent colour + underline. */
.w3-sec p a,
.w3-head .lede a {
  color: var(--green-hi);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
.w3-sec p a:hover,
.w3-head .lede a:hover { color: #eaf3fb; }

/* shortcut hint line: small phosphor key caps grouped with their labels,
   reusing the .kbd-combo cap look. Each .w3-key keeps its caps + label from
   breaking apart when the row wraps. */
.w3-keys {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin: 0 0 18px;
  font-size: 12.5px;
  color: var(--green-dim);
}
.w3-key {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.w3-keys kbd,
.w3-legend-keys kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.6em;
  height: 1.6em;
  padding: 0 .45em;
  border: 1px solid var(--border-hi);
  border-bottom-width: 2px;
  border-radius: 6px;
  background: rgba(77, 200, 245, .07);
  box-shadow: inset 0 1px 0 rgba(102, 217, 255, .12);
  color: var(--green-hi);
  font: 600 12px/1 var(--mono);
}

/* Full shortcut reference — mirrors the app's in-world legend panels, filling
   out the right column below the showcase sections and doubling as a real
   cheat-sheet. One bordered card per legend mode, each grouped into titled
   sections divided by hairlines. */
.w3-legend {
  margin-top: 42px;
  padding-top: 32px;
  border-top: 1px solid var(--border-hi);
}
.w3-legend > h3 {
  font-size: clamp(19px, 2.2vw, 23px);
  margin: 0 0 8px;
  color: #eaf3fb;
  letter-spacing: -.2px;
}
.w3-legend-lede {
  color: var(--green-dim);
  font-size: 13px;
  margin: 0 0 20px;
}
.w3-legend-mode {
  margin-top: 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--panel);
  overflow: hidden;
}
.w3-legend-mode > h4 {
  margin: 0;
  padding: 8px 14px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.5px;
  color: var(--green-dim);
}
.w3-legend-body { padding: 2px 14px 8px; }
.w3-legend-sec { padding: 9px 0 1px; }
.w3-legend-sec + .w3-legend-sec { border-top: 1px solid var(--border); }
.w3-legend-sec-title {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--green-dim);
  opacity: .85;
  margin-bottom: 7px;
}
.w3-legend-row {
  display: grid;
  grid-template-columns: 114px 1fr;
  gap: 6px 12px;
  align-items: baseline;
  margin: 0 0 5px;
}
.w3-legend-keys {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.w3-legend-desc {
  color: var(--green-dim);
  font-size: 12.5px;
  line-height: 1.45;
}

/* animated GIF frame — click-to-zoom via the shared [data-full] lightbox */
.w3-shot { margin: 0; }
.w3-zoom {
  display: block;
  position: relative;
  z-index: 3;                     /* above the scanline overlay (2) */
  width: 100%;
  padding: 8px;
  border: 1px solid var(--green-dim);
  border-radius: 14px;
  overflow: hidden;
  background: #000;
  cursor: zoom-in;
  box-shadow: 0 20px 50px rgba(0,0,0,.45), 0 0 22px rgba(77,200,245,.10);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.w3-zoom:hover,
.w3-zoom:focus-visible {
  border-color: var(--green);
  box-shadow: 0 22px 56px rgba(0,0,0,.5), 0 0 30px rgba(77,200,245,.15);
  outline: none;
}
.w3-zoom img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
}

/* stack the two columns on narrow viewports */
@media (max-width: 900px) {
  .about-split {
    grid-template-columns: 1fr;
    padding: 44px 18px 40px;
    gap: 8px;
  }
  .about-3d { margin-top: 8px; }
}

/* ---------- lightbox (full-size screenshot modal) ---------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 10001;            /* above the nav (9000) and progress bar (10000) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(4, 9, 16, .82);
  backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity .2s ease;
}
.lightbox[hidden] { display: none; }
.lightbox.open { opacity: 1; }
.lightbox-img {
  /* size to the viewport so the whole screenshot always fits */
  max-width: calc(100vw - 48px);
  max-height: calc(100vh - 48px);
  width: auto;
  height: auto;
  object-fit: contain;
  border: 1px solid var(--border-hi);
  border-radius: 10px;
  box-shadow: 0 30px 90px rgba(0,0,0,.7);
}
.lightbox-close {
  position: fixed;
  top: max(14px, env(safe-area-inset-top));
  right: max(14px, env(safe-area-inset-right));
  z-index: 1;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  line-height: 1;
  color: var(--green-hi);
  background: var(--panel-2);
  border: 1px solid var(--border-hi);
  border-radius: 50%;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.lightbox-close:hover,
.lightbox-close:focus-visible {
  background: var(--border-hi);
  color: #062033;
  outline: none;
}

/* ---------- form thank-you modal ---------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 10001;            /* same layer as the lightbox */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(4, 9, 16, .82);
  backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity .2s ease;
}
.modal[hidden] { display: none; }
.modal.open { opacity: 1; }
.modal-card {
  width: min(440px, 100%);
  box-shadow: 0 30px 90px rgba(0,0,0,.7);
  transform: translateY(8px) scale(.98);
  transition: transform .2s ease;
}
.modal.open .modal-card { transform: none; }
.modal-body { position: relative; padding: 30px 28px 28px; text-align: center; }
.modal-title {
  margin: 6px 0 10px;
  color: #eaf3fb;
  font-size: 22px;
  letter-spacing: -.2px;
}
.modal-text {
  margin: 0 auto 22px;
  max-width: 42ch;
  color: var(--green);
  font-size: 14.5px;
  line-height: 1.65;
}
.modal-ok { align-self: center; }
.modal-close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  line-height: 1;
  color: var(--green-dim);
  background: transparent;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.modal-close:hover,
.modal-close:focus-visible {
  color: var(--green-hi);
  background: rgba(77,200,245,.1);
  outline: none;
}

/* ---------- CTA ---------- */
.cta {
  max-width: 760px;
  margin: 60px auto;
  padding: 56px 28px;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: 16px;
  background:
    radial-gradient(120% 120% at 50% 0%, rgba(77,200,245,.07), transparent 60%),
    var(--panel);
}
.cta h2 {
  font-size: clamp(26px, 4vw, 38px);
  margin: 0 0 10px;
  color: #eaf3fb;
}
.cta p { color: var(--green-dim); margin: 0 0 26px; }
.cta .hero-cta { justify-content: center; }

/* ---------- LIVE DEMO PAGE / EMBEDDED ISSUES PAGE ---------- */
/* Both are chromeless: while one is active (script.js toggles
   body.demo-active / body.issues-active) the page stops scrolling and the
   embedded client fills everything below the sticky nav. */
body.demo-active,
body.issues-active,
body.discuss-active {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}
body.demo-active main,
body.issues-active main,
body.discuss-active main { flex: 1; min-height: 0; }
#page-demo.is-active,
/* Both tabs that frame the tracker need to be full height, or the iframe's
   `height: 100%` resolves against a page box that only wraps its content and
   the frame collapses. #page-discuss is only an embed when the forum master
   toggle is on the URL; without it the page renders the GitHub placeholder,
   which is ordinary flow content and unaffected by this. */
#page-issues.is-active,
#page-discuss.is-active { height: 100%; }
.demo, .issues { height: 100%; }
.demo iframe,
.issues iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
.demo iframe { background: #fff; /* the client paints its own theme over this */ }
/* The tracker's page background is transparent so this page shows through the
   frame with no seam; the frame itself carries the ground colour. White (as
   the demo uses) would flash on load against this dark page. */
.issues iframe { background: var(--bg); }

/* ---------- DOWNLOAD PAGE ---------- */
.dl {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 72px 20px 40px;
}
.dl-head { text-align: center; margin-bottom: 44px; }
.dl-head h1 { color: #eaf3fb; }
.dl-head .lede { margin-left: auto; margin-right: auto; }
.dl-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}
.dl-card { display: flex; flex-direction: column; }
/* The mobile cards (iOS, Android) stack in the right column, leaving macOS a
   single-row-height card in the left column (same height as the iOS box). */
.dl-grid .dl-card:not(.term-focused) { grid-column: 2; }
/* The star card fills the empty cell under macOS (left column, second row),
   overriding the rule above that pushes non-focused cards to column 2. */
.dl-grid .dl-card.dl-star { grid-column: 1; grid-row: 2; }
/* The star card holds two CTAs on one row at the card base: Star on GitHub on
   the left, Get in touch pushed to the lower-right via space-between. */
.dl-star-actions {
  margin-top: auto;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}
.dl-star .dl-star-actions .btn { margin-top: 0; align-self: center; }
.dl-card .term-bar { flex: none; }
.dl-body {
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}
/* Platform name + version badge on the left, the small "Changelog" text link
   pushed to the far right of the same row. */
.dl-plat-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
}
.dl-plat {
  font-size: 22px;
  color: #eaf3fb;
  font-weight: 700;
  letter-spacing: -.2px;
}
.dl-ver { color: var(--green-dim); font-size: 13px; }
.dl-body p { color: var(--green); margin: 4px 0 0; font-size: 14px; }
/* Card base row: the download/CTA button on the left, the "Version log" link
   pushed to the lower-right corner via space-between. Pinned to the card base
   with margin-top:auto so cards of differing copy length stay aligned. */
.dl-foot {
  margin-top: auto;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}
.dl-foot .btn { align-self: center; margin-top: 0; }
/* High-contrast "source" pill beside the download button; space-between in
   .dl-foot pushes it to the far right of the row. Bordered + tinted so it
   reads as meaningful info, not skippable metadata. */
.dl-src {
  color: var(--green);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .2px;
  white-space: nowrap;
  padding: 5px 11px;
  border: 1px solid var(--border-hi);
  border-radius: 7px;
  background: rgba(77, 200, 245, .06);
}
.dl-src-note { color: var(--green-dim); font-weight: 500; }
.dl-src-arrow { opacity: .7; }
/* Small, borderless "Changelog" text link, pushed to the far right of the
   platform row. */
.dl-vlog {
  margin-left: auto;
  color: var(--green-dim);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .2px;
  white-space: nowrap;
  padding: 4px 10px;
  border: 1px solid var(--border-hi);
  border-radius: 7px;
  transition: color .2s, border-color .2s, background .2s;
}
.dl-vlog:hover {
  color: var(--green);
  border-color: var(--green-dim);
  background: rgba(77,200,245,.06);
}
.dl-note {
  margin: 36px auto 0;
  max-width: 60ch;
  text-align: center;
  color: var(--green-dim);
  font-size: 13px;
}
.dl-note code { color: var(--green); }
.dl-note a {
  color: var(--green);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color .15s;
}
.dl-note a:hover { color: var(--green-hi); }
/* Page footer notes: an inline link should read as part of the sentence, not
   brighter than the surrounding text. */
.dl-note.reveal a { color: inherit; }
.dl-note.reveal a:hover { color: var(--green); }

/* ---------- pages: per-platform version logs ---------- */
/* A single centered terminal card listing releases newest-first. */
.vlog-card { max-width: 640px; margin: 0 auto; }
.vlog-body { gap: 28px; }
.vlog-release { display: flex; flex-direction: column; gap: 10px; }
/* A subtle divider between releases (skipped above the first one). */
.vlog-release + .vlog-release {
  padding-top: 26px;
  border-top: 1px solid rgba(77,200,245,.14);
}
.vlog-rel-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
}
.vlog-ver {
  margin: 0;
  font-size: 18px;
  color: #eaf3fb;
  font-weight: 700;
  letter-spacing: -.2px;
}
.vlog-date {
  color: var(--green-dim);
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.vlog-list {
  margin: 0;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.vlog-list li {
  color: var(--green);
  font-size: 14px;
  line-height: 1.5;
}
.vlog-list li::marker { color: var(--green-dim); }

/* ---------- page: news ---------- */
/* Reuses the version-log terminal card; each item is a .vlog-release with a
   body paragraph and an optional "Learn more" button. */
.news-card { max-width: 640px; }
.news-text {
  margin: 0;
  color: var(--green);
  font-size: 14px;
  line-height: 1.6;
}
.news-actions { margin-top: 2px; }
/* Keep the button hugging its text rather than stretching the card width. */
.news-more { align-self: flex-start; }
.news-status {
  margin: 0;
  color: var(--green-dim);
  font-size: 14px;
}

/* ---------- page: android access form ---------- */
/* A single centered card rather than the download grid. */
.form-card { max-width: 520px; margin: 0 auto; }
.form-body { gap: 18px; }
.form-field { display: flex; flex-direction: column; gap: 7px; }
.form-label {
  color: var(--green-dim);
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.form-body input,
.form-body textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 11px 13px;
  font: inherit;
  font-size: 14px;
  color: #eaf3fb;
  background: rgba(77,200,245,.04);
  border: 1px solid rgba(77,200,245,.22);
  border-radius: 8px;
  transition: border-color .2s, box-shadow .2s, background .2s;
}
.form-body textarea { resize: vertical; min-height: 110px; }
.form-body input:focus,
.form-body textarea:focus {
  outline: none;
  border-color: var(--green);
  background: rgba(77,200,245,.07);
  box-shadow: 0 0 0 3px rgba(77,200,245,.12);
}
.form-body .btn { align-self: flex-start; margin-top: 4px; }
/* Inline submission error, shown above the fields on a failed POST. Stays
   collapsed until script.js fills it with a message. */
.form-error-summary { font-size: 14px; line-height: 1.5; }
.form-error-summary:not(:empty) {
  padding: 11px 13px;
  border-radius: 8px;
  color: #ffb4b4;
  background: rgba(255,120,120,.07);
  border: 1px solid rgba(255,120,120,.28);
}
.form-back { margin-top: 22px; }
.form-back a { color: var(--green); text-decoration: none; }
.form-back a:hover { text-decoration: underline; }

@media (max-width: 820px) {
  .dl { padding: 44px 18px 28px; }
  .dl-grid { grid-template-columns: 1fr; }
  .dl-grid .dl-card:not(.term-focused) { grid-column: auto; }
}

/* ---------- credits: Framna studio block ---------- */
/* Logo + blurb that closes the credits page. */
.framna-block {
  text-align: center;
  margin: 28px auto 0;
}
.framna-logo {
  display: flex;
  justify-content: center;
  margin: 4px auto 14px;
  color: var(--green-hi);
  transition: opacity .2s;
}
.framna-logo:hover { opacity: .82; }
.framna-wordmark {
  width: min(340px, 72%);
  height: auto;
  color: inherit;
  filter: drop-shadow(0 0 22px rgba(77,200,245,.18));
}
/* The Framna mark, used as the Framna row's icon. It is a logo rather than
   one of the drawn 16×16 outlines, so it takes the icon slot's 16px box and
   lets the SVG's own preserveAspectRatio centre it there — a hair shorter
   than the drawn set, which keeps it from out-weighing them. */
.nav-link .framna-symbol {
  display: block;
  height: 15px;
  color: inherit;
}
.framna-body {
  max-width: 60ch;
  margin: 0 auto;
  color: var(--green-dim);
  font-size: 15px;
  line-height: 1.7;
}
/* Links in the blurb (e.g. Framna cases) keep the surrounding text color so
   they don't stand out — only the underline signals they're links. */
.framna-body a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color .15s;
}
.framna-body a:hover { color: var(--green-hi); }
/* The three call-to-action points beneath the blurb, as a card grid that
   borrows the bordered-panel look used by the screenshot frames elsewhere. */
.framna-points {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  max-width: 760px;
  margin: 26px auto 0;
}
.framna-card {
  display: flex;
  flex-direction: column;
  padding: 18px 20px 20px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  text-align: left;
  color: var(--green-dim);
  text-decoration: none;
  transition: border-color .2s, box-shadow .2s, transform .2s;
}
.framna-card:hover {
  border-color: var(--border-hi);
  box-shadow: 0 0 0 1px var(--border-hi), 0 18px 50px rgba(0,0,0,.5);
  transform: translateY(-2px);
}
.framna-card-label {
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--green-hi);
  opacity: .85;
}
.framna-card-body {
  margin-top: 12px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--green-dim);
}
/* Pin the link/CTA to the bottom so cards of uneven copy stay aligned. */
.framna-card-link {
  margin-top: auto;
  padding-top: 16px;
  font-size: 14px;
  color: var(--green);
}
.framna-card:hover .framna-card-link { color: var(--green-hi); }
.framna-card-arrow {
  display: inline-block;
  transition: transform .2s;
}
.framna-card:hover .framna-card-arrow { transform: translateX(3px); }

@media (max-width: 680px) {
  .framna-points {
    grid-template-columns: 1fr;
    max-width: 60ch;
    gap: 12px;
  }
}
.framna-disclaimer {
  max-width: 60ch;
  margin: 18px auto 0;
  padding-top: 18px;
  color: var(--green);
  opacity: .85;
  font-size: 11px;
  line-height: 1.6;
}

/* Inline app-icon chip in running copy — the real toolbar glyph rendered as a
   small phosphor mark so the prose matches what the user sees. Used by the
   version changelog; the manual has its own .docs-icon variant. */
.inline-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: -0.25em;
  margin: 0 0.15em;
  color: var(--green-hi);
}
.inline-icon svg { height: 16px; width: auto; display: block; }

/* ---------- docs: the twisty on the contents disclosure ---------- */
/* Inherited from the retired Q&A tree, which used the same chip to expand a
   node. Only the manual's collapsible contents uses it now. */
.docs-tw {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  border: 1px solid var(--border-hi);
  border-radius: 5px;
  color: var(--green);
  font-size: 9px;
  line-height: 1;
  transition: transform .18s ease, color .15s, background .15s, border-color .15s;
}

/* ---------- docs: attributed pull quote ---------- */
/* A big phosphor opening quote mark, gently emphasised text, and an
   attribution footer. Also inherited from the retired Q&A page. */
.docs-quote {
  position: relative;
  margin: 10px 0 2px;
  padding: 14px 18px 16px 52px;
  border: 1px solid var(--border-hi);
  border-radius: 10px;
  background: rgba(77, 200, 245, 0.045);
  color: var(--green);
  font-style: italic;
}
.docs-quote::before {
  content: "\201C";
  position: absolute;
  top: 0.06em;
  left: 12px;
  font-style: normal;
  font-size: 56px;
  line-height: 1;
  color: var(--green-hi);
  opacity: 0.5;
}
.docs-quote p { margin: 0 0 0.9em; }
.docs-quote p:last-of-type { margin-bottom: 0; }
.docs-quote-by {
  margin-top: 1em;
  font-style: normal;
  color: var(--green-dim);
  font-size: 13.5px;
  letter-spacing: 0.02em;
}
.docs-quote-by::before { content: "— "; }

/* ---------- page: credits ---------- */
.credits-grid {
  max-width: var(--maxw);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}
/* Credits layout: "Made by" and "Inspired by" stack in the left column;
   "Built with" fills the right column across both rows. The spanning box
   stretches the left rows so the stacked pair matches its height. */
.credits-page .credit-group:nth-child(1) { grid-column: 1; grid-row: 1; }   /* Made by */
.credits-page .credit-group:nth-child(2) { grid-column: 1; grid-row: 2; }   /* Inspired by */
.credits-page .credit-group:nth-child(3) { grid-column: 2; grid-row: 1 / span 2; } /* Built with */
/* Contributors page: a single full-width box. */
.contributors-page .credits-grid { grid-template-columns: 1fr; }
.credit-group {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 22px 24px;
  display: flex;
  flex-direction: column;
}
.credit-title {
  margin: 0 0 14px;
  color: var(--green-dim);
  font-size: 12px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.credit-blurb {
  margin: -6px 0 14px;
  color: var(--green-dim);
  font-size: 13px;
  line-height: 1.5;
}
/* Sub-heading for a section nested inside a credit box (e.g. "Feedback"). */
.credit-subtitle {
  margin: 22px 0 14px;
  color: var(--green-dim);
  font-size: 12px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.credit-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.credit-item { display: flex; flex-direction: column; gap: 2px; }
/* Name paired with a chip tagging how the person helped. */
.credit-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.credit-chip {
  color: var(--green-dim);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .5px;
  text-transform: uppercase;
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
}
.credit-name, .credit-link { color: #eaf3fb; font-size: 15px; font-weight: 600; }
.credit-link {
  align-self: flex-start;
  border-bottom: 1px solid var(--border-hi);
  transition: color .15s, border-color .15s;
}
.credit-link:hover { color: var(--green-hi); border-color: var(--green-hi); }
.credit-role { color: var(--green-dim); font-size: 13px; }
/* CTA button anchored to the box's lower-left; margin-top:auto pushes it to the
   bottom of the (stretched) credit-group box. */
.credit-actions {
  margin-top: auto;
  padding-top: 18px;
  /* Full width so item buttons stay on the left while a trailing group
     button (e.g. "Contributors") is pushed to the box's far right. */
  align-self: stretch;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px;
}
.credit-actions .btn { margin-top: 0; }
@media (max-width: 820px) {
  .credits-grid { grid-template-columns: 1fr; }
  .credits-page .credit-group:nth-child(1),
  .credits-page .credit-group:nth-child(2),
  .credits-page .credit-group:nth-child(3) { grid-column: auto; grid-row: auto; }
}

/* ---------- LEGAL PAGES (privacy.html / terms.html) ----------
   These two are not part of the single-page app: they are plain documents
   with their text in the HTML, so they keep working with JS off and stay
   fetchable at a stable URL (the app stores link straight to them). They
   borrow the app's chrome and type, and lay the copy out in a .term panel
   like the Discuss page does. */
.legal-page {
  max-width: 860px;
  margin: 0 auto;
  padding: 72px 20px 48px;
}
.legal-head { text-align: center; margin-bottom: 36px; }
/* Shown while a legal tab is fetching its page, and if that fetch fails. */
.legal-status { color: var(--green-dim); text-align: center; padding: 40px 0; }
.legal-status a { color: var(--green-hi); text-decoration: underline; }
.legal-head h1 { margin-bottom: 12px; }
.legal-updated {
  color: var(--green-dim);
  font-size: 13px;
  margin: 0;
}
.legal-body { padding: 34px 36px 38px; }
/* The document's own headings. First one has no rule above it — it opens the
   panel rather than dividing it. */
.legal-body h2 {
  font-size: 17px;
  color: #eaf3fb;
  margin: 34px 0 12px;
  padding-top: 22px;
  border-top: 1px solid var(--border);
}
.legal-body h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.legal-body p { margin: 0 0 14px; }
.legal-body strong { color: var(--green-hi); font-weight: 600; }
.legal-body a { color: var(--green-hi); text-decoration: underline; }
.legal-body a:hover { text-shadow: 0 0 18px var(--glow); }
.legal-body ul { padding-left: 20px; margin: 0 0 14px; }
.legal-body li { margin-bottom: 8px; }
.legal-body code {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: .1em .4em;
  font-size: .9em;
}
/* The one-paragraph plain-language version, up top: the part most people
   actually read, so it gets the accent rule and a lift off the panel. */
.legal-summary {
  border-left: 2px solid var(--green-hi);
  background: rgba(77, 200, 245, .06);
  border-radius: 0 8px 8px 0;
  padding: 16px 18px;
  margin: 0 0 26px;
}
@media (max-width: 640px) {
  .legal-page { padding-top: 48px; }
  .legal-body { padding: 26px 22px 28px; }
}

/* ---------- reveal animation ---------- */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .7s ease, transform .7s cubic-bezier(.2,.7,.2,1);
}
.feature[data-side="left"].reveal  { transform: translateX(-40px); }
.feature[data-side="right"].reveal { transform: translateX(40px); }
/* the centered, screenshot-free section rises straight up instead */
.feature.feature-noshot.reveal { transform: translateY(28px); }
.reveal.visible { opacity: 1; transform: none; }
/* The side selectors above are more specific (0,3,0) than `.reveal.visible`
   (0,2,0), so without this the revealed end-state never clears their transform:
   the feature stays offset AND its lingering transform forms a stacking context
   that traps the shot's z-index:3 below the scanline overlay (z-index 2), banding
   light screenshots. Match their specificity so `visible` actually wins. */
.feature[data-side="left"].reveal.visible,
.feature[data-side="right"].reveal.visible { transform: none; }

/* ---------- responsive ---------- */
@media (max-width: 820px) {
  .hero { padding: 48px 18px 36px; }
  .hero-grid { grid-template-columns: 1fr; gap: 36px; }
  .feature,
  .feature[data-side="right"] { grid-template-columns: 1fr; gap: 28px; }
  .feature[data-side="right"] .feature-copy,
  .feature[data-side="right"] .shot { order: initial; }
  .features { gap: 64px; }
  .feature-index { font-size: 44px; }
  .feature[data-side="left"].reveal,
  .feature[data-side="right"].reveal { transform: translateY(28px); }
}

/* ---------- reduced motion: show everything, kill animation ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1 !important; transform: none !important; transition: none; }
  .page.is-active { animation: none; }
  .progress { transition: none; }
  .brand .dot { animation: none; }
  .btn:hover { transform: none; }
}

/* ============================================================
   DOCS — the manual (#/docs)
   ------------------------------------------------------------
   Two-column: a sticky table of contents on the left, the
   article on the right. The TOC mirrors SITE.docs.sections and
   is scroll-spied by script.js, which boxes the entry you're
   currently reading. Below 900px the columns stack and the TOC
   becomes a collapsible <details> above the article.
   ============================================================ */
/* Tighter gutters than the rest of the site: this is a two-column reading
   page, so the width is better spent on the contents rail and the article
   than on empty margin. */
.docs-page { max-width: 1180px; padding-left: 10px; padding-right: 10px; }
.docs-layout {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 44px;
  align-items: start;
}

/* ---------- table of contents ---------- */
.docs-toc-wrap {
  position: sticky;
  /* clears the sticky nav */
  top: 62px;
  max-height: calc(100vh - 84px);
  overflow-y: auto;
  padding-right: 6px;
  /* a hairline rule separating the TOC from the article */
  border-right: 1px solid var(--border);
}
/* Slim, unobtrusive scrollbar — the default one is a heavy grey slab
   against the navy. */
.docs-toc-wrap::-webkit-scrollbar { width: 8px; }
.docs-toc-wrap::-webkit-scrollbar-thumb {
  background: var(--green-dimmer);
  border-radius: 4px;
}
.docs-toc-wrap::-webkit-scrollbar-thumb:hover { background: var(--green-dim); }
.docs-toc-list,
.docs-toc-sublist { list-style: none; margin: 0; padding: 0; }
.docs-toc-group { margin-bottom: 18px; }
.docs-toc-sublist { margin: 4px 0 0; }
.docs-toc-link {
  display: block;
  padding: 5px 8px 5px 5px;
  border-left: 2px solid transparent;
  color: var(--green-dim);
  font-size: 13px;
  line-height: 1.45;
  transition: color .15s, border-color .15s, background .15s;
}
.docs-toc-link:hover {
  color: var(--green);
  background: rgba(77, 200, 245, .05);
}
/* Top-level entries read as headers: brighter, uppercase, tracked out. */
.docs-toc-top {
  color: #eaf3fb;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .8px;
  text-transform: uppercase;
}
.docs-toc-sub { padding-left: 13px; }
/* The section currently in the viewport (set by script.js). */
.docs-toc-link.active {
  color: var(--green-hi);
  border-left-color: var(--green-hi);
  background: rgba(77, 200, 245, .07);
}

/* ---------- article ---------- */
.docs-body { min-width: 0; max-width: 88ch; }
.docs-section { padding-bottom: 20px; }
.docs-section + .docs-section {
  margin-top: 46px;
  padding-top: 40px;
  border-top: 1px solid var(--border-hi);
}
.docs-h2 {
  /* the sticky nav is ~44px; keep deep-linked headings clear of it */
  scroll-margin-top: 70px;
  margin: 0 0 10px;
  color: #eaf3fb;
  font-size: clamp(22px, 2.6vw, 27px);
  letter-spacing: .2px;
}
.docs-sub { scroll-margin-top: 70px; margin-top: 34px; }
.docs-h3 {
  scroll-margin-top: 70px;
  margin: 0 0 10px;
  color: var(--green-hi);
  font-size: 16.5px;
  letter-spacing: .2px;
}
/* The "#" self-link, revealed on heading hover. */
.docs-anchor {
  margin-left: 10px;
  color: var(--green-dimmer);
  font-size: .75em;
  opacity: 0;
  transition: opacity .15s, color .15s;
}
.docs-h2:hover .docs-anchor,
.docs-h3:hover .docs-anchor { opacity: 1; }
.docs-anchor:hover { color: var(--green-hi); }
.docs-anchor:focus-visible { opacity: 1; }
.docs-intro {
  margin: 0 0 18px;
  color: var(--green);
  font-size: 15px;
  line-height: 1.75;
}
.docs-body p {
  color: var(--green-dim);
  font-size: 14.5px;
  line-height: 1.75;
}
.docs-body strong { color: var(--green); font-weight: 600; }
.docs-body code { color: var(--green); }
/* Cross-references between sections, underlined so they're findable in prose. */
.docs-body a:not(.docs-anchor):not(.docs-shot-zoom) {
  color: var(--green);
  border-bottom: 1px solid var(--border-hi);
  transition: color .15s, border-color .15s;
}
.docs-body a:not(.docs-anchor):not(.docs-shot-zoom):hover,
.docs-body a:not(.docs-anchor):not(.docs-shot-zoom):focus-visible {
  color: var(--green-hi);
  border-bottom-color: var(--green-hi);
}

/* ---------- lists ---------- */
.docs-ul {
  margin: 0 0 16px;
  padding-left: 18px;
  color: var(--green-dim);
  font-size: 14.5px;
  line-height: 1.75;
}
.docs-ul li { margin-bottom: 6px; }
.docs-ul li::marker { color: var(--green-dimmer); }
/* Labelled list — same "key + description" shape as the About bullets. */
.docs-kv {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: grid;
  gap: 9px;
}
/* Two columns per row: the term, then its description. Laid out as flex rather
   than leaving the description inline, so a description that wraps stays inside
   its own column instead of running back under the term. */
.docs-kv li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  color: var(--green-dim);
  font-size: 14.5px;
  line-height: 1.7;
}
.docs-kv-v { flex: 1 1 auto; min-width: 0; }
/* The term being defined. Deliberately NOT on the cyan accent ramp: the accent
   belongs to links and inline app icons, and a term tinted the same competes
   with the links sitting right beside it in its own description. Weight does
   the separating instead — bold against the regular-weight definition — so the
   column still scans as a column without shouting. */
.docs-kv-k {
  flex: 0 0 auto;
  min-width: 82px;
  color: #cfe0ee;
  font-weight: 700;
}

/* ---------- shortcut tables ---------- */
.docs-keys {
  margin: 0 0 18px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel);
}
.docs-keys-title {
  margin: 0 0 10px;
  color: var(--green-dim);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.docs-keys-grid { display: grid; gap: 2px; }
.docs-key-row {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  padding: 5px 0;
}
.docs-key-row + .docs-key-row { border-top: 1px solid rgba(77, 200, 245, .07); }
.docs-key-caps { display: inline-flex; gap: 4px; flex-wrap: wrap; }
/* Same phosphor keycaps as the 3D shortcut deck. */
.docs-key-caps kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.6em;
  height: 1.6em;
  padding: 0 .45em;
  border: 1px solid var(--border-hi);
  border-bottom-width: 2px;
  border-radius: 6px;
  background: rgba(77, 200, 245, .07);
  box-shadow: inset 0 1px 0 rgba(102, 217, 255, .12);
  color: var(--green-hi);
  font: 600 12px/1 var(--mono);
}
.docs-key-desc { color: var(--green-dim); font-size: 13.5px; line-height: 1.5; }

/* ---------- callouts ---------- */
/* "Under the hood" asides: a left rule and a small tag, so they read as an
   aside you can skip without losing the thread. */
.docs-note {
  margin: 0 0 18px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-left: 2px solid var(--green-hi);
  border-radius: 0 10px 10px 0;
  background: rgba(77, 200, 245, .04);
}
.docs-note--warn {
  border-left-color: var(--yellow);
  background: rgba(254, 188, 46, .05);
}
.docs-note-tag {
  display: block;
  margin-bottom: 5px;
  color: var(--green-hi);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.docs-note--warn .docs-note-tag { color: var(--yellow); }
.docs-note-body { color: var(--green-dim); font-size: 14px; line-height: 1.7; }
.docs-note-body p { margin: 0 0 .7em; font-size: 14px; }
.docs-note-body p:last-child { margin-bottom: 0; }

/* ---------- screenshots ---------- */
/* Frameless, like the About page's .shot-zoom: a simple bordered slot with the
   image inset, and no fake window chrome. Every shot in the manual is already
   a picture of a window (or a phone), so a drawn-on title bar would just nest
   one set of traffic lights inside another. Unlike the About page this slot
   has no fixed aspect-ratio — the manual mixes wide desktop captures with tall
   phone ones — so the image keeps its own shape and only its height is capped. */
.docs-shot { margin: 0 0 22px; }
.docs-shot-zoom {
  display: block;
  position: relative;
  z-index: 3;                     /* above the scanline overlay (2), as on About */
  /* The frame hugs the picture rather than filling the column: the manual mixes
     wide desktop captures with tall portrait phone ones, and a full-width box
     around a phone screenshot is mostly empty panel. */
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
  padding: 12px;
  border: 1px solid var(--green-dim);
  border-radius: 14px;
  background: var(--panel);
  cursor: zoom-in;
  overflow: hidden;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .4), 0 0 20px rgba(77, 200, 245, .08);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.docs-shot-zoom:hover,
.docs-shot-zoom:focus-visible {
  border-color: var(--green);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .5), 0 0 28px rgba(77, 200, 245, .14);
  outline: none;
}
/* Capped and centred so a portrait phone capture doesn't run to twice the
   height of the reading column; wide captures still fill the slot. */
.docs-shot-zoom img {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 520px;
  height: auto;
  margin: 0 auto;
  border-radius: 6px;
}
.docs-shot figcaption {
  margin-top: 8px;
  color: var(--green-dim);
  font-size: 12.5px;
  line-height: 1.6;
}

/* ---------- stacked layout ---------- */
@media (max-width: 900px) {
  .docs-layout { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .docs-toc-wrap {
    position: static;
    max-height: none;
    overflow: visible;
    padding: 0;
    border-right: 0;
    border-bottom: 1px solid var(--border-hi);
    padding-bottom: 18px;
  }
  .docs-key-row { grid-template-columns: minmax(0, 1fr); gap: 4px; }
}

/* The TOC's <details> wrapper: on desktop it's always open and its summary is
   hidden, so the nav reads as a plain sidebar. The summary only appears in the
   stacked layout below. */
.docs-toc-details > summary { display: none; }
.docs-toc-summary {
  list-style: none;
  cursor: pointer;
  align-items: center;
  gap: 10px;
  padding: 10px 2px;
  color: #eaf3fb;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.docs-toc-summary::-webkit-details-marker { display: none; }
.docs-toc-details[open] > .docs-toc-summary .docs-tw { transform: rotate(90deg); }

@media (max-width: 900px) {
  .docs-toc-details > summary { display: flex; }
}

/* Inline app icon in docs prose — the real glyph from the app, rendered as a
   small phosphor chip so a sentence naming a button shows that button. Same
   The SVG inherits the text color via
   currentColor, so it brightens with headings and links around it. */
.docs-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: -0.25em;
  margin: 0 0.15em;
  color: var(--green-hi);
}
.docs-icon svg { height: 16px; width: auto; display: block; }
/* In a labelled list the key column is already accent-colored and tight on
   space, so an icon there sits a touch smaller and inherits the label color. */
.docs-kv-k .docs-icon { color: inherit; margin: 0 0.1em; }
.docs-kv-k .docs-icon svg { height: 14px; }

/* A labelled-list row whose key is only an icon (the top-bar tour). The wide
   text column would leave the glyph marooned in whitespace, so the key shrinks
   to the icon and the description follows straight after. The icon keeps its
   accent here — it's carrying the row on its own, with no word beside it. */
.docs-kv-icon .docs-kv-k {
  /* just wide enough to keep the glyphs in a column with each other — the
     82px text column would strand them in whitespace. */
  min-width: 22px;
  color: var(--green-hi);
}
.docs-kv-icon .docs-kv-k .docs-icon { margin: 0; }
.docs-kv-icon .docs-kv-k .docs-icon svg { height: 16px; }

/* Re-space the pull quote for the wider docs column. */
.docs-quote { margin: 0 0 20px; max-width: none; }
