/*
  Dark-first, as the design system requires: people open this at 7am and 9pm.

  THE ATTITUDE COMES FROM SCALE AND STRUCTURE, NOT FROM DECORATION. The brand
  brief asks for "Gen Z without pandering" and then names what that rules out:
  no slang, no gradient blobs, no emoji as brand elements. So the energy here
  is carried by type size, hard contrast, numbered sections and one full-bleed
  band — devices that are confident rather than cute, and that still read as
  this brand rather than as a template.

  Two crimsons, for the reason the design system gives for having two of
  anything: #D6144B is 3.78:1 on the dark ground — enough for shapes, fills,
  rules and DISPLAY type, not enough for running text. #FF5C86 is 6.63:1 and
  carries accent words. One colour doing both jobs is how a brand quietly
  fails a contrast audit.
*/
:root {
  --ground: #0B0C10;
  --surface: #12141A;
  --line: #1E222C;
  --text: #F4F5F7;
  --soft: #98A0B2;
  --accent: #D6144B;
  --on-accent: #FFFFFF;

  /*
    THE SECOND CRIMSON, FINALLY DEFINED. The note at the top of this file has
    always said #FF5C86 is the one that "carries accent words" — 6.63:1 on the
    ground, where #D6144B is 3.78:1 and may only be used for shapes, fills and
    display type. It had never been given a token, so the page had no legal
    way to accent a word and simply did not accent any.

    It does NOT break "red marks an action". That rule is about the FILL:
    nothing on this page is painted crimson except a button. This is a single
    word of display type in the headline, at a contrast ratio that running
    text would pass, and it is used exactly once on the page.
  */
  --accent-word: #FF5C86;

  /*
    THE ONE OTHER COLOUR ON THE PAGE, AND IT IS NOT DECORATION.

    Red means "press this" and nothing else. Green here means "this costs
    nothing" — a fact about the column, not a highlight — which is why it is
    allowed to break the rule where a tinted rule or heading was not.

    It is the app's own `good` token so the two agree: #3FBF9A in the dark
    theme, unchanged. The light one is a shade darker than the app's #17886B,
    because at 12px bold that green is 4.40:1 on white and this is the size
    the label actually renders at.
  */
  --good: #3FBF9A;

  /*
    RED MARKS AN ACTION. NOTHING ELSE IS RED.

    Rules, figures, borders, active tabs, the strike through "lose" — all of it
    was crimson, and a colour used on everything marks nothing. It is now the
    button colour and the button colour only, on this page and inside the
    mockups, so the one red thing on any screen is the thing to press.

    What replaces it is not more grey. The colour on this page is the
    PHOTOGRAPHY: five full-bleed and half-bleed images doing the work the
    accent was doing badly. Type stays ink on paper, and the eye goes to the
    pictures and the buttons, which is where it should have been going.
  */
  --wash: color-mix(in srgb, var(--text) 4%, var(--ground));
  --shadow: none;

  /*
    A LIGHT PAGE THAT IS ONLY PAPER AND WHITE IS THE "ALL GREY" PROBLEM.

    Rhythm on a page this long is contrast BETWEEN blocks, not contrast inside
    one — so one section is full-bleed and heavy, and it is the only place on
    the page with real weight.

    THE CONTRAST BLOCK POINTS AWAY FROM WHATEVER THE PAGE IS.

    In daylight that means ink. At night ink IS the page, so a block of it is
    invisible and the rhythm quietly disappears for half the audience — the
    same bug as the light palette being an inversion, in the other direction.
    So the block is a step further from the ground rather than a fixed colour:
    darker than paper, lighter than night.
  */
  --block: #161922;
  --block-surface: #1F2330;
  --block-line: #2C3140;
  --block-text: #F4F5F7;

  --measure: 36rem;
  /* Body copy reads at 18.5px, which is wider than 36rem at that size. */
  --measure-wide: 42rem;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter,
          Helvetica, Arial, sans-serif;
  /*
    MONOSPACE IS THE LABEL VOICE, and it is the one typographic idea the page
    did not have. Section numbers, the evidence terms and the eyebrows are all
    apparatus rather than prose — they point at content instead of being it —
    and a mono face says that instantly without needing size or colour to do
    it. Everything a reader actually reads stays in the sans.
  */
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  /*
    RUNNING TEXT IS NOT --soft. The section paragraphs were set in the same
    muted grey as captions and card bodies, which flattened the page: the
    argument and the footnotes had one voice. Body copy gets its own ink, a
    step up from --soft and a step down from --text.
  */
  --body: #D3D8E1;
}

/*
  THERE IS NO LIGHT PALETTE. THIS PAGE IS BLACK, ALWAYS.

  It used to carry a full warm-paper palette behind
  `prefers-color-scheme: light`, and it was a good one — its own colours
  rather than the dark set inverted. It is gone on purpose.

  WHY. The product decision is that this page has one look, and it is the
  night one: floodlit track, black ground, type and photography doing the
  work. A reader whose laptop happens to be in light mode was getting a
  materially different site from the one that was designed, reviewed and
  signed off — same words, different object. Two palettes also means every
  new section has to be checked twice, and the second check is the one that
  quietly stops happening.

  `color-scheme: dark` on the root is what makes the REST of the browser
  agree: scrollbars, form controls and the flash of background before CSS
  lands. Without it a dark page in a light OS gets a white scrollbar and a
  white first paint.
*/
:root { color-scheme: dark; }

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.wrap { width: min(74rem, 100% - 2rem); margin-inline: auto; }
.tnum { font-variant-numeric: tabular-nums; }

