/* Two pages, three languages, no framework. The app's own design system is for a 1.2" round
   screen and does not transfer; what does transfer is the intent — dark by default, one dominant
   element, and type doing the work.

   Three states, not two: the OS preference, and an explicit light or dark the reader chose. The
   palettes are named once and then *mapped* to the semantic tokens, so a colour is written in one
   place while the mapping — which is what actually has to be repeated per state — is six lines.
   Writing the values twice is how the light theme drifts from itself. */
:root {
  color-scheme: dark light;
  --measure: 34rem;

  --dark-surface: #05060a;
  --dark-surface-raised: #0e111a;
  --dark-on-surface: #f4f6fb;
  --dark-on-surface-muted: #98a1b5;
  --dark-accent: #c8f065;
  --dark-divider: #1d2230;

  --light-surface: #fbfbfd;
  --light-surface-raised: #ffffff;
  --light-on-surface: #10131b;
  --light-on-surface-muted: #565f73;
  --light-accent: #2f6d1f;
  --light-divider: #e3e6ee;

  --surface: var(--dark-surface);
  --surface-raised: var(--dark-surface-raised);
  --on-surface: var(--dark-on-surface);
  --on-surface-muted: var(--dark-on-surface-muted);
  --accent: var(--dark-accent);
  --divider: var(--dark-divider);
}

/* The OS preference, unless the reader has said otherwise on this browser. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --surface: var(--light-surface);
    --surface-raised: var(--light-surface-raised);
    --on-surface: var(--light-on-surface);
    --on-surface-muted: var(--light-on-surface-muted);
    --accent: var(--light-accent);
    --divider: var(--light-divider);
  }
}

/* What the reader chose. Both directions are written out: a reader on a light OS who picks dark
   needs the dark half as much as the other way round, and only the first is covered by the
   default above. */
:root[data-theme="light"] {
  color-scheme: light;
  --surface: var(--light-surface);
  --surface-raised: var(--light-surface-raised);
  --on-surface: var(--light-on-surface);
  --on-surface-muted: var(--light-on-surface-muted);
  --accent: var(--light-accent);
  --divider: var(--light-divider);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --surface: var(--dark-surface);
  --surface-raised: var(--dark-surface-raised);
  --on-surface: var(--dark-on-surface);
  --on-surface-muted: var(--dark-on-surface-muted);
  --accent: var(--dark-accent);
  --divider: var(--dark-divider);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--surface);
  color: var(--on-surface);
  font: 400 17px/1.65 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }
a:hover { text-decoration: none; }

/* Three columns: the name on the left, the guide and the FAQ in the middle of the page, the tools on
   the right. The outer two share the leftover width equally, which is what keeps the middle centred
   on the page rather than between two things of different widths. */
.bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--divider);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: -0.02em;
  text-decoration: none;
}

/* The mark carries its own dark ground, so it needs no theme variant -- it reads on both. */
.wordmark img { display: block; border-radius: 0.42rem; }

.bar nav { color: var(--on-surface-muted); font-size: 0.9rem; }

.bar-links { display: flex; gap: 1.5rem; font-size: 0.95rem; }
.bar-links a { color: var(--on-surface-muted); text-decoration: none; }
.bar-links a:hover { color: var(--on-surface); }
.bar nav [aria-current] { color: var(--on-surface); font-weight: 600; }

.bar .wordmark { justify-self: start; }

.bar-tools {
  display: flex;
  justify-self: end;
  align-items: center;
  gap: 0;
}

/* Revealed only when theme.js ran. Without it the button could not do anything, and `hidden` in
   the markup means no-JS readers never see a control that does nothing. */
:root.js .themetoggle[hidden] { display: inline-flex; }

.themetoggle {
  align-items: center;
  justify-content: center;
  /* Matches the language summary's box exactly, so the two sit as a pair rather than as a button
     next to a link. 44px on a phone. */
  padding: 0.55rem 0.6rem;
  border: 0;
  border-radius: 0.5rem;
  background: transparent;
  color: var(--on-surface);
  cursor: pointer;
}

