/* ===========================================================================
   Rehearsio — website
   ---------------------------------------------------------------------------
   Every value below is lifted from docs/10-design-tokens.md. Nothing is
   invented here except the two display sizes in §2, which are marked as such:
   a landing page headline sits above the app's screen title (28) and below its
   hero numeral (96), and the app has no token for that because the app has no
   landing page.

   The rules the app lives by, carried over verbatim:
   - No accent colour. Hierarchy is built from fill, weight and size.
   - Warm neutrals only, not one cold grey.
   - Separation by background and air, not by lines. Borders are the exception.
   - Icons are thin, monochrome, unfilled (Lucide).
   - Anything that changes state moves, and it moves on the tokens in §7.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. Colour — docs/10-design-tokens.md §1
   Light is the default; dark follows the system, and [data-theme] wins over
   both so the toggle works in either direction.
   --------------------------------------------------------------------------- */

:root {
  --bg-canvas: #ffffff;
  --bg-subtle: #f7f6f4;
  --bg-sunken: #efede9;
  --bg-elevated: #ffffff;

  --overlay-hover: rgba(46, 44, 40, 0.05);
  --overlay-press: rgba(46, 44, 40, 0.1);

  --text-primary: #2e2c28;
  --text-secondary: #625e58;
  --text-muted: #78746e;
  --text-disabled: #a6a199;
  --text-inverted: #ffffff;

  --border-subtle: #edebe7;
  --border-default: #e0ddd7;
  --border-strong: #c9c5bd;
  --border-focus: #2e2c28;

  --fill-solid: #2e2c28;
  --fill-solid-pressed: #46433e;
  --fill-subtle: #f1efeb;
  --fill-track: #e0ddd7;

  /* The tile is the same dark one in both appearances — S13.2, app.json.
     --tile-edge is what holds it off the page underneath: nothing in the light
     theme, where the shadow does that, and a hairline in the dark one, where
     the ground under it is the tile's own colour. */
  --tile-ground: #191817;
  --tile-mark: #edebe8;
  --tile-edge: transparent;

  --shadow-card: 0 1px 2px rgba(46, 44, 40, 0.06);
  --shadow-popover: 0 8px 24px rgba(46, 44, 40, 0.12);

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg-canvas: #191817;
    --bg-subtle: #211f1e;
    --bg-sunken: #131211;
    --bg-elevated: #2a2826;

    --overlay-hover: rgba(255, 255, 255, 0.06);
    --overlay-press: rgba(255, 255, 255, 0.11);

    --text-primary: #edebe8;
    --text-secondary: #a8a39c;
    --text-muted: #8c8781;
    --text-disabled: #5e5a55;
    --text-inverted: #191817;

    --border-subtle: #262422;
    --border-default: #322f2c;
    --border-strong: #4a4642;
    --border-focus: #edebe8;

    --fill-solid: #edebe8;
    --fill-solid-pressed: #ffffff;
    --fill-subtle: #2a2826;
    --fill-track: #3a3734;

    --tile-edge: #4a4642; /* border.strong — §7: in the dark a layer is edged, not shadowed */
    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-popover: 0 8px 24px rgba(0, 0, 0, 0.55);

    color-scheme: dark;
  }
}

:root[data-theme='dark'] {
  --bg-canvas: #191817;
  --bg-subtle: #211f1e;
  --bg-sunken: #131211;
  --bg-elevated: #2a2826;

  --overlay-hover: rgba(255, 255, 255, 0.06);
  --overlay-press: rgba(255, 255, 255, 0.11);

  --text-primary: #edebe8;
  --text-secondary: #a8a39c;
  --text-muted: #8c8781;
  --text-disabled: #5e5a55;
  --text-inverted: #191817;

  --border-subtle: #262422;
  --border-default: #322f2c;
  --border-strong: #4a4642;
  --border-focus: #edebe8;

  --fill-solid: #edebe8;
  --fill-solid-pressed: #ffffff;
  --fill-subtle: #2a2826;
  --fill-track: #3a3734;

  --tile-edge: #4a4642; /* border.strong — §7: in the dark a layer is edged, not shadowed */
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-popover: 0 8px 24px rgba(0, 0, 0, 0.55);

  color-scheme: dark;
}

