/* ─────────────────────────────────────────────────────────────────────────
   page-start.css — the /start/ route's own layer, scoped under .start-page.

   WHY THIS FILE EXISTS. /start/ was the thinnest page on the site: the
   brief form alone in a single column, the one route where nothing moved.
   This layer gives it the same standard as the rebuilt pages —

     · a two-column composition: the brief on the left, the signature
       phone-shaped sequence (sections.css's .phone-*, mounted by start.js)
       running live on the right. Type left, moving element right — the
       law every composition on the site follows.
     · one-shot entrance choreography keyed off body[data-start-ready],
       which form/project.js sets when the form is in the DOM — the same
       pattern hero.css keys off data-hero-ready. This page is short, so
       reveals are load-driven, never scroll-driven.
     · the chip, tally and focus polish for the form. Base form styles
       stay in page.css (they are shared vocabulary); everything here is
       an override, and this file loads LAST so the override always wins.

   Loops here are transform/opacity only, and every infinite one is
   removed — not merely crushed — under prefers-reduced-motion, because
   base.css's 0.01ms clamp turns an infinite loop into a strobe, not a
   stop (the same reasoning hero.css records for its rings).
   ───────────────────────────────────────────────────────────────────────── */

/* ── composition: the brief beside the running system ──────────────────── */

.start-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.66fr);
  gap: clamp(var(--s5), 6vw, var(--s7));
  align-items: start;
}

/* The sequence failed to mount and its column was removed (start.js):
   back to the single, measured column the page always had. */
.start-grid.is-solo { grid-template-columns: minmax(0, 1fr); }
.start-grid.is-solo .start-form-col { max-width: 900px; }

/* page.css caps .start at 900px for the solo layout; inside a column the
   measure is the column, so the cap only fights the grid. */
.start-page .start { max-width: 760px; }

/* ── the panel column ──────────────────────────────────────────────────────
   Sticky, so the sequence rides beside the whole brief rather than being
   scrolled past after the first fieldset. Its top padding mirrors the
   form head's own clamp, so panel and headline arrive on one shelf. */

.start-side {
  position: sticky;
  top: 0;
  align-self: start;
  display: grid;
  justify-items: center;
  gap: var(--s3);
  padding-top: clamp(96px, 14vh, 150px);
  padding-bottom: var(--s6);
}

/* Sized by whichever runs out first: its own cap, its column, or the
   height the viewport leaves for a 9:16.6 panel (1.844 × its width —
   the same arithmetic hero.css documents). aspect-ratio reserves the
   slot before the module lands: zero CLS. */
.start-stage {
  width: min(360px, 86%, calc((100svh - 220px) / 1.844));
  aspect-ratio: 9 / 16.6;
}

/* The panel fills the stage; the stage is the one thing that is sized.
   Two classes outrank sections.css's single-class widths at every
   breakpoint, so the panel cannot be resized out from under the stage. */
.start-page .phone { width: 100%; }

.start-stage-cap {
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--ink-60);
}

/* Reduced motion grows mountScreen's NEXT STEP button under the panel.
   flow.css owns this treatment on the home page but is not linked on this
   route, so it is restated here verbatim. */
.start-page .hero-stepper {
  margin-top: var(--s3);
  background: none;
  border: var(--hairline);
  color: var(--ink);
  padding: 10px var(--s3);
  min-height: 44px;
  cursor: pointer;
  letter-spacing: 0.10em;
}

.start-page .hero-stepper:hover { border-color: var(--leaf-ink); color: var(--leaf-ink); }

/* ── entrance choreography ─────────────────────────────────────────────────
   One shot, on load, keyed off body[data-start-ready]. Head first, then
   the panel joins while the fieldsets deal themselves out in reading
   order; `backwards` holds each at opacity 0 through its delay. */

body[data-start-ready] .start-page .start-head > *,
body[data-start-ready] .start-page .start-form > *,
body[data-start-ready] .start-page .start-side {
  animation: start-rise var(--dur-reveal) var(--ease-out) backwards;
}

body[data-start-ready] .start-page .start-head > :nth-child(1) { animation-delay: 40ms; }
body[data-start-ready] .start-page .start-head > :nth-child(2) { animation-delay: 100ms; }
body[data-start-ready] .start-page .start-head > :nth-child(3) { animation-delay: 170ms; }
body[data-start-ready] .start-page .start-side                 { animation-delay: 220ms; }
body[data-start-ready] .start-page .start-form > :nth-child(1) { animation-delay: 260ms; }
body[data-start-ready] .start-page .start-form > :nth-child(2) { animation-delay: 340ms; }
body[data-start-ready] .start-page .start-form > :nth-child(3) { animation-delay: 420ms; }
body[data-start-ready] .start-page .start-form > :nth-child(4) { animation-delay: 500ms; }