.themetoggle:hover { background: var(--surface-raised); }

/* One icon at a time, and it shows what you would get rather than what you have: on a dark page
   the sun, because the sun is where the click leads. The pair is driven by the same three states
   as the palette, so the icon can never disagree with the background. */
.themetoggle .icon-sun { display: block; }
.themetoggle .icon-moon { display: none; }

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .themetoggle .icon-sun { display: none; }
  :root:not([data-theme="dark"]) .themetoggle .icon-moon { display: block; }
}

:root[data-theme="light"] .themetoggle .icon-sun { display: none; }
:root[data-theme="light"] .themetoggle .icon-moon { display: block; }
:root[data-theme="dark"] .themetoggle .icon-sun { display: block; }
:root[data-theme="dark"] .themetoggle .icon-moon { display: none; }

/* The language picker: a globe and the current code, opening a list. `position: relative` on the
   details so the menu can hang off it, and the whole thing is `<details>` so it needs no script. */
/* Flex, so the summary is not placed on a line of text: inline, it sat on that line's baseline and
   came out a few pixels below the theme toggle beside it. */
.langpick { position: relative; display: flex; }
.bar-tools nav { display: flex; }

.langpick summary {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  /* 44px of touch target on a phone, where the header is otherwise a 16px icon nobody can hit. */
  padding: 0.55rem 0.6rem;
  margin-right: -0.6rem;
  border-radius: 0.5rem;
  color: var(--on-surface);
  cursor: pointer;
  list-style: none;
}

/* Both spellings: WebKit still uses the pseudo-element, everyone else honours list-style. */
.langpick summary::-webkit-details-marker { display: none; }

.langpick summary:hover { background: var(--surface-raised); }
.langpick .globe { display: block; }
.langpick-current { font-weight: 650; letter-spacing: 0.04em; }

.langpick-menu {
  position: absolute;
  right: 0;
  z-index: 2;
  display: grid;
  min-width: 9rem;
  margin-top: 0.5rem;
  padding: 0.35rem;
  border: 1px solid var(--divider);
  border-radius: 0.7rem;
  background: var(--surface-raised);
}

.langpick-menu > * {
  padding: 0.6rem 0.7rem;
  border-radius: 0.45rem;
  color: var(--on-surface-muted);
  text-decoration: none;
}

.langpick-menu a:hover { background: var(--surface); color: var(--on-surface); }
.langpick-menu [aria-current] { color: var(--on-surface); font-weight: 650; }

main { padding: 0 1.5rem; }

.hero { max-width: var(--measure); margin: 4rem auto 3rem; }