/* ---------------------------------------------------------------------------
   2. Type — docs/10-design-tokens.md §4
   Seven steps with wide gaps. Body never goes below 17: the phone is on a
   music stand 60–80 cm away.
   --------------------------------------------------------------------------- */

:root {
  --font-system:
    -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
    sans-serif;
  --font-mono:
    ui-monospace, 'SF Mono', SFMono-Regular, Menlo, 'Roboto Mono', 'Courier New', monospace;

  --size-caption: 13px;
  --size-label: 15px;
  --size-body: 17px;
  --size-subhead: 20px;
  --size-title: 28px;

  /* Web only. The two steps a landing page needs and a screen does not. */
  --size-headline: clamp(28px, 4.2vw, 40px);
  --size-display: clamp(38px, 7vw, 68px);

  --measure: 34em; /* ~68 characters at body size */
}

/* ---------------------------------------------------------------------------
   3. Space, 4. Radius, 5. Layout — §5, §6
   --------------------------------------------------------------------------- */

:root {
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-lg: 16px;
  --space-xl: 24px;
  --space-xxl: 32px;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-full: 999px;

  --page-max: 1080px;
  --page-gutter: var(--space-lg);
  --header-h: 60px;
}

@media (min-width: 640px) {
  :root {
    --page-gutter: var(--space-xxl);
  }
}

/* ---------------------------------------------------------------------------
   6. Motion — §8. Three durations, three curves, and nothing else.
   --------------------------------------------------------------------------- */

:root {
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 320ms;

  --easing-standard: cubic-bezier(0.2, 0, 0, 1);
  --easing-enter: cubic-bezier(0, 0, 0.2, 1);
  --easing-exit: cubic-bezier(0.4, 0, 1, 1);
}

/* ---------------------------------------------------------------------------
   7. Reset
   --------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Where a jumped-to anchor comes to rest: clear of the sticky header, with
     spacing.xl of air under it. **This is the only place that offset is
     allowed to be set.** scroll-padding here and scroll-margin on the target
     do not override one another, they add: with the same 84 on both, every
     heading in a contents list landed 168 down, and what filled the gap was
     the end of the chapter before it — which is what the reader saw and
     reported. One offset, on the container, so it also covers the section
     anchors on the landing page, which are not headings and carry no rule. */
  scroll-padding-top: calc(var(--header-h) + var(--space-xl));
}