a { color: var(--text); }
a:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

h1, h2, h3 { margin: 0; text-wrap: balance; }
p { margin: 0; }

/*
  Display type: tight, heavy, large — and SENTENCE CASE.

  It was uppercase, which is why every headline on this page read as a poster
  rather than as a sentence. The copy here is argumentative — "Charging
  somebody to go for a walk is the wrong business" — and an argument set in
  capitals is a slogan, which is the one thing this page is trying not to
  sound like. Uppercase also costs about 30% more width per line and loses
  every ascender and descender a reader uses to recognise word shapes, so the
  longest headlines were the worst hit.

  What carries the attitude instead is what always was: size, weight and a
  very tight track.
*/
.display {
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.0;
}

/* ---------------------------------------------------------------- header */
header {
  position: sticky; top: 0; z-index: 20;
  backdrop-filter: saturate(150%) blur(14px);
  background: color-mix(in srgb, var(--ground) 80%, transparent);
  border-bottom: 2px solid var(--line);
}
.bar { display: flex; align-items: center; gap: 1rem; padding: 0.8rem 0; }
.brand { display: flex; align-items: center; gap: 0.55rem; text-decoration: none; color: inherit; }
.brand strong { font-size: 1.2rem; font-weight: 800; letter-spacing: -0.02em; }
.bar nav { margin-inline-start: auto; display: flex; gap: 0.4rem; }
.bar nav a {
  color: var(--soft); text-decoration: none; font-size: 0.82rem;
  font-weight: 600; letter-spacing: 0;
  padding: 0.45rem 0.8rem; border-radius: 999px;
}
.bar nav a:hover { color: var(--text); background: var(--surface); }
/*
  THE NAVIGATION USED TO BE display:none HERE.

  Nine sections, and a phone visitor got a wordmark and a language switcher.
  It is three links now, not six, so they fit on a row of their own rather
  than needing a menu to hide in — and a visible row beats a disclosure
  nobody opens. The row scrolls if a translation runs long.
*/
@media (max-width: 52rem) {
  .bar { flex-wrap: wrap; row-gap: 0.45rem; }
  .bar nav {
    order: 3; flex-basis: 100%; margin-inline-start: 0;
    gap: 0.3rem; overflow-x: auto; scrollbar-width: none;
    padding-block-end: 0.15rem;
  }
  .bar nav::-webkit-scrollbar { display: none; }
  /* Sized so the longest set — the French one — fits a 390px phone without
     clipping. Anything longer still scrolls rather than wrapping to a third
     row, and the fade says so. */
  .bar nav a { padding: 0.3rem 0.5rem; font-size: 0.68rem; letter-spacing: 0.01em; white-space: nowrap; }
  .bar nav { mask-image: linear-gradient(to right, #000 calc(100% - 1.5rem), transparent); }
  [dir="rtl"] .bar nav { mask-image: linear-gradient(to left, #000 calc(100% - 1.5rem), transparent); }
  .langs { margin-inline-start: auto; }
}

/* ------------------------------------------------------------------ hero */
.hero { padding: clamp(3rem, 10vw, 6rem) 0 clamp(2rem, 6vw, 3.5rem); }
.hero h1 {
  font-size: clamp(3.2rem, 15vw, 10rem);
  margin-bottom: 1.6rem;
}
/*
  "LOSE" is struck through, in the accent. The sentence is the positioning
  line and the strike is the argument in one mark — it says the thing the copy
  says, before anybody has read the copy.
*/
/* The strike is still the argument made as a mark; it no longer needs to be
   red to be one, and the word stays the same weight as the rest of the line. */
.hero h1 .struck { color: inherit; opacity: 0.55; text-decoration: line-through; text-decoration-thickness: 0.07em; }
/*
  ONE WORD OF THE HEADLINE, IN THE ACCENT. The word is "move" — the whole
  argument of the page in one syllable — and it is the only accented word on
  the site. Two would make it a highlighter.
*/
.hero h1 .hi { color: var(--accent-word); }
.hero .lede { font-size: clamp(1.08rem, 2.2vw, 1.3rem); color: var(--soft); max-width: var(--measure); }

.pill {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font-size: 0.75rem; font-weight: 750; letter-spacing: 0.1em; text-transform: uppercase;
  color: currentColor;
  border: 2px solid color-mix(in srgb, currentColor 40%, transparent);
  border-radius: 999px; padding: 0.35rem 0.85rem;
  margin-bottom: 1.5rem;
}

.cta { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 2.25rem; }
.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: var(--accent); color: var(--on-accent);
  text-decoration: none; font-weight: 650; font-size: 1rem;
  letter-spacing: 0;
  padding: 0.95rem 1.6rem; border-radius: 999px; border: 2px solid var(--accent);
}
.btn:hover { filter: brightness(1.1); }
.btn.ghost { background: transparent; color: var(--text); border-color: var(--line); }
.btn.ghost:hover { border-color: var(--text); filter: none; }
.note { color: var(--soft); font-size: 0.9rem; }

/* ----------------------------------------------------------- free strip */
/*
  FOUR WORDS DIRECTLY UNDER THE HERO, IN THE GREEN THAT MEANS "NO COST".

  Not a band and not a ticker: it is a fact, stated once, flush against the
  headline that claims it. Green is the page's one exception to "red marks an
  action, nothing else is coloured" — it means "this costs nothing", and this
  is the single most important place on the page for it to say that.

  It WRAPS rather than scrolls. Four short phrases fit one line on a desktop
  and two on a phone, and a horizontal scroller here would hide the last
  word, which is the one that says nothing is sold.
*/
.freestrip { border-block: 2px solid var(--line); background: var(--surface); padding: 0.85rem 0; }
.freestrip .wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem clamp(1rem, 4vw, 2.25rem); }
.freestrip span {
  color: var(--good); font-size: 0.78rem; font-weight: 800;
  letter-spacing: 0.12em; text-transform: uppercase;
}
[dir="rtl"] .freestrip span { letter-spacing: 0; }
/*
  THE WAYS TO MOVE, ON THE SAME LINE, PUSHED TO THE FAR SIDE.

  This is what the scrolling ticker used to say, and it now says it once and
  holds still. The animated band was the page's one piece of pure swagger and
  it cost a full screen-height of nothing above the first real section; the
  words matter more than the motion, and here they sit beside the four that
  say it is free — which is the pairing the page is actually about.

  It drops to its own line below 52rem rather than scrolling, because a
  horizontal scroller here would hide "at home, no kit", and that is the item
  doing the most work in the list.
*/
.freestrip small {
  margin-inline-start: auto; color: var(--soft); font-size: 0.78rem;
  display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap;
}
.freestrip small svg { inline-size: 0.6rem; block-size: 0.6rem; opacity: 0.45; flex: none; }
@media (max-width: 52rem) { .freestrip small { margin-inline-start: 0; flex-basis: 100%; } }

/* --------------------------------------------------------------- section */
section { padding: clamp(2.75rem, 6vw, 4.5rem) 0; border-top: 2px solid var(--line); }

/*
  Numbered, editorial — and the figure is now SMALL.

  It used to be a 5rem hollow outlined numeral, which was the loudest thing in
  every section and competed with the headline beside it for the first
  fixation. Fourteen sections of that is a page that shouts its own table of
  contents. As a small mono figure it does the job a section number is for:
  it tells you where you are when you go looking, and it is invisible when you
  are not.
*/
.head { display: flex; gap: clamp(1rem, 4vw, 2.5rem); align-items: flex-start; }
.head .num {
  font-family: var(--mono);
  font-size: 0.875rem; font-weight: 400; line-height: 1;
  color: var(--soft);
  padding-block-start: 0.75rem;
  flex: none;
}
/*
  ON A PHONE THE FIGURE SITS ABOVE THE TITLE, NOT BESIDE IT.

  As a column it reserved about 80px that only the first line of the heading
  ever reached, so every paragraph under it began at an indent with nothing to
  its left — the single thing that made the mobile page look unorganised. It
  is structure, so it goes back to being a column the moment there is room.
*/
@media (max-width: 46rem) {
  .head { display: block; }
  .head .num { padding-block-start: 0; margin-bottom: 0.35rem; }
}
.head h2 { font-size: clamp(1.875rem, 4.4vw, 3.25rem); max-width: 21ch; }

section .body {
  color: var(--body); max-width: var(--measure-wide);
  font-size: 1.16rem; line-height: 1.62;
  display: grid; gap: 1rem; margin-top: 1.5rem;
}

/*
  BOXED, AND THE EARLIER "NO BOX" NOTE IS SUPERSEDED.

  That note was right about the version it was describing: a bordered card
  with a heavy rule floating inside its own padding reads as a stray line, and
  three of them look like receipts. The fix it chose was to drop the box.

  This keeps the box and drops the rule instead, which is the other way out of
  the same problem — one edge doing one job. It matters more now than it did:
  with the phone mockups gone, several sections are four cards and nothing
  else, and four top-ruled text blocks in a row have no edges at all to tell a
  reader where one stops. The surface fill is also the only thing left
  breaking up long stretches of flat ground now that the screenshots are not.

  Headings are sentence case here for the same reason the display type is:
  these are short sentences, not labels.
*/
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1.5rem;
  /*
    SIZED BY ITS OWN TEXT, NEVER BY ITS NEIGHBOUR'S.

    Grid items stretch to the row by default. While cards had no fill that was
    invisible; with a surface and a border it means a card holding two lines
    is drawn as tall as the longest card in the row — a box mostly full of
    nothing. `start` makes each one end where its text does.
  */
  align-self: start;
}
.card h3 {
  font-size: 1.03rem; font-weight: 700; line-height: 1.3;
  margin-bottom: 0.55rem;
}
.card p { color: var(--soft); font-size: 0.88rem; line-height: 1.58; }

/* ------------------------------------------------------------------ band */
/*
  FULL-BLEED PHOTOGRAPH, ONE SENTENCE OVER IT.

  These were flat crimson. They are the two places on the page where somebody
  should see what the app is actually for — people running, people lifting —
  rather than read another claim about it.

  The scrim is not decoration. White display type over an unknown part of a
  photograph is a contrast bet you lose somewhere, so there is a dark gradient
  under the text and the type sits above it. Used twice; a third would make it
  wallpaper.
*/
.band {
  position: relative; border: none; isolation: isolate;
  color: #FFFFFF;
  background: var(--ink);
  overflow: hidden;
}
.band img {
  position: absolute; inset: 0; z-index: -2;
  inline-size: 100%; block-size: 100%; object-fit: cover;
}
.band::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(105deg,
    rgba(9, 10, 13, 0.92) 0%, rgba(9, 10, 13, 0.82) 45%, rgba(9, 10, 13, 0.45) 100%);
}
[dir="rtl"] .band::before { background: linear-gradient(255deg,
    rgba(9, 10, 13, 0.92) 0%, rgba(9, 10, 13, 0.82) 45%, rgba(9, 10, 13, 0.45) 100%); }