.eyebrow {
  margin: 0 0 0.75rem;
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

h1 {
  margin: 0;
  font-size: clamp(2.6rem, 9vw, 4rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.02;
}

/* The mark beside the name, at the proportion the brand already fixed rather than at one invented
   here: `brand/courtovo-logo.svg` sets a 48-tall mark against a 33px wordmark, so the mark is
   1.45× the type size. It looks larger than the letters because it is a rounded square around a
   letterform — the square has to clear the cap height on both sides to read as an icon, and
   matching it to the caps instead makes it look shrunken.

   0.06em of optical nudge: the square's own padding leaves it sitting a hair high against a
   baseline, and the eye reads that as misalignment rather than as the geometry it is. */
.wordmark-large {
  display: flex;
  align-items: center;
  gap: 0.28em;
}

/* No border-radius here: the SVG draws its own rounded square (rx 26 of 96), and a CSS radius on
   top would be a second, disagreeing corner. */
.wordmark-large img {
  height: 1.45em;
  width: auto;
  transform: translateY(0.06em);
}

.subtitle {
  margin: 0.5rem 0 1.5rem;
  font-size: 1.3rem;
  color: var(--on-surface-muted);
}

.lead { margin: 0 0 1.5rem; font-size: 1.12rem; }
.stores { margin: 0; color: var(--on-surface-muted); font-size: 0.95rem; }

/* The way into the manual, as a button pair under the hero. The app is small on the screen and has
   a lot of rules behind it, and the guide is where they are — so it is offered where a first-time
   reader is still deciding, not in a footer they never reach. */
.start-here {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 0.75rem;
  margin: 1.75rem 0 0;
}
.start-here-label {
  width: 100%;
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.features {
  max-width: var(--measure);
  margin: 0 auto 3rem;
  display: grid;
  gap: 1.75rem;
}

.feature h2 { margin: 0 0 0.4rem; font-size: 1.1rem; letter-spacing: -0.01em; }
.feature p { margin: 0; color: var(--on-surface-muted); }

/* Wider than the reading measure, because the grids below need room. */
.sports {
  max-width: 48rem;
  margin: 0 auto 3rem;
}

.sports > h2 { margin: 0 0 1.25rem; font-size: 1.1rem; letter-spacing: -0.01em; }

/* What it counts: the ten tiles beside the paragraph about them, and what it does not count as a
   full-width band underneath, after a hairline. Side by side, "not yet" was a column as tall as the
   ten tiles and mostly empty, which made a short list look like a large gap. Under the rule it is two
   lines, and its size on the page is its size in the product. */
.sports-now,
.sports-not-yet { margin: 0 0 1.25rem; }

.sports-now-body { display: grid; gap: 1rem 2rem; align-items: start; }

@media (min-width: 44rem) {
  .sports-now-body { grid-template-columns: 1fr 1fr; }
  .sports-now-body .sport-grid { margin: 0; }
}

.sports-not-yet {
  padding-top: 1.25rem;
  border-top: 1px solid var(--divider);
}

.sports-now h3,
.sports-not-yet h3 {
  margin: 0 0 0.6rem;
  font-size: 0.95rem;
  font-weight: 650;
}

.sports-now h3 { color: var(--accent); }
.sports-not-yet h3 { color: var(--on-surface-muted); }
.sports-now p,
.sports-not-yet p { margin: 0; color: var(--on-surface-muted); font-size: 0.98rem; }
.sports-ask { margin: 0 0 1rem; }

/* The sports, as their own drawings with their names under them.

   **Two grids and not one, and the difference is what a tile does.** The counted six are links to a
   page about that sport; the measured fifteen are not links, because there is nothing sport-specific
   to say about measuring one. One flat wall of identical tiles would promise that the watch scores
   yoga, which is the claim §"What the app counts" exists to prevent.

   The *name* is the link, not the picture: a drawing does not rank and cannot be read aloud, so the
   icons are `aria-hidden` and the word carries both jobs. */
.sport-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr));
  gap: 1rem 0.5rem;
  margin: 0 0 1.25rem;
}

.sport-grid > * {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.45rem;
  padding: 0.6rem 0.25rem;
  border-radius: 0.6rem;
  color: var(--on-surface);
  font-size: 0.88rem;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
}

.sport-grid a:hover { background: var(--surface-raised); }

.sport-grid svg {
  width: 2rem;
  height: 2rem;
  /* Converted from the app's own vectors and inlined, so this is the colour they take. */
  color: var(--accent);
}

/* Quieter in every way the counted ones are loud: smaller, muted, and not a link. */
.sport-grid.measured {
  grid-template-columns: repeat(auto-fill, minmax(4.25rem, 1fr));
  gap: 0.75rem 0.25rem;
}

.sport-grid.measured > * { color: var(--on-surface-muted); font-size: 0.8rem; }
.sport-grid.measured svg { width: 1.5rem; height: 1.5rem; color: var(--on-surface-muted); }

.sports-measured-label {
  margin: 1.5rem 0 0.6rem;
  font-size: 0.95rem;
  font-weight: 650;
  color: var(--on-surface-muted);
}

.sports-measured { margin: 0 0 1.5rem; color: var(--on-surface-muted); font-size: 0.98rem; }

/* The other five sports, at the foot of each sport page. */
.sport-others {
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--divider);
  color: var(--on-surface-muted);
  font-size: 0.92rem;
}

.cta.secondary {
  background: transparent;
  color: var(--on-surface);
  border: 1px solid var(--divider);
}

