/* SYSTEM: 2.0
 * ==========================================================================================
 * THE CLIENT INTAKE PORTAL -- STYLESHEET
 *
 * This is a CLIENT-FACING surface. Everything below follows from that one fact.
 *
 * 1. MOBILE FIRST, NOT MOBILE-TOLERANT. Every rule outside the one media query at the bottom
 *    is written for a phone held in one hand. The desktop layout is the adaptation, and it is
 *    twelve lines long. The client is going to open this from an email on a phone; that is the
 *    real screen and it gets the real design.
 *
 * 2. NO OPERATOR CHROME. There is no rail, no sidebar, no toolbar, no table. One column, one
 *    thing to do. The Client Manager stylesheet this palette comes from has all of those and
 *    they are all deliberately absent here.
 *
 * 3. THE STATUS COLOURS CARRY MEANING, AND ONLY THREE THINGS MAY SAY THEM.
 *      GREEN means done. Nothing else may be green -- not a heading, not a button, not a tick
 *      on something that is merely started. If green appears, a step is finished.
 *      BLUE means in progress. NEUTRAL means not started.
 *      THERE IS NO RED IN THIS FILE. Not as an error colour, not as a warning, not as a border.
 *      A client who cannot open their link has not done anything wrong, and a red screen tells
 *      them they have. The one failure surface in this project is styled exactly like the
 *      ordinary ones.
 *
 * 4. EVERY COLOUR IS A TOKEN. No hex below the token block. The brand navy and blue are copied
 *    character for character from itv-client-manager/css/app.css, which copied them from the
 *    company's own live stylesheet. If the brand changes it changes there first.
 *
 * 5. CONTRAST IS MEASURED, NOT ASSUMED. Every ratio in a comment below was computed off the two
 *    hex values it names, not estimated. The lowest pairing on the page is 4.78:1.
 * ==========================================================================================
 */

/* ==========================================================================================
   01  TOKENS
   ========================================================================================== */

