/* ==========================================================================
   FILI — ink on graph paper.
   Every value is taken from the app mark (docs/icon-candidate/icon.svg): white
   paper, ink, two weights of rule blue, and one red flame. Blue is the paper's
   ruling, not a brand colour; red is the only saturated ink. The primary
   surface is ink on paper and inverts with the appearance, the way the icon
   does. Ships light and dark as equal citizens.

   The app has not been brought across yet — OgiveLog/Utilities/Theme.swift is
   still on the old cobalt-and-orange palette. When it moves, these values are
   the ones to port.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@500;600;700&family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap');

:root {
  color-scheme: light dark;

  /* Paper — light */
  --bg:        #F4F6FA;
  --card:      #FFFFFF;
  --fg:        #111318;
  --sec:       #545C6B;
  --ter:       #8A93A3;

  /* Graph paper. Rules are the icon's grid blue at hairline strength, so a
     divider reads as a ruling rather than a grey line drawn over the page. */
  --grid-major: #529FDD;
  --grid-minor: #A5D0EF;
  --rule:      rgba(82, 159, 221, 0.30);
  --rule-soft: rgba(82, 159, 221, 0.15);
  --grid:      rgba(82, 159, 221, 0.16);

  /* Rule blue as interactive ink — the same blue the paper is ruled in,
     darkened until it clears AA as text. It marks what can be touched; it
     never fills a hero surface. */
  --accent:      #1B6FB0;
  --accent-ink:  #1B6FB0;
  --accent-soft: rgba(82, 159, 221, 0.14);

  /* Flame — the one saturated ink, spent as sparingly as the icon spends it */
  --flame: #D0161D;
  --warm:  #C4421C;

  /* Two coloured pencils, for the notebook drawings only. Amber is weather;
     blue is what was predicted rather than measured. Both clear 3:1 on the
     sheet, which is what a drawn line needs. Neither is a UI colour. */
  --pencil-amber: #B8790A;
  --pencil-blue:  #2C6E9E;

  /* The primary surface: ink on paper, inverting with the appearance */
  --ink-fill:       #111318;
  --on-accent:      #FFFFFF;
  --on-accent-soft: rgba(255, 255, 255, 0.78);
  --on-accent-mut:  rgba(255, 255, 255, 0.52);   /* 5.67:1 on the ink fill */
  --on-accent-trk:  rgba(255, 255, 255, 0.20);

  /* Motor-class keys — graphite, rule blue, flame core, flame */
  --motor-fg: #5F6874;
  --motor-hi: #1B6FB0;
  --motor-jk: #C4421C;
  --motor-l:  #D0161D;

  /* Shape */
  --r-card: 16px;
  --r-hero: 18px;
  --r-btn:  14px;
  --r-thumb:10px;
  --r-pill: 4px;
  --hair: 0.5px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:        #0E0F11;
    --card:      #17191D;
    --fg:        #F5F5F2;
    --sec:       #9BA3AF;
    --ter:       #5C636D;

    --grid-major: #3D6180;
    --grid-minor: #2A3D4F;
    --rule:      rgba(61, 97, 128, 0.75);
    --rule-soft: rgba(42, 61, 79, 0.75);
    --grid:      rgba(61, 97, 128, 0.30);

    --accent:      #7CBDF0;
    --accent-ink:  #7CBDF0;
    --accent-soft: rgba(124, 189, 240, 0.16);

    --flame: #FF6B62;
    --warm:  #FF7A5E;

    --pencil-amber: #EFC15A;
    --pencil-blue:  #79B6E4;

    /* The sheet inverts: white ink on black paper, exactly as the dark icon does */
    --ink-fill:       #F5F5F2;
    --on-accent:      #111318;
    --on-accent-soft: rgba(17, 19, 24, 0.74);
    /* Ink at 0.52 composites to #7E7F81 on the paper fill — 3.67:1, under the
       4.5 small text needs, and the provenance labels are 8.5px. 0.62 clears it. */
    --on-accent-mut:  rgba(17, 19, 24, 0.62);
    --on-accent-trk:  rgba(17, 19, 24, 0.20);

    --motor-fg: #8A93A3;
    --motor-hi: #7CBDF0;
    --motor-jk: #FF7A5E;
    --motor-l:  #FF6B62;
  }
}