.band .wrap { position: relative; padding-block: clamp(0.75rem, 3.5vw, 2rem); }
.band p {
  font-size: clamp(1.6rem, 4.2vw, 2.9rem);
  font-weight: 800; letter-spacing: -0.03em; line-height: 1.05;
  max-width: 46rem;
}
/* `.band p` sets the display leading of 1.05 for the headline. This is a
   sentence of prose sharing that selector, so it has to take its leading
   back or its two lines collide. */
.band .sub { font-size: clamp(0.95rem, 2vw, 1.1rem); font-weight: 500;
  line-height: 1.5; letter-spacing: 0; margin-top: 1.1rem; opacity: 0.9; max-width: 34rem; }

/* ------------------------------------------------------------------ stat */
/*
  A RULE ABOVE AND BELOW, AND EQUAL COLUMNS.

  As a loose flex row the four figures drifted apart at wide widths and the
  labels under them tore to different line counts, so it read as four stray
  numbers rather than one measurement of the app. Bounded and gridded, it is
  a single object.
*/
.stat {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1.5rem clamp(1.5rem, 4vw, 3rem); margin-top: 2.75rem;
  border-block: 2px solid var(--line); padding-block: 1.9rem;
}
.stat div span {
  display: block; font-size: clamp(2.25rem, 5vw, 2.75rem);
  font-weight: 800; letter-spacing: -0.03em; line-height: 1; color: var(--text);
}
.stat div small {
  display: block; color: var(--soft); font-size: 0.78rem; margin-top: 0.5rem;
  text-transform: uppercase; letter-spacing: 0.09em; font-weight: 650;
}