:root {
  /* ---- BRAND -- copied from itv-client-manager/css/app.css, not chosen here --------------- */
  --brand-navy:      #063a6c;   /* the header bar. THE company colour */
  --brand-blue:      #2494e0;   /* the bright half of the brand */
  --on-brand:        #ffffff;   /* text on navy -- 11.48:1 */
  --on-brand-dim:    #b9d9f5;   /* secondary text on navy -- 7.82:1 */

  /* ---- THE CALL TO ACTION: ORANGE. THE VIOLET IS DEAD. -------------------------------------
   *
   * Gerek's ruling, family-wide. The violet was this surface's own invention -- chosen so a
   * client-facing button would not look like an operator's Save -- and inventing a colour was the
   * mistake. THE COMPANY ALREADY HAS AN ACTION COLOUR and it is in the brand: legacy reserves
   * `--orange: #dd6b00` for "brand / CTA / action accents ONLY (RUN, Finalize, ...)". That is the
   * same rule the violet was carrying here, in the house colour instead of a made-up one.
   *
   * COPIED, NOT EYEBALLED, from `itv-aeo-tool/shared/itv-tokens.css` -- the file the AEO Article
   * Tool 2.0 draws from, which took them from the legacy design. --brand-navy and --brand-blue
   * below were ALREADY character for character identical to that file; the two tools have been
   * drawing from the same well the whole time and only the action colour differed.
   *
   * -------------------------------------------------------------------------------------------
   * THE TEXT ON IT IS BLACK, AND THAT IS A MEASUREMENT RATHER THAN A TASTE
   * -------------------------------------------------------------------------------------------
   *
   * WHITE ON #dd6b00 IS 3.40:1 AND FAILS. It clears the 3:1 floor for LARGE text only, which is
   * why the AEO tool can use white on it -- that tool sets 24px all-caps Bebas Neue in the same
   * rule as the fill, so its orange only ever carries display type. THIS APP HAS NO DISPLAY FACE:
   * its buttons are 17px system text, so the large-text allowance is not available and white here
   * would be a quiet failure on the one control that commits a client's answers.
   *
   * Measured across the candidates, on the fill AND on its hover, because a button under a cursor
   * still has to be readable:
   *
   *     ink        on #dd6b00   on #c25e00      both >= 4.5?
   *     #ffffff       3.40         4.29             no
   *     #101828       5.22         4.14             no   <- this file's own --ink
   *     #0d0a06       5.81         4.60             yes
   *     #000000       6.18         4.89             YES  <- and it invents nothing
   *
   * Pure black wins on both numbers and is the only candidate that is not a hex somebody chose.
   * Both brand orange values are kept exactly as the brand file defines them; the only thing
   * decided here is what is written on top of them. */
  --brand-orange:        #dd6b00;   /* legacy --orange / itv-tokens --cta. THE committing button */
  --brand-orange-strong: #c25e00;   /* hovered -- itv-tokens --cta-strong */
  --brand-orange-ink:    #b35700;   /* orange as TEXT or a border on a light ground -- 4.61:1 on --bg */
  --brand-orange-wash:   #fdf1e6;   /* the faintest orange */
  --on-orange:           #000000;   /* 6.18:1 on the fill, 4.89:1 on the hover. See above */

  /* THE FOCUS RING IS THE BRAND BLUE, from the same file. A ring is not an action, so it has no
   * business wearing the action colour -- and an orange ring around an orange button is invisible
   * at exactly the moment a keyboard user needs to see it. */
  --focus-ring:      rgba(36, 148, 224, .45);

  /* ---- SURFACES -------------------------------------------------------------------------- */
  --bg:              #f6f8fb;   /* the page */
  --panel:           #ffffff;   /* a card */
  --panel-2:         #f1f4f9;   /* a quiet fill */
  --line:            #e4e9f0;   /* hairline */
  --line-strong:     #d3dae4;
  --panel-3:         #e9edf4;   /* a quiet fill, pressed. Step 1's choice buttons on hover */

  /* ---- TEXT ------------------------------------------------------------------------------ */
  --ink:             #101828;   /* body     -- 17.75:1 on a card */
  --ink-dim:         #4e5a6a;   /* secondary --  7.01:1 on a card */
  --ink-mute:        #5a6675;   /* meta      --  5.85:1 on a card */

  /* ---- THE ACCENT: the brand's deep blue, for a CHOSEN state and for a link ----------------
   *
   * From `itv-aeo-tool/shared/itv-tokens.css`, character for character, like the rest. It is the
   * same #0e5aa6 as --doing-ink below, and they are kept as separate names on purpose: one means
   * "a client picked this", the other means "this step is in progress". A single token doing both
   * jobs is a token that cannot be changed for one of them.
   *
   * THIS BLOCK DID NOT EXIST UNTIL THE VIOLET WAS REMOVED, and its absence was a live defect for
   * one deploy: `.choice.is-on` and the new segmented control were both pointed at `var(--accent)`
   * on the assumption it was already here -- it is in Client Manager and in the AEO tool, not in
   * this repo. An undefined custom property does not error, it resolves to NOTHING, so a selected
   * button rendered transparent with dark text and still looked like a button. Caught by clicking
   * through the deployed page, not by reading it. See the token check in check.js, added the same
   * afternoon so it cannot happen twice. */
  --accent:          #0e5aa6;   /* white on it -- 6.93:1 */
  --accent-strong:   #063a6c;   /* hovered: straight to the company navy -- 11.48:1 */
  --on-accent:       #ffffff;

  /* ---- THE THREE STATUS COLOURS ---------------------------------------------------------- */
  --done-ink:        #116b39;   /* on --done-bg -- 5.81:1 */
  --done-bg:         #e6f4ec;
  --done-edge:       #bfe3cd;

  --doing-ink:       #0e5aa6;   /* on --doing-bg -- 5.91:1 */
  --doing-bg:        #e4eefb;
  --doing-edge:      #c4dcf6;

  --todo-ink:        #4e5a6a;   /* on --todo-bg -- 6.19:1 */
  --todo-bg:         #eef1f6;
  --todo-edge:       #dfe4ec;

  /* ---- SHAPE ----------------------------------------------------------------------------- */
  --r-sm:  8px;
  --r-md:  12px;
  --r-lg:  16px;
  --r-pill: 999px;

  --shadow-card:  0 1px 2px rgba(16, 24, 40, .04), 0 6px 20px rgba(16, 24, 40, .06);
  --shadow-lift:  0 2px 4px rgba(16, 24, 40, .06), 0 12px 28px rgba(16, 24, 40, .10);
  --shadow-bar:   0 -2px 16px rgba(16, 24, 40, .08);   /* the fixed bar, lit from below */

  /* The modal backdrop. Dark enough that the form behind it is plainly out of reach, light
   * enough that the client can still see their own answers underneath and knows what they are
   * about to lock. */
  --scrim-fill:   rgba(16, 24, 40, .45);

  /* ---- SPACE ----------------------------------------------------------------------------- */
  --gap-1: 4px;
  --gap-2: 8px;
  --gap-3: 12px;
  --gap-4: 16px;
  --gap-5: 24px;
  --gap-6: 32px;
  --gap-7: 48px;

  /* ---- TYPE ------------------------------------------------------------------------------
   * System stack only. A webfont is a second request before the client can read anything, and
   * on a phone on a bad signal that is the difference between "it opened" and "it is broken". */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* ==========================================================================================
   02  RESET AND BASE
   ========================================================================================== */

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

/* THE `hidden` ATTRIBUTE ACTUALLY HIDES THINGS. A SAFETY NET, NOT THE FIX.
 *
 * `hidden` is not a property of an element; it is a UA stylesheet rule, `[hidden] { display:
 * none }`, with effectively no specificity -- so ANY author rule that sets `display` on the same
 * element silently defeats it. That shipped: `.card3__summary { display: flex }` beat it, and an
 * empty chip and a live "Change" link rendered on every unanswered Step 3 card while the code
 * setting `hidden = true` ran correctly every time.
 *
 * The card was fixed by CONSTRUCTION -- it attaches one presentation or the other and never
 * hides anything (see showOnly() in js/step3-render.js). This rule is here so the NEXT element
 * somebody hides cannot fail the same way silently. It is a floor, and it is not permission to
 * go back to hiding things that should not be in the document at all. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;   /* iOS must not resize our type when the phone rotates */
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font);
  /* 17px, not 16. This is read by people who are not looking at screens all day. */
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