/* Wider than --measure, and that is the point of having the variable at all. 34rem is a *reading*
   measure — 65-75 characters, past which the eye loses the start of the next line — and it belongs
   to running text. Pictures are not read a line at a time, so constraining them to it made the
   whole page look cramped and blamed the text for it. Text keeps the measure; this does not. */
.shots {
  max-width: 60rem;
  margin: 0 auto 3.5rem;
}

/* Centred, unlike every other section heading. Those sit on the text column's left edge; this
   block is wider than that column, so a left-aligned heading here would start further left than
   all of them and read as a misalignment rather than as a wider section. */
.shots > h2 {
  margin: 0 0 1.5rem;
  font-size: 1.1rem;
  letter-spacing: -0.01em;
  text-align: center;
}

.shots-row {
  display: grid;
  gap: 2rem;
  justify-items: center;
}

@media (min-width: 40rem) {
  .shots-row { grid-template-columns: repeat(3, 1fr); gap: 1.5rem; }
}

.shots-row figure { margin: 0; max-width: 15rem; }

/* Round, because the watch is. The goldens are square renders of a round device, so the corners
   they carry are black padding the hardware never shows — cropping them is the truthful shape, not
   a flattering one. The ring is what stops a black circle from dissolving into a dark page. */
.shots-row img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 50%;
  border: 1px solid var(--divider);
  background: #000;
}

.shots-row figcaption {
  margin-top: 0.85rem;
  color: var(--on-surface-muted);
  font-size: 0.92rem;
  text-align: center;
}

.shots-note {
  max-width: var(--measure);
  margin: 1.75rem auto 0;
  color: var(--on-surface-muted);
  font-size: 0.9rem;
  text-align: center;
}

/* Four looks of one screen. Narrower frames than the screenshots above and deliberately so: these
   are not screens to read, they are the same screen four times, and the eye needs them close enough
   together to compare in one glance rather than by scrolling between them. */
.themes {
  max-width: 48rem;
  margin: 0 auto 3.5rem;
}

.themes > h2 {
  margin: 0 0 0.6rem;
  font-size: 1.1rem;
  letter-spacing: -0.01em;
  text-align: center;
}

.themes-lead {
  max-width: var(--measure);
  margin: 0 auto 1.75rem;
  color: var(--on-surface-muted);
  text-align: center;
}

/* Two across on a phone rather than one: a single column would make this a list of four watches,
   and a comparison that has to be remembered between scrolls is not one. */
.themes-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
  justify-items: center;
}

@media (min-width: 40rem) {
  .themes-row { grid-template-columns: repeat(4, 1fr); gap: 1.25rem; }
}

.themes-row figure { margin: 0; max-width: 9rem; }

/* The same round crop as the screenshots, and for the same reason -- but no black backdrop here:
   half of these are light themes, and a black disc behind a pale one would show as a rim. */
.themes-row img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 50%;
  border: 1px solid var(--divider);
}

.themes-row figcaption {
  margin-top: 0.6rem;
  color: var(--on-surface-muted);
  font-size: 0.85rem;
  text-align: center;
}

.feedback {
  max-width: var(--measure);
  margin: 0 auto 3rem;
}

.feedback > h2 { margin: 0 0 0.6rem; font-size: 1.1rem; letter-spacing: -0.01em; }
.feedback > p { margin: 0 0 1.25rem; color: var(--on-surface-muted); }

/* Wraps rather than shrinking: two buttons side by side is the intent, but on a 320px screen a
   button squeezed to fit stops looking like one, and this pair must read as two equal offers. */
.feedback-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.feedback-include-label { margin: 0 0 0.5rem; font-size: 0.95rem; }

.feedback-include {
  margin: 0 0 1rem;
  padding-left: 1.1rem;
  color: var(--on-surface-muted);
  font-size: 0.95rem;
}

.feedback-include li { margin-bottom: 0.25rem; }

.feedback-note {
  margin: 0;
  color: var(--on-surface-muted);
  font-size: 0.9rem;
}