body {
  margin: 0;
  background: var(--bg-canvas);
  color: var(--text-primary);
  font-family: var(--font-system);
  font-size: var(--size-body);
  line-height: 24px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
h4,
p,
ul,
ol,
figure {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

img,
svg {
  display: block;
  max-width: 100%;
}

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

/* The focus ring from §1: 2pt, offset 2pt, in border.focus. One rule, every
   focusable thing, and only for keyboards. */
:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------------------------------------------------------------------------
   8. Type helpers
   --------------------------------------------------------------------------- */

.display {
  font-size: var(--size-display);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.headline {
  font-size: var(--size-headline);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.title {
  font-size: var(--size-title);
  font-weight: 700;
  line-height: 34px;
  letter-spacing: -0.5px;
}

.body {
  font-size: var(--size-body);
  font-weight: 400;
  line-height: 26px;
}

.caption {
  font-size: var(--size-caption);
  font-weight: 500;
  line-height: 18px;
  letter-spacing: 0.2px;
}

.muted {
  color: var(--text-secondary);
}

.lead {
  font-size: var(--size-subhead);
  font-weight: 400;
  line-height: 30px;
  color: var(--text-secondary);
  max-width: 30em;
}

/* The eyebrow above a heading. Small caps, wide tracking — the "very small
   next to very large" half of the contrast rule in 09-design-brief.md §3.1. */
.eyebrow {
  font-size: var(--size-caption);
  font-weight: 500;
  line-height: 18px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------------------
   9. Shell
   --------------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  left: var(--space-lg);
  top: var(--space-lg);
  z-index: 100;
  padding: var(--space-md) var(--space-lg);
  background: var(--fill-solid);
  color: var(--text-inverted);
  border-radius: var(--radius-md);
  font-size: var(--size-label);
  font-weight: 500;
  transform: translateY(-200%);
  transition: transform var(--duration-base) var(--easing-enter);
}

.skip-link:focus {
  transform: translateY(0);
}

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

/* The site header is a solid surface, not glass. In the app the material is
   used on the tab bar and nowhere else (09-design-brief.md §3.1); a translucent
   header here would be the one place the rule was broken for decoration. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg-canvas);
  border-bottom: 1px solid transparent;
  transition: border-color var(--duration-base) var(--easing-standard);
}

.site-header[data-scrolled='true'] {
  border-bottom-color: var(--border-subtle);
}

.site-header__inner {
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: var(--space-lg);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-md);
  margin-right: auto;
  padding: var(--space-sm);
  margin-left: calc(var(--space-sm) * -1);
  border-radius: var(--radius-md);
  transition: background-color var(--duration-fast) var(--easing-standard);
}

.brand:hover {
  background: var(--overlay-hover);
}

.brand:active {
  background: var(--overlay-press);
}

.brand__mark {
  width: 15px;
  color: var(--text-primary);
}

.brand__name {
  font-size: var(--size-body);
  font-weight: 600;
  letter-spacing: -0.2px;
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.nav__link {
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  font-size: var(--size-label);
  font-weight: 500;
  color: var(--text-secondary);
  transition:
    background-color var(--duration-fast) var(--easing-standard),
    color var(--duration-fast) var(--easing-standard);
}

.nav__link:hover {
  background: var(--overlay-hover);
  color: var(--text-primary);
}

.nav__link:active {
  background: var(--overlay-press);
}

.nav__link[aria-current='page'] {
  color: var(--text-primary);
  background: var(--fill-subtle);
}

@media (max-width: 519px) {
  .nav__link--wide {
    display: none;
  }
}

/* The theme switch. The app follows the system and offers no such control;
   this one exists because a website is looked at on somebody else's machine. */
.theme-toggle {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--text-secondary);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-standard),
    color var(--duration-fast) var(--easing-standard),
    transform var(--duration-fast) var(--easing-standard);
}

.theme-toggle:hover {
  background: var(--overlay-hover);
  color: var(--text-primary);
}

.theme-toggle:active {
  background: var(--overlay-press);
  transform: scale(0.92); /* IconButton press scale, §8 */
}

.theme-toggle .icon-moon {
  display: none;
}

:root[data-theme='dark'] .theme-toggle .icon-moon,
:root:not([data-theme='light']) .theme-toggle .icon-moon {
  display: block;
}

:root[data-theme='dark'] .theme-toggle .icon-sun {
  display: none;
}

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

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

/* ---------------------------------------------------------------------------
   10. Sections
   --------------------------------------------------------------------------- */

.section {
  padding-block: clamp(56px, 9vw, 104px);
}

.section--sunken {
  background: var(--bg-subtle);
}

.section__head {
  max-width: var(--measure);
  margin-bottom: var(--space-xxl);
}

.section__head > * + * {
  margin-top: var(--space-md);
}

.rule {
  border: 0;
  height: 1px;
  background: var(--border-subtle);
  margin: 0;
}

/* ---------------------------------------------------------------------------
   11. Hero
   --------------------------------------------------------------------------- */

.hero {
  padding-block: clamp(48px, 8vw, 96px) clamp(56px, 9vw, 104px);
}

.hero__grid {
  display: grid;
  gap: clamp(40px, 6vw, 72px);
  align-items: center;
}

@media (min-width: 860px) {
  .hero__grid {
    grid-template-columns: minmax(0, 1fr) auto;
  }
}

.hero__copy > * + * {
  margin-top: var(--space-xl);
}

.hero__copy .eyebrow + h1 {
  margin-top: var(--space-md);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
}

/* The tile, drawn from the same numbers as the icon on the phone:
   mark height 64 % of the tile, field 55 × 72 (tools/build-brand-assets).

   The hairline is not decoration. The tile ships dark on both system themes
   (S13.2), and its ground is the dark theme's own bg.canvas — the very same
   #191817. On a dark page the icon has nothing to sit against, and the shadow
   that separates it by day is invisible by night. §7 of the tokens already says
   how a layer is separated in the dark: a lightening ground and a border, not a
   shadow. On a phone the wallpaper does this job; on the page we do. */
.tile {
  --tile-size: clamp(168px, 30vw, 232px);
  width: var(--tile-size);
  height: var(--tile-size);
  border-radius: calc(var(--tile-size) * 0.2237); /* iOS squircle, near enough */
  background: var(--tile-ground);
  display: grid;
  place-items: center;
  box-shadow: var(--shadow-popover);
  border: 1px solid var(--tile-edge);
  flex: none;
}

.tile svg {
  height: 64%;
  width: auto;
  color: var(--tile-mark);
}

.hero__tile {
  display: grid;
  justify-items: center;
  gap: var(--space-lg);
}

/* ---------------------------------------------------------------------------
   12. Buttons — the three levels from §1: solid, quiet, bare.
   --------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  min-height: 44px;
  padding: var(--space-md) var(--space-xl);
  border: 0;
  border-radius: var(--radius-md);
  font-family: inherit;
  font-size: var(--size-label);
  font-weight: 500;
  cursor: pointer;
  transition:
    transform var(--duration-fast) var(--easing-standard),
    background-color var(--duration-fast) var(--easing-standard);
}

.btn:active {
  transform: scale(0.96); /* Button press scale, §8 */
}

.btn--primary {
  background: var(--fill-solid);
  color: var(--text-inverted);
}

.btn--primary:hover {
  background: var(--fill-solid-pressed);
}

.btn[aria-disabled='true'] {
  color: var(--text-disabled);
  background: var(--fill-subtle);
  cursor: default;
  pointer-events: none;
}

/* The store badges, as Apple and Google publish them: Apple's SVG from its own
   marketing tools, Google's PNG from play.google.com/badges. Both are
   trademarks and neither may be recoloured, outlined or re-drawn, so nothing
   here touches the artwork — the rules below only size it and choose which of
   Apple's two variants the theme calls for.

   The two files are not built alike. Apple's is the badge and nothing else,
   119.66 x 40. Google's is a 646 x 250 canvas with the badge sitting 41px in
   on every side — that margin is the clear space its guidelines demand, and it
   stays. Matching them by height therefore means scaling Google's file by the
   ratio of canvas to badge, 250/168, so the two visible buttons come out the
   same height rather than Google's arriving a quarter short. */
.hero__actions {
  align-items: center;
  gap: var(--space-sm);
}

.badge {
  --badge-h: clamp(42px, 4.4vw, 52px);
  display: inline-flex;
}

.badge img {
  display: block;
  width: auto;
  height: var(--badge-h);
}

.badge--google img {
  height: calc(var(--badge-h) * 250 / 168);
}

/* Apple ships a black badge and a white one; which reads depends on the ground,
   and the ground here follows the reader's theme. Same three-state pattern as
   the sun and moon in the header. Google publishes one generic badge, black
   with a grey outline, and that outline is what carries it on a dark page. */
.badge img.badge__dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .badge img.badge__light {
    display: none;
  }

  :root:not([data-theme='light']) .badge img.badge__dark {
    display: block;
  }
}

