/* Home — the evidence: stat cards, the scrolling wall of real slides, the
   three steps.

   The .slide* rules have no counterpart in the markup: main.js builds those
   cards, and it composes the caption class by concatenation
   (`slide__hook--` + preset). Nothing here can be checked against index.html,
   which is why no unused-CSS tool may be pointed at this file. */

/* ── Stat cards ─────────────────────────────────────────────── */

.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(10px, 1.2vw, 16px); }
.stat { position: relative; background: var(--ink); color: var(--cream); border-radius: 22px; padding: clamp(22px, 2.4vw, 30px); }
/* One size across all four. "Automatic" used to need a per-tile step-down (--fs)
   because it was wider than its content box between the 981px four-column floor
   and about 1200px; giving the mark its own band above the value returned the
   full card width, and it now fits at every breakpoint — measured, not assumed. */
.stat b { display: block; font-family: var(--display); font-weight: 900; font-size: clamp(34px, 4vw, 50px); letter-spacing: -.03em; line-height: 1; color: var(--cream); }
.stat p { margin: 14px 0 0; font-size: 14.5px; font-weight: 600; }
.stat small { display: block; margin-top: 6px; font-size: 13px; color: var(--on-ink-dim); font-weight: 400; line-height: 1.45; }

/* Duotone marks: one solid blue shape carrying the colour, one white line on top
   carrying the detail. Two tones, and both of them are already in the system.

   Two tiles used to say what they meant in colour instead — a pastel green
   numeral on "~2 min", a pastel yellow one on "Automatic" — which were the only
   two appearances of either hue on the site, and pastel fills are exactly what
   this palette dropped. The numerals are all white now and the accent moved to
   the marks, so the strip reads as one thing and the blue is the section's
   single accent rather than a third and fourth colour.

   Blue on --ink is 3.4:1: under the 4.5 a numeral would need, comfortably over
   the 3:1 WCAG 1.4.11 asks of a meaningful graphic. Which is the other reason
   the colour lives on the icon and the text stays white.

   Top right, on its own band rather than floated into the corner: pushed over
   with margin-left rather than positioned absolutely, so it still occupies
   height and the value below it gets the full width of the card — which is what
   lets all four values share one font size. */
.stat__icon {
  display: block; margin: 0 0 15px auto;
  width: clamp(24px, 2.4vw, 30px); height: auto;
}
.stat__icon-fill { fill: var(--blue-deep); }
.stat__icon-dot,
.stat__icon-line { fill: none; stroke: var(--cream); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.stat__icon-dot { fill: var(--cream); stroke: none; }
/* The detail line on a shape that is mostly filled — a fold, a ferrule —
   wants to be lighter than an outline, or it cuts the shape in half. */
.stat__icon-line--hair { stroke-width: 1.5; }

/* ── The wall of real slides ────────────────────────────────── */

.wall { padding-block: var(--gap); background: var(--cream-2); overflow: hidden; }
.wall__rows { display: grid; gap: clamp(12px, 1.4vw, 20px); margin-top: clamp(34px, 4vw, 54px); transform: rotate(-1.6deg); width: 108%; margin-left: -4%; }
.row { display: flex; overflow: hidden; }
/* A real loop, not a ping-pong. main.js measures one repeat of the row's card set
   and hands it back as --travel, so the track slides exactly that far and restarts
   on a pixel-identical frame. The old -50% landed half a gap short of a whole
   repeat, and that 10px jump is what read as a row running past its last card;
   ping-ponging away from the seam cost the wall its motion instead of fixing it.
   --dur is derived from a fixed px/s speed, so a phone and a 4K display drift at
   the same pace. Linear, because easing stretched over a cycle this long doesn't
   read as a soft turn — it reads as the wall stalling. */
.row__track {
  display: flex; gap: clamp(12px, 1.4vw, 20px); flex: none;
  animation: slide var(--dur, 60s) linear infinite;
}
.row--b .row__track { animation-direction: reverse; }
/* Nothing to watch while the band is off screen, and letting the clock run there
   only means arriving to find the rows parked at some arbitrary offset. */
.wall.is-idle .row__track { animation-play-state: paused; }
@keyframes slide { to { transform: translateX(calc(var(--travel, 50%) * -1)); } }
@media (prefers-reduced-motion: reduce) {
  /* Decorative band: it stands still as a collage. Stated here because the global
     reduce block would otherwise get there by running a 1µs animation. */
  .row__track { animation: none !important; }
}

.slide {
  position: relative; flex: none;
  width: clamp(140px, 15vw, 196px); aspect-ratio: 9/16;
  border-radius: 16px; overflow: hidden;
  /* The photo is lazy, so this is what a card looks like before it arrives: a
     quiet placeholder sitting on the band, not the near-black hole --ink left. */
  background: #E7E4E0;
  box-shadow: 0 12px 30px -18px rgba(25,27,30,.45);
  /* 1cqw = 1% of the card's width, which is exactly how the product sizes
     captions (fractions of canvas width). The app establishes the same
     container for the same reason — see MediaEditor.css .meditor__canvas. */
  container-type: inline-size;
}
.slide img { width: 100%; height: 100%; object-fit: cover; }

/* Only the two shadow-only presets get a scrim; classic carries a stroke and
   boxed sits on a solid box, so neither needs help off the photo. */
.slide__scrim { position: absolute; inset: 0; background: linear-gradient(to top, rgba(0,0,0,.45) 0%, rgba(0,0,0,.06) 44%, transparent 60%); }

/* The four real caption presets, ported from frontend/src/lib/slideshowStyle.js
   (TEXT_STYLE_PRESETS) with the geometry from slideshowExport.js. All four are
   TikTok Sans, centred, no letter-spacing — as the canvas compositor draws them.
   --x/--y are the product's free-position fractions, set per card. */
.slide__hook {
  position: absolute; margin: 0;
  left: calc(var(--x, .5) * 100%); top: calc(var(--y, .84) * 100%);
  translate: -50% -50%;
  width: 84cqw;                    /* the compositor's 0.08 side padding, both sides */
  font-family: var(--post); text-align: center;
}
.slide__hook--classic {
  color: #fff; font-weight: 600; font-size: 6cqw; line-height: 1.25;
  /* the canvas stroke is centred on the glyph edge, so CSS takes half of 0.008 */
  -webkit-text-stroke: .4cqw #000; paint-order: stroke fill;
}
.slide__hook--pop {
  color: #F5E39B; font-weight: 600; font-size: 6.2cqw; line-height: 1.25;
  text-shadow: 0 .25cqw .8cqw rgba(0,0,0,.5);
}
.slide__hook--boxed {
  color: #000; font-weight: 600; font-size: 6cqw; line-height: 1.46;  /* 1 + 2*0.23 */
}
.slide__hook--boxed span {
  background: #fff; box-decoration-break: clone; -webkit-box-decoration-break: clone;
  padding: .23em .385em; border-radius: .154em;
}
.slide__hook--punch {
  color: #F5A3A3; font-weight: 700; font-size: 7cqw; line-height: 1.25;
  text-shadow: 0 .25cqw .8cqw rgba(0,0,0,.6);
}
.wall__note { margin: clamp(30px, 3.4vw, 46px) auto 0; text-align: center; font-size: 13.5px; color: var(--ink-50); max-width: 60ch; }

/* ── Steps ──────────────────────────────────────────────────── */

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 1.8vw, 24px); }
/* The number is an index, so it sits in the corner and stays out of the reading
   column; everything that IS the content — art, title, body, timing — is centred
   on one axis so the three cards scan as a set. */