.clubs {
  max-width: var(--measure);
  margin: 0 auto 4rem;
  padding: 1.75rem;
  border: 1px solid var(--divider);
  border-radius: 1rem;
  background: var(--surface-raised);
}

.clubs h2 { margin: 0 0 0.6rem; font-size: 1.15rem; }
.clubs p { margin: 0 0 1rem; color: var(--on-surface-muted); }
.clubs p:last-child { margin-bottom: 0; }

.cta {
  display: inline-block;
  padding: 0.6rem 1.1rem;
  border-radius: 0.6rem;
  background: var(--accent);
  color: var(--surface);
  font-weight: 650;
  text-decoration: none;
}

.policy,
.guide { max-width: var(--measure); margin: 3.5rem auto 4rem; }
.policy h1,
.guide h1 { margin: 0 0 1.5rem; font-size: clamp(2rem, 6vw, 2.6rem); line-height: 1.1; }
.policy .lead,
.guide .lead { margin: 1.25rem 0; font-size: 1.08rem; }
.policy .updated,
.guide .updated { color: var(--on-surface-muted); font-size: 0.88rem; margin: 0 0 2.5rem; }
.policy section,
.guide section { margin: 0 0 2rem; }
.policy h2,
.guide h2 { margin: 0 0 0.5rem; font-size: 1.05rem; letter-spacing: -0.01em; }
.policy p,
.guide p { margin: 0 0 0.75rem; color: var(--on-surface-muted); }
.policy .lead p,
.guide .lead p { color: var(--on-surface); }
.policy .back,
.guide .back { margin-top: 3rem; }

/* The policy is rendered from Markdown now, so it can contain anything those files contain:
   the two comparison tables, the deletion list, and the operator placeholders. */
.policy ul,
.guide ul { margin: 0 0 0.75rem; padding-left: 1.1rem; color: var(--on-surface-muted); }
.policy li,
.guide li { margin: 0 0 0.4rem; }
.policy strong,
.guide strong { color: var(--on-surface); font-weight: 600; }
.policy em,
.guide em { color: var(--on-surface-muted); }
.policy code,
.guide code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.92em; }

/* A two- or three-column table of prose does not fit a phone, and squeezing it produces one word
   per line. It scrolls sideways in its own box instead, which keeps the rest of the page still. */
.policy .table-scroll,
.guide .table-scroll { overflow-x: auto; margin: 0 0 1rem; }
.policy table,
.guide table { border-collapse: collapse; width: 100%; min-width: 28rem; font-size: 0.94rem; }
.policy th,
.guide th,
.policy td,
.guide td {
  border-bottom: 1px solid var(--divider);
  padding: 0.55rem 0.7rem 0.55rem 0;
  text-align: left;
  vertical-align: top;
  color: var(--on-surface-muted);
}
.policy th,
.guide th { color: var(--on-surface); font-weight: 600; }
.policy td:last-child,
.guide td:last-child,
.policy th:last-child,
.guide th:last-child { padding-right: 0; }
/* The legal notice is a label and a value per row. Side by side where there is room; on a phone the
   label goes above its value, because the German labels ("Handelsregisternummer") are single words
   that would otherwise either squeeze the value into a column or break in the middle. */
.imprint table { min-width: 0; margin: 0 0 1.5rem; }
.imprint th { width: 40%; }
@media (max-width: 30rem) {
  .imprint tr,
  .imprint th,
  .imprint td { display: block; width: auto; }
  .imprint th { border-bottom: 0; padding-bottom: 0.1rem; }
}

/* The guide's own pieces: a third heading level, numbered steps, the one verbatim drawing, and the
   way back to the contents. The policy has none of these -- it is one flat run of numbered sections
   -- so they are the only rules the two documents do not share. */
.guide h3 {
  margin: 1.75rem 0 0.5rem;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--on-surface);
}

/* A document heading, clearly a step above the text: at 1.05rem it was body-sized and bold, and a
   page of those read as one long run of paragraphs. The rule above it is what separates topics on a
   page that is scrolled rather than paged. */