:root[data-theme='dark'] .badge img.badge__light {
  display: none;
}

:root[data-theme='dark'] .badge img.badge__dark {
  display: block;
}

:root[data-theme='light'] .badge img.badge__light {
  display: block;
}

:root[data-theme='light'] .badge img.badge__dark {
  display: none;
}

/* A chip: state carried by a dot as well as by colour, per 04-conventions.md
   — information is never colour alone. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  padding: 6px var(--space-md);
  border-radius: var(--radius-full);
  background: var(--fill-subtle);
  color: var(--text-secondary);
  font-size: var(--size-caption);
  font-weight: 500;
  letter-spacing: 0.2px;
}

.chip__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--text-muted);
  flex: none;
}

/* ---------------------------------------------------------------------------
   13. Feature grid
   --------------------------------------------------------------------------- */

.features {
  display: grid;
  gap: var(--space-lg);
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
}

.feature {
  padding: var(--space-xl);
  border-radius: var(--radius-lg);
  background: var(--bg-canvas);
  border: 1px solid var(--border-subtle);
  transition:
    border-color var(--duration-base) var(--easing-standard),
    transform var(--duration-base) var(--easing-standard);
}

.section--sunken .feature {
  background: var(--bg-elevated);
  border-color: transparent;
  box-shadow: var(--shadow-card);
}