/* Nothing on this site is decorative-motion. One transition, and it is off for anybody who has
   asked their machine for less. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ==========================================================================================
   03  THE SHELL
   ========================================================================================== */

.site-header {
  background: var(--brand-navy);
  color: var(--on-brand);
  padding: var(--gap-4) var(--gap-4);
}

.wordmark {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: .2px;
  color: var(--on-brand);
}

.wrap {
  width: 100%;
  max-width: 680px;
  margin: 0 auto;
  padding: var(--gap-6) var(--gap-4) var(--gap-7);
}

.site-footer {
  padding: 0 var(--gap-4) var(--gap-6);
  text-align: center;
  color: var(--ink-mute);
  font-size: 14px;
}

/* ==========================================================================================
   04  PAGE HEAD AND COPY
   ========================================================================================== */

.page-title {
  margin: 0 0 var(--gap-3);
  font-size: 27px;
  line-height: 1.25;
  font-weight: 700;
  letter-spacing: -.2px;
  /* A name can be long and it can be one unbroken word. Neither may push the page sideways. */
  overflow-wrap: anywhere;
}

.lede {
  margin: 0 0 var(--gap-5);
  color: var(--ink-dim);
  font-size: 17px;
}

/* THE ONE-TIME THANK-YOU, under the welcome, for somebody who finalized a step seconds ago.
 *
 * It replaced a pop-up the client had to dismiss (see js/step1.js), so its whole job is to cost
 * them nothing: one line, no card, no icon, no button. It uses --done-ink because that is what
 * this project's green means and this sentence is about something being done -- it is not a
 * fourth status colour and it is not a success banner for an ordinary load, which §10 still
 * forbids. 6.20:1 on the page. */
.thanks {
  margin: 0 0 var(--gap-4);
  color: var(--done-ink);
  font-size: 17px;
  font-weight: 600;
}

.section-label {
  margin: 0 0 var(--gap-3);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/* ==========================================================================================
   05  THE STEP LIST -- the whole point of the checklist screen
   ========================================================================================== */

.step-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gap-3);
}

/*
 * ONE TAP TARGET PER STEP, AND IT IS THE WHOLE CARD.
 *
 * Not a "Start" link inside a card -- the card. A small link inside a large box is the single
 * most common way a phone screen becomes annoying: the thing that looks tappable is tappable
 * and the 90% of it that also looks tappable is not. min-height is 76px against a 44px floor,
 * because this is the only control on the screen and it can afford to be generous.
 */
.step-card {
  display: flex;
  align-items: center;
  gap: var(--gap-4);
  width: 100%;
  min-height: 76px;
  padding: var(--gap-4);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease;
}

.step-card:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-lift);
}

.step-card:active { transform: translateY(1px); }

.step-card:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  border-color: var(--brand-blue);
}

/* The number. Quiet on purpose -- it is an ordering aid, not a label, and the client is looking
   for the words next to it. */
.step-num {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-pill);
  background: var(--panel-2);
  color: var(--ink-dim);
  font-size: 15px;
  font-weight: 700;
}

.step-body {
  flex: 1 1 auto;
  min-width: 0;   /* lets a long name wrap instead of stretching the flex row */
}