/* The finish state appears later (the form swaps for the composed brief),
   and rises the same way the moment it is unhidden. */
.start-page .start-done { animation: start-rise var(--dur-reveal) var(--ease-out) backwards; }

@keyframes start-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ── the legends' index and the tally ──────────────────────────────────── */

.start-page .field-no {
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-tracking);
  color: var(--ink-60);
  font-weight: 400;
  margin-right: var(--s3);
  vertical-align: 0.4em;
}

/* Sits opposite the first legend; .field-group is already relative
   (page.css uses that for its hairline). Green as text only while the
   count is live — a picked service is current flowing, a zero is not. */
.start-page .chip-count {
  position: absolute;
  top: calc(var(--s5) + 8px);
  right: 0;
  font-size: var(--eyebrow-size);
  letter-spacing: 0.12em;
  color: var(--ink-60);
  transition: color 180ms var(--ease-out);
}

.start-page .chip-count.is-live { color: var(--leaf-ink); }

/* ── the nine chips ────────────────────────────────────────────────────────
   Hairline chips whose :checked state carries the live green dot — the
   same signal vocabulary as the panel's LIVE dot beside them. */

.start-page .chip {
  position: relative;
  padding-right: calc(var(--s3) + 18px);   /* room for the dot */
}

.start-page .chip-dot {
  position: absolute;
  top: calc(var(--s3) + 2px);
  right: var(--s3);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid var(--graphite);
  transition: background 180ms var(--ease-out),
              border-color 180ms var(--ease-out),
              box-shadow 180ms var(--ease-out);
}

.start-page .chip:hover .chip-dot { border-color: var(--ink-60); }

.start-page .chip-input:checked + .chip .chip-dot {
  background: var(--leaf);
  border-color: var(--leaf);
  box-shadow: 0 0 0 3px var(--leaf-14);
}

/* The quiet ambience on a picked chip: a hairline ring leaving the dot,
   the same figure as the hero's pulse at chip scale. transform/opacity
   only, and gone entirely under reduced motion. */
.start-page .chip-input:checked + .chip .chip-dot::after {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  border: 1px solid var(--leaf);
  animation: start-dot-ring 2.6s var(--ease-out) infinite;
}

@keyframes start-dot-ring {
  0%   { transform: scale(1); opacity: 0.7; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* Generous ink focus ring — page.css's 1px outline, widened. */
.start-page .chip-input:focus-visible + .chip {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* ── the submit ────────────────────────────────────────────────────────── */

.start-page .cta-submit { min-width: 240px; min-height: 52px; }

.start-page .cta-submit:focus-visible,
.start-page .start-done .cta:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* Sending…: still the accent, visibly held rather than washed out,
   with the reduced opacity page.css already gives a disabled .cta. */
.start-page .cta-submit[disabled] { transform: none; }

/* ── breakpoints ───────────────────────────────────────────────────────── */

@media (max-width: 1000px) {
  /* Stacked: the panel ABOVE the form at a capped height, so the visitor
     sees the thing they are buying before the questions about it. */
  .start-grid { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }

  .start-side {
    position: static;
    order: -1;
    padding-top: clamp(96px, 12vh, 128px);
    padding-bottom: 0;
  }

  /* Capped by height first: the whole panel in view over the fold. */
  .start-stage { width: min(260px, 64%, calc(58svh / 1.844)); }

  /* The side column now carries the top clearance under the fixed header,
     so the head hands its clamp back. */
  .start-page .start-head { padding-top: var(--s5); }
}

@media (max-width: 720px) {
  .start-stage { width: min(240px, 72%, calc(56svh / 1.844)); }
  .start-page .chip-count { top: calc(var(--s5) + 4px); }
}

/* ── reduced motion: everything arrives settled ────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  body[data-start-ready] .start-page .start-head > *,
  body[data-start-ready] .start-page .start-form > *,
  body[data-start-ready] .start-page .start-side,
  .start-page .start-done { animation: none; }

  /* An infinite loop at base.css's 0.01ms clamp is a strobe, not a stop. */
  .start-page .chip-input:checked + .chip .chip-dot::after {
    animation: none;
    opacity: 0;
  }
}