.feature:hover {
  border-color: var(--border-default);
  transform: translateY(-2px);
}

.feature__icon {
  width: 24px;
  height: 24px;
  color: var(--text-secondary);
  margin-bottom: var(--space-lg);
}

.feature h3 {
  font-size: var(--size-body);
  font-weight: 600;
  line-height: 24px;
  margin-bottom: var(--space-sm);
}

.feature p {
  font-size: var(--size-label);
  line-height: 22px;
  color: var(--text-secondary);
}

/* ---------------------------------------------------------------------------
   14. Statement — the one big claim, alone on the page.
   --------------------------------------------------------------------------- */

.statement {
  max-width: 22em;
  font-size: var(--size-headline);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.statement__note {
  margin-top: var(--space-xl);
  max-width: var(--measure);
  color: var(--text-secondary);
  line-height: 28px;
}

/* A numbered walk-through of the one scenario. */
.steps {
  display: grid;
  gap: var(--space-xl);
  counter-reset: step;
  margin-top: var(--space-xxl);
}

@media (min-width: 720px) {
  .steps {
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-lg);
  }
}

.step {
  padding-top: var(--space-lg);
  border-top: 1px solid var(--border-default);
  counter-increment: step;
}

.step::before {
  content: counter(step, decimal-leading-zero);
  display: block;
  font-family: var(--font-mono);
  font-size: var(--size-caption);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  margin-bottom: var(--space-md);
}

.step h3 {
  font-size: var(--size-body);
  font-weight: 600;
  margin-bottom: var(--space-xs);
}

.step p {
  font-size: var(--size-label);
  line-height: 22px;
  color: var(--text-secondary);
}

/* ---------------------------------------------------------------------------
   15. Screens — real screenshots in a tablet frame
   The app is drawn for a music stand, so the tablet is the honest way to show
   it: these are iPad screenshots at their own 834 × 1210 points, and the frame
   around them keeps that ratio rather than inventing one.
   --------------------------------------------------------------------------- */

/* The four screens as one overlapping row, run out to the full width of the
   window. They are the same object seen four times, so they are shown as a
   deck rather than as four separate cards: same size, same overlap, and the
   bezel plus its shadow is what separates one from the next.

   Breaking out of the page's column is done with a negative inline margin
   rather than 100vw positioning, and the scroller is what keeps that safe: a
   deck too wide for the window is swiped instead of pushing the page sideways,
   which is also what makes the row survive a phone. */
.screens-bleed {
  margin-inline: calc(50% - 50vw);
  width: 100vw;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}

.screens-bleed::-webkit-scrollbar {
  display: none;
}

.screens {
  /* max-content plus min-width:100% is the trick that lets one row both centre
     itself when it fits and scroll when it does not. */
  display: flex;
  align-items: flex-start;
  justify-content: center;
  width: max-content;
  min-width: 100%;
  padding-inline: var(--page-gutter);
  /* Room inside the scroller for the shadows, which overflow-y would clip. */
  padding-block: var(--space-xl);
}

