
:root {
  color-scheme: light dark;
  /* Beds, lightest at the top of the section. */
  --rock-1: #f4f6f7;
  --rock-2: #eaeef0;
  --rock-3: #e0e6e9;
  --panel: #ffffff;
  --ink: #1b2225;
  --ink-2: #5f6c71;
  --line: #cdd6da;
  --plane: rgba(255, 255, 255, 0.65);
  --seam: #3e7c8c;
  --seam-text: #2f6373;
  --good: #3f6f5b;
  --danger: #96504a;
  /* The footer is the deepest bed, so it is a colour in its own right rather
     than a reuse of --ink. Borrowing ink inverts with the theme and paints a
     near-white slab across the bottom of a dark page. */
  --foot-bg: #1b2225;
  --foot-dim: #9aa8ad;
  --foot-link: #dce4e7;
  /* One measure token: changing the site's width is a one-line edit. */
  --measure: 71rem;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;
}
/* The dark theme is designed rather than inverted: the beds darken in the same
   order, and the seam lightens enough to hold contrast on a dark ground. */
@media (prefers-color-scheme: dark) {
  :root {
    --rock-1: #101416;
    --rock-2: #161b1e;
    --rock-3: #1c2225;
    --panel: #131819;
    --ink: #e6ecee;
    --ink-2: #93a1a6;
    --line: #2a3337;
    --plane: rgba(255, 255, 255, 0.045);
    --seam: #6fb4c6;
    --seam-text: #86c3d3;
    --good: #7fbba1;
    --danger: #d2867e;
    /* Darker than the deepest bed rather than lighter than it: the page should
       settle at the bottom, not brighten. */
    --foot-bg: #0a0d0e;
    --foot-dim: #7e8c91;
    --foot-link: #c9d5d9;
  }
}
* { box-sizing: border-box; }
/* Column layout so a short page still pins its footer to the bottom of the
   viewport: the sign-in page is one card, and without this the footer floats
   mid-screen with bare background beneath it. */
body {
  margin: 0;
  font: 16px/1.65 var(--sans);
  background: var(--rock-1);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
main { flex: 1; }
a { color: var(--seam-text); }
:focus-visible { outline: 2px solid var(--seam); outline-offset: 3px; }
h1 {
  font-size: clamp(1.9rem, 5.5vw, 2.9rem); line-height: 1.02;
  letter-spacing: -0.042em; font-weight: 700; margin: 0 0 1rem;
  max-width: 20ch; text-wrap: balance;
}
h2 {
  font-size: clamp(1.35rem, 2.6vw, 1.85rem); line-height: 1.1;
  letter-spacing: -0.032em; font-weight: 700; margin: 0 0 0.5rem;
  text-wrap: balance;
}
/* §17.3's shell. The old rule centred a 26rem column, which on a monitor was a
   ribbon in whitespace; width is now per-band and mobile-first. */
.band { max-width: var(--measure); margin: 0 auto; padding: 2.5rem 1.15rem; }
.band.tight { padding-block: 1.75rem; }
/* Beds: alternating stone with a hairline bedding plane between them. */
.bed { border-bottom: 1px solid var(--line); }
.bed-1 { background: var(--rock-1); }
.bed-2 { background: var(--rock-2); }
.bed-3 { background: var(--rock-3); }
.bed + .bed { box-shadow: inset 0 1px 0 var(--plane); }
/* The seam: a section label with a dashed ore rule running to the edge. */
.seam {
  font: 600 0.66rem/1 var(--mono); letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--seam-text); margin: 0 0 1.2rem;
  display: flex; align-items: center; gap: 0.7rem;
}
.seam::after {
  content: ""; flex: 1; height: 1px; opacity: 0.5;
  background: repeating-linear-gradient(90deg, var(--seam) 0 4px, transparent 4px 9px);
}
/* The same ore rule with no label, where a heading already names the section.
   An eyebrow that repeats the H2 beneath it is noise, but the rule still marks
   where one bed ends and the next begins. */