/* ============================================================== the ask */
/*
  THE PAGE HAD NO ENDING AND NOTHING TO DO.

  Two calls to action, both of which scrolled further down the same page, and
  then it stopped at a pricing table. Whatever else a launch page is for, it
  is for this.

  WHY A mailto AND NOT A FORM. There is no endpoint to post to — the API's
  `waiting` module is an authenticated inbox, not a waiting list — and a form
  that pretends to capture an address it cannot store is worse than an honest
  link. When the store listings exist this block becomes two badges and the
  button goes; it is built so that is a content change, not a rebuild.
*/
#get { background: var(--block); color: var(--block-text); border-top-color: var(--block); }
#get .display { font-size: clamp(2rem, 6vw, 3.6rem); max-width: 20ch; }
#get .lede { color: #98A0B2; max-width: var(--measure); margin-top: 1.1rem; }
#get .cta { margin-top: 2rem; }
#get .note { color: #98A0B2; margin-top: 1.2rem; }

/* ---------------------------------------------------------------- footer */
footer { border-top: 2px solid var(--line); padding: 3rem 0 3.5rem; color: var(--soft); font-size: 0.93rem; }
/*
  space-between rather than an auto margin on the nav. Both put the links at
  the far end while the two fit on one line; only this one leaves them at the
  starting edge — under the wordmark — once they wrap onto a second.
*/
.footrow { display: flex; flex-wrap: wrap; gap: 1.25rem 2rem;
  align-items: center; justify-content: space-between; }
footer nav { display: flex; flex-wrap: wrap; gap: 1.25rem; }
footer a { color: var(--soft); text-decoration: none; }
footer a:hover { color: var(--text); text-decoration: underline; }
.legal { margin-top: 1.75rem; font-size: 0.85rem; max-width: var(--measure); }
.by { margin-top: 2rem; padding-top: 1.5rem; border-top: 2px solid var(--line); font-size: 0.88rem; }
.by a { color: var(--text); font-weight: 650; }

/* ------------------------------------------------------------- language */
.langs { display: flex; gap: 0.15rem; margin-inline-start: 0.5rem; }
.langs a {
  color: var(--soft); text-decoration: none; font-size: 0.78rem; font-weight: 750;
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 0.4rem 0.6rem; border-radius: 999px;
}
.langs a:hover { color: var(--text); background: var(--surface); }
.langs a[aria-current="true"] { color: var(--ground); background: var(--text); }