.step-name {
  display: block;
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.step-meta {
  display: block;
  margin-top: var(--gap-1);
  font-size: 14px;
  color: var(--ink-mute);
}

/* The chevron. A pure affordance; it says "this goes somewhere" without any words. */
.step-go {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--ink-mute);
  border-bottom: 2px solid var(--ink-mute);
  transform: rotate(-45deg);
}

/* ==========================================================================================
   06  THE STATUS CHIP -- THE ONLY THING ON THIS SITE THAT MAY USE THE STATUS COLOURS
   ========================================================================================== */

.chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  border: 1px solid;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

/* NOT STARTED. Neutral, and neutral is correct -- an untouched step is not a problem. */
.chip--todo  { color: var(--todo-ink);  background: var(--todo-bg);  border-color: var(--todo-edge); }

/* IN PROGRESS. Blue, the brand's own colour. */
.chip--doing { color: var(--doing-ink); background: var(--doing-bg); border-color: var(--doing-edge); }

/* DONE. The only green in the file. */
.chip--done  { color: var(--done-ink);  background: var(--done-bg);  border-color: var(--done-edge); }

/* ==========================================================================================
   07  CARDS AND BUTTONS
   ========================================================================================== */

.card {
  padding: var(--gap-5);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}

.card > :first-child { margin-top: 0; }
.card > :last-child  { margin-bottom: 0; }

.card-title {
  margin: 0 0 var(--gap-3);
  font-size: 20px;
  font-weight: 700;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0 var(--gap-5);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}

.btn:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}

.btn--primary {
  background: var(--brand-orange);
  color: var(--on-orange);
}
.btn--primary:hover { background: var(--brand-orange-strong); }

.btn--quiet {
  background: var(--panel);
  color: var(--ink-dim);
  border-color: var(--line-strong);
}
.btn--quiet:hover { background: var(--panel-2); }

.btn--block { display: flex; width: 100%; }

/* ------------------------------------------------------------------------------------------
 * A BUTTON THAT ANSWERS FOR ITSELF
 *
 * Feedback belongs ON the control that was pressed. The save state used to live in a grey line
 * in the opposite corner of the bar; it was correct, live, and far enough away that Gerek
 * pressed Save three times on the live site believing it was dead. See js/button-state.js.
 * ------------------------------------------------------------------------------------------ */

/* The label is a span so its text can be swapped without rebuilding the button -- rebuilding
   would destroy the spinner and, worse, drop the keyboard's focus. */
.btn__label { display: inline-block; }

/* THE SPINNER EXISTS AT REST AND IS MERELY INVISIBLE. Collapsed to zero width with no margin, so
   entering the working state does not reflow the bar and slide the other button under a finger
   that may be about to tap again. */
.btn__spin {
  width: 0;
  height: 14px;
  margin-right: 0;
  border: 2px solid currentColor;
  border-radius: var(--r-pill);
  border-right-color: transparent;
  opacity: 0;
  transition: none;
}

.btn.is-working .btn__spin {
  width: 14px;
  margin-right: var(--gap-2);
  opacity: .55;
  animation: btn-spin .7s linear infinite;
}

@keyframes btn-spin { to { transform: rotate(360deg); } }

/* WORKING. Dimmed and un-pressable, and the LABEL carries the whole message -- which is what
   keeps this honest under prefers-reduced-motion, where the reset at the top of this file stops
   the spinner turning and leaves a static ring. Somebody who has asked their machine for less
   motion still reads "Saving…". */
.btn.is-working {
  cursor: default;
  opacity: .85;
}

.btn--quiet.is-working { background: var(--panel-2); }

/* DONE. THE SANCTIONED GREEN, ruled by Gerek: an outcome the client asked for, on the control
   they pressed, for a second and a half.
 *
 * §10 says green means Done and nothing else may be green. That rule protects the STATUS CHIPS
 * -- it exists so a styling decision can never make a claim about a client's data. This is not a
 * new green: it is --done-ink itself, borrowed briefly, and it describes an event rather than a
 * record. White on it is 6.59:1. */
.btn.is-done,
.btn--quiet.is-done,
.btn--primary.is-done {
  background: var(--done-ink);
  border-color: var(--done-ink);
  color: var(--on-brand);
  opacity: 1;
}

/* The hover rules above are more specific than they look once a state class is on. Held, so a
   mouse resting on the button does not undo the green mid-flash. */
.btn--primary.is-done:hover,
.btn--quiet.is-done:hover { background: var(--done-ink); }

