/* ============================================================
   Mission wizard — the calculator asked one question at a time.

   Rendered by templates/partials/_calculator_wizard.html from
   public_site/calculator_wizard.py, and driven by
   js/calculator-wizard.js. It replaced a grid of thirty inputs, so
   the anatomy is deliberately the opposite of a form: one question
   fills the frame, the answer is a target rather than a field, and
   the only persistent chrome is the rail that says which stage of
   the walk this is.

   It shares the lead form's vocabulary — same rail, same option
   button, same progress track — because they are the same gesture
   on the same site, and a visitor who has answered one should not
   have to learn the other. It does not share the *stylesheet*: a
   lead form asks for a person, a wizard asks for a mission, and the
   two have different anatomy below the option (units, numeric
   fields, a recap, a value reading).

   The value reading at the end is styled here rather than in the
   result panel's sheet because it belongs to the wizard's promise:
   the number is the answer, the reading is what the answer means.

   Every colour is a token, so light and dark follow with no second
   palette.
   ============================================================ */
.mission-wizard{
  --mw-gap:20px;
  --mw-selected:color-mix(in srgb,var(--violet) 42%,transparent);
  display:grid;
  gap:var(--mw-gap);
  container-type:inline-size;
  padding:28px;
  border:1px solid var(--line);
  border-radius:var(--radius);
  background:linear-gradient(145deg,var(--surface),var(--surface-2));
  box-shadow:var(--shadow);
  min-width:0;
}
.mission-wizard.loading{opacity:.72;pointer-events:none}

/* --- Progress and the phase rail ---------------------------- */
/* A walk that runs from eight screens to thirty-three needs named
   stages: "question 14 of 33" says nothing about whether fourteen is
   nearly done. The rail is built from the *walked* screens, so the
   branches only some visitors see never inflate it. */
.mission-wizard-progress{display:grid;gap:9px}
.mission-wizard-rail{
  list-style:none;margin:0 0 4px;padding:0;
  display:flex;flex-wrap:wrap;gap:4px 10px;align-items:center;
}
.mission-wizard-rail-step{
  display:flex;align-items:center;gap:6px;
  font-size:.7rem;letter-spacing:.01em;color:var(--silver);
  opacity:.5;transition:opacity .2s ease,color .2s ease;
}
.mission-wizard-rail-mark{
  width:7px;height:7px;border-radius:50%;flex:none;
  border:1px solid var(--line-strong);
  transition:background .2s ease,border-color .2s ease,box-shadow .2s ease;
}
.mission-wizard-rail-step.is-done{opacity:.85}
.mission-wizard-rail-step.is-done .mission-wizard-rail-mark{
  background:var(--lavender);border-color:var(--lavender);
}
.mission-wizard-rail-step.is-current{opacity:1;color:var(--paper);font-weight:700}
.mission-wizard-rail-step.is-current .mission-wizard-rail-mark{
  background:var(--cyan);border-color:var(--cyan);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--cyan) 22%,transparent);
}
.mission-wizard-rail-step.is-current[data-rail-position]:after{
  content:attr(data-rail-position);
  font-variant-numeric:tabular-nums;font-weight:600;
  color:var(--cyan);font-size:.66rem;
}
/* A stage this visitor's branch never reaches. Dimmed rather than removed:
   a rail that loses an entry between two screens reads as a fault. */
.mission-wizard-rail-step.is-skipped{opacity:.28}

.mission-wizard-progress-meta{
  display:flex;justify-content:space-between;align-items:baseline;gap:14px;
  font-size:.76rem;color:var(--silver);
}
.mission-wizard-progress-meta strong{font-variant-numeric:tabular-nums}
/* The graph, made visible. "Eleven ruled out by your answers" is the only
   place a visitor sees that the form is shorter *because* of what they said. */
.mission-wizard-remaining{color:var(--cyan);font-weight:700}
.mission-wizard-remaining[hidden]{display:none}

.mission-wizard-progress-track{
  height:5px;border-radius:999px;overflow:hidden;
  background:color-mix(in srgb,var(--paper) 10%,transparent);
}
.mission-wizard-progress-track>span{
  display:block;height:100%;width:0;border-radius:999px;
  background:linear-gradient(90deg,var(--violet),var(--cyan));
  transition:width .32s cubic-bezier(.22,.75,.3,1);
}
@media (prefers-reduced-motion:reduce){
  .mission-wizard-progress-track>span{transition:none}
}

