/*
 * The public site's own layer, on top of the product's design tokens.
 *
 * ## The one rule
 *
 * Every colour here is a `var(--token)` from `tokens.css`, which the build
 * copies verbatim from `packages/portal/src/design/`. There is no literal
 * colour in this file -- no hex, no `rgb()`, no named colour -- and
 * `test/build.test.ts` greps for all three. That is not tidiness. A literal is
 * a colour that cannot follow the theme: the tokens are redefined for dark
 * mode and a literal is not, so one hex here is text that reads on white and
 * vanishes on #0D1420. That exact failure has shipped in this repository
 * before.
 *
 * ## Contrast
 *
 * Every text/ground pair this file introduces was computed in BOTH themes and
 * clears 4.5:1; the lowest is --ink-2 on --line-2 at 5.84 (light). Two grounds
 * are worth naming:
 *
 *   - `--rail` is the header band, and it is the one ground here whose ink does
 *     not come from the --ink ramp. It is #1C3760 in all three theme states --
 *     a brand band does not change colour because the reader's machine is in
 *     dark mode -- while --ink flips, so nothing from that ramp reads on it.
 *     That is why this file used to avoid the rail entirely and said so here.
 *     `tokens.css` now names the inks that belong to the surface, and because
 *     the surface never changes, one measurement covers every theme: --rail-ink
 *     at 11.90:1 and --rail-ink-2 at 7.49:1. They are tokens, not the white
 *     literal this comment used to say the job would need. The FOOTER is still
 *     --card: it is a block of prose, and two dark bands on one page is a page
 *     with a stripe through it.
 *   - `--ink-3` is NOT used for text. It is a hint colour at roughly 3.4:1 on
 *     --paper in light mode -- fine for a disabled control, not for a sentence.
 *
 * `--accent` paints no text. It carries the decorative hero rule, and it is the
 * focus ring inside the header -- the global ring is --link, which is 1.05:1 on
 * the light rail and therefore invisible exactly where the first Tab lands.
 * Orange is 5.13:1 on the light rail and 8.16:1 on the dark one, comfortably
 * past the 3:1 a focus indicator needs. The current page in the nav is marked
 * with `aria-current` (announced), a weight change, and a --rail-ink underline
 * -- never by colour alone, because --rail-ink and --rail-ink-2 are only 1.59:1
 * apart and that difference is emphasis, not information.
 *
 * ## No JavaScript
 *
 * These pages ship no script (design §1). Anything that would want one --
 * a theme toggle, a menu -- is either absent or done in CSS. The theme follows
 * the reader's system preference through `tokens.css`'s own media query.
 */

/* -- Page ---------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  /* Prose, not a dashboard: looser than the application's own line height. */
  line-height: 1.65;
}

/*
 * One measure for the whole site, so the header, every section and the footer
 * line up down the page rather than each choosing a width.
 */
.site-header > *, main > section, main > figure, .site-footer > * {
  max-width: 68rem;
  margin-inline: auto;
}

main { display: block; }

/* -- Type ---------------------------------------------------------------- */

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1.15;
  color: var(--ink);
  margin: 0 0 var(--space-4);
  /* The display face is wide; it reads better slightly closed up. */
  letter-spacing: -0.01em;
}

/*
 * Bigger than the application's scale tops out at. `--text-2xl` is a panel
 * heading in a console; a landing page headline is a different job, and
 * `clamp` keeps it from overflowing a phone.
 */
h1 { font-size: clamp(var(--text-2xl), 5.5vw, 3rem); }
h2 { font-size: clamp(var(--text-xl), 3.4vw, 2rem); margin-top: var(--space-6); }
h3 { font-size: var(--text-lg); }

p { margin: 0 0 var(--space-4); }

/*
 * A comfortable measure for prose, and for the headings above it: a heading
 * that runs to the full 68rem while the paragraph under it stops at 44 reads
 * as a ragged edge rather than as a column. Cards and the plan grid keep the
 * full width -- they are a row of narrow measures already.
 */
main > section > h1,
main > section > h2,
main > section > p,
main > section > ul.facts { max-width: 44rem; }

.lede {
  font-size: var(--text-lg);
  color: var(--ink-2);
  max-width: 44rem;
}

strong { font-weight: 600; color: var(--ink); }

code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--line-2);
  color: var(--ink);
  padding: 0 var(--space-1);
  border-radius: var(--space-1);
}

a { color: var(--link); }