.guide h2 {
  margin: 2.75rem 0 0.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--divider);
  font-size: 1.35rem;
  line-height: 1.25;
  letter-spacing: -0.015em;
}
.guide h2:first-of-type { margin-top: 2rem; }

.guide ol { margin: 0 0 0.75rem; padding-left: 1.3rem; color: var(--on-surface-muted); }
.guide ol li { margin: 0 0 0.4rem; }

/* Scrolls rather than wraps: it is a drawing made of spaces, and a wrapped line stops being one. */
.guide pre {
  overflow-x: auto;
  margin: 0 0 1rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--divider);
  border-radius: 0.5rem;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--on-surface-muted);
}

/* A link has to look like one. It used to inherit the muted paragraph colour with an underline in
   the divider colour — close to invisible on the dark theme, so a reader of the guide's third line
   never found the link in it. The accent underline is the signal, and the brighter text is what
   carries it for a reader who does not see the colour. */
.guide a {
  color: var(--on-surface);
  text-decoration-color: var(--accent);
  text-decoration-thickness: 0.09em;
  text-underline-offset: 0.2em;
}
.guide a:hover { color: var(--accent); }
.guide h2 a, .guide h3 a { text-decoration: none; }

/* A paragraph that is nothing but drawings. They are the gesture table's pictures, so they sit in a
   row at the reading measure and wrap rather than shrink -- five 100-unit drawings squeezed onto a
   320px screen would be five smudges, and the table below says the same thing in words anyway. */
.guide .figures {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.25rem;
  justify-content: center;
  margin: 1.5rem 0;
}

/* Inlined, so `currentColor` inside them resolves against this rule and one drawing serves both
   themes. Fetched through `<img>` they would render in a document of their own and come out black
   on a black page, which is why the header icons here are inlined too. */
.guide .figures svg {
  width: 4.5rem;
  height: 4.5rem;
  color: var(--on-surface-muted);
}

.guide-back {
  max-width: var(--measure);
  margin: 2.5rem auto -1.5rem;
  font-size: 0.9rem;
}

.guide-back a { color: var(--on-surface-muted); }


/* The club connection, announced. It is the only band on the page with a filled ground: the hero
   is type on paper and the features are a plain grid, so one solid block reads as "this is new"
   without a colour nobody else uses or an animation that would age badly. */
.whats-new {
  max-width: var(--measure);
  margin: 0 auto 3rem;
  padding: 1.75rem;
  border-radius: 1rem;
  background: var(--surface-raised);
  border: 1px solid var(--divider);
}
.whats-new .badge {
  display: inline-block;
  margin: 0 0 0.75rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: var(--accent);
  /* The page ground, not a fixed navy: the accent is light green on the dark theme and dark green
     on the light one, so a single ink colour is unreadable on one of them. */
  color: var(--surface);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.whats-new h2 { margin: 0 0 0.6rem; font-size: 1.5rem; letter-spacing: -0.02em; }
.whats-new-lead { margin: 0 0 1.5rem; color: var(--on-surface-muted); }
.whats-new-points { display: grid; gap: 1.1rem; }
.whats-new-points h3 { margin: 0 0 0.3rem; font-size: 0.98rem; }
.whats-new-points p { margin: 0; color: var(--on-surface-muted); font-size: 0.95rem; }
.whats-new-note {
  margin: 1.5rem 0 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--divider);
  color: var(--on-surface-muted);
  font-size: 0.92rem;
}

@media (min-width: 46rem) {
  .whats-new-points { grid-template-columns: repeat(3, 1fr); gap: 1.4rem; }
}

/* On a phone the middle has no room of its own: the links take a centred second row. */
@media (max-width: 30rem) {
  .bar { grid-template-columns: 1fr auto; row-gap: 0.6rem; }
  .bar-links { grid-column: 1 / -1; grid-row: 2; justify-content: center; }
}

footer {
  border-top: 1px solid var(--divider);
  padding: 2rem 1.5rem 3rem;
  color: var(--on-surface-muted);
  font-size: 0.88rem;
}

footer p { max-width: var(--measure); margin: 0 auto 0.75rem; }
footer .links { margin-bottom: 0; }