.seam-rule {
  border: 0; height: 1px; margin: 0 0 1.4rem; opacity: 0.5;
  background: repeating-linear-gradient(90deg, var(--seam) 0 4px, transparent 4px 9px);
}
.lede { font-size: clamp(1.02rem, 1.5vw, 1.2rem); color: var(--ink-2); margin: 0 0 1.9rem; max-width: 34rem; }
.lede b, .lede strong { color: var(--ink); font-weight: 600; }
.dek { color: var(--ink-2); font-size: 0.97rem; margin: 0 0 1.5rem; max-width: 34rem; }
/* Header. The old site had no navigation at all — the only route to Manage,
   Support, Privacy or Terms was five identical footer links, which is what
   made "where do I click for X" a structural problem rather than a cosmetic
   one (§17.2 wants the support and privacy routes reachable, not merely
   present). */
.top { position: sticky; top: 0; z-index: 6; background: var(--rock-1); border-bottom: 1px solid var(--ink); }
.top-in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 0.8rem 1.15rem; max-width: var(--measure); margin: 0 auto;
}
.brand { display: flex; align-items: center; gap: 0.7rem; text-decoration: none; color: var(--ink); }
.brand svg { display: block; flex: none; }
.brand .nm { display: grid; line-height: 1; }
.brand .nm b { font: 700 1.05rem/1 var(--sans); letter-spacing: -0.035em; }
.brand .nm span {
  font: 600 0.6rem/1 var(--mono); letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--ink-2); margin-top: 0.32rem;
}
.top nav { display: flex; gap: 1.05rem; align-items: center; }
.top nav a {
  font: 500 0.82rem/1 var(--sans); text-decoration: none; color: var(--ink-2);
  padding-bottom: 0.28rem; border-bottom: 2px solid transparent; white-space: nowrap;
}
.top nav a[aria-current] { color: var(--ink); border-bottom-color: var(--seam); font-weight: 650; }
.top nav a:hover:not([aria-current]) { color: var(--ink); }
/* Secondary items fold away on the narrowest screens rather than wrapping into
   a second row; the brand, Support and Manage always survive. */
.top nav a.fold { display: none; }
/* The purchase page carries no nav (§17.3) — this replaces it, so the page
   does not read as one that lost its header. */
.secure { font: 600 0.66rem/1 var(--mono); letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2); }
/* Cards, in three roles rather than one. A single .card rule for the price,
   the privacy claim, the voucher field and the delete button is what made
   every page read flat: nothing signalled which block mattered. */
.card { background: var(--panel); border: 1px solid var(--line); padding: 1.4rem 1.5rem; }
.card > :first-child { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }
/* Body copy only. Scoped with :not() so it cannot outrank the component classes
   it sits beside: a bare ".card p" is more specific than ".price", so an
   unscoped rule here silently shrank the price to body size wherever a price
   sat in a card — which is every page that quotes one. */
.card p:not([class]) { font-size: 0.95rem; }
.card p { margin: 0 0 0.7rem; }
/* Role 2: the offer. One seam edge, on the thing being sold. */
.card.offer { border-left: 4px solid var(--seam); }
/* Role 3: destructive. Transfers are capped and deletion is irreversible;
   neither should look like "Save name" (§17.3's accessibility rule is why the
   border is not the only signal — the label and button carry the colour too). */
.card.grave { border-left: 4px solid var(--danger); }
.card.grave .label { color: var(--danger); }
.stack { display: grid; gap: 1rem; }
/* A grid lays out every child, including ones that render nothing — a <script>
   or an empty error line between two cards would otherwise occupy a row and
   open a gap with nothing in it. :empty covers the error paragraph, which is
   present from first paint and filled only when something fails. */
.stack > script, .stack > [hidden], .stack > .error:empty { display: none; }
.label {
  font: 600 0.66rem/1 var(--mono); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-2); margin: 0 0 0.75rem;
}
.device { font: 600 1.15rem/1 var(--mono); letter-spacing: 0.16em; margin: 0; }
.price {
  font: 700 3rem/0.94 var(--sans); letter-spacing: -0.052em; margin: 0 0 0.5rem;
  font-variant-numeric: tabular-nums;
}
.price small { font: 500 0.9rem/1 var(--sans); color: var(--ink-2); letter-spacing: 0; }
.muted { color: var(--ink-2); font-size: 0.9rem; }
/* The primary action is ink, not accent: the seam marks structure, and a
   coloured button would be a fourth accent hit on a page budgeted for three. */