.screen {
  /* Sized so the deck itself is nearly the width of the window: four cards
     overlapping by 26 % come to 3.22 x this, and 28vw puts that at about 90vw —
     wide enough to read as full-bleed, narrow enough that the gutter survives. */
  --tablet: clamp(178px, 28vw, 520px);
  flex: 0 0 auto;
  width: var(--tablet);
  margin: 0;
}

/* Every card after the first slides back over the one before it. A later
   sibling paints on top on its own, so no z-index is needed. */
.screen + .screen {
  margin-left: calc(var(--tablet) * -0.26);
}

/* The frame. A modern tablet has one even bezel and no button, so the whole
   drawing is two rounded rectangles and a hairline: the outer edge catches the
   light, the inner one is the glass. Nothing here is a picture — a bezel drawn
   in CSS scales to any width without a second asset, and in a deck it is what
   holds one screen off the next. */
.device {
  width: 100%;
  padding: 2.6%;
  border-radius: clamp(14px, 6%, 24px);
  background: linear-gradient(155deg, #3a3835, #1d1c1a 42%, #121110);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.07) inset,
    var(--shadow-popover);
}

.device__screen {
  aspect-ratio: 834 / 1210;
  border-radius: clamp(7px, 3.4%, 12px);
  overflow: hidden;
  background: var(--tile-ground);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6);
}

.device__screen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

/* ---------------------------------------------------------------------------
   15a. The four beats of a session, each with the part of the screen it means
   --------------------------------------------------------------------------- */

.step__shot {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  margin-bottom: var(--space-lg);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--tile-ground);
  border: 1px solid var(--border-default);
}

.step__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The step is a card now rather than a bare column, so the picture has an edge
   to sit against; the rule that used to separate them would be a second edge. */
.step {
  padding-top: 0;
  border-top: 0;
}

.step::before {
  margin-bottom: var(--space-sm);
}

/* ---------------------------------------------------------------------------
   17. Footer
   --------------------------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--border-subtle);
  padding-block: var(--space-xxl) clamp(32px, 5vw, 56px);
  background: var(--bg-canvas);
}

.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xl);
  justify-content: space-between;
  align-items: flex-start;
}

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

.site-footer a {
  font-size: var(--size-label);
  color: var(--text-secondary);
  transition: color var(--duration-fast) var(--easing-standard);
}

.site-footer a:hover {
  color: var(--text-primary);
}

.site-footer__legal {
  color: var(--text-muted);
  font-size: var(--size-caption);
  letter-spacing: 0.2px;
  margin-top: var(--space-xxl);
}

/* ---------------------------------------------------------------------------
   18. Long-form pages — privacy, terms
   --------------------------------------------------------------------------- */

.doc {
  padding-block: clamp(40px, 6vw, 72px) clamp(56px, 9vw, 96px);
}

.doc__grid {
  display: grid;
  gap: clamp(32px, 5vw, 64px);
}

@media (min-width: 900px) {
  .doc__grid {
    grid-template-columns: 200px minmax(0, 1fr);
    align-items: start;
  }
}

.doc__head {
  margin-bottom: var(--space-xxl);
}

.doc__head h1 {
  margin-block: var(--space-md) var(--space-lg);
}

.doc__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  align-items: center;
}

/* The table of contents. Sticky on a wide screen, plain list on a phone. */
.toc {
  order: 2;
}

@media (min-width: 900px) {
  .toc {
    order: 0;
    position: sticky;
    top: calc(var(--header-h) + var(--space-xl));
  }
}

.toc__title {
  color: var(--text-muted);
  margin-bottom: var(--space-md);
}

.toc ol {
  counter-reset: toc;
  border-left: 1px solid var(--border-subtle);
}

.toc a {
  display: block;
  padding: var(--space-sm) var(--space-md);
  margin-left: -1px;
  border-left: 1px solid transparent;
  font-size: var(--size-label);
  line-height: 20px;
  color: var(--text-secondary);
  transition:
    color var(--duration-fast) var(--easing-standard),
    border-color var(--duration-fast) var(--easing-standard);
}