/* --- One screen --------------------------------------------- */
.mission-wizard-screen{
  display:grid;gap:18px;
  margin:0;padding:0;border:0;min-width:0;
}
/* Which screens are on view.
 *
 * Without scripting every screen stays visible and the wizard reads as the one
 * long questionnaire it replaced — the questions are legible even though the
 * estimate itself has always needed the JSON endpoint. With scripting the
 * controller owns the walk, and the screens start hidden so thirty-three of
 * them do not flash past before it runs. Same reservation the service graph on
 * the homepage uses, for the same reason. */
@media (scripting: enabled){
  .mission-wizard-screen{display:none}
  .mission-wizard-screen:not([hidden]){display:grid}
}
.mission-wizard-screen[hidden]{display:none}
.mission-wizard-screen-head{display:grid;gap:6px;padding:0;width:100%}
.mission-wizard-screen-kicker{
  font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--cyan);font-weight:700;
}
.mission-wizard-screen-head strong{
  font-family:var(--font-display);
  font-size:clamp(1.35rem,3.1vw,1.95rem);
  line-height:1.16;letter-spacing:-.015em;
}
.mission-wizard-screen-head small{
  color:var(--silver);font-size:.85rem;line-height:1.5;max-width:58ch;
}

.mission-wizard-question{display:grid;gap:11px}
/* Kept in the accessibility tree, taken out of the page: the label of a
   question whose screen heading already asks it. Namespaced to the component
   rather than published as a site-wide utility. */
.mission-wizard-label.is-quiet{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;
}
.mission-wizard-help{margin:0;font-size:.82rem;color:var(--silver);line-height:1.5;max-width:60ch}