/* NO TRANSITION INTO EITHER STATE, and this is a fix rather than a preference.
 *
 * `.btn` carries `transition: background .15s ease` for hover, which is right for a hover and
 * wrong for this. Entering the done state sets the text to white and the background to green;
 * with the transition running, the background spends 150ms crossing from --panel to --done-ink
 * while the text is ALREADY white -- so the label is white-on-near-white and effectively
 * invisible for a fifth of a second. Measured in the browser: `backgroundColor` read
 * `rgb(255,255,255)` with `color` reading `rgb(255,255,255)` on the frame the class landed.
 *
 * The whole purpose of these two states is to be seen the instant they are entered, so they are
 * entered instantly. Leaving them keeps the transition -- fading back to the ordinary label is
 * the one moment here where a fade is the right answer. */
.btn.is-working,
.btn.is-done { transition: none; }

.btn:disabled { cursor: default; }

/* The back link on a step screen. A link, not a button -- going back is not an action with a
   consequence, and giving it a button's weight would suggest it is. It keeps a 44px target
   anyway, because it is the only way off this screen on a phone. */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-2);
  min-height: 44px;
  margin-bottom: var(--gap-3);
  color: var(--doing-ink);
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
}
.back-link:hover { text-decoration: underline; }
.back-link:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; border-radius: var(--r-sm); }

.back-arrow {
  width: 9px;
  height: 9px;
  border-left: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
}

/* ==========================================================================================
   08  THE WAITING STATE
   ========================================================================================== */
/*
 * A calm line of text and nothing else. No spinner, no skeleton, no progress bar.
 *
 * It is also NOT announced the instant the page paints: the CSS delays it, so a fast lookup --
 * which is most of them -- shows nothing at all rather than flashing "one moment" for 80ms.
 * A flicker reads as a fault.
 */
.waiting {
  color: var(--ink-mute);
  font-size: 17px;
  opacity: 0;
  animation: fade-in .2s ease .5s forwards;
}

@keyframes fade-in { to { opacity: 1; } }

/* ==========================================================================================
   09  UTILITIES
   ========================================================================================== */

.stack   { display: flex; flex-direction: column; gap: var(--gap-4); }
.mt-5    { margin-top: var(--gap-5); }
.mt-6    { margin-top: var(--gap-6); }
.muted   { color: var(--ink-mute); font-size: 15px; }

/* Visible to a screen reader, invisible on screen. Used for the live region that announces a
   screen change to somebody who cannot see that the page has redrawn. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================================
   10  WIDER SCREENS -- the adaptation, and it is deliberately small
   ========================================================================================== */

@media (min-width: 720px) {
  .site-header { padding: var(--gap-4) var(--gap-6); }
  .wrap        { padding: var(--gap-7) var(--gap-5) var(--gap-7); }
  .page-title  { font-size: 34px; }
  .step-card   { padding: var(--gap-5); min-height: 84px; }
  .btn--block  { display: inline-flex; width: auto; }
}

/* ==========================================================================================
   11  STEP 1 -- THE FORM
   ------------------------------------------------------------------------------------------
   Mobile first, and on this page that is not a slogan: twenty questions on a phone held in one
   hand, at the end of a working day. Every tap target here is at least 48px tall, every text
   box is big enough to see three lines of what you typed, and nothing is a small grey link.

   NO RED. Not for the secret steer, not for an unsaved state, not for a refusal. A client who
   pastes something they shouldn't, or loses their signal, has not done anything wrong -- and the
   one colour that says "you have made a mistake" is the one colour this site does not own.
   The steer is amber-free too: it uses the ordinary quiet fill and bold ink, which reads as
   "look at this" without reading as "you are in trouble".

   GREEN STAYS SACRED. It appears on this page in exactly one place: the finished note.
   ========================================================================================== */

.form { margin-top: var(--gap-5); }

.form__section { margin-bottom: var(--gap-6); }

.form__section-title {
  margin: 0 0 var(--gap-3);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/* ---- one question ---------------------------------------------------------------------- */

.q {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  padding: var(--gap-5) var(--gap-4);
  margin-bottom: var(--gap-4);
}

/* THE QUESTION IS THE BIGGEST THING IN THE CARD, and the pre-filled value is inside it. The
   whole design of this step is that a wrong value in front of somebody's eyes gets corrected in
   four seconds -- which does not happen if it is set at the size of body copy. */
.q__text {
  margin: 0 0 var(--gap-4);
  font-size: 19px;
  line-height: 1.45;
  font-weight: 600;
  color: var(--ink);
}

.q__why {
  margin: var(--gap-4) 0 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-mute);
}

.q__body { display: block; }

/* ---- the two buttons ------------------------------------------------------------------- */

.q__choices {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gap-3);
}

.choice {
  min-height: 52px;
  padding: var(--gap-3) var(--gap-4);
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  background: var(--panel-2);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-md);
  cursor: pointer;
  text-align: center;
  -webkit-tap-highlight-color: transparent;
}