.toc a:hover {
  color: var(--text-primary);
}

.toc a[aria-current='true'] {
  color: var(--text-primary);
  border-left-color: var(--fill-solid);
  font-weight: 500;
}

.prose {
  max-width: var(--measure);
}

.prose section + section {
  margin-top: clamp(40px, 5vw, 56px);
}

.prose h2 {
  font-size: var(--size-subhead);
  font-weight: 600;
  line-height: 26px;
  letter-spacing: -0.2px;
  margin-bottom: var(--space-lg);
}

.prose h3 {
  font-size: var(--size-body);
  font-weight: 600;
  margin-block: var(--space-xl) var(--space-sm);
}

.prose p {
  line-height: 28px;
  color: var(--text-secondary);
}

.prose p + p {
  margin-top: var(--space-lg);
}

.prose ul {
  margin-top: var(--space-lg);
  display: grid;
  gap: var(--space-md);
}

.prose li {
  position: relative;
  padding-left: var(--space-xl);
  line-height: 28px;
  color: var(--text-secondary);
}

.prose li::before {
  content: '';
  position: absolute;
  left: var(--space-sm);
  top: 12px;
  width: 4px;
  height: 4px;
  border-radius: var(--radius-full);
  background: var(--border-strong);
}

/* Long-form text needs three things the landing page never asked for: emphasis
   that reads as emphasis, links that look like links inside a paragraph, and a
   way to mark the handful of facts nobody has decided yet. */

.prose strong {
  color: var(--text-primary);
  font-weight: 600;
}

.prose a,
.summary a {
  color: var(--text-primary);
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 3px;
  transition: text-decoration-color var(--duration-fast) var(--easing-standard);
}

.prose a:hover,
.summary a:hover {
  text-decoration-color: var(--text-primary);
}

/* The answer before the argument. A policy nobody reads past the first screen
   should still have told the truth on that screen. */
.summary {
  padding: clamp(20px, 3vw, 28px);
  border-radius: var(--radius-lg);
  background: var(--bg-subtle);
  margin-bottom: clamp(40px, 5vw, 56px);
}

.summary h2 {
  margin-bottom: var(--space-lg);
}

.summary p {
  line-height: 28px;
  color: var(--text-primary);
}

.summary p + p {
  margin-top: var(--space-lg);
}

/* A short aside inside a section — the practical consequence of the paragraph
   above it, which people skip when it is set as another paragraph. */
.aside {
  margin-top: var(--space-lg);
  padding: var(--space-lg);
  border-left: 2px solid var(--border-strong);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--bg-subtle);
}

.aside p {
  line-height: 26px;
}

.aside p + p {
  margin-top: var(--space-md);
}

/* The Impressum is data, not prose: label on the left, value on the right, and
   the eye goes straight to the value. Stacks on a phone, where two columns
   would leave the address hyphenating in a 140px track. */
.identity {
  margin: 0 0 clamp(40px, 5vw, 56px);
  display: grid;
  gap: 1px;
  background: var(--border-subtle);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.identity__row {
  display: grid;
  gap: var(--space-xs);
  padding: var(--space-lg);
  background: var(--bg-canvas);
}

@media (min-width: 560px) {
  .identity__row {
    grid-template-columns: 190px minmax(0, 1fr);
    gap: var(--space-lg);
    align-items: baseline;
  }
}

.identity dt {
  font-size: var(--size-label);
  font-weight: 500;
  color: var(--text-secondary);
}

.identity dd {
  margin: 0;
  font-size: var(--size-body);
  line-height: 26px;
  color: var(--text-primary);
}

.identity a {
  color: var(--text-primary);
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 3px;
}

.identity a:hover {
  text-decoration-color: var(--text-primary);
}

/* The two policy pages carry a status chip under the title; this one carries a
   single line, and it should sit closer than a chip would. */
.doc__head--plain h1 {
  margin-block: var(--space-md) var(--space-sm);
}
