/* IntervalNext — the site's one stylesheet.
 *
 * BUILD.md §8.2: "convert each page's inline styles into one stylesheet on the
 * tokens in SITE.md §2, keeping the markup, spacing and copy identical."
 * §15: "Do not redesign a page."
 *
 * So every rule below is a transcription of an inline style from
 * docs/site/pages/*.html. Nothing is rounded, harmonised or improved. Where
 * the designer used an unusual value — a 20px button pad next to a 24px one,
 * a 1.5 line-height next to a 1.55 — the value is kept and, where it looks
 * like a mistake, a comment says so rather than fixing it.
 *
 * Class names are the design's own nouns: nav, lockup, hero, shelf, card,
 * step, rail, foot. A class says what a thing IS, never what it looks like,
 * so that changing a colour never makes a name a lie.
 *
 * Contents
 *   1  tokens
 *   2  document
 *   3  page shell — nav, lockup, foot
 *   4  type and small shared pieces
 *   5  buttons
 *   6  device renders (.shot)
 *   7  landing: hero, edges, screens, trial, pricing, faq
 *   8  docs: rail, doc, callout, chip, aside
 *   9  the phone pages: connect, linked, unlock, paid, account
 *  10  responsive — SITE.md §4
 */

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

/* SITE.md §2. The names are the spec's names. */
:root {
  --paper: #F4F3EF;        /* page ground */
  --ink: #1A1A1A;          /* text, buttons, the mark's rest bar */
  --body: #3E3E3C;         /* paragraphs */
  --muted: #5F5F5A;        /* captions, secondary nav, labels */
  --hairline: #DDDBD4;     /* borders, dividers */
  --input-border: #C9C7C0; /* inputs — and the one hairline button */
  --white: #FFFFFF;        /* cards, inputs */
  --amber: #F2C300;        /* the field's handover yellow: the mark's tall bar, the docs callout's rule, the waiting ring — nothing else */
  --green: #46883A;        /* done states; the pricing ticks */
  --paper-2: #EDECE6;      /* a deeper paper: the Edges strip, the hero plinth */

  /* Not in §2's table, but used consistently by every page: the 1px ring
   * drawn around a device render so a white Edge screen has an edge against
   * PAPER. It is a render frame, not a UI border, which is why it is neither
   * the hairline nor the input border. */
  --ring: #D8D8D8;

  /* One face for every page since 25 Oct 2026 (owner): Onest, for text,
   * headings, numbers and buttons alike. Self-hosted by fonts.css (BUILD.md
   * §8.2 — an EU visitor's IP must not go to Google for a font). */
  --sans: 'Onest', system-ui, sans-serif;
  --display: 'Onest', system-ui, sans-serif;
  --mono: 'Onest', system-ui, sans-serif;
  /* The wordmark's face (owner, 13 Oct 2026): Plus Jakarta Sans, Interval
   * 500 and Next 800, on every page. Onest stands in until its file is
   * served. */
  --brand: 'Plus Jakarta Sans', 'Onest', var(--display);

  /* The one measurement that repeats often enough to be worth a name: the
   * page's side gutter, 80px as drawn and 20px below 480 (§4). */
  --gutter: 80px;

  /* The width the designer drew at. It is a maximum for the content column
   * (.page) and, since the nav and the footer became full-bleed bands, also
   * the column their contents are aligned to — so it is named here rather
   * than written out three times and drifting. */
  --page-max: 1440px;
  --border-strong: #BDBBB3;
  --on-ink: #F5F5F2;       /* text on the ink bands (bar, footer, hero) */
  --on-ink-2: #C9C9C4;     /* secondary text on ink */
  --on-ink-3: #9C9C97;     /* captions on ink */
  --ink-rule: #2E2E2E;
  --ink-edge: #4A4A4A;
  --red: #B0362B;
  --radius: 16px;
  --radius-sm: 12px;
}

/* ------------------------------------------------------------- 2 document */

/* Transcribed from the <style> block both pages carry. */
body {
  margin: 0;
  font-family: var(--sans);
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: var(--ink); }
a:hover { color: var(--muted); }

/* An inline style outranks `a:hover`, so in the designer's HTML every link
 * that pinned its own colour kept that colour on hover: the INK buttons stay
 * white, the muted nav and footer links stay muted. Moving those colours into
 * classes loses that, because `a:hover` (0,1,1) beats `.foot__link` (0,1,0).
 * Each such class therefore re-states its colour for :hover below, marked
 * "pin". This is fidelity, not preference. */

img { display: block; }

/* A form is a layout wrapper on these pages and never a visible box, but the
 * UA gives it a bottom margin that would show up as an extra gap inside a
 * card. The designer drew no form at all, so there is nothing to transcribe
 * and nothing to keep. */
form { margin: 0; }

/* ---------------------------------------------- 3 page shell — nav, lockup, foot */

/* The designer wrapped each page in a fixed `width: 1440px; height: 4200px`
 * div. The width is the drawing width and becomes a maximum; the height is a
 * canvas artifact — the content is what it is — so it is deliberately not
 * reproduced. At exactly 1440 the result is pixel-identical.
 *
 * The nav and the footer are no longer inside it — see .nav below. */
.page {
  max-width: var(--page-max);
  margin-inline: auto;
  box-sizing: border-box;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  font-family: var(--sans);
  color: var(--ink);
}

/* The shell is a flex column with a 100vh floor, so that on a page shorter
 * than the window the footer sits at the bottom of the window instead of
 * halfway up it with bare paper under the rule. Measured before this: the 404
 * left 376.37px of paper below its footer at 1920 × 1080 and 736 at
 * 2560 × 1440, and /refunds is within 10px of doing the same.
 *
 * This is the same treatment, for the same reason and in the same shape, that
 * .shell--phone has from 480 up (see §10, which says it in full). It was
 * applied there and not here in the change that moved both bands out of the
 * column; on the phone pages a short page was obvious, on the full-frame ones
 * only the 404 is short enough to show it, so it was missed.
 *
 * `body:not(.shell--phone)` because the phone shell keeps its own copy and
 * must: below 480 it deliberately has neither the floor nor a footer, and a
 * rule reaching it from here would move the 390 rendering.
 *
 * It moves nothing on a page taller than the window, which is every page the
 * designer drew — the landing is 4144 tall at 1440 and the docs 1524 — so the
 * drawing is untouched. */
body:not(.shell--phone) {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* Neither band may be squeezed by the flex container to make room for a long
 * page — the bar's height and the footer's padding are the drawing's, not a
 * budget. Only the column grows, and it keeps the full width of the shell so
 * that its own max-width and auto margins still do the centring. */
body:not(.shell--phone) > .nav,
body:not(.shell--phone) > .foot { flex: none; }
body:not(.shell--phone) > .page { flex: 1 0 auto; width: 100%; }

/* The bar. It sits outside .page, so it is as wide as the window and its
 * ground and its hairline run edge to edge; inside it, the padding below puts
 * its contents back on the same column .page centres, so the lockup is always
 * directly above the hero's left edge.
 *
 * Read the padding as "the gutter, measured from the content column rather
 * than from the window once the window is wider than the column". Below the
 * drawing width the first term wins and it is exactly the 80px the designer
 * drew; at 1680 it is 192.5 and at 2560 it is 632.5, which is where .page's
 * own left edge plus its gutter land. Measured: identical to the drawing at
 * 1440, aligned to the hero at 1680 and 2560.
 *
 * Before this the bar was the first child of .page and stopped dead at 1440
 * with its hairline hanging in the middle of the window — the one thing on
 * the page that said "fixed-width mock" on any monitor wider than the
 * drawing. */
.nav {
  height: 72px;
  box-sizing: border-box;
  padding-block: 0;
  padding-inline: max(var(--gutter), calc((100% - var(--page-max)) / 2 + var(--gutter)));
  display: flex;
  align-items: center;
  gap: 40px;
  border-bottom: 1px solid var(--ink-rule);
  background: var(--ink);
  color: var(--on-ink);
}

/* SITE.md §3, the lockup: the mark at 24–26px beside `IntervalNext`, set in
 * Roboto Condensed 700 since the October redesign, baseline-aligned, gap
 * 0.4 × the type size. Defined once here; the header and the footer differ
 * only in size. */
.lockup {
  display: inline-flex;
  align-items: baseline;
  gap: 8px; /* 0.4 × 20 */
  font-family: var(--brand);
  font-weight: 500;
  font-size: 20px;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--ink);
}
.lockup:hover { color: var(--ink); } /* pin */

.lockup__mark {
  width: 26px;
  height: 26px;
  align-self: center;
  margin-top: -4px;
}
/* The mark is drawn inline (base.html): its rest bar takes the lockup's own
 * colour, paper on the ink bands and ink on the bar once it turns white, and
 * its tall bar is the handover yellow on both. */
.lockup__rest { fill: currentColor; }
.lockup__tall { fill: var(--amber); }

.lockup__next { font-weight: 800; }

/* The footer lockup. The designer's gap is 6, not 6.4. */
.lockup--sm { gap: 6px; font-size: 16px; }
.lockup--sm .lockup__mark { width: 20px; height: 20px; margin-top: -3px; }

.nav__links {
  flex-grow: 1;
  display: flex;
  gap: 28px;
  font-size: 15px;
  font-weight: 500;
}

.nav__link { text-decoration: none; color: var(--on-ink-2); }
.nav__link:hover { color: var(--on-ink); }

/* Account sits at the far end of the links, beside the call to action. */
.nav__link--end { margin-left: auto; }

/* On a page that marks a current item, the others go muted (Docs.html). */
.nav__link--muted { color: var(--on-ink-3); }
.nav__link--muted:hover { color: var(--on-ink); } /* pin */

.nav__link--current {
  border-bottom: 2px solid var(--amber);
  padding-bottom: 2px;
  color: var(--on-ink);
}