/*
 * A visible focus ring everywhere, in the link colour so it is legible on
 * every ground this site uses. Never `outline: none`: keyboard navigation is
 * the whole of how some readers move through a page.
 */
:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 2px;
  border-radius: var(--space-1);
}

/* -- Skip link ------------------------------------------------------------
 *
 * Off-screen until focused rather than `display: none`, which would take it
 * out of the tab order and make it decoration.
 */
.skip {
  position: absolute;
  left: var(--space-3);
  top: calc(-1 * var(--space-7));
  z-index: 2;
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-4);
  text-decoration: none;
  transition: top 120ms ease;
}

.skip:focus { top: var(--space-3); }

/* -- Header -------------------------------------------------------------- */

/*
 * The masthead is a navy band, and the brand mark sits directly on it.
 *
 * The mark is a REVERSED lockup -- 34 of its 39 shapes are white -- so it needs
 * a dark ground. It had one for a day, as a plaque behind it, and a plaque is a
 * box around a logo rather than a masthead: in dark mode especially it read as
 * a small rectangle stuck on the header rather than as part of it. The band is
 * what a reversed mark is drawn for, so the band is what it gets, and every
 * other thing in the header moved onto the navy with it.
 *
 * The border is the band's finish rather than the thing that makes it a band.
 * --rail holds its navy through the dark theme so the header is still blue
 * there, and at 1.55:1 against --paper it is -- quiet, but a hue shift rather
 * than a luminance one. The hairline draws that boundary crisply instead of
 * leaving the eye to find the edge of a soft fill. See --rail-line in
 * tokens.css.
 */
.site-header {
  background: var(--rail);
  color: var(--rail-ink);
  border-bottom: 1px solid var(--rail-line);
  padding: var(--space-3) var(--space-5);
  /* The three groups wrap onto their own lines on a phone rather than being
     squeezed; no menu button, because a menu button needs a script. */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-5);
}

/* The measure rule above centres block children; the header is a flex row and
   would collapse under it. */
.site-header > * { margin-inline: 0; }

/*
 * The mark itself carries no ground of its own: it is on the band. No width or
 * height here either -- the `<img>` carries both as attributes (see
 * `render.ts`) so the row is its final height on first paint, and a
 * `height: auto` in this file would throw that away.
 */
.brand {
  display: inline-flex;
  align-items: center;
  margin-right: auto;
  text-decoration: none;
}

/* Block, so the line box under an inline image does not leave a gap under the
   mark and push the band taller than the artwork. */
.brand img { display: block; }

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.site-nav a {
  color: var(--rail-ink-2);
  text-decoration: none;
  padding-bottom: var(--space-1);
  /* Reserved on every entry so the current one does not shift the row. */
  border-bottom: 2px solid transparent;
}

.site-nav a:hover { color: var(--rail-ink); }

/*
 * The current page: announced by `aria-current`, and shown three ways for
 * everyone else -- ink, weight and a rule.
 *
 * The rule is the one that does the work now. On the old white header the two
 * inks were far apart; on the band --rail-ink and --rail-ink-2 are 1.59:1, near
 * enough that a reader glancing at the row would not be sure. A solid
 * --rail-ink underline at 11.90:1 (light) / 18.94:1 (dark) against the band is
 * unmissable, and it is a shape rather than a colour -- which is the property
 * that makes it survive a reader who cannot separate the two inks at all.
 */
.site-nav a[aria-current="page"] {
  color: var(--rail-ink);
  font-weight: 600;
  border-bottom-color: var(--rail-ink);
}

/*
 * The one filled control on the band, and it inverts.
 *
 * NOT --primary-bg, which is #1C3760 in light mode -- the rail's own colour, so
 * the button would have vanished into the band completely. On navy the highest
 * contrast fill available is the light ink itself, with the band's colour as
 * its label: 11.90:1 in light, 18.94:1 in dark.
 */
.nav-cta {
  background: var(--rail-ink);
  color: var(--rail);
  text-decoration: none;
  font-weight: 600;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius);
}

/*
 * The focus ring, inside the band only.
 *
 * The global ring is --link, which on the light rail is 1.05:1 -- an invisible
 * focus indicator on the first thing a keyboard reader reaches. --accent is
 * 5.13:1 there and 8.16:1 on the dark rail. This is also why `tokens.css` gives
 * the portal's own focus ring the same colour: it has to survive the rail.
 */
.site-header :focus-visible { outline-color: var(--accent); }

/* -- Sections ------------------------------------------------------------ */

.hero {
  padding: var(--space-7) var(--space-5) var(--space-6);
}