/* Latin brand words keep their direction inside a right-to-left sentence:
   "Dash" is a name, not a word for the bidi algorithm to reorder. */
[dir="rtl"] .brand strong, [dir="rtl"] .tnum { direction: ltr; unicode-bidi: isolate; }

/*
  THE WORDMARK DOES NOT MIRROR, AND NEITHER DOES THE SLOGAN.

  Everything else on this page flips for Arabic, because that is what reading
  right to left means. A logo is not text being read — it is a mark, and it
  belongs in the same corner in every language, the way it does on the app
  icon and the store listing. So the two rows that carry it lay out
  left-to-right whatever the page direction is, and only the link text inside
  them goes back to RTL.
*/
[dir="rtl"] .bar, [dir="rtl"] .footrow { direction: ltr; }
[dir="rtl"] .bar nav a, [dir="rtl"] footer nav a { direction: rtl; }

/* "Move. Meet. Challenge." is the slogan, kept in English everywhere — so it
   is set left-to-right even on the Arabic page, full stops and all. */
[dir="rtl"] .pill { direction: ltr; }

/* Arabic has no capitals, so uppercasing does nothing — but the tight
   tracking actively hurts a joined script, and the tight leading crowds the
   marks that sit above and below the line. */
[dir="rtl"] .display,
[dir="rtl"] .pill,
[dir="rtl"] .btn,
[dir="rtl"] .card h3,
[dir="rtl"] .bar nav a,
[dir="rtl"] .stat div small { letter-spacing: 0; }
[dir="rtl"] .display { line-height: 1.2; }


/* ------------------------------------------------------- body + a photo */
/*
  THE COLUMN BESIDE THE COPY, WHICH WAS EMPTY.

  Body copy is held to 42rem for readability while the page is 74rem wide, so
  every section had a third of its width doing nothing. That was fine when a
  phone mockup sat there and wrong the moment the mockups came out.

  The photographs are the app's own programme tiles. SQUARE, because that is
  what they are — a 16:9 crop of a square portrait takes somebody's head off —
  and 22rem, which is wide enough to read as a picture and narrow enough that
  the paragraph beside it keeps a comfortable measure.

  `align-items: start` so the photo hangs from the first line of the copy
  rather than centring against it: a two-line paragraph and a square would
  otherwise leave the text floating in the middle of a tall row.

  It collapses to one column under 56rem, where the photo goes BELOW the copy.
  A square photo above the argument on a phone would push the argument off the
  screen, and the words are why anybody is here.
*/
.split { display: grid; gap: clamp(1.5rem, 4vw, 3rem); align-items: start; }
@media (min-width: 56rem) { .split { grid-template-columns: minmax(0, 1fr) 22rem; } }
.split .body { margin-top: 1.5rem; }

.tile {
  margin: 1.5rem 0 0; border-radius: 16px; overflow: hidden;
  border: 1px solid var(--line); background: var(--surface);
}
.tile img { display: block; inline-size: 100%; block-size: auto; }

/* ---------------------------------------------------------------- cards */
/*
  ONE GRID, FULL WIDTH. This was forty lines of two-column layout built around
  a phone mockup: a flex row with a fixed 17rem column for the screenshot, a
  bezel, a two-up variant, a caption, and an `:only-child` escape hatch for
  the sections that had no screenshot yet.

  The screenshots are gone, so the escape hatch is the only case left and it
  is now simply the rule. `.showcase` survives as the spacing wrapper because
  fourteen sections name it in the markup; it no longer lays anything out.

  Cards size to their own text — see `align-self: start` on `.card`. The body
  paragraph is a SIBLING of this grid, never a cell in it: as a cell it was
  squeezed to one column's width and it stretched every card beside it to the
  height of a full paragraph of prose.
*/
.showcase { margin-top: 1.8rem; }
.cards {
  display: grid; gap: 1.1rem;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}


/* ================================================================ rhythm */
/*
  WHY SECTIONS LOOK DIFFERENT FROM EACH OTHER.

  Seven sections built to one template — figure, heading, two paragraphs,
  screen, three blocks — is a page where nothing is more important than
  anything else, so the eye never lands anywhere. Two devices fix it and
  neither is decorative: the showcase changes side, so the scroll alternates
  rather than marches; and one section is a full-bleed block, which is the
  only place on the page with real weight and therefore where the eye goes.
*/
@media (min-width: 56rem) { .showcase.flip { flex-direction: row-reverse; } }

/*
  Remapping the tokens rather than restating the colours means everything
  inside comes along without knowing it moved.

  The block points AWAY from whatever the page is: ink in daylight, and a step
  lighter than the ground at night, because a block of ink on an ink page is
  invisible and the rhythm would quietly disappear for half the audience.
*/
section.ink {
  --ground: var(--block);
  --surface: var(--block-surface);
  --line: var(--block-line);
  --text: var(--block-text);
  --soft: #98A0B2;
  --wash: color-mix(in srgb, #FFFFFF 7%, var(--block));
  --shadow: none;
  background: var(--block);
  color: var(--block-text);
  border-top-color: var(--block);
}

.eyebrow {
  font-family: var(--mono);
  font-size: 0.7rem; font-weight: 500; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--soft);
}
[dir="rtl"] .eyebrow { letter-spacing: 0; }
[dir="rtl"] .eyebrow { letter-spacing: 0; }