.choice--wide {
  display: block;
  width: 100%;
  margin-top: var(--gap-3);
  text-align: left;
  line-height: 1.4;
}

.choice:hover { background: var(--panel-3); }

.choice:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}

/* THE CHOSEN ONE IS THE BRAND ACCENT BLUE, and it is deliberately NOT the orange.
 *
 * Orange is reserved for the one control on a screen that COMMITS something -- itv-tokens.css
 * says so in as many words, and this page would otherwise put nine orange fills above the single
 * orange button that actually finalizes. A picked choice is a state, not an action.
 *
 * And still not green: green on this site means a whole step is Done, and a picked button is not
 * a finished anything. White on --accent is 6.93:1. */
.choice.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.choice.is-on:hover { background: var(--accent-strong); border-color: var(--accent-strong); }

/* ---- the boxes -------------------------------------------------------------------------- */

.q__fix { margin-top: var(--gap-3); }

.q__box {
  display: block;
  width: 100%;
  box-sizing: border-box;
  min-height: 96px;
  padding: var(--gap-3) var(--gap-4);
  font: inherit;
  font-size: 17px;          /* 17px or larger, or iOS zooms the whole page on focus */
  line-height: 1.5;
  color: var(--ink);
  background: var(--panel);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-md);
  resize: vertical;
}

.q__box:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 1px;
  border-color: var(--brand-blue);
}

.q__box--extra { margin-top: var(--gap-2); }

.q__extra-label {
  margin: var(--gap-4) 0 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-dim);
}

/* ---- the secret steer -- a notice, never an alarm ---------------------------------------- */

.q__steer {
  margin: var(--gap-3) 0 0;
  padding: var(--gap-3) var(--gap-4);
  font-size: 15px;
  line-height: 1.5;
  font-weight: 600;
  color: var(--ink);
  background: var(--panel-2);
  border: 1px solid var(--line-strong);
  border-left: 4px solid var(--brand-blue);
  border-radius: var(--r-sm);
}

/* ---- the services list ------------------------------------------------------------------ */

.q__checks { display: block; }

.check {
  display: flex;
  align-items: center;
  gap: var(--gap-3);
  min-height: 52px;
  padding: var(--gap-2) var(--gap-3);
  border-radius: var(--r-md);
  cursor: pointer;
}

.check:hover { background: var(--panel-2); }

/* A 24px box, because the default is about 13px and this is a phone. */
.check__input {
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  accent-color: var(--accent);
  cursor: pointer;
}

.check__label { font-size: 17px; line-height: 1.4; color: var(--ink); }

/* ---- the bottom bar --------------------------------------------------------------------- */

/* ALWAYS ON SCREEN. A save button twenty questions down the page is a save button that is not
   found, and the client who does not find it is the client who loses their evening's work. */
.bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: var(--gap-2);
  padding: var(--gap-3) var(--gap-4) calc(var(--gap-3) + env(safe-area-inset-bottom));
  background: var(--panel);
  border-top: 1px solid var(--line);
  box-shadow: var(--shadow-bar);
}

/* `auto 1fr`, NOT `1fr 1fr`. Two equal columns on a 375px phone leaves about 150px a side, and
   "Save and finalize" does not fit in it -- it wrapped to two lines and sat half behind the edge
   of its own button. Seen on the deployed page at 375x812, not reasoned about. So "Save draft"
   takes the width its words need and the longer label gets everything else. */
/* THE LINE AND THE BUTTONS ARE ONE GROUP. This wrapper is the whole fix for the bottom-left
   problem: previously the bar's two children were pushed apart by `space-between` at desktop
   width, leaving the save text a screen away from the button it described. */
.bar__actions {
  display: flex;
  flex-direction: column;
  gap: var(--gap-2);
}

.bar__buttons { display: grid; grid-template-columns: auto 1fr; gap: var(--gap-3); }

.bar__buttons .btn {
  width: 100%;
  min-height: 52px;
  padding: 0 var(--gap-4);
  white-space: nowrap;
}

/* QUIET. Small, grey, and it holds "Saved just now" -- no banner, no toast, no colour. A save
   that announces itself teaches somebody to watch for it, and then a save that is merely fast
   looks like a save that did not happen. It reserves its line so the buttons never jump. */
.bar__state {
  margin: 0;
  min-height: 18px;
  font-size: 13px;
  line-height: 18px;
  color: var(--ink-mute);
  text-align: center;
}

/* The page has to be able to scroll clear of the fixed bar. */
body:has(.bar) .wrap { padding-bottom: 148px; }