/* ---- Reset-ish base ---- */
* { box-sizing: border-box; }

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

body {
  font-family: 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  color: var(--fg);
  background: var(--bg);
  line-height: 1.6;
  margin: 0;
  font-feature-settings: "ss01" 1;
}

.mono {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', 'SFMono-Regular', Menlo, monospace;
}

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

a { color: var(--accent-ink); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Mono eyebrow — the signature "instrument label" */
.eyebrow {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--sec);
  margin: 0;
}
.eyebrow .accent { color: var(--accent-ink); }
.eyebrow .dot { color: var(--ter); padding: 0 0.35em; }

/* ==========================================================================
   Document pages (privacy / support / impressum) — spec-sheet styling
   ========================================================================== */

body.doc {
  max-width: 760px;
  margin: 0 auto;
  padding: 3.5rem 1.5rem 5rem;
}
body.doc h1 {
  font-size: clamp(1.7rem, 4vw, 2.2rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin: 0 0 0.4rem;
}
body.doc .updated {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 11px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--sec);
  margin: 0 0 1.5rem;
  padding-bottom: 1.5rem;
  border-bottom: var(--hair) solid var(--rule);
}
body.doc h2 {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 2.4rem 0 0.5rem;
}
body.doc h3 {
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  margin: 1.8rem 0 0.4rem;
}
body.doc p, body.doc li { color: var(--fg); }
body.doc ul { padding-left: 1.25rem; }
body.doc li { margin-bottom: 0.35rem; }
body.doc nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin: 0 0 2.5rem;
  padding-bottom: 1.25rem;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 11px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}
body.doc nav a { color: var(--sec); }
body.doc nav a:hover { color: var(--accent-ink); text-decoration: none; }
body.doc footer {
  margin-top: 4rem;
  padding-top: 1.5rem;
  border-top: var(--hair) solid var(--rule);
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 11px;
  letter-spacing: 0.6px;
  color: var(--ter);
}

/* ==========================================================================
   Landing page
   ========================================================================== */