/* --- Answers ------------------------------------------------- */
.mission-wizard-options{display:grid;gap:10px}
@container (min-width: 540px){
  .mission-wizard-options{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* A catalogue can run to a dozen rows of one line each, so it packs
     tighter than a three-way decision with help text under it. */
  .mission-wizard-options.is-catalog{grid-template-columns:repeat(3,minmax(0,1fr))}
}
.mission-wizard-option{
  position:relative;display:grid;align-items:center;
  grid-template-columns:1fr auto;gap:2px 12px;
  padding:14px 44px 14px 15px;
  border:1px solid var(--line-strong);border-radius:14px;
  background:color-mix(in srgb,var(--ink) 22%,transparent);
  cursor:pointer;font-size:.9rem;font-weight:600;color:var(--paper);
  transition:border-color .18s ease,background .18s ease,transform .18s ease;
}
.mission-wizard-option:hover{
  border-color:color-mix(in srgb,var(--violet) 50%,transparent);
  transform:translateY(-1px);
}
.mission-wizard-option input{
  position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none;
}
.mission-wizard-option-copy{display:grid;gap:3px;min-width:0}
.mission-wizard-option-copy strong{font-weight:720;line-height:1.25}
.mission-wizard-option-copy small{
  color:var(--silver);font-size:.78rem;font-weight:500;line-height:1.4;
}
.mission-wizard-option-mark{
  position:absolute;right:14px;top:50%;transform:translateY(-50%);
  width:20px;height:20px;border-radius:50%;
  border:1px solid var(--line-strong);
}
.mission-wizard-option:has(input:checked){
  border-color:var(--mw-selected);
  background:color-mix(in srgb,var(--violet) 15%,transparent);
}
.mission-wizard-option:has(input:checked) .mission-wizard-option-mark{
  border-color:var(--cyan);background:var(--cyan);
}
.mission-wizard-option:has(input:checked) .mission-wizard-option-mark:after{
  content:"";position:absolute;left:6px;top:2px;
  width:5px;height:10px;border:solid var(--ink);
  border-width:0 2px 2px 0;transform:rotate(45deg);
}
/* Keyboard focus lands on the visually hidden input, so the ring has to be
   drawn on the label it belongs to. */
.mission-wizard-option:has(input:focus-visible){
  outline:2px solid color-mix(in srgb,var(--violet) 62%,transparent);
  outline-offset:2px;
}

/* --- A number, given the room a question deserves ------------ */
/* On a screen that asks one thing, a 40px input in a 900px card reads as
   an afterthought. The field is the answer here, so it is sized like one. */
.mission-wizard-field{display:grid;gap:8px}
.mission-wizard-field-label{
  font-size:.79rem;font-weight:700;color:var(--silver);
}
.mission-wizard-field-input{
  display:flex;align-items:baseline;gap:12px;
  padding:14px 16px;
  border:1px solid var(--line-strong);border-radius:14px;
  background:color-mix(in srgb,var(--ink) 22%,transparent);
  transition:border-color .18s ease;
  max-width:26rem;
}
.mission-wizard-field-input:focus-within{
  border-color:var(--mw-selected);
}
.mission-wizard-field-input input{
  flex:1 1 auto;min-width:0;width:100%;
  margin:0;padding:0;border:0;background:none;box-shadow:none;
  font-family:var(--font-display);
  font-size:clamp(1.5rem,4vw,2.1rem);line-height:1.1;
  font-variant-numeric:tabular-nums;
  color:var(--paper);
}
.mission-wizard-field-input input:focus{outline:none}
.mission-wizard-unit{
  flex:none;font-style:normal;font-size:.84rem;font-weight:700;color:var(--silver);
}

/* --- The recap on the last screen --------------------------- */
/* Every answer, in the order it was given, each one a button back to the
   screen that asked it. Editing an answer that reroutes the walk is the
   point: the graph recomputes, and screens appear or vanish accordingly. */
.mission-wizard-review{display:grid;gap:12px}
.mission-wizard-recap{
  list-style:none;margin:0;padding:0;display:grid;gap:6px;
  counter-reset:recap;
}
.mission-wizard-recap>li{margin:0}
.mission-wizard-recap button{
  width:100%;display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:10px 13px;border:1px solid var(--line);border-radius:11px;
  background:color-mix(in srgb,var(--ink) 16%,transparent);
  color:var(--silver);font-size:.82rem;font-weight:600;text-align:left;
  cursor:pointer;transition:border-color .16s ease,color .16s ease;
}
.mission-wizard-recap button:hover{border-color:var(--mw-selected);color:var(--paper)}
.mission-wizard-recap button b{color:var(--paper);font-weight:720;text-align:right}
.mission-wizard-recap-note{
  margin:0;font-size:.8rem;color:var(--cyan);font-weight:640;
}

/* --- Actions and errors -------------------------------------- */
.mission-wizard-actions{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.mission-wizard-actions-spacer{flex:1 1 auto}
.mission-wizard-error{margin:0;font-size:.79rem;font-weight:640;color:var(--danger)}
.mission-wizard-error[hidden]{display:none}
.mission-wizard-error--global{
  padding:11px 13px;border-radius:11px;
  border:1px solid color-mix(in srgb,var(--danger) 40%,transparent);
  background:color-mix(in srgb,var(--danger) 12%,transparent);
}

/* ============================================================
   The value reading — what the number means.

   Drawn inside the result panel by MR.quoteView from the server's
   `value_reading`. Four axes, each with a band, a measure, a reading
   and the lever that would move it. The band is carried by an accent
   bar rather than by a coloured surface: this sits under a price, and
   a red card under a price reads as an error rather than as advice.
   ============================================================ */
.value-reading{
  display:grid;gap:14px;
  margin-top:18px;padding:18px;
  border:1px solid var(--line);border-radius:16px;
  background:color-mix(in srgb,var(--ink) 20%,transparent);
}
.value-verdict{display:flex;align-items:center;gap:16px}
.value-verdict>div{display:grid;gap:4px;min-width:0}
.value-verdict strong{
  font-family:var(--font-display);font-size:1.16rem;line-height:1.2;
}
.value-verdict p{margin:0;font-size:.86rem;color:var(--silver);line-height:1.5}
.value-verdict-score{
  flex:none;display:grid;place-items:center;
  width:66px;height:66px;border-radius:50%;
  font-family:var(--font-display);font-size:1.7rem;font-weight:700;
  font-variant-numeric:tabular-nums;color:var(--paper);
  border:2px solid var(--vr-accent,var(--cyan));
  background:color-mix(in srgb,var(--vr-accent,var(--cyan)) 12%,transparent);
}
.value-verdict-score i{font-style:normal;font-size:.62rem;color:var(--silver);display:block;text-align:center}

.value-reading--strong{--vr-accent:var(--cyan)}
.value-reading--solid{--vr-accent:var(--lavender)}
.value-reading--watch{--vr-accent:var(--warning)}
.value-reading--weak{--vr-accent:var(--danger)}
.value-reading--na{--vr-accent:var(--line-strong)}

/* Auto-fit rather than a container query: this list is drawn inside the result
   panel, which is a sidebar on wide screens and a full column on narrow ones,
   and it has no container context of its own to query. */
.value-axis-list{
  list-style:none;margin:0;padding:0;
  display:grid;gap:10px;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));
}
.value-axis{
  display:grid;gap:6px;
  padding:13px 14px 13px 16px;
  border:1px solid var(--line);border-radius:12px;
  background:color-mix(in srgb,var(--ink) 14%,transparent);
  /* The band lives in the left rule. It is the whole colour story of the
     card, which keeps four stacked axes legible instead of loud. */
  border-left:3px solid var(--va-accent,var(--line-strong));
}
.value-axis--strong{--va-accent:var(--cyan)}
.value-axis--solid{--va-accent:var(--lavender)}
.value-axis--watch{--va-accent:var(--warning)}
.value-axis--weak{--va-accent:var(--danger)}
.value-axis--na{--va-accent:var(--line-strong);opacity:.72}