/* ==========================================================================================
   STEP 3 -- THE ACCOUNT CARDS
   ==========================================================================================
   Nine questions, most of which are "no". The card starts as one question with three answers and
   grows only for the ones that turn out to be the client's -- a page showing nine account-name
   boxes at once reads as nine jobs. */

.card3-list {
  display: flex;
  flex-direction: column;
  gap: var(--gap-4);
  margin-top: var(--gap-5);
}

.card3 {
  padding: var(--gap-5);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}

/* FOLDED, NOT HIDDEN. An answered card keeps its name and shows what was said, on one line, with
   a way back in. The client can see they answered it and can still change their mind.
   FOLDING IS INSTANT -- no height transition. A card that animates shut on every answer turns
   nine quick taps into nine little waits, and the movement is the thing being complained about,
   not the thing being enjoyed. */
.card3--folded { padding: var(--gap-4) var(--gap-5); background: var(--panel-2); box-shadow: none; }
.card3--folded .card3__why { display: none; }

.card3__summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-2) var(--gap-3);
  margin: var(--gap-2) 0 0;
}

.card3__said { font-size: 15px; color: var(--ink-mute); overflow-wrap: anywhere; }

/* A LINK, NOT A BUTTON. Reopening a card undoes nothing and commits nothing; a button's weight
   would suggest otherwise. 44px so it is still a thumb target. */
.card3__change {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-left: auto;
  color: var(--accent);
  font-size: 15px;
  font-weight: 600;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}
.card3__change:hover { color: var(--accent-strong); }
.card3__change:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; border-radius: var(--r-sm); }

/* ==========================================================================================
   THE SEGMENTED CONTROL -- one switch, not three buttons
   ==========================================================================================
   Three flat buttons in a row read as three separate things a client could press in any
   combination. A segmented control reads as ONE question with one answer in it, which is what
   this actually is -- and it says so to a screen reader too: role="radiogroup" around
   role="radio", arrow keys to move, one tab stop for the whole group.

   THE SEGMENTS ARE EQUAL WIDTH BY FLEX-BASIS ZERO, not by content. That is what stops the tick
   appearing on selection from resizing the chosen segment and shoving the others sideways under
   a finger that is still on the screen. */

.seg {
  display: flex;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--panel);
}

.seg__opt {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-2);
  min-height: 56px;
  padding: var(--gap-2) var(--gap-3);
  border: 0;
  border-left: 1.5px solid var(--line-strong);
  background: transparent;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
  text-align: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.seg__opt:first-child { border-left: 0; }
.seg__opt:hover { background: var(--panel-2); }

/* THE FOCUS RING IS DRAWN INSIDE, because the group clips its children -- an outline drawn
   outward would be cut off by `overflow: hidden` and a keyboard user would see nothing. */
.seg__opt:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: -3px;
}

/* SELECTED: the brand accent blue, and deliberately NOT the orange -- see .choice.is-on. */
.seg__opt[aria-checked="true"] {
  background: var(--accent);
  color: var(--on-accent);
}

.seg__opt[aria-checked="true"]:hover { background: var(--accent-strong); }

/* The tick is decoration; the aria-checked state is what is actually announced. */
.seg__tick { font-size: 15px; line-height: 1; }

/* ---- the nested panel: visually INSIDE the choice that opened it ---- */
.card3__nest {
  margin-top: var(--gap-4);
  padding: var(--gap-1) 0 0 var(--gap-4);
  border-left: 3px solid var(--brand-blue);
}

.card3__nest-gap { margin-top: var(--gap-4); }

/* ---- THE STICKY PROGRESS STRIP ----------------------------------------------------------
 * Slim, quiet, and it stays. On a nine-card page "how much is left" is the first thing to
 * scroll off, and it is the one thing a client wants while they are working.
 *
 * z-index BELOW the save bar's 20, deliberately: a sticky top strip and a fixed bottom bar
 * cannot meet at any sane viewport height, and if they ever did the bar is the one that must
 * win -- it holds the buttons. */
.progress-strip {
  position: sticky;
  top: 0;
  z-index: 15;
  margin: var(--gap-2) 0 var(--gap-5);
  padding: var(--gap-3) 0 var(--gap-3);
  /* OPAQUE, or the cards scroll through it. --bg is the page, so it reads as the page. */
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

/* At least body size and medium weight -- it is a status a client reads at a glance, not a
   caption. The old version was 15px --ink-mute and got lost against the why-lines. */
.progress-strip__label {
  margin: 0 0 var(--gap-2);
  font-size: 17px;
  font-weight: 600;
  color: var(--ink-dim);
}

.progress-strip__track {
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--panel-3);
  overflow: hidden;
}