/* ================================================================ what for */
/*
  WHAT THE PROGRAMMES ARE FOR, WHICH THE PAGE PREVIOUSLY NEVER SAID.

  The section counted them — sixty, fifty-three, seven — and a count answers
  "how many", which is nobody's question. The app's own library asks "What
  for" and answers with these eight, in this order.
*/
.whatfor { margin-top: 2.75rem; }
/* Explicit columns rather than auto-fit: eight tiles into auto-fit gives six
   and two, and two orphans on a second row read as an accident. 2x4 then 4x2. */
.goals {
  display: grid; gap: 0.7rem; margin-top: 1.1rem;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 50rem) { .goals { grid-template-columns: repeat(4, 1fr); } }
.goal {
  background: var(--surface);
  border: 2px solid var(--line);
  border-radius: 14px;
  padding: 0.85rem 1rem;
  font-weight: 750; font-size: 0.95rem; letter-spacing: -0.01em;
  display: flex; align-items: center; gap: 0.55rem;
}
.goal svg { color: var(--soft); flex: none; }
.whatline { color: var(--soft); max-width: var(--measure); margin-top: 1.2rem; }

/* The two axes that narrow the eight, in the order the app asks them. */
.axes {
  display: grid; gap: 1rem; margin-top: 1.75rem;
  grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr));
}
.axis { border-inline-start: 3px solid var(--text); padding-inline-start: 1.1rem; }
.axis strong {
  display: block; font-size: 1.03rem; font-weight: 700;
  line-height: 1.3; margin-bottom: 0.4rem;
}
[dir="rtl"] .axis strong { letter-spacing: 0; }
.axis p { color: var(--soft); font-size: 0.95rem; }

/* ================================================================== photos */
/*
  WHERE THE COLOUR ON THIS PAGE COMES FROM NOW.

  The first version carried its energy in crimson and the second in crimson
  plus a dark block, and both answers were the same answer: tint something.
  These are photographs of the thing the app is for. They do the job better
  than any amount of accent, and they leave red free to mean "press this".

  Every one is served as a srcset with a `sizes` declared at the point of use,
  and every one below the fold is lazy — a phone should not pay for the
  Pilates studio before it has read the headline.
*/

/* ------------------------------------------------------------- photo hero */
.shout {
  position: relative; isolation: isolate; overflow: hidden;
  color: #FFFFFF; background: var(--ink);
  display: flex; align-items: flex-end;
  min-block-size: min(86vh, 42rem);
}
.shout > img {
  position: absolute; inset: 0; z-index: -2;
  inline-size: 100%; block-size: 100%; object-fit: cover; object-position: 50% 35%;
}
/* Two stops, not one: a flat scrim kills the picture, and a gradient that only
   darkens the bottom leaves the header floating on a bright sky. */
.shout::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, rgba(9,10,13,0.55) 0%, rgba(9,10,13,0.10) 30%, rgba(9,10,13,0.86) 88%),
    linear-gradient(90deg, rgba(9,10,13,0.62) 0%, rgba(9,10,13,0) 62%);
}
[dir="rtl"] .shout::before {
  background:
    linear-gradient(180deg, rgba(9,10,13,0.55) 0%, rgba(9,10,13,0.10) 30%, rgba(9,10,13,0.86) 88%),
    linear-gradient(270deg, rgba(9,10,13,0.62) 0%, rgba(9,10,13,0) 62%);
}
.shout .wrap { padding-block: clamp(2.25rem, 5vw, 3.5rem); }
/* Smaller than the old text-only hero: ten rem of display type over a
   photograph is two things fighting for the same job. */