/* The footer is the bar's mirror and is bled the same way and for the same
 * reason: a page whose header rule reaches the window edge and whose footer
 * rule stops 240px short of it at 1920 reads as half-converted. Same
 * expression, same alignment — measured, the footer lockup's left edge is the
 * nav lockup's at 1440, 1680 and 2560. */
.foot {
  margin-top: 112px;
  box-sizing: border-box;
  padding-block: 40px;
  padding-inline: max(var(--gutter), calc((100% - var(--page-max)) / 2 + var(--gutter)));
  border-top: 1px solid var(--ink-rule);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 28px;
  row-gap: 20px;
  font-size: 14px;
  color: var(--on-ink-2);
  background: var(--ink);
}

.foot__link { text-decoration: none; color: var(--on-ink-2); }
.foot__link:hover { color: var(--on-ink); } /* pin */

/* The Garmin trademark attribution: its own row under the links. */
.foot__legal { flex-basis: 100%; margin: 0; font-size: 12px; line-height: 1.55; color: var(--on-ink-3); max-width: 900px; }

/* The official "Available on the Connect IQ Store" badge (Garmin brand pack
 * 2024, dark badge for light backgrounds) stands where the ink button stood:
 * 56px tall, the SVG's own proportions, nothing redrawn or recoloured, and
 * only a lift on hover, as on the renders. Clear space is the row's gap. */
.store-badge { display: inline-flex; flex: none; line-height: 0; border-radius: 12px; transition: opacity 160ms ease; }
.store-badge:hover { opacity: 0.8; }   /* a fade, not a lift: Garmin's artwork stays as drawn (night.css .n-store) */
.store-badge__img { display: block; height: 56px; width: auto; }

/* The designer's `<span style="flex-grow: 1"></span>` push, in the footer and
 * in the Edges strip. */
.spacer { flex-grow: 1; }

/* ------------------------------------- 4 type and small shared pieces */

/* The small label over a heading: hero, price card, docs kicker. Sentence
 * case in the display face since the October redesign (§13). */
.eyebrow {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
  font-family: var(--display);
}
/* The docs sidebar's group headings are a point smaller. */
.eyebrow--sm { font-size: 14px; }

/* Body copy. 17px is the landing's and the docs lede's size; --sm is the
 * docs' running text. Line-height is 1.55 for both; the small grey .note
 * below is a different thing at 1.5. */
.prose {
  margin: 0;
  font-size: 17px;
  line-height: 1.55;
  color: var(--body);
}
.prose--sm { font-size: 15px; }

/* The small grey caption under a card or a device screen. */
.note {
  font-size: 14px;
  line-height: 1.5;
  color: var(--muted);
}

/* Emphasis inside running copy. The designer used two: a plain 600, which
 * inherits the paragraph's colour, and a 600 that also lifts to INK. They are
 * not interchangeable — inside a #444 paragraph the second one is visibly
 * darker, which is the point. */
.strong { font-weight: 600; }
.strong--ink { font-weight: 600; color: var(--ink); }

/* An INK link inside grey copy (the price card's footnote). */
/* An inline link in running copy. It is the one link class in this sheet that
 * does not clear the underline, and that is deliberate rather than an
 * oversight — WCAG 2.1 SC 1.4.1: a link a reader is meant to notice inside a
 * paragraph must not be distinguishable from the text around it by colour
 * alone. INK on BODY is a colour difference and nothing else.
 *
 * It matters most for the four support addresses in the legal copy
 * (privacy ×3, imprint, refunds), which are contact routes a reader is meant
 * to act on: before they were linked they were plain #444 text, and an
 * underline is what now says they can be clicked. The footer's own printing
 * keeps .foot__link and stays as drawn — see the note in base.html's "foot".
 *
 * So: do not add `text-decoration: none` here to make the legal pages match
 * their pre-mailto rendering. TestInCopySupportAddressesStayUnderlined
 * asserts this and will say the same thing. */
.link-ink { color: var(--ink); font-weight: 500; }
.link-ink:hover { color: var(--ink); } /* pin */

/* A 1px divider inside a card. */
.rule { height: 1px; background: var(--hairline); }

/* ------------------------------------------------------------ 5 buttons */

/* Size carries padding, because in this design the solid call to action is
 * deliberately chunkier than the quiet one beside it (24 vs 20). Fill and
 * size are independent. */
.btn {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  transition: transform .15s ease, opacity .15s ease, background-color .15s ease;
  /* The phone pages use <button> for the three that submit or open a payment
   * sheet, and a button inherits neither the family nor the cursor and comes
   * with a border and a padding of its own. The designer set all four on
   * every one of them. A size modifier re-states the padding after this, and
   * --outline / --hairline re-state the border, so nothing here reaches an
   * anchor that did not already look like this. */
  padding: 0;
  border: 0;
  font-family: var(--display);
  cursor: pointer;
  /* Deliberately no box-sizing. The designer drew the bordered buttons as
   * <a> on four pages and as <button> on the unlock page, and a browser gives
   * those two different defaults: an anchor's 48px height is inside its
   * border and a button's is around it, so the same "48" is 50 tall in one
   * place and 48 in the other. That is in the design and stating a
   * box-sizing here would silently move one of them by 2px. */
   font-weight: 700;
   letter-spacing: 0.01em;
}

/* Header height, SITE.md §2: "48 in the header" — the pages draw 40. The
 * pages win (§15). */
.btn--sm {
  height: 40px;
  padding: 0 18px;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 700;
}

.btn--lg {
  height: 52px;
  padding: 0 24px;
  border-radius: var(--radius-sm);
  font-size: 18px;
  font-weight: 700;
}

/* Full width inside a card or a phone screen, with a centred label. Not a
 * size: it fills the column it is in and the height, radius and type still
 * come from a size modifier beside it. */
.btn--block {
  display: flex;
  justify-content: center;
}

/* The phone pages draw three heights — 56, 52 and 48 — and two type sizes
 * across them, so the sizes are named by height: it is how SITE.md §2
 * specifies them ("buttons are 52–56 px tall on the phone") and the only
 * thing that tells 52/17 from the landing's 52/16 apart.
 *
 * min-height, not height: at 390 nothing wraps and the box is the drawn one,
 * but the paid page's "Another Edge?" label is two lines at 390 and three at
 * 320, and a fixed height would spill it out of the button. */
.btn--h56 {
  min-height: 56px;
  border-radius: var(--radius-sm);
  font-size: 17px;
  font-weight: 700;
  gap: 10px; /* the connect button's mark sits 10 from its label */
}

.btn--h52 {
  min-height: 52px;
  border-radius: var(--radius-sm);
  font-size: 17px;
  font-weight: 700;
}

.btn--h48 {
  min-height: 48px;
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-weight: 700;
}

/* The one below a --h48, a weight lighter (the paid page's "Read the docs"). */
.btn--h48-quiet {
  min-height: 48px;
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-weight: 600;
}

.btn--ink { background: var(--ink); color: var(--white); }
.btn--ink:hover { color: var(--white); } /* pin */

.btn--outline { border: 1px solid var(--ink); color: var(--ink); }
.btn--outline:hover { color: var(--ink); } /* pin */

.btn--hairline { border: 1px solid var(--input-border); color: var(--ink); }
.btn--hairline:hover { color: var(--ink); } /* pin */

/* The ground is independent of the border, the same way the fill is
 * independent of the size: the landing's bordered buttons sit straight on
 * PAPER, the phone's are filled white. */
.btn--white { background: var(--white); }

/* A borderless button in MUTED — the paid page's second action. */
.btn--muted { color: var(--muted); }
.btn--muted:hover { color: var(--muted); } /* pin */

/* Apple's own button is pure black, not INK. It is the one #000 in the
 * design and belongs to Apple's guidelines rather than to §2's palette,
 * which is why it is not a token. */