.value-axis-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.value-axis-name{font-size:.8rem;font-weight:720;color:var(--paper)}
.value-axis-band{
  font-size:.68rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--va-accent,var(--silver));white-space:nowrap;
}
.value-axis-measure{
  font-family:var(--font-display);font-size:1.5rem;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--paper);
}
.value-axis-measure i{font-style:normal;font-size:.7rem;color:var(--silver);font-family:var(--font-body)}
.value-axis-reading{margin:0;font-size:.83rem;color:var(--paper);line-height:1.45}
/* The lever is the only actionable line on the card, so it is the only one
   that carries the accent. */
.value-axis-lever{
  margin:0;font-size:.8rem;line-height:1.45;
  color:var(--silver);
  padding-left:11px;border-left:2px solid color-mix(in srgb,var(--va-accent,var(--cyan)) 45%,transparent);
}
.value-axis-detail{display:block;font-size:.72rem;color:var(--silver);opacity:.8;line-height:1.4}

.value-reading-basis{
  margin:0;font-size:.72rem;color:var(--silver);opacity:.8;line-height:1.45;
}

/* The offers under the reading. The cards themselves are `lead-form.css` — one
   panel of offers, one set of styles wherever it is drawn. What belongs here is
   only the seam: the separation from the reading above it, and the sentence that
   says the reading was free before the first amount appears.

   `container-type` is the load-bearing line. The offer card is a three-column
   grid that collapses to one under `@container (max-width: 640px)`, and that
   query needs a container to measure. In a lead form the `.lead-form` root is
   it; here the panel is drawn straight into this aside, which is roughly a
   third of the viewport however wide the window is — so without this the card
   keeps its wide layout inside a narrow column and sets the reason one word per
   line. Declaring the container reuses the component's own breakpoint instead of
   writing a second, disagreeing set of rules for the same card. */
.quote-result{container-type:inline-size}
.quote-result .lead-form-offers{
  margin-top:18px;padding-top:18px;
  border-top:1px solid var(--line);
}
.lead-form-offers-intro{
  margin:0;font-size:.83rem;color:var(--silver);line-height:1.5;
}

/* Under ~480px the option grid, the rail labels and the axis pairs all stop
   fitting. Only the rail marks stay — they still show how many stages there
   are and where the visitor is, which is the part that carries the meaning. */
/* The card's own padding cannot be set from a query on itself, so it stays a
   media query; everything inside it is measured on the wizard. */
@media (max-width: 560px){
  .mission-wizard{padding:20px}
}
@container (max-width: 480px){
  .mission-wizard-rail{gap:4px 7px}
  .mission-wizard-rail-label{display:none}
  .mission-wizard-rail-step.is-current .mission-wizard-rail-label{display:inline}
}