button, .btn {
  display: block; width: 100%; padding: 0.9rem; text-align: center; text-decoration: none;
  font: 650 0.95rem/1 var(--sans); background: var(--ink); color: var(--rock-1);
  border: 0; cursor: pointer; margin-top: 1rem;
}
button.secondary, .btn.secondary {
  background: transparent; color: var(--ink); border: 1px solid var(--ink);
}
button.danger, .btn.danger {
  background: transparent; color: var(--danger); border: 1px solid var(--danger);
}
button:disabled { opacity: 0.6; cursor: progress; }
.error { color: var(--danger); margin-top: 0.75rem; min-height: 1.25rem; }
.ok { color: var(--good); font-weight: 600; }
/* Status. Colour is never the only signal (§17.3): each state carries a glyph
   and a border as well as a hue. */
.state {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font: 600 0.72rem/1 var(--mono); letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.42rem 0.65rem; border: 1px solid currentColor;
}
.state.on { color: var(--good); }
.state.on::before { content: "\25B0"; }
.state.off { color: var(--danger); }
.state.off::before { content: "\25B1"; }
/* §5.5: the payment form is mounted here rather than on a Stripe-hosted page.
   Hidden until a client secret arrives so the page does not show an empty box. */
#payment[hidden] { display: none; }
#payment { margin-top: 1.25rem; }
.consent { display: grid; grid-template-columns: 1.1rem 1fr; gap: 0.7rem; align-items: start; margin-top: 1rem; }
.consent input { margin: 0.2rem 0 0; width: 1.1rem; height: 1.1rem; accent-color: var(--ink); }
.consent label { font-size: 0.88rem; color: var(--ink-2); }
.terms { font-size: 0.78rem; color: var(--ink-2); margin-top: 1rem; }
/* §15.4's redemption field. Monospace and wide letter-spacing for the same
   reason the device ID uses them: a code read off a screen or a card is
   compared character by character. */
.code {
  width: 100%; padding: 0.82rem 1rem; font-size: 1.05rem;
  font-family: var(--mono); letter-spacing: 0.14em;
  text-transform: uppercase; text-align: center;
  border: 1px solid var(--ink); background: var(--panel); color: inherit;
}
/* An email or a device name is read as words, not compared character by
   character, so it opts out of the code field's monospace treatment. Was an
   inline style attribute on three fields, which §19.5's CSP forbids — it was
   silently doing nothing. */
.code.plain { text-transform: none; letter-spacing: normal; text-align: left; font-family: var(--sans); }
/* Field and button side by side once there is room for them (§17.2's forms are
   one input and one action almost everywhere). */
.pair { display: grid; gap: 0.6rem; }
.pair button, .pair .btn { margin-top: 0; }
/* §17.2: the footer carries the trust signals — a named legal entity, a real
   support route, a linked privacy policy — on every page rather than on
   whichever page someone remembered to add them to. */
footer {
  background: var(--foot-bg); color: var(--foot-dim);
  padding: 2.25rem 1.15rem 2.75rem; font-size: 0.86rem;
}
footer .fin { max-width: var(--measure); margin: 0 auto; }
footer nav { display: flex; flex-wrap: wrap; gap: 0.55rem 1.6rem; margin-bottom: 1.1rem; }
footer nav a { color: var(--foot-link); text-decoration: none; font-weight: 500; }
footer nav a:hover { text-decoration: underline; }
footer .ent { font: 0.74rem/1.6 var(--mono); opacity: 0.75; }
/* Prose pages (§20.7's documents, §17.2's support page) read top to bottom at a
   comfortable measure, rather than in the phone-width ribbon the old rule gave
   them on a monitor. */
.prose { max-width: 36rem; }
.prose h2 { font-size: 1.3rem; margin-top: 2.25rem; }
.prose h3 { font-size: 1.05rem; margin-top: 1.75rem; margin-bottom: 0.4rem; }
.prose li { margin-bottom: 0.35rem; }
.prose blockquote {
  margin: 1.25rem 0; padding: 0.1rem 0 0.1rem 1.1rem;
  border-left: 3px solid var(--seam); color: var(--ink-2);
}
.prose table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
.prose th, .prose td {
  text-align: left; padding: 0.6rem 0.5rem; vertical-align: top;
  border-bottom: 1px solid var(--line);
}
.prose code {
  font-family: var(--mono); font-size: 0.9em;
  background: var(--rock-3); padding: 0.1em 0.3em;
}
/* §30 is unresolved on the legal entity, so the published documents still carry
   placeholders. Marking them visibly is deliberate: an unnoticed [COUNTRY] on a
   live terms page is worse than an obvious one. */