.wrap {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

section { padding: 5rem 0; }

.section-head { max-width: 640px; margin: 0 0 2.5rem; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head h2 {
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.12;
  margin: 0.8rem 0 0.6rem;
}
.section-head p {
  color: var(--sec);
  font-size: 1.02rem;
  margin: 0;
}
/* A section whose label IS its heading. Without this the eyebrow renders at h2
   size, because `.section-head h2` outranks `.eyebrow` on specificity — only the
   properties that actually collide are restated, so the eyebrow rule still owns
   the family, colour and casing. Keeps the heading outline honest: the <h3>
   cases under it would otherwise hang off the previous section's <h2>. */
.section-head h2.eyebrow {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 1.4px;
  line-height: inherit;
  margin: 0;
}

/* ---- Header ---- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(140%) blur(12px);
  border-bottom: var(--hair) solid var(--rule);
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 60px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: -0.02em;
  color: var(--fg);
}
.brand:hover { text-decoration: none; }
.brand img { border-radius: 8px; display: block; }
.header-nav {
  display: flex;
  align-items: center;
  gap: 1.6rem;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 11px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}
.header-nav a { color: var(--sec); }
.header-nav a:hover { color: var(--fg); text-decoration: none; }
.header-nav .header-status {
  color: var(--ter);
  display: none;
}
@media (min-width: 720px) { .header-nav .header-status { display: inline; } }

/* Small phones: tighten the shell so brand + nav never overflow the viewport. */
@media (max-width: 480px) {
  .wrap { padding: 0 1.1rem; }
  .header-nav { gap: 0.85rem; font-size: 10px; letter-spacing: 0.4px; }
  .brand { font-size: 0.95rem; gap: 0.45rem; }
}

/* ---- Buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.25rem;
  border-radius: var(--r-btn);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  border: var(--hair) solid transparent;
  cursor: pointer;
  transition: transform 0.12s ease, background 0.2s ease, border-color 0.2s ease;
}
.btn:hover { text-decoration: none; }
.btn-primary {
  background: var(--ink-fill);
  color: var(--on-accent);
  box-shadow: 0 6px 20px rgba(17, 19, 24, 0.22);
}
.btn-primary:hover { transform: translateY(-1px); }
.btn-secondary {
  background: transparent;
  color: var(--fg);
  border-color: var(--rule);
}
.btn-secondary:hover { border-color: var(--accent-ink); color: var(--accent-ink); }

/* ---- Hero ---- */
.hero {
  position: relative;
  padding: 4.5rem 0 4rem;
  overflow: hidden;
}
/* faint hairline grid, like a logbook page */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--grid) var(--hair), transparent var(--hair)),
    linear-gradient(90deg, var(--grid) var(--hair), transparent var(--hair));
  background-size: 48px 48px;
  mask-image: radial-gradient(ellipse 80% 70% at 50% 30%, #000 40%, transparent 100%);
  pointer-events: none;
}
.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: 3rem;
  align-items: center;
}
@media (min-width: 900px) {
  .hero-grid { grid-template-columns: 1.05fr 0.95fr; gap: 3.5rem; }
}
.hero h1 {
  font-size: clamp(2.1rem, 5.4vw, 3.3rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.05;
  margin: 1rem 0 1.1rem;
}
/* The headline is the one place the page raises its voice, so it spends the
   flame rather than the rule blue — blue marks what can be touched, and a
   headline cannot be. */
.hero h1 .accent { color: var(--flame); }
.hero-sub {
  font-size: 1.08rem;
  color: var(--sec);
  max-width: 30rem;
  margin: 0 0 1.75rem;
}
.cta-row { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.hero-note {
  margin: 1.5rem 0 0;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 10.5px;
  letter-spacing: 0.4px;
  color: var(--ter);
  max-width: 30rem;
  line-height: 1.7;
}

/* ---- Flight card: the launch clip and the record it produced ----
   Replaces the invented instrument readout. The clip is the one asset a
   competitor cannot manufacture, so it sits in the hero's strongest slot and
   the record reads beside it rather than under it. */
.flight {
  position: relative;
  margin: 0;
  display: grid;
  /* Narrow first: the clip sits above the record, wide enough to read. It
     only moves beside it once there is room for both. */
  grid-template-columns: minmax(0, 1fr);
  gap: 1.1rem;
  align-items: stretch;
  background: var(--ink-fill);
  color: var(--on-accent);
  border-radius: var(--r-hero);
  padding: 1rem;
  overflow: hidden;
  box-shadow: 0 8px 28px rgba(17, 19, 24, 0.22);
}
@media (min-width: 460px) { .flight { grid-template-columns: minmax(0, 150px) minmax(0, 1fr); } }
@media (min-width: 760px) { .flight { grid-template-columns: minmax(0, 190px) minmax(0, 1fr); gap: 1.25rem; } }

/* The evidence column: the launch, the interval, the recovery. */
.flight-media { display: flex; flex-direction: column; gap: 0.5rem; min-width: 0; }

.flight-clip { position: relative; }

/* Pause control for the hero loop. Created by the same script that starts the
   clip, so the control exists exactly when the motion does — WCAG 2.2.2 wants a
   mechanism to stop motion that runs past five seconds, and a 2.4 s clip on
   loop does. It sits on photography in both appearances, so it is deliberately
   fixed rather than themed. */
.clip-toggle {
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
  background: rgba(10, 11, 13, 0.62);
  color: #FFFFFF;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition: background 0.15s ease;
}
.clip-toggle:hover { background: rgba(10, 11, 13, 0.82); }
.clip-toggle:focus-visible { outline: 2px solid #FFFFFF; outline-offset: 2px; }
.clip-toggle svg { display: block; width: 11px; height: 11px; fill: currentColor; }

.flight-clip,
.flight-recovery {
  border-radius: 12px;
  overflow: hidden;
  background: #0B0C0E;
  display: block;
  width: 100%;
}
.flight-clip { aspect-ratio: 4 / 3; }
/* Intrinsic ratio, with width/height on the tag so it reserves its space. */
.flight-recovery { height: auto; }

@media (min-width: 460px) {
  /* Beside the record there is height to spend, so the clip runs tall the way
     it was shot and the recovery frame sits under it as a band. */
  .flight-clip { aspect-ratio: 3 / 4; }
}

/* The interval between the two frames is the provenance, so it is set as a
   reading rather than a caption. */
.flight-gap {
  margin: 0;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 8.5px;
  letter-spacing: 1px;
  color: var(--on-accent-mut);
  text-align: center;
}
.flight-clip video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* A portrait clip cropped to any shorter frame would centre on empty sky —
     bias down so the pad and the smoke stay in it. */
  object-position: center 78%;
}

.flight-record { display: flex; flex-direction: column; gap: 0.7rem; min-width: 0; }
.flight-top { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; }

.flight-pair { display: grid; grid-template-columns: auto auto; justify-content: start; gap: 1.5rem; align-items: start; }
.fp-v {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 2.15rem;
  font-weight: 600;
  letter-spacing: -0.045em;
  line-height: 0.95;
}
.fp-u { font-size: 0.8125rem; font-weight: 500; letter-spacing: 0; margin-left: 0.28rem; color: var(--on-accent-soft); }
.fp-k {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 8.5px;
  letter-spacing: 0.8px;
  color: var(--on-accent-mut);
  margin-top: 0.42rem;
  /* The desktop hero gives the record its narrowest column, so one label wraps
     there and the other does not. Reserving two lines for both keeps the pair
     aligned at every width instead of stepping. */
  min-height: 2.2em;
}
/* The empty half of the pair is the point, so it is styled as a real value
   that happens to be absent — not as a broken or pending one. */
.fp.muted .fp-v { color: var(--on-accent-mut); font-weight: 400; }

.flight-note { font-size: 0.8125rem; line-height: 1.45; color: var(--on-accent-soft); margin: 0; }
.flight-note b { color: var(--on-accent); font-weight: 600; }



/* Reduced motion is handled in markup, not here: the clip ships without an
   autoplay attribute and the script below only starts it when motion is
   welcome, so a reduced-motion visitor gets the poster and a play control
   rather than a hidden video still decoding in the background. */

/* Any surface filled with --ink-fill is the sheet inverted, so a colour drawn
   on it has to take the value it would have on the opposite appearance —
   otherwise the flame tones land on a background of their own lightness and
   disappear. Every inverted surface belongs on this selector: the flight card
   was added without it and its powered-ascent segment fell to 2.35:1. */
.flight { --warm: #FF7A5E; --flame: #FF6B62; }
@media (prefers-color-scheme: dark) {
  .flight { --warm: #C4421C; --flame: #D0161D; }
}
.flight-eyebrow {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--on-accent-soft);
}
.flight-trace { width: 100%; height: 66px; display: block; margin-bottom: 1rem; }
/* The provenance line carries two longer sources than the deleted readout did,
   so it wraps rather than colliding at narrow widths. */
.flight-source {
  margin: auto 0 0;
  padding-top: 0.85rem;
  border-top: var(--hair) solid var(--on-accent-trk);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.15rem 1.1rem;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 9px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--on-accent-mut);
}
.flight-source .conf { color: var(--on-accent); }

/* Motor pill (mono chip, class-keyed) */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.2px;
  color: var(--on-accent);
  padding: 2px 7px;
  border-radius: var(--r-pill);
  background: var(--motor-hi);
}
.pill.fg { background: var(--motor-fg); }
.pill.hi { background: var(--motor-hi); }
.pill.jk { background: var(--motor-jk); }
.pill.l  { background: var(--motor-l); }
.pill .sep { opacity: 0.75; }

/* Text for assistive technology only: a mark that is aria-hidden still has to
   say what it means to someone who cannot see it. */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* ---- Notebook page ----
   Two drawings of one real flight. The graph paper is painted on the sheet
   rather than the page, so the drawing sits ON paper while the type around it
   does not — that contrast is the whole point, and it is why the grid is not
   a body background. */
.notebook {
  border-top: var(--hair) solid var(--rule);
  border-bottom: var(--hair) solid var(--rule);
  padding: 4.5rem 0;
}
.notebook .wrap { display: flex; flex-direction: column; gap: 1.25rem; }
.sheet {
  border: var(--hair) solid var(--rule);
  border-radius: 3px;
  background-color: var(--card);
  background-image:
    linear-gradient(var(--grid-minor) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-minor) 1px, transparent 1px),
    linear-gradient(var(--grid-major) 1.5px, transparent 1.5px),
    linear-gradient(90deg, var(--grid-major) 1.5px, transparent 1.5px);
  background-size: 24px 24px, 24px 24px, 120px 120px, 120px 120px;
  background-position: -1px -1px;
  padding: 1.6rem 1.4rem 1.3rem;
}
@media (max-width: 30rem) {
  .sheet { padding: 1rem 0.7rem 0.9rem; }
}
.sheet figure { margin: 0; }
/* A safety net only. The two drawings below are sized so neither one has to
   scroll at the width it serves. */
