/* Landing page only. style.css carries the tokens and the document styling the
   legal pages use; this adds the pieces that exist nowhere else, so a reviewer
   opening /privacy still downloads the small stylesheet and not this one.

   One rule governs the layout: everything on the page shares a single left
   edge, the `--wide` shell. The header, the section headings, the first
   screenshot in the rail and the footer all start on the same axis. The
   previous version had three axes — a 680px document column, a 1040px
   screenshot rail and a centred hero — and the 204px step between the first
   two is what read as "not properly aligned".

   The rail is the one exception now, because it slides on its own. A loop has
   to have content at the very left edge in every frame or the wrap shows the
   gap, so while it is moving the rail bleeds to both edges instead. It keeps
   the shell axis under prefers-reduced-motion, where it is a strip again and
   the axis still means something. */

/* ------------------------------------------------------------------ hero */

.hero {
  /* Full-bleed, so the warm tint runs edge to edge behind the shell. The
     header sits inside it rather than above it — that gap between a bordered
     header and the hero was 136px of nothing. */
  background: radial-gradient(120% 90% at 50% 0%, var(--tint) 0%, var(--surface) 64%);
  border-bottom: 1px solid var(--line);
  padding-top: 34px;
  /* clip, not hidden: it contains the horizontal bleed without creating a
     scroll container, so the phones' drop shadows are not sliced off. */
  overflow-x: clip;
}

.hero header.site {
  border-bottom-color: var(--line-hair);
  margin-bottom: 0;
}

.hero-inner {
  text-align: center;
  padding-top: 58px;
  padding-bottom: 4px;
}

.app-icon {
  width: 76px;
  height: 76px;
  border-radius: 18px;
  margin: 0 auto 24px;
  display: block;
}

h1.display {
  font-size: clamp(38px, 7.4vw, 62px);
  line-height: 1.06;              /* HlType.display1 */
  letter-spacing: -0.02em;
  margin: 0 auto 20px;
  max-width: 20ch;
  /* No <br>. A forced break and `balance` are contradictory instructions —
     the break decides line one, then balance is left to even out what it was
     handed, which at 390px produced three ragged lines. Balance alone gets
     two even lines at every width. */
  text-wrap: balance;
}

h1.display em {
  font-style: italic;
  color: var(--accent);
}

.lede {
  font-size: clamp(17px, 2.2vw, 20px);
  line-height: 1.62;
  color: var(--body);
  max-width: 34em;
  margin: 0 auto 30px;
  text-wrap: pretty;
}

/* The two store badges. Both are the vendors' own artwork, byte-for-byte:
   Apple's SVG from tools.applemediaservices.com, Google's PNG from
   play.google.com/intl/en_us/badges. Neither may be redrawn, recoloured,
   cropped or set on a busy ground, so this file only ever sizes and spaces
   them — there is nothing here that touches the artwork itself.

   The two files disagree about clear space. Google bakes a quarter of the
   badge height into its PNG: the artwork is 564x168 inside a 646x250 canvas.
   Apple ships the badge alone, at 119.66x40. So both are sized from the height
   of the *visible* badge rather than the height of the file, and Apple is given
   Google's quarter-height margin as padding — comfortably past Apple's own
   minimum of a tenth, and it makes the two boxes identical in height so the
   space between them reads as even. Change --badge and both stay correct. */
.stores {
  --badge: 44px;      /* visible badge height, the same for both stores */
  display: flex;
  flex-wrap: wrap;
  gap: 2px 6px;
  justify-content: center;
  align-items: center;
  margin: 0 0 4px;
}