.placeholder {
  background: #fde68a; color: #78350f; padding: 0.05em 0.3em; font-weight: 600;
}
.notice {
  border: 1px solid var(--seam); background: var(--rock-3);
  padding: 0.85rem 1rem; margin-bottom: 1.5rem; font-size: 0.9rem;
}
/* §17.2's screenshot on a real watch. width and height are declared on the
   element so the layout does not jump once it loads — the page may be read on
   mobile data, where the image arrives well after the text. */
.shot { margin: 0; padding: 1.5rem; background: var(--panel); border: 1px solid var(--line); text-align: center; }
.shot img { width: 100%; max-width: 17rem; height: auto; }
.shot figcaption { margin-top: 0.9rem; font: 500 0.72rem/1.5 var(--mono); color: var(--ink-2); }
/* The trial steps as a core log: depths down the side, each stratum described.
   The numbering encodes real sequence — the trial genuinely starts at step two
   and ends thirty days later — rather than decorating three unordered points. */
.core { display: grid; border: 1px solid var(--line); background: var(--panel); }
.core > div {
  display: grid; grid-template-columns: 4.5rem 1fr; gap: 1.1rem;
  padding: 1.1rem 1.25rem; border-bottom: 1px solid var(--line); align-items: start;
}
.core > div:last-child { border-bottom: 0; }
.core .depth {
  font: 600 0.64rem/1.5 var(--mono); letter-spacing: 0.1em; color: var(--seam-text);
  border-right: 3px solid var(--seam); padding-right: 0.6rem;
}
.core p { margin: 0; font-size: 0.94rem; }
.core p b { display: block; font-weight: 650; margin-bottom: 0.25rem; font-size: 1rem; }
.core p span { color: var(--ink-2); }
/* Kept for any ordinary ordered list in a card. */
.steps { margin: 0; padding-left: 1.2rem; }
.steps li { margin-bottom: 0.5rem; }
/* The device-family summary, as mineral chips rather than a run-on sentence. */
.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0 0 1rem; }
.chip {
  font: 500 0.79rem/1 var(--sans); background: var(--panel);
  border: 1px solid var(--line); color: var(--ink); padding: 0.45rem 0.72rem;
}
/* A definition table for the facts blocks. */
.ledger { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.ledger th, .ledger td {
  text-align: left; padding: 0.7rem 0; vertical-align: top;
  border-bottom: 1px solid var(--line);
}
.ledger tr:last-child th, .ledger tr:last-child td { border-bottom: 0; }
.ledger th { font-weight: 600; width: 45%; }
.ledger td { color: var(--ink-2); }
.ledger td b { color: var(--ink); font-weight: 650; }
/* §17.1's growth views. Every rule below exists because §19.5's CSP sets
   style-src 'self' with no 'unsafe-inline' — a chart cannot carry its own
   styling in a style attribute, so the shape lives here and the markup
   supplies only geometry through presentation attributes. */
.metrics { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem; margin-bottom: 1.25rem; }
.metric { border: 1px solid var(--line); background: var(--panel); padding: 0.9rem 1rem; }
.metric .figure {
  font-size: 1.6rem; font-weight: 700; margin: 0.15rem 0 0;
  letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
}
.metric .label { margin: 0; }
/* A figure that could not be computed reads as "—" rather than as 0 (§17.1's
   conversion rate with no trials issued). Dimmed so it is visibly not a
   number, since a zero and an absence mean opposite things here. */
.metric .none { font-size: 1.6rem; font-weight: 700; margin: 0.15rem 0 0; color: var(--ink-2); opacity: 0.5; }
.chart { width: 100%; height: auto; display: block; margin: 0.5rem 0 0; overflow: visible; }
.chart .bar { fill: var(--seam); }
/* §17.3: colour is never the only signal. The two activation series differ in
   fill and are also labelled and separately totalled beneath the chart. */
.chart .bar-renewal { fill: color-mix(in srgb, var(--seam) 45%, transparent); }
.chart .axis { stroke: var(--line); stroke-width: 1; }
.chart-caption {
  font: 500 0.72rem/1.5 var(--mono); color: var(--ink-2);
  display: flex; justify-content: space-between; margin: 0.25rem 0 0;
}
.swatches { display: flex; gap: 1rem; font-size: 0.8rem; color: var(--ink-2); margin: 0.4rem 0 0; }
.swatch { display: flex; align-items: center; gap: 0.35rem; }
.swatch i { width: 0.7rem; height: 0.7rem; background: var(--seam); display: inline-block; }
.swatch.renewal i { background: color-mix(in srgb, var(--seam) 45%, transparent); }
.rows { width: 100%; border-collapse: collapse; margin: 0.5rem 0 0; }
.rows th, .rows td {
  text-align: left; padding: 0.5rem; font-size: 0.9rem;
  border-bottom: 1px solid var(--line);
}
.rows td.num, .rows th.num { text-align: right; font-variant-numeric: tabular-nums; }
.window { display: flex; gap: 0.5rem; margin-bottom: 1.25rem; }
.window a {
  flex: 1; text-align: center; padding: 0.55rem; border: 1px solid var(--line);
  text-decoration: none; font-size: 0.9rem; color: var(--ink);
}
.window a.on { background: var(--rock-3); border-color: var(--ink); font-weight: 650; }
.stadia input {
  width: 100%; padding: 0.75rem; font-size: 1rem;
  border: 1px solid var(--ink); background: var(--panel); color: inherit;
}
/* §17.2's supported-device list. A <details> element rather than a
   script-driven toggle, so the full list opens with no JavaScript (§17.3's
   "render usefully without it"); the filter is an enhancement layered over a
   list that is already present and already readable. */
.devices { margin-top: 0.75rem; }
.devices summary { cursor: pointer; padding: 0.5rem 0; font-weight: 650; }
.device-filter {
  width: 100%; padding: 0.75rem; margin: 0.5rem 0; font-size: 1rem;
  background: var(--panel); color: inherit; border: 1px solid var(--ink);
}
/* Capped and scrollable: 118 names would otherwise push §17.2's privacy and
   trust sections off the bottom of a phone screen, and those are the parts
   that do the conversion work. */
.device-list {
  margin: 0; padding-left: 1.2rem; max-height: 18rem; overflow-y: auto;
  font-size: 0.9rem;
}
.device-list li { margin-bottom: 0.25rem; }

/* ---------------------------------------------------------------------------
   Widening. Every rule above is the phone layout; everything below is a
   min-width enhancement over it, which is what keeps §5.4's mobile-first
   requirement honest rather than nominal.

   §5.4 scopes mobile-first to *purchase and management* specifically, so the
   landing page is free to use a monitor — and .checkout below deliberately
   does not, because a single decision funnel spread across a full-width row
   detaches the buy button from the price it belongs to.
   --------------------------------------------------------------------------- */
@media (min-width: 46rem) {
  .top nav a.fold { display: block; }
  .band { padding-inline: 2rem; }
  .two { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: start; }
  .pair { grid-template-columns: 1fr auto; align-items: center; }
  .pair button, .pair .btn { width: auto; padding-inline: 1.5rem; }
}
@media (min-width: 62rem) {
  .band { padding-inline: 2.5rem; padding-block: 3rem; }
  .band.tight { padding-block: 2.25rem; }
  /* Landing hero: copy left, watch right. This is the change that removes the
     long scroll before the price on a monitor. */
  .split { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 3.5rem; align-items: center; }
  /* Portal: a sticky summary rail beside the working column, so licence state
     stays on screen while the actions scroll. */
  .portal { display: grid; grid-template-columns: 22rem 1fr; gap: 2rem; align-items: start; }
  .portal .rail { position: sticky; top: 6rem; display: grid; gap: 1rem; }
  .checkout {
    display: grid; grid-template-columns: 1fr 20rem; gap: 2.5rem;
    align-items: start; max-width: 60rem; margin: 0 auto;
  }
  .checkout .aside { position: sticky; top: 6rem; }
  .metrics { grid-template-columns: repeat(4, 1fr); }
}