.sheet-scroll { overflow-x: auto; }
.sheet svg {
  display: block; width: 100%; height: auto;
  font-family: 'Caveat', 'Bradley Hand', 'Segoe Print', cursive;
}

/* Two drawings of the same page, not one drawing that shrinks. A landscape
   composition squeezed onto a phone puts the handwriting at about five pixels,
   so a narrow screen gets a portrait redraw instead — the sources funnelling
   down a spine into the record rather than left to right. The hidden one is
   out of the accessibility tree, so only the drawing on screen is announced. */
.sheet svg.draw-wide { min-width: 40rem; }
.sheet svg.draw-tall { display: none; }
@media (max-width: 48rem) {
  .sheet svg.draw-wide { display: none; }
  .sheet svg.draw-tall {
    display: block;
    /* Phone-shaped, so it stays phone-width rather than growing to a
       two-thousand-pixel column on a small tablet. */
    min-width: 0;
    max-width: 24rem;
    margin: 0 auto;
  }
}

/* ---- In use ----
   Three worked examples as prose, not a feature-card grid: no border, fill or
   radius per item, since each of those says "separate object" and this is one
   set of three (docs/surface-to-leave-behind.md §19, §20). A single ruling above
   each row is enough to separate them, and the columns collapse to one on a
   narrow screen without the items ever sitting alone in a row. */