.stores a {
  display: inline-flex;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.stores a:hover { opacity: 0.86; }
.stores a:active { transform: translateY(1px); }

.stores img { display: block; width: auto; }

/* Apple: artwork only, so the clear space is added here. */
.stores .apple { padding: calc(var(--badge) * 41 / 168); }
.stores .apple img { height: var(--badge); }

/* Google: clear space already in the file, so the box is the full canvas. */
.stores .google img { height: calc(var(--badge) * 250 / 168); }

/* --------------------------------------------------------------- screens */

/* A scroller rather than a grid: six phones do not fit a laptop at a size
   worth looking at, and a horizontal rail is honest about that instead of
   shrinking them all to thumbnails.

   Two elements, two jobs. `.shots` is the scroll container and nothing else —
   it keeps the tabindex, the drag, the arrow keys and the reduced-motion
   fallback. `.track` is the row that slides. Keeping them apart is what lets
   the slide run on the compositor without the scroller underneath it having
   any opinion about it. */
.rail {
  position: relative;
  margin-top: 46px;
}

.shots {
  /* One width for every phone, and the gap between them. Both are named here
     because the slide distance below is derived from the pair and has to agree
     with the layout to the pixel, or the loop shows a seam. */
  --shot-w: 244px;
  --shot-gap: 24px;
  --set: calc(6 * (var(--shot-w) + var(--shot-gap)));
  --drift: 52s;
  --fade: 96px;

  display: flex;
  align-items: flex-start;
  overflow-x: auto;
  /* proximity, not mandatory. On a wide screen four phones are visible at
     once; mandatory snap yanks the rail to re-centre a phone the reader was
     not aiming at, which feels like the page fighting the trackpad. Turned off
     entirely while the rail is moving — see below. */
  scroll-snap-type: x proximity;
  /* Aligns the first phone's left edge with the shell — the same axis as the
     logo and every heading below. `100%` rather than `100vw`: vw includes the
     scrollbar, which pushed the whole rail ~8px right of true centre on every
     browser with a classic scrollbar. */
  padding-inline: max(var(--gutter), calc((100% - var(--wide)) / 2 + var(--gutter)));
  /* Bottom clearance for the two-layer shadow, which reaches 52px below the
     image; the old 42px sliced it off with a hard line. */
  padding-block: 8px 58px;
  scroll-padding-inline: max(var(--gutter), calc((100% - var(--wide)) / 2 + var(--gutter)));
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.shots::-webkit-scrollbar { display: none; }

/* `flex: 0 0 auto` so the row sizes to its eighteen phones rather than being
   squeezed to the width of the scroller. `.shots` stays a flex container for
   the same reason it always was: Chrome only honours a scroll container's
   inline-end padding in the scrollable area when the child that overruns it
   is a flex item. */
.track {
  display: flex;
  align-items: flex-start;
  flex: 0 0 auto;
  gap: var(--shot-gap);
}

.shots figure {
  flex: 0 0 auto;
  margin: 0;
  scroll-snap-align: start;
  width: var(--shot-w);
}

.shots img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 26px;
  border: 1px solid var(--line);
  /* Two shadows: a tight one for the edge, a wide soft one for the lift. */
  box-shadow:
    0 2px 6px -2px rgba(52, 38, 24, 0.28),
    0 26px 50px -24px rgba(52, 38, 24, 0.42);
  background: var(--raised);
}

.shots figcaption { padding-top: 16px; }

.shots figcaption b {
  display: block;
  font: 500 11px/1 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  letter-spacing: 0.14em;    /* HlType.eyebrowTight */
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 7px;
}

.shots figcaption span {
  display: block;
  font-size: 14px;
  line-height: 1.5;
  color: var(--body);
  max-width: 26ch;
}

/* One copy's width, linear, forever. Copy two lands exactly where copy one
   started, so the frame the loop restarts on is pixel-identical to the frame
   before it and there is nothing to see. Linear is not a preference: any
   easing would make the row visibly slow down into the wrap. */
@keyframes rail-drift {
  to { transform: translate3d(calc(-1 * var(--set)), 0, 0); }
}

@media (prefers-reduced-motion: no-preference) {
  .track {
    animation: rail-drift var(--drift) linear infinite;
  }

  .shots {
    /* Snap points that move every frame fight the slide — the scroller spends
       its time re-targeting a phone that has already left. */
    scroll-snap-type: none;

    /* Edge to edge on the left, not to the shell axis, and this one is not a
       taste call. The row can only ever start at the left padding, so with the
       shell's inset still in place — 230px at a 1,440px window, and wider the
       wider the screen — the first frame of each cycle shows bare background
       where the frame before it had the tail of a phone, which is the one thing
       a loop must never show. At zero there is no dead strip to expose:
       the row starts at x=0, copy two lands on x=0, and the wrap has nothing
       in it. The axis survives where it still means something, on the
       reduced-motion strip below.

       The inline-end padding stays. Three copies with one copy of travel means
       the row reaches (3 - 1) x 1608 - 24 = 3,192px past the left edge at the
       far end of the cycle, so the right edge holds up to a 3,192px viewport.
       Past that, add a fourth copy. */
    padding-inline-start: 0;
  }

  /* Stop it. A pointer over the rail, focus anywhere inside it, a mouse held
     down on it, or — via the script, which is the only case CSS cannot see —
     a finger on it. Motion a reader cannot stop is a WCAG 2.2.2 failure, and
     motion that keeps going under a thumb mid-swipe just feels broken. */
  .shots:hover .track,
  .shots:focus-within .track,
  .shots:active .track,
  .shots.is-held .track { animation-play-state: paused; }

  @supports (mask-image: linear-gradient(to right, #000, transparent)) {
    /* Both edges now, where the static rail faded only the right. A moving row
       enters at one edge and leaves at the other, and a hard cut at either end
       reads as clipping rather than as motion. */
    .shots {
      mask-image: linear-gradient(to right,
        transparent 0, #000 var(--fade),
        #000 calc(100% - var(--fade)), transparent 100%);
    }
  }
}

/* Motion off means off: no slide, and the two duplicate copies drop out of the
   layout, so what is left is the six-phone strip exactly as it was — scrolling,
   snapping, first phone on the shell axis — with the fade back on the right
   edge alone to say there is more.

   The "Scroll for more" hint that used to sit under the rail is gone from the
   page rather than kept for this branch. It only says something true while the
   rail is standing still, which is now the exception, and it needed the script
   to work out whether to show itself at all. Everyone else is brought the rest
   of the strip without asking. */
@media (prefers-reduced-motion: reduce) {
  .track [aria-hidden="true"] { display: none; }

  @supports (mask-image: linear-gradient(to right, #000, transparent)) {
    .shots {
      mask-image: linear-gradient(to right, #000 calc(100% - var(--fade)), transparent 100%);
    }
  }
}

/* ---------------------------------------------------------------- steps */

.steps { padding-block: 72px 4px; }

.step-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 30px 26px;
  grid-template-columns: 1fr;
}

@media (min-width: 560px) { .step-list { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .step-list { grid-template-columns: repeat(4, 1fr); } }

.step-list li { margin: 0; }

.step-list .n {
  display: block;
  font-family: 'Newsreader', Georgia, serif;
  font-weight: 300;
  font-size: 30px;
  line-height: 1;
  color: var(--accent);
  margin-bottom: 12px;
}

.step-list h3 {
  font-family: 'Newsreader', Georgia, serif;
  font-weight: 300;
  font-size: 21px;
  line-height: 1.25;
  letter-spacing: -0.015em;
  margin: 0 0 8px;
  color: var(--text);
}

.step-list p {
  margin: 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--body);
}

/* -------------------------------------------------------------- pillars */

/* The one dark band on the page. The app's signature surface is the deep
   green — splash, paywall, analysis, the score card, the weekly insight — and
   a site that never once uses it does not look like the same product. */
.band {
  background: var(--ink);
  color: var(--on-ink-body);
  margin-top: 76px;
  padding-block: 76px;
}

.band h2 { color: var(--on-ink); }
.band .eyebrow { color: var(--on-ink-soft); }

.pillars {
  display: grid;
  gap: 22px;
  grid-template-columns: 1fr;
  margin-top: 34px;
}

/* Three cards, three columns — stated, not left to auto-fit. With three items
   and minmax(250px) inside a fixed measure, auto-fit has exactly one answer
   and it was 2 + 1 with a hole beside the third. */
@media (min-width: 860px) { .pillars { grid-template-columns: repeat(3, 1fr); } }

.pillar {
  border: 1px solid var(--line-on-ink);
  border-radius: var(--r-card);   /* HlRadius.card */
  padding: 26px 24px;
  background: rgba(251, 247, 242, 0.04);
}

.pillar h3 {
  font-family: 'Newsreader', Georgia, serif;
  font-weight: 300;
  font-size: 21px;
  line-height: 1.3;
  letter-spacing: -0.015em;
  margin: 0 0 10px;
  color: var(--on-ink);
}

.pillar p {
  margin: 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--on-ink-body);
}

/* --------------------------------------------------------------- closing */

.closing { padding-block: 72px 0; }
.closing p { max-width: var(--measure); }

.closing .callout {
  background: var(--tint);
  border: 1px solid var(--line-card);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-tile);
  padding: 18px 20px;
  max-width: var(--measure);
}

/* ------------------------------------------------------------------ get */

/* The badges again, at the end of the page. Not a repeat for its own sake: by
   this point the reader has been through the four steps, the three promises
   and the disclaimer, and until now the only thing within reach at the bottom
   of the page was the footer. */
.get {
  padding-block: 68px 0;
  text-align: center;
}
.get h2 { margin: 0 0 6px; }
.get p { color: var(--muted); margin: 0 0 22px; }

footer.site.home { margin-top: 72px; padding-bottom: 56px; }

/* --------------------------------------------------------------- mobile */

@media (max-width: 520px) {
  .hero { padding-top: 26px; }
  .hero-inner { padding-top: 38px; }
  /* Narrower phones and a tighter gap, so --set re-derives itself; --drift
     comes down with it to hold the apparent speed at roughly 30px a second.
     The fade shrinks too — 96px of it on a 360px screen would be eating a
     third of the leading phone. */
  .shots {
    --shot-w: 208px;
    --shot-gap: 16px;
    --drift: 44s;
    --fade: 34px;
    padding-block: 8px 48px;
  }
  .shots img { border-radius: 22px; }
  .steps { padding-block: 56px 0; }
  .band { margin-top: 58px; padding-block: 58px; }
  .closing { padding-block: 56px 0; }
  .get { padding-block: 56px 0; }
}