.btn--apple { background: #000000; color: var(--white); }
.btn--apple:hover { color: var(--white); } /* pin */

/* The burger, and the checkbox that remembers whether it is open.
 *
 * Both are in the markup of every full-frame page at every width and both are
 * drawn only below the bar's own breakpoint — §10 turns them on. They live
 * here, after the buttons, for a cascade reason and not a filing one: the
 * label carries `btn btn--sm btn--hairline` so that the burger IS the docs
 * page's hairline button, 40px tall with the same radius and the same border,
 * and `display: none` has to come after `.btn`'s `display: inline-flex` to
 * win. Everything else about it is in §10.
 *
 * Why a checkbox. SITE.md's menu has to work with JavaScript off (§15 leaves
 * no build step and no framework to lean on), which leaves a checkbox or
 * `:target`. `:target` writes the open state into the URL and into history,
 * and every one of this nav's own links is already a fragment — #screens,
 * #trial, #pricing — so opening the menu and then following a link would have
 * the two fighting over the same hash and the back button walking through
 * menu-open states. The checkbox holds the state without touching the URL.
 * It is also what lets the script change nothing about the CSS: nav-menu.js
 * keeps this input as the state and only puts a real <button> in front of it
 * (see the file), so `:checked` is the single mechanism with and without
 * JavaScript. */
.nav__toggle { display: none; }
.nav__burger { display: none; }

/* The glyph is two paths in one <svg> — three bars, and the cross that
 * replaces them when the menu is open. A <path> rather than a second file or
 * an icon font, drawn in currentColor like the two ticks in base.html. */
.nav__burger-cross { display: none; }
.nav__toggle:checked + .nav__burger .nav__burger-bars { display: none; }
.nav__toggle:checked + .nav__burger .nav__burger-cross { display: inline; }

/* ------------------------------------------------- 6 device renders (.shot) */

/* Every screenshot of the Edge carries the same 1px ring; the lift is what
 * differs, and the design uses five of them. They are named by elevation
 * because that is what the design varies — a hero screen sits higher off the
 * page than one in a row of four. */
.shot {
  border-radius: 10px;
  box-shadow: 0 0 0 1px var(--ring);
  transition: transform .3s ease, box-shadow .3s ease;
}
.shot--lift-sm { box-shadow: 0 0 0 1px var(--ring), 0 16px 40px rgba(0, 0, 0, 0.10); }

.shot--lg { width: 240px; height: 400px; }

/* The docs rail's second render sits lower than the caption above it. */
.shot--spaced { margin-top: 24px; }

/* ------------------------------ 7 landing: hero, edges, screens, trial, pricing, faq */

/* A numbered step. The landing and the docs draw the same thing at two
 * sizes; --docs carries the differences. */
.steps {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.step { display: flex; gap: 20px; }

.step__num {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-sm);
  border: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  font-weight: 800;
  background: var(--amber);
  color: var(--ink);
  font-size: 20px;
}

.step__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.step__title { font-weight: 700; font-size: 19px; font-family: var(--display); line-height: 1.2; }

.step__note { font-size: 15px; line-height: 1.5; color: var(--muted); }

.steps--docs { gap: 28px; }
.steps--docs .step__num { width: 36px; height: 36px; border-radius: 10px; font-size: 17px; }
.steps--docs .step__body { gap: 6px; }
/* The docs' step copy is body-dark and set a shade looser than the
 * landing's grey. */
.steps--docs .step__note { line-height: 1.55; color: var(--body); }

.price__amount {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.price__value {
  font-family: var(--display);
  font-weight: 700;
  font-size: 72px;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.price__once { font-size: 16px; color: var(--muted); }

/* ---------------------------------- 8 docs: rail, doc, callout, chip, aside */

.docs {
  box-sizing: border-box;
  padding: 56px var(--gutter);
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr) 260px;
  gap: 64px;
  align-items: start;
}

/* The left contents rail. */
.rail {
  display: flex;
  flex-direction: column;
  gap: 28px;
  font-size: 14px;
  position: sticky;
  top: 96px;
}

.rail__group {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.rail__link { text-decoration: none; color: var(--body); }
.rail__link:hover { color: var(--body); } /* pin */

/* The page you are on. It takes INK from `a` rather than pinning a colour,
 * so unlike its siblings it greys on hover — as drawn. */
.rail__link--current { position: relative; color: var(--ink); font-weight: 600; }
.rail__link--current:hover { color: var(--muted); }

/* The middle column. */
.doc {
  display: flex;
  flex-direction: column;
  gap: 40px;
  max-width: 680px;
}

.doc__block {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.doc__title {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 44px;
  line-height: 1.05;
  letter-spacing: -0.01em;
}

.doc__h2 {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 30px;
  line-height: 1.1;
  letter-spacing: -0.005em;
}

/* SITE.md §2: AMBER is "the docs callout's left rule — nothing else". */
.callout {
  box-sizing: border-box;
  padding: 20px 24px;
  background: var(--white);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--amber);
  border-radius: var(--radius-sm);
  font-size: 15px;
  line-height: 1.55;
  color: var(--body);
}

/* An inline URL, in mono. */
.chip {
  font-family: var(--mono);
  font-size: 14px;
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 1px 6px;
}

/* The right rail of renders. */
.aside {
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: center;
}

.aside__caption {
  font-size: 13px;
  color: var(--muted);
  text-align: center;
  line-height: 1.5;
}

/* -------------------------------- 9 the phone pages (Connect … Paid, account) */

/* SITE.md §4: "The four phone pages are already 390 wide — they must also be
 * fine at 320 (older phones) and centred at 480+ with the same width."
 *
 * The designer wrapped each of them in a fixed `width: 390px; height: Npx`
 * div, exactly as on the landing. The width becomes a maximum and the height
 * is a canvas artifact, so it is not reproduced; .page already centres what
 * it holds, which is the "centred at 480+" half.
 *
 * Side padding is 20 on every one of these pages, so --gutter is redefined
 * on the column and .screen follows it rather than carrying its own 20. The
 * two bands are outside the column now (see .shell--phone below), so they
 * read their own copy of the token — §10 says where from at which width.
 *
 * /account (BUILD.md §8.4) is not one of the designer's pages. It is built
 * out of this vocabulary and nothing else, and every piece of it that the
 * designer has not seen carries a comment saying so. */

.page--phone {
  max-width: 390px;
  --gutter: 20px;
}

/* .shell--phone is the <body> of all six. It carries no measurement of its
 * own here: what it does is scope the two things §10 does to these pages —
 * where the two full-bleed bands align, and everything the desktop treatment
 * adds. See the two blocks at the end of the sheet.
 *
 * The phone page as drawn had no footer. Since the owner's mobile pass (21 Oct
 * 2026) it is drawn at every width: on a phone it is where Privacy, Refunds and
 * Terms are, beside the pages that ask for a key or a payment. */

/* The bar: the same hairline rule and the same lockup as the desktop nav,
 * 16px shorter, with a word of state where the links and the button are.
 * From 480 up it is the site's own 72 — §10, and the reason is there. */
.nav--phone {
  height: 56px;
  /* The bar is a lockup, a .spacer and the state word, so the gap is never
   * what separates them at 390 — it is the floor that keeps them apart on a
   * 320 phone, where the two together are nearly the whole line. */
  gap: 16px;
}

.nav__status { font-size: 13px; color: var(--on-ink-2); }

/* The third size of the lockup: 18px, between the header's 20 and the
 * footer's 16. The mark keeps the header's −4px optical lift. */
.lockup--md { gap: 7px; font-size: 18px; }
.lockup--md .lockup__mark { width: 24px; height: 24px; }

/* Everything below the bar. The designer draws three rhythms across the four
 * pages — 24 on linked and paid, 22 on connect, 20 on unlock — and two top
 * paddings. Kept apart rather than averaged (§15). */
.screen {
  box-sizing: border-box;
  padding: 28px var(--gutter) 0 var(--gutter);
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.screen--connect { gap: 22px; }
.screen--unlock { padding-top: 24px; gap: 20px; }

/* A <form> the layout should not be able to see. The designer drew no form
 * anywhere on these pages, so one must cost nothing: this makes it the same
 * flex column as whatever it sits in, and `inherit` takes that parent's own
 * gap — 22 inside a connect screen, 10 inside a device card — so its children
 * land exactly where they would have landed as siblings.
 *
 * It is also what makes a <button> inside a form full width. An <a> stretches
 * because it is a flex child; a bare <button> in a block <form> sizes to its
 * label instead. The fix is to make the form the column, not to put a width
 * on the button: a width would have to bring a box-sizing with it, and .btn
 * says why that is not free. */
.form-stack {
  display: flex;
  flex-direction: column;
  gap: inherit;
}

/* h1 on a phone page: 30, against the landing's 64 and the docs' 44. */
.screen__title {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 30px;
  line-height: 1.1;
  letter-spacing: -0.01em;
}

/* The paragraph under it. Same 15px as the docs' .prose--sm, but at 1.5
 * rather than 1.55 — the designer's value, kept. */
.screen__lede {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--body);
}

/* The heading group. --status is the two pages that open with the GREEN
 * eyebrow, which the designer sets a notch tighter. */
.intro { display: flex; flex-direction: column; gap: 10px; }
.intro--status { gap: 8px; }

/* "LINKED · PLAMEN P.", "PAID · 14,95 €" — the eyebrow in GREEN, which §2
 * reserves for done states. */
.eyebrow--done { color: var(--green); }

/* The phone pages' small print: 13px MUTED, under a card or at the foot of
 * the screen. Often holds a .link-ink. */
.footnote { font-size: 13px; color: var(--muted); }

/* The three white boxes. They are one box drawn three times — the device
 * card, the status card and (phase A) the sign-in card — differing only in
 * padding and inner rhythm. */
.device,
.status,
.signin {
  box-sizing: border-box;
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
}

/* The device card: which Edge this page is about. Connect draws it as a
 * single row, unlock as the row plus a found line and a footnote; one
 * column with a 10 gap is both. */
.device { padding: 16px; gap: 10px; }

.device__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  /* Not drawn — space-between is what separates the two at 390 and there is
   * 60px of slack even at 320, so this only ever stops them touching. */
  gap: 12px;
}

/* An Edge's card: the code under the model (owner, 6 Nov 2026), because with
 * its four characters it no longer fits beside one on a phone. */
.device__row--stacked {
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
.device__row--stacked .device__field--code {
  align-items: flex-start;
  margin-left: 0;
  text-align: left;
}

.device__field { display: flex; flex-direction: column; gap: 2px; }

/* The code sits right, and keeps sitting right when it is the row's only
 * field — which is the "Edge not seen yet" card, where there is no model to
 * put on the left. */
.device__field--code {
  align-items: flex-end;
  margin-left: auto;
  text-align: right;
}

/* The card's own label. It is the eyebrow a point smaller and a shade
 * tighter (12/0.06em against 13/0.08em), so it is its own rule rather than
 * an .eyebrow modifier that would have to undo both. */
.device__label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
  font-family: var(--display);
}

.device__model { font-size: 17px; font-weight: 600; }

/* The code, in the display face at 700. Not tabular: fixed-width digits stood
 * wider apart than the letters beside them (owner, 6 Nov 2026). */
.device__code {
  font-family: var(--display);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* "Found — in its trial since 9 September, 9 rides". §2: GREEN is the done
 * state, and "found" is one. */
.device__found {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--green);
}

/* SITE.md §5's "Edge not seen yet — keep the phone near it and press lap".
 * It is the same line as --found in the not-yet case. It stays MUTED rather
 * than going amber: §2 gives AMBER the waiting *ring* and nothing else. */
.device__waiting {
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
}

/* The status card on linked and paid: three rows, two done and one waiting,
 * row 3 polling (SITE.md §5). */
.status { padding: 18px 16px; gap: 14px; }

.status__row { display: flex; gap: 12px; align-items: center; }

.status__mark {
  width: 22px;
  height: 22px;
  border-radius: 11px;
  box-sizing: border-box;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.status__mark--done { background: var(--green); }
/* §2: AMBER is "the work bar of the mark, the 'waiting' ring, the docs
 * callout's left rule — nothing else". This is the waiting ring. */
.status__mark--waiting { border: 2px solid var(--amber); }

.status__text { font-size: 15px; }

/* "every 30 s" or the countdown, pushed to the end of the waiting row. */
.status__every { margin-left: auto; font-size: 13px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* BUILD.md §8.3's phase-A card and §8.4's sign-in. The designer drew an
 * OAuth button in this slot, not a form, so the box is the device card's and
 * the 14px inner rhythm is the status card's — DESIGNER TO REVIEW. */
.signin { padding: 16px; gap: 14px; }

/* A labelled input. The unlock page draws two (e-mail, card); phase A and
 * /account reuse them exactly. */
.field { display: flex; flex-direction: column; gap: 6px; }
.field__label { font-size: 13px; font-weight: 500; }

.input {
  height: 46px;
  box-sizing: border-box;
  padding: 0 14px;
  border: 1px solid var(--input-border);
  border-radius: 10px;
  background: var(--white);
  font-family: var(--sans);
  font-size: 16px;
  color: var(--ink);
  /* A text input's intrinsic width is around 180px and a flex item will not
   * shrink below it by default. Inside a card on a 320 phone that is wider
   * than the column. */
  min-width: 0;
}

/* The six-digit code, set in the type the device card prints it in. SITE.md
 * §1: on /c and /u without a code, this takes the device card's place. The
 * designer drew the link to it ("Enter the code from your Edge") but never
 * the field itself — DESIGNER TO REVIEW. */
.input--code {
  font-family: var(--display);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}

/* A form has to be able to say no, and §2 has no error colour: INK at the
 * label's size, a weight heavier. Not drawn — DESIGNER TO REVIEW. */
.form-error { font-size: 13px; font-weight: 600; color: var(--ink); }

/* The explanatory rows under a card: a line-art icon and a sentence. */
.points {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
}
/* Unlock draws 10 where connect draws 12. */
.points--unlock { gap: 10px; }

.point { display: flex; gap: 10px; }
.point__icon { flex-shrink: 0; margin-top: 1px; }

/* "What happens next" and "If it hasn't switched after a minute": 14px at
 * body dark, which is not the MUTED .note of the same size. Its lead line is
 * a .strong--ink. */
.followup {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--body);
}

/* The unlock page's price: the landing's price parts at the phone's scale,
 * without the landing's card around them. */
.pricebar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.pricebar .price__amount { gap: 8px; }
.pricebar .price__value { font-size: 44px; }
.pricebar .price__once { font-size: 14px; }

.pricebar__terms {
  font-size: 13px;
  color: var(--muted);
  text-align: right;
  line-height: 1.4;
}

/* Two buttons stacked at the foot of a screen (paid, account). */
.actions { display: flex; flex-direction: column; gap: 10px; }

/* The checkout stack. SITE.md §5: the merchant's overlay replaces the card
 * form, and the price row and the two promises above it stay. Same 10 as
 * .actions, but it holds the wallets, the divider and the two fields too. */
.pay { display: flex; flex-direction: column; gap: 10px; }

/* "or with a card" between two hairlines — each of them a .rule that is also
 * a .spacer. */
.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  color: var(--muted);
  padding: 4px 0;
}

/* /account's list of linked Edges: a column of device cards. Not drawn —
 * DESIGNER TO REVIEW. */
.devices { display: flex; flex-direction: column; gap: 12px; }

/* ----------------------------------------------- 10 responsive — SITE.md §4 */

/* §4 gives two breakpoints, 1024 and 480, and says the landing and docs are
 * "drawn at 1440". Between 1024 and 1440 it says nothing — and that range is
 * where most laptops sit. Four things on the landing are composites wider than
 * the column they are drawn in, and they only clear the viewport at 1440
 * because they are allowed to spill into the gutter beside them. The two
 * blocks below are that gap, and nothing else: each rule turns a single-line
 * or overlapped row into a wrapping one, and each takes effect only at the
 * width where the drawn version would otherwise push a horizontal scrollbar
 * across the whole page. */

/* "Below 1024: the two-column grids (hero, trial steps, pricing, docs) stack;
 *  the device-screen shelf scrolls horizontally or wraps to two rows; the nav
 *  collapses to the lockup + Get it on Connect IQ."
 *
 * The last clause is no longer done here. It used to be `.nav__links {
 * display: none }` and nothing else, which is why on every tablet and every
 * phone the four links simply disappeared and the header could not reach the
 * docs at all. The menu that replaces them, and the measured width it starts
 * at, are in the block below this one. */

@media (max-width: 1023px) {
  /* The header's button carries the longest string on the page at exactly
   * the widths where there is least room for it.
   *
   * Measured at 320: the row is 280px inside the gutter, the lockup takes
   * 146.5 and the drawn 40px gap another 40, leaving 93.5 for a label that
   * wants 130.9 on one line. It wrapped to three lines — 54px of text in a
   * box whose height is fixed at 40 — and spilled 7px out of the dark fill
   * above and below it. The docs header does the same with "Unlock with a
   * code", 6px each way.
   *
   * So the height becomes a minimum, which is what every button on the phone
   * pages already does and for exactly this reason (see .btn--h56): a label
   * that wraps should make the fill taller, not run out of it.
   *
   * Nothing else changes with it — no padding, no box-sizing, no font size —
   * because min-height on the same content box is invisible until a label
   * actually wraps past 40px. Measured: the button is 166.9 × 40 on the
   * landing and 160.6 × 42 on the docs at 1440, 1024 and 768, with and
   * without this rule. The drawing is untouched; only the case it could not
   * survive is. */
  .btn--sm {
    height: auto;
    min-height: 40px;
  }

  .docs {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  /* The rail is no longer a column beside the text, so it stops sticking. */
  .rail { position: static; }

  /* The footer and the pair of hero buttons are the last two single-line rows
   * drawn for 1440. Wrapping engages only when a line runs out of room, so at
   * 900 both still lay out exactly as drawn. */
  .foot { row-gap: 16px; }

}

/* ---- the bar's own breakpoint: the menu that replaces the vanished links ---
 *
 * 1000, and it is a measurement rather than §4's paragraph. Measured in a
 * browser at 1440 after the October 2026 redesign, with the bar as built —
 * gutter 80, gap 40, links 28 apart, in Roboto:
 *
 *   landing  80 + 132.06 + 40 + 362.67 + 40 + 117.05 + 80 = 851.78
 *   docs     80 + 132.06 + 40 + 275.13 + 40 + 153.66 + 80 = 800.84
 *
 * — the landing's four links, Account and its store badge, the docs' three
 * links, Account and its button — and again with the two webfonts forced out
 * of the bar, so that what is measured is the fallback chain a visitor sees
 * while they are still loading: the landing then needs 858.06. The landing
 * (and the legal pages, which carry the same bar) are the binding case.
 *
 * Those are content widths, and a media query is compared against the
 * viewport. The first viewport that keeps the links in the bar is 1000,
 * which on Windows or Linux leaves 985 of content against a requirement of
 * 858.06, so 127 remain. (It was 900 until Account joined the bar on
 * 1 Oct 2026, when the landing needed 942.95; Screens left it the same day
 * with the row of screens, and 1000 was kept rather than move the sticky
 * bar and its white state, which start where the links do.)
 * TestBreakpointsDerivedFromAContentWidthAllowForTheScrollbar holds it with
 * the other two.
 *
 * This block is after the 1024 one on purpose: below 1000 both match and the
 * later rules are the ones that win.
 *
 * What it builds is a disclosure, not a dialog: a button in the bar and a
 * panel directly under it. Nothing is trapped, nothing is inert, the page
 * behind it keeps scrolling, and the panel follows the button in the DOM so
 * Tab walks straight into it. The call to action is not in it — the store
 * badge, or the docs' button, stays in the bar at every width, because the
 * one thing a menu must never hide is the reason the page exists. */
@media (max-width: 999px) {
  .nav { position: relative; }

  /* The 40px gap is drawn for a row that also holds four links. From here
   * down the row is the lockup, the burger and the button, and 40px of gap
   * is 40px the label does not get: 12 is the landing's own figure for the
   * space between two buttons (.hero__actions). .nav--phone is excluded by
   * name — it holds no button and its own 16px is the floor that keeps the
   * lockup off the state word at 320. */
  .nav:not(.nav--phone) { gap: 12px; }

  /* The control. Visually hidden but still focusable, because with
   * JavaScript off it IS the control: Tab reaches it, Space toggles it, and
   * the ring below is drawn on the label beside it so that the focus is
   * visible even though the input is not. nav-menu.js takes it out of the
   * tab order and puts a real <button> in its place — see the file for what
   * that buys and what the no-JS path does without it. */
  .nav__toggle {
    display: block;
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* The burger itself: .btn--sm's 40px box and radius and .btn--hairline's
   * border, square instead of padded, pushed to the right by the margin the
   * hidden links no longer supply. 40 × 40 is also the touch target. */
  .nav__burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    box-sizing: border-box;
    width: 40px;
    padding: 0;
    margin-left: auto;
  }

  /* A static drawing has no focus state, so this is not transcribed from
   * anything. It is the UA's own ring in the page's own ink: 2px, offset by
   * 2, on the button when the script is running and on the label beside the
   * input when it is not. */
  .nav__burger:focus-visible,
  .nav__toggle:focus-visible + .nav__burger {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
  }

  /* Closed. */
  .nav__links { display: none; }

  /* Open: a panel under the bar, the full width of the window, on INK with
   * the bar's own rule closing it. `top` is calc(100% + 1px) and not 72px
   * because the bar grows a second row below 540 (the 539 block below), and
   * the 1px is the bar's own border, which the panel starts just under. */
  .nav__toggle:checked ~ .nav__links {
    display: flex;
    flex-direction: column;
    gap: 0;
    position: absolute;
    top: calc(100% + 1px);
    left: 0;
    right: 0;
    z-index: 2;
    padding: 0;
    background: var(--ink);
    border-bottom: 1px solid var(--ink-rule);
  }

  /* One row per link, 48 tall so the whole width of the window is the target,
   * indented to the gutter so the labels line up under the lockup. The rule
   * between two rows is the sheet's hairline; the first row has none, because
   * the bar's own border is already there. */
  .nav__toggle:checked ~ .nav__links .nav__link {
    display: flex;
    align-items: center;
    min-height: 48px;
    box-sizing: border-box;
    padding-inline: var(--gutter);
    border-top: 1px solid var(--ink-rule);
  }
  .nav__toggle:checked ~ .nav__links .nav__link:first-child { border-top: 0; }
  .nav__toggle:checked ~ .nav__links .nav__link--end { margin-left: 0; }

  /* The current page. The marker is a 2px yellow rule under the label,
   * which in a full-width row would underline the whole window; the same 2px
   * rule down the left of the row says the same thing in a column. The
   * link also carries aria-current="page", which is what a screen reader
   * reads and what stops this being colour alone.
   * DESIGNER TO REVIEW: the menu is not drawn, and neither is this. */
  .nav__toggle:checked ~ .nav__links .nav__link--current {
    border-bottom: 0;
    padding-bottom: 0;
    border-left: 2px solid var(--amber);
    padding-left: calc(var(--gutter) - 2px);
  }
}

/* ---- and the width below which the bar stops being one row ----------------
 *
 * 552, measured the same way.
 *
 * What the row has to hold once the links are in the menu is three items and
 * therefore TWO of the 12px gaps the block above sets — the lockup, the
 * burger and the call to action. The binding page is the docs, whose button
 * is wider than the landing's badge:
 *
 *   132.06 + 12 + 40 + 12 + 153.66 = 349.72, plus 2 × 80 of gutter = 509.72
 *
 * so it needs a CONTENT width of 509.72 and is squeezed below it. Squeezing
 * instead of wrapping is what the page did before the burger existed, and it
 * broke the button's label over several lines at 390 and 320; the honest fix
 * is the one the footer and the hero's buttons already use: let the row wrap.
 *
 * The result is the lockup and the burger on the first row and the call to
 * action full width on the second, which is what every button on the four
 * phone pages already is.
 *
 *   16 + 40 + 12 + 40 + 16 + 1 = 125
 *
 * — the two padding-blocks, the two 40px rows, the row-gap and the bar's own
 * 1px border, which counts because .nav is border-box with `height: auto`
 * here. Against the drawn 72 (which also includes that border) the header is
 * 53px taller on a phone and everything below it moves down 53. Measured at
 * 400: .nav is 125.00 tall and .page starts at y = 125. (This used to read
 * 124 and +52, which left the border out of one side of the comparison and
 * not the other.)
 *
 * The breakpoint is compared against the viewport, which carries a classic
 * 15px scrollbar on Windows and Linux: at 553 the content is 538, 28 more
 * than the 509.72 the row needs. (Before the redesign the row needed 537.37
 * and 552 was the last viewport that had to wrap; it is kept, so the bar
 * changes shape where it always has.) TestBreakpointsDerivedFromAContentWidthAllowForTheScrollbar
 * holds the arithmetic. */
@media (max-width: 552px) {
  .nav:not(.nav--phone) {
    height: auto;
    flex-wrap: wrap;
    align-content: center;
    padding-block: 16px;
    row-gap: 12px;
  }

  /* The second row. box-sizing is stated here and only here: .btn leaves it
   * alone on purpose (see the note there — an <a> and a <button> disagree
   * about where a border sits, and the design contains both), but a
   * full-width button whose 18px of padding lands outside its 100% would
   * push the bar sideways. The selector says `a` because the burger wears
   * .btn--sm too and must stay a 40px square on the first row; inside this
   * one rule the button is an <a> and nothing else, so there is nothing to
   * disagree with. */
  .nav a.btn--sm {
    box-sizing: border-box;
    width: 100%;
    justify-content: center;
  }
}

/* "Below 480: side padding 20, h1 34, the three-screen hero becomes one
 *  screen (ride--in-range)." */
@media (max-width: 479px) {
  :root { --gutter: 20px; }

  .doc__title { font-size: 34px; }

  .price__value { font-size: 56px; }

  /* The footer takes the same 72 above it as the sections around it; and on a
   * phone it is a stack, so the push that right-aligns the support line has
   * nothing left to push against.
   *
   * The two halves were two `.foot` blocks a comment apart until the CSS test
   * helpers started refusing to answer questions about a selector declared
   * twice at the same at-rule level — see cssRuleFor in nav_test.go for why
   * that is the shape they have. Nothing about the rendering changed. */
  /* Its links are a tidy three by two under the lockup rather than a row
   * that breaks wherever the width runs out (owner, 1 Oct 2026, the phone
   * pass): each link a third of the row, and the lockup and the support line
   * a row each, as the trademark notice already is. */
  .foot { margin-top: 72px; gap: 16px 32px; }
  .foot .spacer { display: none; }
  .foot > span { flex-basis: 100%; }
  .foot__link { flex: 0 0 calc((100% - 64px) / 3); }
}

/* The phone pages are drawn at 390 and §4 asks for 320 as well. One row on
 * them is laid out side by side and stops fitting first: the unlock page's
 * price against its two lines of terms, which together need about 320px of
 * text. Everything else on those pages is a single column or wraps already. */
@media (max-width: 359px) {
  .pricebar { flex-wrap: wrap; row-gap: 8px; }
  .pricebar__terms { text-align: left; }
}

/* ---- the six activation pages: where their two bands align ----------------
 *
 * The bar and the footer are outside the column on these pages now, as they
 * are on the landing, so they no longer read the column's own --gutter and
 * the pair that positions a full-bleed band has to be declared on the shell.
 *
 * Below 480 that pair is the phone's: 20 is where --gutter has always been
 * declared (on .page--phone) and 390 is what that column has always been
 * capped at, so the bar's contents sit exactly where they sat when the bar
 * was inside it. All that changes below 480 is that the bar's ground and its
 * hairline now reach the window edge instead of stopping at 390 — which is
 * invisible at 390 and under, where the column is the window.
 *
 * From 585 up neither rule below is there, and the bands fall back to the
 * site's own tokens on :root — 80 and 1440. That is deliberate and it is the
 * whole of how the chrome on these pages becomes the landing's chrome rather
 * than a smaller copy of it: same gutter, same band, same place on the
 * window, with the 450 column centred inside it. The cost is that the bar's
 * lockup is then no longer directly above the column's left edge, because
 * the column is not the site's column. The alternative — aligning both bands
 * to the 450 column at every width — was built and measured first, and is
 * why this is written down: the footer's contents (the lockup, six links and
 * the support line) need 675px, and a band aligned to a 450 column offers
 * them a 410px content box at ANY window width, because the expression grows
 * the padding exactly as fast as the window. Flex items do not shrink below
 * min-content, so at 1440 the footer spilled 265px past its own padding and
 * the support line broke into six ragged lines in the middle of the window.
 * A bar that lines up with the column is not worth a footer that does not
 * fit in the band it is drawn on.
 *
 * The swap happens where the two expressions give the same answer, and that
 * is not a taste either. Aligned to the column, the padding is
 * (100% - 450) / 2 + 20; on the site's tokens it is 80 until 1440. They are
 * equal at a CONTENT width of 570, so the lockup does not move by a pixel as
 * it crosses — below it the bar tracks the column, above it tracks the
 * window, and the two meet. Below the crossing the column is wide enough
 * relative to the window that the site's 80px gutter would push the bar
 * INSIDE the content's own left edge, which is the one arrangement that looks
 * like a mistake.
 *
 * 584, therefore, and not 569: `100%` in that expression is the content
 * width, and the media query below is compared against the viewport, which
 * carries a classic 15px scrollbar on Windows and Linux. The crossing is at a
 * content width of 570, so the last viewport that must still track the column
 * is 570 + 15 - 1 = 584. Written as 569 the bar swapped to the window at a
 * viewport of 570, where the content is 555 and the column's own left edge
 * plus its gutter is at 72.5 — so from 570 to 584 the 80px gutter put the
 * lockup 7.5px inside the content's left edge, which is exactly the
 * arrangement the paragraph above rules out. Nothing below 480 is affected:
 * the phone's own token block ends there and this one begins there.
 * TestBreakpointsDerivedFromAContentWidthAllowForTheScrollbar holds it. */
@media (max-width: 479px) {
  .shell--phone {
    --gutter: 20px;
    --page-max: 390px;
  }
}

@media (min-width: 480px) and (max-width: 584px) {
  .shell--phone {
    --gutter: 20px;
    --page-max: 450px;
  }
}

/* ---- the six activation pages, above the phone they were drawn for --------
 *
 * SITE.md §4 says of these pages: "already 390 wide — they must also be fine
 * at 320 (older phones) and centred at 480+ with the same width (they are
 * opened from a QR on a phone; a desktop viewer is the exception, not the
 * design)". That is what the sheet did, and on a monitor the result was a
 * 390px strip of content under a 390px strip of hairline, marooned in the
 * middle of the window. The owner asked for a desktop version of the pages
 * "where code is to activate", so the last clause of §4 is the one thing
 * here that is deliberately not followed; everything else in it still is.
 *
 * The whole of the desktop treatment is this one block and the token block
 * above it. Below 480 nothing on these pages moves — same column, same bar,
 * no footer — which is how "the phone must not regress" is kept provable
 * rather than promised: measured element by element at 320, 375 and 390, the
 * rendering is identical to the build before this change. 480 is §4's own
 * second figure, the width at which it says a desktop viewer begins.
 *
 * THE COLUMN — 450, measured twice, from opposite ends.
 *
 *   The cards. .screen's gutter is 20, so a card in a 450 column is 410
 *   wide. The landing's three text cards at 1440 are (1440 - 160 of gutter
 *   - 48 of gap) / 3 = 410.67. A reviewer who clicks from / to /account is
 *   looking at boxes of the same size, which is most of what "the same
 *   site" means before anybody reads a word.
 *
 *   The measure. Measured in a browser, the average character advance over
 *   these pages' own copy is 6.412px at 15px, 5.985 at 14 and 5.557 at 13.
 *   The running text in a 450 column is 410 wide (the .points' sentences
 *   382, inset by the 18px icon and its 10px gap), which is
 *
 *     15px .screen__lede, .status__text   410 / 6.412 = 63.9 characters
 *     14px .followup                      410 / 5.985 = 68.5
 *     13px .footnote                      410 / 5.557 = 73.8
 *     13px .point span                    382 / 5.557 = 68.7
 *
 *   — every size on the page between 64 and 74, inside the 45-75 band, with
 *   the size the page is actually read in one character under Bringhurst's
 *   66. At the drawn 390 the same text is 350 wide and the 15px line is
 *   54.6 characters, which is right for a phone and thin for a monitor. A
 *   wider column was measured and rejected: at 560 the 13px line is 93
 *   characters, well past the band, and the cards stop matching anything.
 *
 * THE BAR stays what SITE.md drew — the lockup and one word of state, no
 * links and no button. A rider is three taps from a linked Edge and the bar
 * is not the place to offer them somewhere else to go; the footer, which is
 * below the page rather than above it, is. What the bar does take on is the
 * site's own height and lockup size, because at these widths it is drawn
 * beside the landing's and a bar 16px shorter with a lockup 2px smaller
 * reads as a different site rather than as a quieter page of this one.
 *
 * THE FOOTER is the landing's, unchanged, and it is the reason this block
 * exists at all as much as the column is: Docs, Unlock, Pricing, Privacy,
 * Imprint, Refunds and the support address are what make /account read as a
 * product rather than as a fragment of one, and /account is where somebody
 * decides whether to hand this service an intervals.icu key.
 *
 * The shell becomes a flex column with a 100vh floor so that the footer sits
 * at the bottom of a short page (the notice page is 250px tall) instead of
 * halfway up the window with paper under it. */
@media (min-width: 480px) {
  .shell--phone {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
  }

  /* Neither band may be squeezed by the flex container to make room for a
   * long page — the bar's height and the footer's padding are the drawing's,
   * not a budget. Only the column grows. */
  .shell--phone .nav--phone,
  .shell--phone .foot { flex: none; }
  .shell--phone .page--phone {
    max-width: 450px;
    flex: 1 0 auto;
  }


  /* The site's own bar, at the site's own size. The two lockup rules restate
   * .lockup's and .lockup__mark's values because .lockup--md is in the
   * markup and no media query can take a class off an element; if the header
   * lockup is ever resized, TestTheDesktopPhoneBarIsTheSitesOwnBar fails
   * rather than these drifting apart quietly. */
  .nav--phone { height: 72px; }
  .nav--phone .lockup--md { gap: 8px; font-size: 20px; }
  .nav--phone .lockup--md .lockup__mark { width: 26px; height: 26px; }

  /* 28px under the bar is a phone's thumb-reach economy. With a 72px bar and
   * a window to fill, the first thing on the page should not be jammed
   * against the rule; 48 is this sheet's own next step up (.hero's stacked
   * gap, .btn--h48) and is deliberately not a fifth spacing value.
   * The selector carries .shell--phone so that it outranks .screen--unlock's
   * own 24. */
  .shell--phone .screen { padding-top: 48px; }
}

/* ------------------------------------------------- 12 refinement, 2026-09-30
 * A pass over the whole page for depth and rhythm, on the owner's ask, inside
 * the identity of the time: the paper, the ink, the one yellow accent.
 * Everything here overrides the sections above by coming after them. */

/* The header stays with the reader on wide windows — from the width the links
 * are in it — in ink over the hero (owner, 1 Oct 2026). Once the hero has
 * scrolled under it nav-menu.js adds .nav--scrolled and it turns white, the
 * way the page under it is light (owner, 1 Oct 2026, in place of the dark
 * glass it was for a day): ink type and links, the brand's dark mark,
 * Garmin's black badge, a hairline and a soft shadow. The docs' bar
 * (.nav--ink) stays ink. Both are slightly frosted (owner, the same day):
 * the ink at 92% and the white at 90%, so each stays what it is and the page
 * only shows through as it passes under. The ink bar's own rules (§3, §13)
 * are .nav and .nav-plus-one-class, so the ones here that meet them carry
 * .nav.nav--scrolled to outrank them. */
@media (min-width: 1000px) {
  .nav {
    position: sticky;
    top: 0;
    z-index: 30;
    background-color: rgba(26, 26, 26, 0.92);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
    backdrop-filter: blur(20px) saturate(140%);
    transition: background-color 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  }
  .nav__link,
  .lockup { transition: color 0.2s ease; }
  .nav--scrolled {
    background-color: rgba(255, 255, 255, 0.9);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    border-bottom-color: var(--hairline);
    box-shadow: 0 12px 28px -20px rgba(26, 26, 26, 0.45);
  }
  .nav.nav--scrolled .lockup,
  .nav.nav--scrolled .lockup:hover { color: var(--ink); }
  .nav--scrolled .nav__link { color: var(--body); }
  .nav--scrolled .nav__link:hover { color: var(--ink); }
  /* The docs' current item: an ink underline, the yellow one being too faint
   * on white. */
  .nav--scrolled .nav__link--current { color: var(--ink); border-bottom-color: var(--ink); }
  .nav--scrolled .nav__link--muted { color: var(--muted); }
  .nav.nav--scrolled .btn--outline { border-color: var(--border-strong); color: var(--ink); }
  .nav.nav--scrolled .btn--outline:hover { border-color: var(--ink); color: var(--ink); }
  .nav.nav--scrolled :focus-visible { outline-color: var(--ink); }
  .nav--scrolled .store-badge__img--on-ink { display: none; }
  .nav--scrolled .store-badge__img--on-white { display: block; }
}

/* A reader who asks for less transparency gets the two solid. */
@media (min-width: 1000px) and (prefers-reduced-transparency: reduce) {
  .nav {
    background-color: var(--ink);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .nav--scrolled { background-color: var(--white); }
}

/* Buttons answer the pointer. */
.btn:active { transform: translateY(1px); }

@media (prefers-reduced-motion: reduce) {
  .shot,
  .btn,
  .nav { transition: none; }
}

/* --------------------------------------------- 13 Daylight, 2026-10-01
 * The October redesign, on the owner's decision (NOTES.md). The mock is
 * IntervalApp docs/site/redesign-2026-10/index.html; the design before it is
 * the git tag design-2026-09 and docs/site/old-design-2026-09/.
 *
 * The palette is still SITE.md §2's — paper, ink, the handover yellow, the
 * done green — and the type becomes the Edge's own: Roboto Condensed for
 * headings, numbers and buttons, Roboto for text, in sentence case. The bar
 * and the footer are ink bands on every page, cards and buttons take a
 * rounder corner, and the landing is rebuilt as full-width bands
 * (main.html). The measurements the tests pin — the 72px bar, the columns,
 * the phone frame — are kept as they were.
 *
 * The shared rules above were changed in place for it (tokens, bar, footer,
 * type, buttons, boxes); this section holds only what is new. */

/* Focus: ink on paper, the handover yellow on the ink bands. */
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.nav :focus-visible,
.foot :focus-visible,
.hero :focus-visible { outline-color: var(--amber); }

/* ---- the bar, on every page */

.nav .lockup,
.nav .lockup:hover { color: var(--on-ink); }

.nav .btn--outline { border-color: var(--ink-edge); color: var(--on-ink); }
.nav .btn--outline:hover { border-color: var(--on-ink); color: var(--on-ink); }
.nav .btn--ink,
.nav .btn--ink:hover { background: var(--amber); color: var(--ink); }
.nav .btn--hairline,
.nav .btn--hairline:hover { border-color: var(--ink-edge); color: var(--on-ink); background: transparent; }
.nav__burger:focus-visible,
.nav__toggle:focus-visible + .nav__burger { outline-color: var(--amber); }
.store-badge--nav .store-badge__img { height: 40px; }
/* The bar's black badge waits for the white bar (§12). */
.store-badge__img--on-white { display: none; }

/* ---- the lockup and the footer */

.foot .lockup,
.foot .lockup:hover { color: var(--on-ink); }


/* ---- buttons and boxes */


/* The quiet button on an ink band (the hero's "How the trial works"). */
.btn--ghost { border: 1px solid var(--ink-edge); color: var(--on-ink); background: transparent; }
.btn--ghost:hover { border-color: var(--on-ink); color: var(--on-ink); }

/* ---- the landing: full-width bands, each with its content on the column */

.page--bands { max-width: none; }

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

.lede { margin: 0; font-size: 19px; line-height: 1.6; color: var(--body); max-width: 60ch; }

.icon {
  width: 24px;
  height: 24px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The hero: the one dark band, the Edge 1040 in its frame. The render is lit
 * from the right, so the band is too (owner, 1 Oct 2026): a soft, slightly
 * warm light from the right edge, brightest behind the device and gone by
 * the copy, under the yellow glow. */
.hero {
  position: relative;
  overflow: clip;
  padding-block: 72px 64px;
  background-color: var(--ink);
  background-image:
    radial-gradient(ellipse 34% 62% at 100% 46%, rgba(255, 248, 236, 0.13), rgba(255, 248, 236, 0.05) 48%, transparent 78%),
    radial-gradient(ellipse 70% 90% at 100% 50%, rgba(255, 248, 236, 0.05), transparent 70%);
  color: var(--on-ink);
}
.hero::before {
  content: "";
  position: absolute;
  inset: -40% -20% auto;
  height: 120%;
  background: radial-gradient(60% 50% at 70% 30%, rgba(242, 195, 0, 0.14), transparent 70%);
  pointer-events: none;
}
.hero__grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 72px;
  align-items: center;
}
.hero__eyebrow { color: var(--amber); }
.hero__title {
  margin: 18px 0 0;
  font-family: var(--display);
  font-size: clamp(40px, 5.2vw, 68px);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.hero__lede { margin-top: 24px; color: var(--on-ink-2); }
.hero__actions { margin-top: 32px; display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.hero__terms { margin-top: 22px; display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 15px; color: var(--on-ink-3); }
.hero__strong { color: var(--on-ink); font-weight: 600; }
.hero__device {
  margin: 0;
  justify-self: end;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.hero__frame {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.28)) drop-shadow(0 24px 32px rgba(0, 0, 0, 0.55));
}
.hero__cap { margin-top: 14px; text-align: center; font-size: 14px; color: var(--on-ink-3); }
.hero__device picture { display: block; width: 100%; }


/* Four facts in one white strip. */
.blocks { padding-top: 24px; }
.blocks__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  overflow: hidden;
}
.block { padding: 22px 24px 20px; border-left: 1px solid var(--hairline); }
.block:first-child { border-left: 0; }
.block::before {
  content: "";
  display: block;
  width: 28px;
  height: 4px;
  border-radius: 2px;
  margin-bottom: 14px;
  background: var(--ink);
}
.block--yellow::before { background: var(--amber); }
.block--green::before { background: var(--green); }
.block--red::before { background: var(--red); }
.block__v { font-family: var(--display); font-weight: 700; font-size: 30px; line-height: 1; font-variant-numeric: tabular-nums; }
.block__k { margin-top: 6px; font-size: 14px; line-height: 1.4; color: var(--muted); }

.sec { padding-top: 96px; }
.sec__head { display: flex; flex-direction: column; gap: 14px; margin-bottom: 40px; max-width: 760px; }
.sec__title {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(30px, 3.4vw, 44px);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.005em;
  text-wrap: balance;
}

/* Features, and the two themes as one more pair. The row of screens that
 * stood above this was folded in (owner, 1 Oct 2026): the handover is a pane
 * as wide as a theme pane, on the price card's ink with the hero's faint
 * yellow light, its animation beside the words; the score and the Start screen are cards with their screen on the
 * hero plinth's deeper paper and the light theme pane's grey rim; the rest
 * are the plain cards with their yellow icon. Four across, two below 1200,
 * one below 600, where a screen card lies on its side, the screen beside its
 * words, and the pane stands its screen under them. */
.feat { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.feat__pane {
  grid-column: span 2;
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  padding: 28px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(160px, 44%, 270px);
  gap: 28px;
  align-items: center;
  background: var(--ink);
  color: var(--on-ink);
}
.feat__pane::before {
  content: "";
  position: absolute;
  inset: -40% -20% auto;
  height: 120%;
  background: radial-gradient(60% 50% at 70% 30%, rgba(242, 195, 0, 0.14), transparent 70%);
  pointer-events: none;
}
.feat__pane > * { position: relative; }
.feat__pane .card__d { margin-top: 10px; color: var(--on-ink-2); }
.feat__cap { margin: 16px 0 0; font-size: 14px; line-height: 1.45; color: var(--on-ink-3); }
/* The dark theme pane's rim: a white or yellow screen on ink. */
.feat__screen {
  display: block;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 0 0 3px var(--ink-edge), 0 18px 36px rgba(0, 0, 0, 0.5);
}
.feat__screen img { display: block; width: 100%; height: auto; }
.card {
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  transition: border-color 0.18s ease;
}
.card:hover { border-color: var(--border-strong); }
.card__icon {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-sm);
  display: grid;
  place-items: center;
  background: var(--amber);
  color: var(--ink);
}
.card--screen { padding: 0; gap: 0; overflow: hidden; }
/* align-items keeps the screen its own height when the card lies on its
 * side and the plinth is stretched to the words beside it. */
.card__stage {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 28px 24px 26px;
  background: var(--paper-2);
  border-bottom: 1px solid var(--hairline);
}
/* The <img>, or the <picture> that holds the handover's animation. */
.card__screen {
  display: block;
  width: min(100%, 196px);
  height: auto;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 0 0 3px #C9C7BF, 0 12px 24px rgba(26, 26, 26, 0.12);
}
.card__screen img { display: block; width: 100%; height: auto; }
.card__body { display: flex; flex-direction: column; gap: 10px; padding: 20px 22px 24px; }
.card__t { font-family: var(--display); font-weight: 700; font-size: 22px; line-height: 1.1; }
.card__d { margin: 0; font-size: 15px; line-height: 1.5; color: var(--body); }

.theme { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 14px; }
.theme__pane {
  border-radius: var(--radius);
  padding: 28px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 200px;
  gap: 24px;
  align-items: center;
}
.theme__pane .card__d { margin-top: 10px; }
.theme__pane img { width: 100%; height: auto; border-radius: 10px; }
.theme__pane--light { background: var(--white); border: 1px solid var(--hairline); }
.theme__pane--light img { box-shadow: 0 0 0 3px #C9C7BF, 0 14px 28px rgba(26, 26, 26, 0.14); }
.theme__pane--dark { background: var(--ink); color: var(--on-ink); }
.theme__pane--dark .card__d { color: var(--on-ink-2); }
.theme__pane--dark img { box-shadow: 0 0 0 3px var(--ink-edge), 0 14px 28px rgba(0, 0, 0, 0.5); }

/* Every size: four framed Edges at one scale, so their real relative sizes.
 * The columns are the WebPs' own widths (all made at one scale) and the
 * frames stand on one baseline. One soft shadow each, which follows the
 * device's outline (owner, 1 Oct: simpler than the contact shadows). */
.sizes {
  display: grid;
  grid-template-columns: 489fr 532fr 509fr 560fr;
  gap: 28px;
  align-items: end;
}
.sizes__fig { margin: 0; }
.sizes__fig img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 10px 14px rgba(26, 26, 26, 0.18));
}
.sizes__fig figcaption {
  margin-top: 12px;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  font-size: 14px;
  color: var(--muted);
}
.sizes__name { font-family: var(--display); font-weight: 700; font-size: 18px; color: var(--ink); }

/* The trial: three steps beside the three screens they make. */
.trial { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px; align-items: center; }
.trial .steps { gap: 12px; }
.trial .step {
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 18px;
  gap: 14px;
}
.trial .step__note { color: var(--body); }
.trial__shots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; align-items: end; }
.trial__shots figure { margin: 0; }
.trial__shots img { display: block; width: 100%; height: auto; border-radius: 8px; border: 1px solid var(--hairline); box-sizing: border-box; }
.trial__shots figcaption { margin-top: 8px; font-size: 13px; color: var(--muted); text-align: center; }

/* Pricing: the price on ink with the hero's faint yellow light (owner,
 * 1 Oct 2026), and how to get it. */
.pricing { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.price {
  position: relative;
  overflow: hidden;
  background: var(--ink);
  color: var(--on-ink);
  border-radius: 24px;
  padding: 40px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.price::before {
  content: "";
  position: absolute;
  inset: -40% -20% auto;
  height: 120%;
  background: radial-gradient(60% 50% at 70% 30%, rgba(242, 195, 0, 0.14), transparent 70%);
  pointer-events: none;
}
.price > * { position: relative; }
.price .eyebrow { color: var(--amber); }
.price__figure { display: flex; align-items: baseline; gap: 12px; }
.price__big {
  font-family: var(--display);
  font-weight: 700;
  font-size: 84px;
  line-height: 0.85;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.price__unit { font-size: 18px; font-weight: 500; color: var(--on-ink-2); }
.price__note,
.price__foot { margin: 0; font-size: 15px; color: var(--on-ink-2); }
.price__rows { border-top: 1px solid rgba(255, 255, 255, 0.14); }
.price__row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 15px;
  color: var(--on-ink-2);
}
.price__row span:last-child { font-weight: 600; text-align: right; color: var(--on-ink); }
.price .link-ink,
.price .link-ink:hover { color: var(--on-ink); }
.price :focus-visible { outline-color: var(--amber); }

.get {
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: 24px;
  padding: 40px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 18px;
}
.get__title { margin: 0; font-family: var(--display); font-size: clamp(28px, 3vw, 38px); font-weight: 700; line-height: 1.1; }
.get__lede { margin: 0; font-size: 15px; line-height: 1.55; color: var(--body); }
.get__ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; font-size: 15px; color: var(--body); }
.get__ticks li { display: flex; gap: 10px; align-items: center; }
.get__ticks .icon { color: var(--green); flex: none; }
.get__cta { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; margin-top: 6px; }

/* Questions: two columns of folding cards. */
.faq { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start; }
.faq__item {
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 0 20px;
}
.faq__q {
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  min-height: 60px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 19px;
  cursor: pointer;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after { content: "+"; flex: none; font-size: 26px; font-weight: 500; color: var(--muted); }
.faq__item[open] .faq__q::after { content: "–"; }
.faq__a { padding: 0 0 18px; font-size: 15px; line-height: 1.55; color: var(--body); }

@media (max-width: 1199px) {
  .feat { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1023px) {
  .hero__grid { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  /* Stacked, the device is under the copy: the light comes from the right
   * at its height. */
  .hero {
    background-image:
      radial-gradient(ellipse 60% 34% at 100% 74%, rgba(255, 248, 236, 0.13), rgba(255, 248, 236, 0.05) 48%, transparent 78%),
      radial-gradient(ellipse 95% 60% at 100% 72%, rgba(255, 248, 236, 0.05), transparent 70%);
  }
  .hero__device { justify-self: center; width: min(100%, 240px); }
  .blocks__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .block:nth-child(3) { border-left: 0; }
  .block:nth-child(n+3) { border-top: 1px solid var(--hairline); }
  .theme { grid-template-columns: minmax(0, 1fr); }
  .trial,
  .pricing { grid-template-columns: minmax(0, 1fr); }
  .sec { padding-top: 72px; }
  /* The four Edges two by two in equal columns; each frame is then sized
   * against the largest, the 1040, so the scale still holds. */
  .sizes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 20px; }
  .sizes__fig { display: flex; flex-direction: column; align-items: center; }
  .sizes__fig img { width: calc(var(--w) / 560 * 100%); }
  .sizes__fig figcaption { align-self: stretch; }
  .sizes__fig:nth-child(1) { --w: 489; }
  .sizes__fig:nth-child(2) { --w: 532; }
  .sizes__fig:nth-child(3) { --w: 509; }
  .sizes__fig:nth-child(4) { --w: 560; }
}

@media (max-width: 767px) {
  .theme__pane { grid-template-columns: minmax(0, 1fr) 150px; padding: 20px; }
}

/* Phones (owner, 1 Oct 2026: "the mobile version as good as the desktop").
 * The hero shows the Edge in the first screenful: the copy's parts and the
 * device become one column, the device straight after the lede, the badge
 * and the trial link side by side under it (the bar's badge is above). The
 * screen cards stand upright as on the desktop, at a size their screens can
 * be read at; the plain cards put their icon beside the words. */
@media (max-width: 599px) {
  .hero {
    padding-block: 40px 44px;
    background-image:
      radial-gradient(ellipse 70% 30% at 100% 55%, rgba(255, 248, 236, 0.13), rgba(255, 248, 236, 0.05) 48%, transparent 78%),
      radial-gradient(ellipse 100% 50% at 100% 55%, rgba(255, 248, 236, 0.05), transparent 70%);
  }
  .hero__grid { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
  .hero__copy { display: contents; }
  .hero__eyebrow { order: 1; }
  .hero__title { order: 2; font-size: 36px; overflow-wrap: anywhere; }
  .hero__lede { order: 3; margin-top: 18px; }
  .hero__device { order: 4; align-self: center; margin-top: 30px; }
  .hero__actions { order: 5; margin-top: 30px; gap: 8px; }
  .hero__terms { order: 6; margin-top: 18px; }
  .hero__actions .btn--lg { padding: 0 16px; font-size: 15px; }
  .hero__actions .store-badge__img { height: 52px; }
  .lede { font-size: 17px; line-height: 1.55; }
  .feat,
  .faq { grid-template-columns: minmax(0, 1fr); }
  .feat__pane { grid-column: auto; grid-template-columns: minmax(0, 1fr); padding: 22px; }
  .feat__screen { justify-self: center; width: min(100%, 220px); }
  .card__stage { padding: 24px 20px 22px; }
  .card__body { padding: 18px 20px 22px; }
  .card__t { font-size: 19px; }
  .card--icon {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr);
    align-items: start;
    gap: 6px 16px;
    padding: 20px;
  }
  .card--icon .card__icon { grid-row: span 2; width: 40px; height: 40px; }
  .price,
  .get { padding: 28px; }
  .price__big { font-size: 64px; }
  .price__row span:last-child { text-wrap: balance; }
  .trial__shots { gap: 8px; }
  .block { padding: 16px 16px 14px; }
  .block::before { margin-bottom: 12px; }
  .block__v { font-size: 22px; }
  .block__k { font-size: 13px; }
  .sec__head { margin-bottom: 28px; }
  .theme__pane { grid-template-columns: minmax(0, 1fr) 120px; }
}

@media (prefers-reduced-motion: reduce) {
  .card,
  .store-badge { transition: none; }
}

/* --------------------------------------------- 14 the docs, 2026-10-08
 * The docs page rewritten as a setup guide (owner: "less flashy, more
 * practical and easy to understand"), in the landing's vocabulary and
 * nothing new in colour or type: the rail beside one column, the trial's
 * numbered cards for anything done in order, a white pane with a screen
 * beside each screen it describes, rows for the settings and the Edges, the
 * landing's folding questions for troubleshooting, and the landing's footer.
 * The rail (§8), .doc and .callout are the ones the page always had; this
 * section only adds. .aside and .shot--lg from §6 and §8 are no longer used
 * by any page and are kept for the tests that read them. */

/* The two columns: the rail and the text, on the landing's column (.wrap). */
.docs--daylight {
  padding: 48px 0 0;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 72px;
}
.docs--daylight .doc { max-width: 800px; gap: 56px; }
.docs--daylight .doc__block { gap: 12px; }
.docs--daylight .doc__title { font-size: clamp(36px, 4vw, 52px); }
.docs--daylight .doc__h2 { font-size: 30px; }
.docs--daylight .doc__h3 { margin: 0; font-family: var(--display); font-weight: 700; font-size: 22px; line-height: 1.15; }
.docs--daylight .rail { top: 96px; }
/* The current item (its colour and weight are in §8): a 2px rule in the
 * handover yellow beside it, as the bar marks the current page. */
.rail__link--current::before {
  content: ""; position: absolute; left: -14px; top: 2px; bottom: 2px; width: 2px; background: var(--amber);
}

/* What to have ready: the landing's green ticks. */
.need { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; font-size: 15px; line-height: 1.55; color: var(--body); }
.need li { display: flex; gap: 10px; }
.need .icon { color: var(--green); flex: none; width: 20px; height: 20px; margin-top: 2px; }

/* Numbered cards for things done in order: the trial's steps. */
.steps--cards { gap: 12px; }
.steps--cards .step {
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 20px;
  gap: 16px;
}
.steps--cards .step__num { width: 40px; height: 40px; border-radius: 10px; font-size: 18px; }
.steps--cards .step__body { gap: 8px; min-width: 0; }
.steps--cards .step__title { font-size: 19px; }
.steps--cards .step__note { font-size: 15px; line-height: 1.55; color: var(--body); }

/* A path through a menu: Menu › Activity Profiles › Road. */
.path { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; font-family: var(--display); font-weight: 600; font-size: 14px; color: var(--ink); }
.path span { background: var(--paper-2); border: 1px solid var(--hairline); border-radius: 6px; padding: 1px 7px; }
.path i { font-style: normal; color: var(--muted); }

/* A tip under a step: the callout, smaller and on paper. */
.tip { margin-top: 4px; padding: 12px 14px; background: var(--paper); border-left: 3px solid var(--amber); border-radius: 8px; font-size: 14px; line-height: 1.5; color: var(--body); }

/* Photos under the words, 168 wide; a landscape one takes two columns. */
.shots { display: grid; grid-template-columns: repeat(auto-fill, 168px); gap: 12px; margin-top: 8px; }
.shots figure { margin: 0; }
.shots figure:has(.ph--wide) { grid-column: span 2; }
.shots figcaption { margin-top: 6px; font-size: 13px; line-height: 1.4; color: var(--muted); }
/* A photo not taken yet: a dashed frame, in the photo's own shape, that
 * says what to shoot. Replaced by an <img> of the same class when it is. */
.ph {
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  box-sizing: border-box; padding: 14px;
  border: 1.5px dashed var(--border-strong);
  border-radius: 10px;
  background: var(--paper-2);
  color: var(--muted);
  font-size: 13px; line-height: 1.45;
  aspect-ratio: 9 / 16;                  /* a phone screenshot */
}
.ph--edge { aspect-ratio: 282 / 470; }   /* an Edge screen, portrait */
.ph--wide { aspect-ratio: 4 / 3; }       /* the Edge on the bar */
.ph b { display: block; font-family: var(--display); font-weight: 700; font-size: 12px; letter-spacing: 0.02em; color: var(--ink); margin-bottom: 6px; }

/* A screen beside its words: the theme pane, on white, with the landing's
 * card rim on the render. */
.docpane {
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 24px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 150px;
  gap: 28px;
  align-items: center;
}
.docpane .doc__h3 { margin: 0; }
.docpane .prose { margin-top: 8px; }
.docpane__screen { display: block; width: 100%; height: auto; border-radius: 8px; box-shadow: 0 0 0 3px #C9C7BF, 0 10px 20px rgba(26, 26, 26, 0.10); }
.docpane--plain { grid-template-columns: minmax(0, 1fr); }
/* The trial: its three screens under the words. */
.docpane--stack { grid-template-columns: minmax(0, 1fr); gap: 20px; }
.docpane--stack .trial__shots { max-width: 480px; }

/* Rows in a white card: the settings, and the Edges by screen size. */
.spec { margin: 0; background: var(--white); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 4px 20px; }
.spec__row { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 16px; padding: 12px 0; border-top: 1px solid var(--hairline); font-size: 15px; line-height: 1.5; color: var(--body); }
.spec__row:first-child { border-top: 0; }
.spec__row dt { margin: 0; font-family: var(--display); font-weight: 700; font-size: 16px; color: var(--ink); }
.spec__row dd { margin: 0; }
.spec--edges .spec__row { grid-template-columns: 110px minmax(0, 1fr); }

/* Troubleshooting: the landing's folding cards, one column. */
.faq--one { grid-template-columns: minmax(0, 1fr); }
.faq--one .faq__q { font-size: 17px; min-height: 52px; }

/* The changelog: a version beside what it brought. */
.log { display: flex; flex-direction: column; }
.log__row { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 16px; padding: 14px 0; border-top: 1px solid var(--hairline); font-size: 15px; line-height: 1.55; color: var(--body); }
.log__row:first-child { border-top: 0; padding-top: 0; }
.log__v { font-family: var(--display); font-weight: 700; font-size: 19px; line-height: 1.1; color: var(--ink); }

@media (max-width: 1023px) {
  .docs--daylight { padding-top: 32px; gap: 40px; }
  .rail__link--current::before { display: none; }
}
@media (max-width: 599px) {
  .docpane { grid-template-columns: minmax(0, 1fr); padding: 18px; }
  .docpane__screen { width: min(100%, 180px); justify-self: center; }
  .spec__row, .spec--edges .spec__row { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .steps--cards .step { padding: 16px; gap: 12px; }
}