/* BRAND BLUE, NEVER GREEN. Green means a whole step is Done, and answering the ninth card is
   not finishing the step -- finalizing is. A bar that filled to green would promise that. */
.progress-strip__fill {
  height: 100%;
  width: 0;
  background: var(--brand-blue);
  border-radius: var(--r-pill);
  /* The one movement on this strip, and it is the width following the number. The global
     reduced-motion reset at the top of this file switches it off. */
  transition: width .2s ease;
}

/* ---- the finished step, read-only ---- */
.card3--done { padding: var(--gap-4) var(--gap-5); }
.card3__name-done {
  margin: 0 0 var(--gap-1);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink-dim);
}
.card3__done-id {
  margin: var(--gap-2) 0 0;
  font-size: 15px;
  color: var(--ink-mute);
  overflow-wrap: anywhere;
}

/* ---- the finished step ------------------------------------------------------------------- */

/* THE ONE GREEN ON THIS PAGE. */
.note {
  margin-top: var(--gap-5);
  padding: var(--gap-4);
  background: var(--done-bg);
  border: 1px solid var(--done-edge);
  border-radius: var(--r-lg);
}

.note__title { margin: 0 0 var(--gap-1); font-size: 17px; font-weight: 700; color: var(--done-ink); }

.q__support { margin: 0; font-size: 15px; line-height: 1.5; color: var(--done-ink); }
.q__support a { color: var(--done-ink); font-weight: 600; }

.q--done { padding: var(--gap-4); }
.q--done .q__text { font-size: 16px; font-weight: 600; color: var(--ink-dim); margin-bottom: var(--gap-2); }

.q__answer {
  margin: 0;
  font-size: 18px;
  line-height: 1.45;
  font-weight: 600;
  color: var(--ink);
  white-space: pre-wrap;
}

.q__answer--none { font-weight: 500; color: var(--ink-mute); }

/* ---- the modal --------------------------------------------------------------------------- */

.scrim {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: var(--gap-4);
  background: var(--scrim-fill);
}

.dialog {
  width: 100%;
  max-width: 460px;
  padding: var(--gap-5) var(--gap-4) calc(var(--gap-4) + env(safe-area-inset-bottom));
  background: var(--panel);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lift);
}

.dialog__title { margin: 0 0 var(--gap-3); font-size: 21px; line-height: 1.3; color: var(--ink); }
.dialog__body  { margin: 0 0 var(--gap-5); font-size: 16px; line-height: 1.55; color: var(--ink-dim); }
.dialog__actions { display: grid; gap: var(--gap-3); }
.dialog__actions .btn { min-height: 52px; }

body.is-modal { overflow: hidden; }

@media (prefers-reduced-motion: no-preference) {
  .scrim  { animation: scrim-in .16s ease-out; }
  .dialog { animation: dialog-in .2s ease-out; }
}

@keyframes scrim-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes dialog-in { from { transform: translateY(12px); opacity: 0; } to { transform: none; opacity: 1; } }

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

/* NARROW: THE SEGMENTS STACK, AND THEY STACK INSIDE THE BORDER.
   The group keeps its single outline and its single radius; only the flow direction and which
   edge carries the divider change. That is the difference between a switch that got taller and
   three buttons that happen to be touching. Below 560px "We don't use this" cannot share a row
   with two others without hyphenating. */
@media (max-width: 559px) {
  .seg { flex-direction: column; }
  .seg__opt { border-left: 0; border-top: 1.5px solid var(--line-strong); min-height: 52px; }
  .seg__opt:first-child { border-top: 0; }
}

@media (min-width: 720px) {
  .q            { padding: var(--gap-5); }
  .q__text      { font-size: 21px; }
  .q__choices   { grid-template-columns: auto auto; justify-content: start; }
  .choice       { min-width: 190px; }
  /* RIGHT-ALIGNED AS ONE GROUP, not spread to the two corners. `flex-end` is doing the work that
     `space-between` used to undo: the quiet line now sits immediately beside the buttons, which
     is the only place a person who just clicked one is looking. */
  .bar          { flex-direction: row; align-items: center; justify-content: flex-end; padding: var(--gap-4) var(--gap-6); }
  .bar__actions { flex-direction: row; align-items: center; gap: var(--gap-4); }
  .bar__state   { text-align: right; }
  .bar__buttons { grid-template-columns: auto auto; }
  .card3        { padding: var(--gap-5) var(--gap-6); }
  .bar__buttons .btn { min-width: 170px; }
  body:has(.bar) .wrap { padding-bottom: 120px; }
  .scrim        { align-items: center; }
}