.usecases { border-top: var(--hair) solid var(--rule); }
.uses {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0 2.75rem;
  /* One column, then three — never two, which would leave the third item alone
     in a row. The cap keeps the single-column measure readable on a wide-ish
     tablet rather than letting a paragraph run the full width of the page. */
  grid-template-columns: 1fr;
  max-width: 46rem;
}
.uses li {
  padding: 1.1rem 0 1.2rem;
  border-top: var(--hair) solid var(--rule);
}
.uses h3 {
  margin: 0 0 0.55rem;
  font-size: 1.08rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.25;
  text-wrap: balance;
}
/* Once the list is more than one column the headings set where the paragraphs
   start, so reserve the two-line height — otherwise a one-line heading lets its
   column begin higher than its neighbours. Single column has no rows to align. */
@media (min-width: 64rem) {
  .uses { grid-template-columns: repeat(3, 1fr); max-width: none; }
  .uses h3 { min-height: 2.5em; }
}
.uses p {
  margin: 0;
  color: var(--sec);
  font-size: 0.93rem;
  line-height: 1.6;
}
.uses-more {
  margin: 2rem 0 0;
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--accent-ink);
}

/* ---- Importer chips, demoted under the drawing ----
   A chip may carry a transport mark. The mark is the claim, so it goes only on
   devices Fili can actually reach that way; everything else arrives as a file
   and carries nothing. */
.chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chips li {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 11px;
  letter-spacing: 0.3px;
  color: var(--sec);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-pill);
  padding: 0.4rem 0.7rem;
  background: var(--card);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.chip-io {
  width: 0.72rem;
  height: 0.72rem;
  flex: none;
  color: var(--accent-ink);
}
.chip-legend {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0.9rem 0 0;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.02em;
  color: var(--sec);
}
.chip-legend .chip-io { width: 0.8rem; height: 0.8rem; }
.chip-legend .dot { color: var(--rule); }

/* ---- Provenance line under a section ---- */
.provenance {
  margin: 1.5rem 0 0;
  text-align: center;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--sec);
}
.provenance .accent { color: var(--accent-ink); }

/* ---- Across devices ---- */
.devices { border-top: var(--hair) solid var(--rule); }

/* ---- The sync demo ----
   Two recordings of one moment, read left to right: the drag on the Mac, an
   arrow, the plan arriving on the phone. The phone gets a drawn bezel — the
   one place device chrome earns itself, because at this size a bare rectangle
   of light UI does not read as a phone, and the arrow needs a phone at the end
   of it to mean anything. */