.step {
  position: relative;
  background: #fff; border: 1px solid var(--line); border-radius: 24px;
  padding: clamp(46px, 4vw, 54px) clamp(22px, 2.4vw, 30px) clamp(24px, 2.6vw, 32px);
  box-shadow: var(--shadow);
  display: flex; flex-direction: column; align-items: center; text-align: center;
}
.step__n {
  position: absolute; top: clamp(16px, 1.6vw, 20px); left: clamp(16px, 1.6vw, 20px);
  display: inline-grid; place-items: center; width: 32px; height: 32px;
  border-radius: 999px; border: 1.5px solid var(--ink); color: var(--ink);
  font-family: var(--display); font-weight: 900; font-size: 14.5px;
}
/* Holds its square from the start so the mark landing shifts nothing. Empty
   until main.js mounts the animation — the numeral carries the step until then. */
.step__art { display: block; width: 108px; aspect-ratio: 1; margin: 0 auto 6px; }
.step__art svg { display: block; width: 100%; height: 100%; }
/* A slow 6px float while the card is hovered, riding on top of the Lottie's own
   motion. The global prefers-reduced-motion block already collapses this. */
@keyframes step-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
.step:hover .step__art { animation: step-bob 2s ease-in-out infinite; }
.step .h3 { margin-bottom: 8px; }
.step p { margin: 0 0 16px; color: var(--ink-70); font-size: 15.5px; max-width: 30ch; }
.step small { margin-top: auto; font-size: 13px; font-weight: 600; color: var(--ink-50); }
/* The way out of the summary and into the full list. */
.steps__more { margin: clamp(24px, 3vw, 36px) 0 0; text-align: center; }

/* ── Breakpoints ─────────────────────────────────────────────── */

@media (max-width: 980px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: 1fr 1fr; }
  .steps > :last-child { grid-column: 1 / -1; }
}
@media (max-width: 720px) {
  .stats, .steps { grid-template-columns: 1fr; }
  .steps > :last-child { grid-column: auto; }
  /* One column, and the card is suddenly three times wider than its value needs:
     the band the mark sits in becomes an empty row above every tile. So here it
     comes out of flow and into the corner instead — no value is long enough to
     reach it at this width. */
  .stat__icon { position: absolute; top: clamp(22px, 2.4vw, 30px); right: clamp(22px, 2.4vw, 30px); margin: 0; width: 28px; }
}