/*
 * The only appearance of `--accent` on this site, and deliberately decorative:
 * it marks the top of the page and says nothing, so its 2.14:1 against
 * `--paper` in light mode carries no information to lose.
 */
.hero::before {
  content: "";
  display: block;
  width: var(--space-7);
  height: var(--space-1);
  background: var(--accent);
  border-radius: var(--space-1);
  margin-bottom: var(--space-5);
}

.section {
  padding: var(--space-6) var(--space-5);
  border-top: 1px solid var(--line);
}

.section.note {
  background: var(--accent-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* The measure rule centres it; the padding above keeps it off the edges. */
  max-width: 68rem;
  margin: var(--space-6) auto var(--space-7);
}

/* -- Calls to action ----------------------------------------------------- */

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  margin-top: var(--space-5);
}

.cta, .cta-secondary {
  display: inline-block;
  text-decoration: none;
  font-weight: 600;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius);
  border: 1px solid transparent;
}

.cta {
  background: var(--primary-bg);
  color: var(--primary-ink);
}

.cta:hover { box-shadow: var(--shadow); }

.cta-secondary {
  background: var(--card);
  color: var(--link);
  border-color: var(--line);
}

/* -- Cards --------------------------------------------------------------- */

.cards, .plan-grid, .facts {
  list-style: none;
  padding: 0;
  margin: var(--space-5) 0 0;
}

.cards, .plan-grid {
  display: grid;
  /* `auto-fit` + `minmax` is the whole responsive story: three across on a
     laptop, one on a phone, and no breakpoint to keep in step with a design. */
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: var(--space-4);
}

.card, .plan {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--space-5);
}

.card h3, .plan h3 { margin-top: 0; }
.card p, .plan p { color: var(--ink-2); }
.card p:last-child, .plan p:last-child { margin-bottom: 0; }

/* -- Plans --------------------------------------------------------------- */

.plan { display: flex; flex-direction: column; }

.plan-price {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  /* Not `--accent`: orange text is under 3:1 on white, which is why the tokens
     carry a separate ink for it. */
  color: var(--accent-ink);
  margin-bottom: var(--space-2);
}

.plan-allowance {
  color: var(--ink);
  font-weight: 600;
  margin-bottom: var(--space-3);
}

.plan-machines {
  font-size: var(--text-sm);
  border-top: 1px solid var(--line-2);
  padding-top: var(--space-3);
  /* Pushes the call to action to the bottom of every card, so a row of plans
     has one button line however long the blurbs are. */
  margin-top: auto;
}

.plan .cta-row { margin-top: var(--space-4); }

/* -- Product screenshots -------------------------------------------------- */

/*
 * A light/dark pair, side by side where there is room and stacked where there
 * is not.
 *
 * `figure` is a direct child of `main` rather than being wrapped in a section
 * with a heading, and that is the shots' own conditionality showing through:
 * they are absent from every locally built site (see `pages.ts`), and a section
 * heading over nothing is the one thing worse than no picture. A figcaption
 * names it instead, which is a caption's job.
 *
 * `width`/`height` are on each `<img>` from the PNG itself, so the box is
 * reserved before the bytes arrive; `height: auto` here is what stops those
 * attributes from also fixing the rendered size. The images are captured at 2x,
 * so they are always displayed smaller than they are.
 */
.shots {
  /* The same inline padding every `.section` carries, so the images line up
     with the prose above and below them rather than sitting proud of it. */
  margin: 0 auto;
  padding: var(--space-2) var(--space-5) var(--space-6);
}

.shot-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: var(--space-4);
}

.shots img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* The shots are photographed on the product's own paper, and a screenshot
     that bleeds into the page behind it stops reading as a screen. */
  background: var(--card);
}

.shots figcaption {
  margin-top: var(--space-3);
  color: var(--ink-2);
  font-size: var(--text-sm);
}

/* -- Fact lists ---------------------------------------------------------- */

.facts li {
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink-2);
}

.facts li:last-child { border-bottom: 0; }
.facts strong { color: var(--ink); }

/* -- Footer -------------------------------------------------------------- */

/*
 * On `--card`, not on `--rail`. See the module comment: --rail has no ink token
 * that reads on it in both themes, and inventing one would mean a literal.
 */
.site-footer {
  background: var(--card);
  border-top: 1px solid var(--line);
  color: var(--ink-2);
  padding: var(--space-6) var(--space-5);
  font-size: var(--text-sm);
}

.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.footer-nav a { color: var(--link); }

/* -- Motion -------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; }
}