.demo {
  margin: 2.5rem 0 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 13rem);
  /* Captions line up across the top; a phone is simply taller than a laptop
     screen and centring them left the two labels at different heights. */
  align-items: start;
  gap: 1.5rem;
}
.demo-step { display: flex; flex-direction: column; gap: 0.75rem; min-width: 0; }
.demo-cap {
  margin: 0;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sec);
}
.demo-clip { display: block; width: 100%; height: auto; }

.demo-mac {
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--card);
  line-height: 0;
}

.demo-phone {
  border: 7px solid var(--fg);
  border-radius: 2.2rem;
  overflow: hidden;
  background: var(--fg);
  line-height: 0;
  box-shadow: 0 8px 28px rgba(17, 19, 24, 0.18);
}

.demo-mac { position: relative; }
/* One control for the pair: they are the same moment, so pausing one and
   leaving the other running would be worse than either state. */
.demo-toggle {
  position: absolute; right: 10px; bottom: 10px;
  width: 30px; height: 30px; padding: 0; border: none; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(10, 11, 13, 0.62); color: #FFFFFF;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: background 0.15s ease;
}
.demo-toggle:hover { background: rgba(10, 11, 13, 0.82); }
.demo-toggle:focus-visible { outline: 2px solid #FFFFFF; outline-offset: 2px; }
.demo-toggle svg { display: block; width: 11px; height: 11px; fill: currentColor; }

.demo-arrow { width: 3rem; height: auto; color: var(--sec); flex: none; align-self: center; margin-top: 4rem; }

/* Stacked, the arrow has to turn to keep meaning "then". */
@media (max-width: 52rem) {
  .demo {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: 1.25rem;
  }
  .demo-step { width: 100%; }
  .demo-step-phone { max-width: 13rem; }
  .demo-arrow { transform: rotate(90deg); width: 2.25rem; margin-top: 0; }
}

/* ---- Pricing ---- */
.pricing-section { border-top: var(--hair) solid var(--rule); }
/* Pricing */
.pricing { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr)); gap: 1rem; max-width: 800px; margin: 0 auto; }
.price-card {
  background: var(--card);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-card);
  padding: 1.5rem 1.25rem;
  text-align: center;
}
.price-card.featured { border: 1px solid var(--accent-ink); }
.price-name {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--sec);
  margin: 0 0 0.6rem;
}
.price {
  font-size: 2.1rem;
  font-weight: 700;
  letter-spacing: -0.035em;
  font-variant-numeric: tabular-nums;
  margin: 0;
  line-height: 1;
}
.price .per {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.4px;
  color: var(--sec);
}
.price-note { margin: 0.7rem 0 0; font-size: 0.82rem; color: var(--ter); }
.pricing-fine { text-align: center; max-width: 640px; margin: 1.75rem auto 0; font-size: 0.82rem; color: var(--ter); }

/* The lead-in above the cards. Sized below the section's own h2 so the two
   headings read as headline and sub-head rather than competing for the page. */
.pricing-lead {
  text-align: center;
  margin: 0 0 1.5rem;
  font-size: clamp(1.1rem, 2.2vw, 1.35rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent-ink);
  text-wrap: balance;
}

/* ---- Footer ---- */
.site-footer {
  border-top: var(--hair) solid var(--rule);
  background: var(--card);
  padding: 3rem 0;
}
.footer-inner { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1.5rem; align-items: center; }
.site-footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 11px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}
.site-footer nav a { color: var(--sec); }
.site-footer nav a:hover { color: var(--accent-ink); text-decoration: none; }
.footer-note {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.6px;
  color: var(--ter);
  margin: 0;
}

/* ==========================================================================
   Motion — one orchestrated page-load, calm and mechanical
   ========================================================================== */
@keyframes rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.reveal { opacity: 0; animation: rise 0.24s ease-out forwards; }
.reveal.d1 { animation-delay: 0.04s; }
.reveal.d2 { animation-delay: 0.10s; }
.reveal.d3 { animation-delay: 0.16s; }
.reveal.d4 { animation-delay: 0.22s; }
.reveal.d5 { animation-delay: 0.30s; }

html { scroll-behavior: smooth; }

/* Placed after the smooth-scroll rule so the reduced-motion override wins by
   source order (equal specificity) — anchor jumps stay instant for users who
   asked for less motion. */
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; animation: none; }
  .btn { transition: none; }
  html { scroll-behavior: auto; }
}