.shout h1 { font-size: clamp(2.75rem, 7.2vw, 5.4rem); margin-bottom: 1.35rem; }
.shout .lede { color: #DCE0E7; font-size: clamp(1.08rem, 1.9vw, 1.25rem); line-height: 1.5; max-width: var(--measure-wide); }
/*
  The headline is held to the left half on a wide screen. Run full-bleed it
  crossed the runner's chest, which is the one part of the photograph worth
  paying for — and white display type over a bright vest is unreadable anyway.
*/
@media (min-width: 56rem) {
  /* 15ch, not 13ch: "The most important thing is that you move." needs the
     extra two characters to break after "that you" rather than orphaning it. */
  .shout h1 { max-width: 15ch; }
  .shout .lede { max-width: 39rem; }
}
.shout .note { color: rgba(255,255,255,0.7); }
.shout .btn.ghost { color: #FFFFFF; border-color: rgba(255,255,255,0.45); }
.shout .btn.ghost:hover { border-color: #FFFFFF; }

/* ------------------------------------------------------- half-bleed panel */
.panel { display: grid; gap: clamp(1.4rem, 4vw, 3rem); align-items: center; margin-top: 2.75rem; }
@media (min-width: 56rem) {
  .panel { grid-template-columns: 1fr 1fr; }
  .panel.flip .panel__media { order: 2; }
}
.panel__media {
  position: relative; border-radius: 20px; overflow: hidden;
  aspect-ratio: 4 / 3; background: var(--wash);
}
.panel__media img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
.panel h3 {
  font-size: clamp(1.4rem, 3.5vw, 2rem); font-weight: 800;
  letter-spacing: -0.03em; line-height: 1.1;
  margin-bottom: 0.9rem;
}
[dir="rtl"] .panel h3 { letter-spacing: 0; line-height: 1.25; }
.panel p { color: var(--soft); max-width: var(--measure); }
.panel p + p { margin-top: 0.9rem; }

/* ---------------------------------------------------------- what it measures */
/*
  The analysis section's evidence. Chips rather than another three cards,
  because these are a LIST of things measured, and a card each would say they
  are five separate features when they are five columns of one screen.
*/
.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.chip {
  border: 2px solid var(--line); background: var(--surface);
  border-radius: 999px; padding: 0.5rem 0.95rem;
  font-size: 0.88rem; font-weight: 700; letter-spacing: -0.01em;
}
.chip.solid { background: var(--text); color: var(--ground); border-color: var(--text); }

/* ============================================================ diagrams */
/*
  THREE SMALL DRAWINGS, AND THEY ARE DRAWINGS.

  Deliberately not fake app UI — that mistake has been made once on this page
  already. These are diagrams of an idea: what a split chart is, what five
  zones look like, what a climb profile is. Inline SVG so they cost no
  request, take the theme's colour through currentColor, and stay sharp.

  A screenshot of the real session screen would beat all three, and the
  section is built so one can replace them.
*/
/*
  COLOUR HERE IS DATA COLOUR, WHICH IS A DIFFERENT JOB FROM UI COLOUR.

  Red still means "press this" and green still means "this is free" — neither
  appears in a chart. The diagrams get their own hue family so a reader never
  has to wonder whether a blue bar is something they can click.

  Chosen by job, not by taste, and validated rather than eyeballed:

  · SPLITS is one series with one mark emphasised, because that is what the
    app draws: a bar per kilometre scaled across the RUN'S OWN range rather
    than from zero — every kilometre of a steady run sits within a few
    seconds, and a zero-based bar would render them identically — with the
    fastest one picked out. It is not a diverging chart and was wrong to be
    drawn as one: nothing in the app encodes a signed delta against the
    average, so neither should the picture of it.
  · ZONES is ordinal — five bands in a fixed order, low to high. One hue,
    monotone lightness, never a rainbow: the usual five-colour zone chart
    encodes an ordered scale as unordered identity, which is exactly backwards.
  · CLIMB is one series, so one colour and no legend.

  Every set passes the six checks on both surfaces — worst CVD ΔE 24.7 light /
  26.8 dark against an ≥8 target, all steps ≥3:1 on their surface, ordinal
  ramps monotone with ≥0.06 lightness gaps.
*/
/*
  ONE SET NOW, NOT TWO. These were the dark-surface values, behind a
  `prefers-color-scheme: dark` query, with the light-surface set as the
  default underneath. The page has no light surface any more, so the light
  values were unreachable and the dark ones only applied to readers whose OS
  happened to agree — which meant a laptop in light mode drew these charts in
  colours validated against paper, on black.

  The dark set is validated on this ground: every step ≥3:1 on it, ordinal
  ramps monotone, worst CVD ΔE 26.8 against an ≥8 target. Nearest-the-ground
  is the lowest zone, so "more intense" is always more present.
*/
.viz {
  display: block; inline-size: 100%; block-size: 3.4rem;
  margin-bottom: 0.9rem; overflow: visible;

  --viz-line: #3987e5;   /* the single-series hue */
  --viz-warm: #d95926;   /* the second series, where there is one */
  --z1: #184f95; --z2: #256abf; --z3: #3987e5; --z4: #6da7ec; --z5: #9ec5f4;
}
.viz .avg { stroke: var(--soft); }

/* The price of everything above it, which is none. */
.freenote {
  margin-top: 1.4rem; color: var(--soft); max-width: var(--measure);
  border-inline-start: 3px solid var(--good); padding-inline-start: 1.1rem;
}
.freenote strong { color: var(--good); font-weight: 800; }

/*
  The same shape in ink rather than green. Green on this page means "this
  costs nothing" — it is on the free column and on the free callout, and
  spending it on a note about measurement confidence would make it mean
  nothing again, which is the mistake red was making before.
*/
.aside {
  margin-top: 1.6rem; color: var(--soft); max-width: var(--measure);
  border-inline-start: 3px solid var(--text); padding-inline-start: 1.1rem;
}
.aside strong { color: var(--text); font-weight: 800; }

/* ------------------------------------------------------------- evidence */
/*
  A CLAIM AND ITS SOURCE, PAIRED — which is what a description list is for,
  and why this is not four more cards. The term column is fixed and narrow so
  the six labels form a readable spine down the left; below 46rem it stacks,
  because a 9rem column of uppercase and a paragraph beside it is two columns
  too many on a phone.

  THE CITATION IS QUIET ON PURPOSE. It has to be legible enough to check and
  small enough that the page does not read as a paper. Muted, on its own line,
  under the claim it supports — never inline, where it would break the
  sentence somebody is actually reading.
*/
.ev { margin-top: 2.5rem; display: grid; gap: 0; }
.ev > div {
  border-top: 2px solid var(--line);
  padding-block: 1.1rem;
  display: grid; gap: 0.4rem clamp(1rem, 3vw, 2rem);
}
.ev > div:last-child { border-bottom: 2px solid var(--line); }
@media (min-width: 46rem) { .ev > div { grid-template-columns: 11rem 1fr; } }
.ev dt {
  font-family: var(--mono);
  font-size: 0.72rem; font-weight: 500; text-transform: uppercase;
  letter-spacing: 0.13em; color: var(--accent-word);
  padding-block-start: 0.35rem;
}
[dir="rtl"] .ev dt { letter-spacing: 0; }
.ev dd { margin: 0; color: var(--soft); max-width: var(--measure); }
.ev cite {
  display: block; margin-top: 0.5rem; font-style: normal;
  font-size: 0.8rem; font-variant-numeric: tabular-nums;
  color: var(--soft); opacity: 0.8;
}

/* A heading inside a section that already has an h2 — the "and then the part
   that is not in any paper" turn. Same weight as a tenet, not as a title. */
.subhead {
  font-size: clamp(1.2rem, 3vw, 1.6rem); font-weight: 850;
  letter-spacing: -0.03em; margin-top: 0.4rem;
}

/* ============================================================= philosophy */
/*
  The argument, gathered in one place instead of scattered through six
  section introductions. It is what the menu now calls "Our philosophy", and
  it is the part somebody quotes to a friend.
*/
/*
   THREE UP, NOT FOUR. There are five tenets since "moving is free" joined
   them, and at a 17rem minimum the grid fits four — which leaves the fifth
   alone on a row of its own looking like an afterthought. A wider minimum
   gives three and two, which reads as one block.
*/
.tenets { display: grid; gap: 1.6rem 1.5rem; margin-top: 2.5rem;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }
.tenet { border-top: 3px solid var(--text); padding-top: 1.1rem; }
.tenet strong {
  display: block; font-size: 1.05rem; font-weight: 850; letter-spacing: -0.02em;
  margin-bottom: 0.5rem;
}
.tenet p { color: var(--soft); font-size: 0.97rem; }

/* =========================================================== subscription */
/*
  TWO COLUMNS, AND THE FREE ONE IS NOT THE SAD ONE.

  The usual pricing table exists to make the left column look broken. Dash
  sells one thing — the programmes — and everything else is free forever, so
  the honest layout gives the free column the longer list, which it genuinely
  has. A table that lied about that would be selling the wrong product.

  NO PRICE IS PRINTED HERE. The stores quote it, in the reader's own currency,
  which is both App Review guideline 3.1.2 and the only way this page is not
  wrong in Casablanca — see docs/19 and docs/20.
*/
.tiers { display: grid; gap: 1.25rem; margin-top: 2.5rem;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); }
.tier {
  background: var(--surface); border: 2px solid var(--line);
  border-radius: 20px; padding: clamp(1.4rem, 3vw, 2rem);
  box-shadow: var(--shadow); display: flex; flex-direction: column;
}
.tier--paid { border-color: var(--text); }
.tier--free .tier__name { color: var(--good); }
.tier__name {
  font-size: 0.75rem; font-weight: 750; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--soft);
}
[dir="rtl"] .tier__name { letter-spacing: 0; }
.tier h3 {
  font-size: clamp(1.4rem, 3.5vw, 1.9rem); font-weight: 800;
  letter-spacing: -0.03em; margin: 0.5rem 0 0.4rem;
  /* Inherited 1.6 from body, which is a reading measure and far too open for
     two lines of display type. */
  line-height: 1.1;
}
[dir="rtl"] .tier h3 { line-height: 1.3; }
[dir="rtl"] .tier h3 { letter-spacing: 0; }
.tier__lead { color: var(--soft); font-size: 0.95rem; }
.tier ul { list-style: none; margin: 1.4rem 0 0; padding: 0; display: grid; gap: 0.6rem; }
/*
  THE FREE LIST STANDING ALONE, IN SECTION 01, WHERE THERE IS NO SECOND
  COLUMN TO SIT BESIDE. Eight items in one column there is a scroll; in two
  or three it is a glance, which is the point of putting it that high on the
  page. Same card, same ticks — only the list flows.
*/
.tier--wide ul { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 0.6rem 1.75rem; }
.tier li { display: flex; gap: 0.6rem; align-items: flex-start; font-size: 0.95rem; }
/* A tick drawn in CSS: an emoji would be a brand element the design system
   rules out, and an icon font is a request for four characters. */
.tier li::before {
  content: ''; flex: none; inline-size: 0.55rem; block-size: 0.95rem;
  border: solid var(--text); border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg); margin: 0.15rem 0.25rem 0 0.1rem;
}
[dir="rtl"] .tier li::before { margin: 0.15rem 0.1rem 0 0.25rem; }
.tier .btn { margin-top: auto; align-self: flex-start; }
.tier__foot { margin-top: 1.4rem; color: var(--soft); font-size: 0.85rem; }
.tier__foot + .btn { margin-top: 1.2rem; }
