/* build.css — the configurator, build.html.
   ---------------------------------------------------------------------------
   Loaded after v12.css on one page. The shell (bar, footer, type, fields,
   buttons, the reveal) is v10–v12's; this file is the configurator itself.
   Its mechanics are the Hinderer build's, set in Midwest's system: the record
   ground, the three voices, hairlines rather than boxes where a rule will do,
   and oxblood only as a mark on light. Values come from tokens.css and the
   earlier layers' :root; the few this file adds are named first. */

:root {
  /* The running build beside the list. Wide enough for a price and a line of
     choices without wrapping either; narrow enough that the option photographs
     keep most of the page. */
  --cfg-aside: clamp(22rem, 28vw, 27rem);
}

/* ── layout ─────────────────────────────────────────────────────────────── */
.cfg {
  display: grid; grid-template-columns: minmax(0, 1fr) var(--cfg-aside);
  gap: var(--sp-8) var(--col-gap); align-items: start;
}
.cfg__main { display: grid; gap: var(--sp-7); min-inline-size: 0; }
.cfg__intro { display: grid; gap: var(--sp-5); justify-items: start; }
.cfg__intro .lede { max-inline-size: 58ch; }

/* ── progress ───────────────────────────────────────────────────────────────
   The words are the fact, the bar is a picture of it. Filled by transform, so
   nothing reflows as it grows. */
/* Alex, 2026-09-14: "it can't be seen at all". The first cut was a 3px
   bone-200 line on bone-100 — about 1.2:1, a rule rather than a gauge. Now
   the count leads in the display face, and the track is a scale of one cell
   per group, dark enough to read empty (graphite at 0.16 on bone, past the
   3:1 a meaningful graphic needs once filled). build.js sets --steps. */
.cfg-progress { inline-size: 100%; display: grid; gap: var(--sp-3); margin-block-start: var(--sp-2); }
.cfg-progress__count {
  font-family: var(--mono); font-size: var(--micro);
  letter-spacing: var(--track); text-transform: uppercase; color: var(--text-muted);
}
.cfg-progress__count strong {
  font-family: var(--face); font-weight: 600; font-size: var(--h3);
  line-height: var(--lh-tight); letter-spacing: var(--ls-heading);
  font-variant-numeric: tabular-nums; color: var(--text); margin-inline-end: var(--sp-1);
}
.cfg-progress__track {
  position: relative; display: block; block-size: var(--sp-2);
  background: rgb(var(--graphite-950-rgb) / 0.16); overflow: clip;
}
/* The cells: a ground-coloured gap after every step, drawn over the fill. */
.cfg-progress__track::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(to right,
    transparent 0 calc(100% / var(--steps, 10) - var(--hairline) * 3),
    var(--ground) calc(100% / var(--steps, 10) - var(--hairline) * 3) calc(100% / var(--steps, 10)));
}
.cfg-progress__fill {
  display: block; block-size: 100%; background: var(--ink-on-light);
  transform-origin: left; transform: scaleX(var(--done, 0));
  transition: transform var(--dur-4) var(--ease-settle);
}

/* ── the base ───────────────────────────────────────────────────────────────
   Hinderer's one picture above the list: the car the build starts from, and a
   card on it saying where the price starts. Alex, 2026-09-14: "one more image,
   as on Hinderer — a placeholder on ours", then, pointing at Hinderer's card
   on their photograph: "this was on Hinderer". Since then the card became
   step 01 itself (see below), and Alex moved it to the left; the generated
   frames stand the car on the right so the card has the wall. Where the
   picture is too narrow to hold a card beside its subject, the card drops under it. */
.cfg-base {
  position: relative; display: grid; margin: 0; inline-size: 100%; container-type: inline-size;
  overflow: clip; border-radius: var(--radius-media);
}
.cfg-base__img {
  display: block; inline-size: 100%; block-size: auto; aspect-ratio: 2400 / 1018;
  object-fit: cover; object-position: 64% 50%;
  border-radius: var(--radius-media); background: var(--graphite-900);
}
/* The picture follows the model (build.js): two generated frames of the same
   hall at the same ratio, so a swap changes the car and nothing else. It
   settles in out of the dark — never through bone, which is what fading to
   transparent here would show. */
.cfg-base__img.is-swap { animation: cfg-swap var(--dur-6) var(--ease-settle); }
@keyframes cfg-swap { from { filter: brightness(0.25); scale: 1.04; } }
/* Step 01 — Alex, 2026-09-14: the main picture and the Start here choice are
   one thing. Two dresses for one piece of markup. Where the frame is narrow
   (a phone, a small laptop) it sits under the photograph dressed as every
   other step in the list — "in a row with all the steps". Where the frame is
   wide it is a dark card on the picture's empty left wall, with "01 Start
   here" set large. */
.cfg-base__bar { display: grid; gap: var(--sp-4); margin-block-start: var(--sp-6); color: var(--text); }
.cfg-base__step {
  display: flex; align-items: baseline; gap: var(--sp-4); margin: 0;
  padding-block-end: var(--sp-3); border-block-end: var(--hairline) solid var(--ink-on-light);
  font-family: var(--face); font-weight: 600; font-size: var(--h3);
  line-height: var(--lh-heading); letter-spacing: var(--ls-heading); color: var(--text);
}
.cfg-base__step span {
  font-family: var(--mono); font-weight: 400; font-size: var(--micro);
  letter-spacing: var(--track); color: var(--text-muted);
}
.cfg-models { display: grid; gap: var(--sp-2); }
/* A model is a row: the mark says one of these, the name over where its
   price starts. It gives under the hand like every control on the site. */
.cfg-model {
  position: relative;
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 0 var(--sp-3);
  min-block-size: 3rem; padding: var(--sp-3) var(--sp-4); cursor: pointer;
  background: var(--surface); border: var(--hairline) solid var(--rule); border-radius: var(--radius-control);
  transition: border-color var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out),
    transform var(--dur-3) var(--ease-back);
}
.cfg-model input {
  position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; opacity: 0;
}
.cfg-model:hover { border-color: var(--ink-on-light-muted); }
.cfg-model:active { transform: scale(0.97); transition: transform var(--dur-1) var(--ease-press); }
.cfg-model:has(input:checked) { border-color: var(--ink-on-light); }
.cfg-model:has(input:focus-visible) { outline: var(--focus-w) solid var(--oxblood); outline-offset: var(--hairline); }
.cfg-model__mark {
  grid-row: span 2;
  display: grid; place-items: center; inline-size: 1.25rem; block-size: 1.25rem; border-radius: 50%;
  border: calc(var(--hairline) * 2) solid var(--ink-on-light-muted);
  transition: border-color var(--dur-2) var(--ease-out);
}
.cfg-model__mark::after {
  content: ''; inline-size: 0.5rem; block-size: 0.5rem; border-radius: 50%;
  background: var(--oxblood); transform: scale(0);
  transition: transform var(--dur-2) var(--ease-back);
}
.cfg-model:has(input:checked) .cfg-model__mark { border-color: var(--oxblood); }
.cfg-model:has(input:checked) .cfg-model__mark::after { transform: scale(1); }
.cfg-model__name { font-family: var(--face); font-weight: 600; font-size: var(--fs-body); line-height: var(--lh-heading); color: var(--text); }
.cfg-model__price {
  grid-column: 2;
  font-family: var(--mono); font-size: var(--micro); font-variant-numeric: tabular-nums;
  color: var(--text-muted); white-space: nowrap;
}
/* The running total, as in the summary: drums, and what a choice cost beside
   them — oxblood on light, bone on the dark card. */
.cfg-base__sum {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--sp-1) var(--sp-3);
  margin: 0; padding-block-start: var(--sp-3); border-block-start: var(--hairline) solid var(--rule);
}
.cfg-base__sum-k {
  font-family: var(--mono); font-size: var(--micro);
  letter-spacing: var(--track); text-transform: uppercase; color: var(--text-muted);
}
.cfg-base__price {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-1) var(--sp-3);
  font-family: var(--face); font-weight: 600; font-size: var(--h3); color: var(--text);
  line-height: var(--lh-tight); letter-spacing: var(--ls-heading); font-variant-numeric: tabular-nums;
}
.cfg-base__next {
  justify-self: start; display: inline-flex; align-items: center; gap: var(--sp-2); min-block-size: 2.75rem;
  margin-block: calc(var(--sp-2) * -1);
  font-family: var(--mono); font-size: var(--micro); letter-spacing: var(--track); text-transform: uppercase;
  color: var(--text); text-decoration: none;
}
.cfg-base__next[hidden] { display: none; }
.cfg-base__next:focus-visible { outline: var(--focus-w) solid var(--ink-on-light); outline-offset: var(--focus-offset); }

/* On the picture only where it is tall enough to hold the card and wide
   enough to leave the car its two thirds: 50rem of frame. 17rem, on the
   empty wall at the left — the car stands right in both generated frames. */
@container (min-width: 50rem) {
  .cfg-base__bar {
    position: absolute; inset-block-start: 50%; inset-inline-start: var(--sp-5); z-index: 2;
    translate: 0 -50%; margin: 0; inline-size: 17rem; gap: var(--sp-2); padding: var(--sp-4);
    background: var(--graphite-950); color: var(--ink-on-dark);
    border: var(--hairline) solid var(--graphite-700); border-radius: var(--radius-media);
  }
  .cfg-base__step { padding: 0; border: 0; font-size: var(--lot); line-height: var(--lh-tight); color: var(--ink-on-dark); }
  .cfg-base__step span { color: var(--ink-on-dark-muted); }
  .cfg-model { padding: var(--sp-2) var(--sp-3); background: transparent; border-color: var(--graphite-700); }
  .cfg-model:hover { border-color: var(--ink-on-dark-muted); }
  .cfg-model:has(input:checked) { border-color: var(--bone-050); background: rgb(var(--bone-100-rgb) / 0.08); }
  .cfg-model:has(input:focus-visible) { outline-color: var(--bone-050); }
  .cfg-model__mark { border-color: var(--ink-on-dark-muted); }
  .cfg-model:has(input:checked) .cfg-model__mark { border-color: var(--bone-050); }
  .cfg-model__name, .cfg-base__price, .cfg-base__next { color: var(--ink-on-dark); }
  .cfg-model__price, .cfg-base__sum-k { color: var(--ink-on-dark-muted); }
  .cfg-base__sum { border-color: var(--graphite-700); }
  .cfg-base__bar .cfg-delta { color: var(--ink-on-dark); }
  .cfg-base__next:hover { color: var(--bone-050); }
  .cfg-base__next:focus-visible { outline-color: var(--bone-050); }
}

/* ── steps and groups ───────────────────────────────────────────────────────
   The five steps are the home page's own, numbered because they are a real
   order. Each group is a <details>: the head says what the group is and what
   has been chosen in it; the circle fills when it has an answer. */
.cfg-step { display: grid; gap: var(--sp-4); }
.cfg-step__h {
  display: flex; align-items: baseline; gap: var(--sp-4);
  padding-block-end: var(--sp-3); border-block-end: var(--hairline) solid var(--ink-on-light);
  font-family: var(--face); font-weight: 600; font-size: var(--h3);
  line-height: var(--lh-heading); letter-spacing: var(--ls-heading); color: var(--text);
}
.cfg-step__h span {
  font-family: var(--mono); font-weight: 400; font-size: var(--micro);
  letter-spacing: var(--track); color: var(--text-muted);
}

.cfg-group { background: var(--surface); border: var(--hairline) solid var(--rule); }
.cfg-group__head {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center; gap: var(--sp-4);
  min-block-size: 3.5rem; padding: var(--sp-3) var(--sp-5);
  cursor: pointer; list-style: none;
}
.cfg-group__head::-webkit-details-marker { display: none; }
.cfg-group__head:focus-visible {
  outline: var(--focus-w) solid var(--ink-on-light); outline-offset: calc(var(--focus-offset) * -1);
}
.cfg-group__mark {
  display: grid; place-items: center;
  inline-size: 1.125rem; block-size: 1.125rem; border-radius: 50%;
  border: calc(var(--hairline) * 2) solid var(--ink-on-light-muted);
  transition: border-color var(--dur-2) var(--ease-out);
}
.cfg-group__mark::after {
  content: ''; inline-size: 0.5rem; block-size: 0.5rem; border-radius: 50%;
  background: var(--oxblood); transform: scale(0);
  transition: transform var(--dur-2) var(--ease-back);
}
.cfg-group[data-answered] .cfg-group__mark { border-color: var(--oxblood); }
.cfg-group[data-answered] .cfg-group__mark::after { transform: scale(1); }
.cfg-group__name {
  font-family: var(--face); font-weight: 600; font-size: var(--news-h);
  line-height: var(--lh-heading); color: var(--text);
}
.cfg-group__chosen {
  display: grid; justify-items: end; gap: var(--sp-1); text-align: end;
  font-size: var(--fs-body-s); line-height: var(--lh-label); color: var(--text-muted);
}
.cfg-group__chosen strong { font-weight: 400; }
.cfg-group[data-answered] .cfg-group__chosen strong { color: var(--text); }
.cfg-group__chosen .cfg-num { font-family: var(--mono); font-size: var(--micro); font-variant-numeric: tabular-nums; }
.cfg-group__caret {
  inline-size: 0.625rem; block-size: 0.625rem; margin-inline: var(--sp-2);
  border-inline-end: calc(var(--hairline) * 2) solid var(--ink-on-light-muted);
  border-block-end: calc(var(--hairline) * 2) solid var(--ink-on-light-muted);
  transform: translateY(-25%) rotate(45deg);
  transition: transform var(--dur-3) var(--ease-out);
}
.cfg-group[open] .cfg-group__caret { transform: translateY(25%) rotate(-135deg); }
.cfg-group__body { display: grid; gap: var(--sp-4); padding: 0 var(--sp-5) var(--sp-5); }
.cfg-group__mech {
  font-family: var(--mono); font-size: var(--micro);
  letter-spacing: var(--track); text-transform: uppercase; color: var(--text-muted);
}

/* ── option cards ───────────────────────────────────────────────────────────
   The input stays a real input, hidden but focusable; the card is its label.
   The mark says the rule before anything is chosen — a circle is one of
   these, a square is as many as you like — and fills when chosen, while the
   photograph takes a ring. Hover and keyboard focus answer the same way. */
.cfg-options { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 10.5rem), 1fr)); gap: var(--sp-5) var(--sp-4); }
.cfg-options--wide { grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr)); }
.cfg-opt { position: relative; display: grid; gap: var(--sp-2); align-content: start; cursor: pointer; }
.cfg-opt input {
  position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; opacity: 0;
}
.cfg-opt__frame {
  position: relative; display: block; aspect-ratio: 4 / 3; overflow: clip;
  border-radius: var(--radius-media);
  border: var(--hairline) solid var(--rule); background: var(--bone-200);
  transition: outline-color var(--dur-2) var(--ease-out);
  outline: calc(var(--hairline) * 2) solid transparent; outline-offset: calc(var(--hairline) * 2);
}
.cfg-options--wide .cfg-opt__frame { aspect-ratio: 16 / 9; }
.cfg-opt__frame img {
  display: block; inline-size: 100%; block-size: 100%; object-fit: cover;
  transition: transform var(--dur-3) var(--ease-out);
}
.cfg-opt__frame .frame { inline-size: 100%; block-size: 100%; border: 0; }
.cfg-opt:hover .cfg-opt__frame img { transform: scale(1.04); }
.cfg-opt:has(input:checked) .cfg-opt__frame { outline-color: var(--ink-on-light); }
.cfg-opt:has(input:focus-visible) .cfg-opt__frame { outline: var(--focus-w) solid var(--oxblood); }
.cfg-opt__mark {
  position: absolute; inset-block-start: var(--sp-2); inset-inline-end: var(--sp-2);
  display: grid; place-items: center;
  inline-size: 1.5rem; block-size: 1.5rem; border-radius: 50%;
  background: var(--bone-050); border: calc(var(--hairline) * 2) solid var(--ink-on-light);
}
.cfg-opt--any .cfg-opt__mark { border-radius: var(--radius-control); }
.cfg-opt__mark::after {
  content: ''; inline-size: 0.625rem; block-size: 0.625rem; border-radius: inherit;
  background: var(--ink-on-light); transform: scale(0);
  transition: transform var(--dur-2) var(--ease-back);
}
.cfg-opt:has(input:checked) .cfg-opt__mark::after { transform: scale(1); }
.cfg-opt__name { font-size: var(--fs-body-s); line-height: var(--lh-label); color: var(--text); }
.cfg-opt__price { font-family: var(--mono); font-size: var(--micro); font-variant-numeric: tabular-nums; color: var(--text-muted); }

/* ── motion: variant C ──────────────────────────────────────────────────────
   Alex's pick, 2026-09-14, from the genjutsu cast of this page: the home
   page's Green flag — settle, press, overshoot — at the tempo of a tool that
   takes twenty clicks. build.js adds the classes; this is what they do.

   The options arrive when their group opens, in reading order. The group
   itself opens at once: its height is never animated (motion-taste I4), only
   the cards move, and no further than --travel. `backwards`, not `both` — a
   held end frame would pin the transform, and the press could not act. */
.cfg-opt:nth-child(2) { --i: 1; }
.cfg-opt:nth-child(3) { --i: 2; }
.cfg-opt:nth-child(4) { --i: 3; }
.cfg-opt:nth-child(5) { --i: 4; }
.cfg-group[open] .cfg-opt {
  animation: cfg-arrive var(--dur-4) var(--ease-back) backwards;
  animation-delay: calc(var(--i, 0) * var(--stagger));
}
@keyframes cfg-arrive { from { opacity: 0; transform: translateY(var(--travel)); } }

/* A card gives under the hand as every control on the site does (v11.css). */
.cfg-opt { transition: transform var(--dur-3) var(--ease-back); }
.cfg-opt:active { transform: scale(0.95); transition: transform var(--dur-1) var(--ease-press); }

/* The photograph just chosen settles into its frame. On `scale`, not
   `transform`, so it composes with the hover zoom instead of fighting it. */
.cfg-opt__frame img.is-just { animation: cfg-settle var(--dur-6) var(--ease-settle); }
@keyframes cfg-settle { from { scale: 1.08; } }

/* The price is drums (v11.css's odometer), turning at a tool's pace: shorter
   than the Grand Opening's, one step apart. */
.cfg-odo { display: inline-flex; align-items: baseline; column-gap: 0.25em; }
.cfg-odo__pre:empty { display: none; }
.cfg-odo__ch { display: block; block-size: 1em; line-height: 1; }
.cfg-odo .odo__dg > span { transition-duration: var(--dur-6); transition-delay: calc(var(--k, 0) * var(--stagger)); }

/* What the choice cost, beside the price: up into place, held, gone. Oxblood,
   because it is a mark on light; on the phone bar it is bone. */
.cfg-delta {
  display: inline-block; opacity: 0;
  font-family: var(--mono); font-weight: 400; font-size: var(--micro); letter-spacing: 0;
  font-variant-numeric: tabular-nums; color: var(--oxblood);
}
.cfg-delta.is-on { animation: cfg-delta calc(var(--dur-7) + var(--dur-3)) var(--ease-out) both; }
@keyframes cfg-delta {
  0%   { opacity: 0; transform: translateY(var(--travel)); }
  18%  { opacity: 1; transform: none; }
  75%  { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translateY(calc(var(--travel) / -2)); }
}

/* Only what changed rolls in: the group's head and its summary line, with a
   brief wash behind the line. The roll never leaves its own box — each of
   them clips — which is why it may travel its own height. */
.cfg-group__chosen { overflow: clip; }
.cfg-line.is-flash { animation: cfg-flash var(--dur-7) var(--ease-out); }
@keyframes cfg-flash { from { background: var(--bone-200); } to { background: transparent; } }
.cfg-line.is-new dd,
.cfg-group.is-new .cfg-group__chosen > * { animation: cfg-roll var(--dur-4) var(--ease-settle) both; }
@keyframes cfg-roll { from { opacity: 0; transform: translateY(100%); } }

/* ── the running build ──────────────────────────────────────────────────────
   The raised bone surface, held beside the list while it is worked through.
   Sticky, and exactly as tall as the window under the bar: it scrolls inside
   itself, but only under the pointer — Alex, 2026-09-14: "when the mouse is on
   the right panel it scrolls inside; on the left, with the steps, the left
   scrolls". overscroll-behavior keeps a scroll that reaches the panel's end
   from carrying on into the page.

   No scrollbar: the first cut showed one beside the page's, and Alex struck
   it ("Hinderer has no such bar"). What stands in for it is the foot of the
   panel: a wash and a button while there is more below (see .cfg-sum__more). Keyboard
   reach is unaffected — every control in the panel scrolls itself into view
   when it takes focus. On a phone none of this applies: the panel is static. */
.cfg-sum {
  position: sticky; inset-block-start: calc(var(--bar-h, var(--bar-clear)) + var(--sp-5));
  max-block-size: calc(100dvh - var(--bar-h, var(--bar-clear)) - var(--sp-5) * 2);
  overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: none;
  display: grid; gap: var(--sp-4); align-content: start;
  padding: var(--sp-5); background: var(--bone-050); border: var(--hairline) solid var(--rule);
}
.cfg-sum::-webkit-scrollbar { display: none; }
/* More below. A deep wash rising from the foot of the panel, and on it one
   button that names what is further down and takes the panel there — Alex,
   2026-09-14: "show at the bottom of the right panel that it scrolls, with a
   gradient". Sticky to the foot of the scrollport and laid over the content
   rather than adding to it; build.js retires it once the estimate form is in
   view or there is nothing more to show, so it never sits on Send. */
.cfg-sum__more {
  position: sticky; inset-block-end: calc(var(--sp-5) * -1); z-index: 1;
  display: grid; justify-items: center; align-content: end;
  block-size: var(--sp-9); padding-block-end: var(--sp-5);
  margin-block: calc(var(--sp-9) * -1) calc(var(--sp-5) * -1); margin-inline: calc(var(--sp-5) * -1);
  background: linear-gradient(to bottom, transparent, var(--bone-050) 62%);
  pointer-events: none;
  transition: opacity var(--dur-3) var(--ease-out), visibility var(--dur-3);
}
.cfg-sum__more.is-done { opacity: 0; visibility: hidden; }
.cfg-sum__more-btn {
  pointer-events: auto;
  display: inline-flex; align-items: center; gap: var(--sp-3);
  min-block-size: 2.75rem; padding: 0 var(--sp-5); cursor: pointer;
  font-family: var(--mono); font-size: var(--micro); letter-spacing: var(--track); text-transform: uppercase;
  color: var(--bone-050); background: var(--ink-on-light);
  border: 0; border-radius: var(--radius-control);
  transition: transform var(--dur-3) var(--ease-back);
}
.cfg-sum__more-btn span { display: inline-block; transition: transform var(--dur-3) var(--ease-settle); }
.cfg-sum__more-btn:is(:hover, :focus-visible) span { transform: translateY(var(--sp-1)); }
.cfg-sum__more-btn:active { transform: scale(0.95); transition: transform var(--dur-1) var(--ease-press); }
.cfg-sum__more-btn:focus-visible { outline: var(--focus-w) solid var(--ink-on-light); outline-offset: var(--focus-offset); }
.cfg-sum__shot { aspect-ratio: 16 / 9; overflow: clip; border-radius: var(--radius-media); background: var(--bone-200); }
/* The summary shows the same picture as step 01 — Alex, 2026-09-14: the Black
   Edition on the right has to match the one above in colour. The frames are
   21:9 with the car on the right, so the 16:9 crop keeps to the car. */
.cfg-sum__shot img { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; object-position: 64% 50%; }
.cfg-sum__k {
  font-family: var(--mono); font-size: var(--micro);
  letter-spacing: var(--track); text-transform: uppercase; color: var(--text-muted);
}
.cfg-sum__title {
  font-family: var(--face); font-weight: 600; font-size: var(--h3);
  line-height: var(--lh-heading); letter-spacing: var(--ls-heading); color: var(--text);
}
.cfg-sum__price {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-1) var(--sp-3);
  font-family: var(--face); font-weight: 600; font-size: var(--lot);
  line-height: var(--lh-tight); letter-spacing: var(--ls-heading); font-variant-numeric: tabular-nums;
  color: var(--text); padding-block-end: var(--sp-4); border-block-end: var(--hairline) solid var(--ink-on-light);
}
.cfg-lines { display: grid; margin: 0; }
/* The line reaches a step past the text on each side, so the wash behind a
   changed line has an edge to it; it clips, so its value can roll in. */
.cfg-line {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-1) var(--sp-3);
  margin-inline: calc(var(--sp-2) * -1); padding: var(--sp-3) var(--sp-2); overflow: clip;
  border-block-end: var(--hairline) solid var(--rule);
}
.cfg-line dt {
  grid-column: 1 / -1; font-family: var(--mono); font-size: var(--micro);
  letter-spacing: var(--track); text-transform: uppercase; color: var(--text-muted);
}
.cfg-line dd { margin: 0; font-size: var(--fs-body-s); line-height: var(--lh-label); color: var(--text); }
.cfg-line__cost { font-family: var(--mono); font-size: var(--micro); font-variant-numeric: tabular-nums; text-align: end; white-space: nowrap; }
.cfg-line--empty [data-value] { color: var(--text-muted); }
.cfg-sum__note { font-size: var(--fs-body-s); line-height: var(--lh-body); color: var(--text-muted); }
.cfg-sum__reset {
  justify-self: start; min-block-size: 2.75rem; padding: 0; background: none; border: 0; cursor: pointer;
  font-family: var(--mono); font-size: var(--micro); letter-spacing: var(--track); text-transform: uppercase;
  color: var(--text-muted); transition: color var(--dur-2) var(--ease-out);
}
.cfg-sum__reset:hover { color: var(--text); }
.cfg-sum__reset:focus-visible { outline: var(--focus-w) solid var(--ink-on-light); outline-offset: var(--focus-offset); }
.cfg-form { display: grid; gap: var(--sp-4); padding-block-start: var(--sp-5); border-block-start: var(--hairline) solid var(--ink-on-light); }
.cfg-form__title {
  font-family: var(--face); font-weight: 600; font-size: var(--h3);
  line-height: var(--lh-heading); letter-spacing: var(--ls-heading); color: var(--text);
}
.cfg-form .apply__actions { margin: 0; }
.cfg-form .btn { inline-size: 100%; justify-content: center; }

/* ── the phone bar ──────────────────────────────────────────────────────── */
.cfg-bar { display: none; }

@media (max-width: 61.99rem) {
  .cfg { grid-template-columns: minmax(0, 1fr); }
  .cfg-base__img { aspect-ratio: 16 / 9; }
  .cfg-sum { position: static; max-block-size: none; overflow: visible; }
  .cfg-sum__more { display: none; }
  .cfg-options { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cfg-options--wide { grid-template-columns: minmax(0, 1fr); }
  .cfg-group__head { grid-template-columns: auto minmax(0, 1fr) auto; }
  .cfg-group__chosen { grid-column: 2 / -1; grid-row: 2; justify-items: start; text-align: start; }

  .cfg-bar:not([hidden]) {
    position: fixed; z-index: 45; inset-inline: 0; inset-block-end: 0;
    display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
    padding-block: var(--sp-3) calc(var(--sp-3) + env(safe-area-inset-bottom, 0));
    padding-inline: var(--sp-5);
    background: var(--graphite-950); color: var(--ink-on-dark);
    border-block-start: var(--hairline) solid var(--graphite-700);
  }
  .cfg-bar__total {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--sp-3);
    font-family: var(--face); font-weight: 600; font-size: var(--h3);
    line-height: var(--lh-tight); font-variant-numeric: tabular-nums;
  }
  /* Oxblood is never text on the dark ground. */
  .cfg-bar .cfg-delta { color: var(--ink-on-dark); }
  .cfg-bar__count {
    font-family: var(--mono); font-size: var(--micro);
    letter-spacing: var(--track); text-transform: uppercase; color: var(--ink-on-dark-muted);
  }
  /* The footer's last line stays above the bar. */
  .page-build .site-foot { padding-block-end: calc(var(--pad) + var(--sp-10)); }
}

@media (prefers-reduced-motion: reduce) {
  .cfg-progress__fill, .cfg-group__mark, .cfg-group__mark::after, .cfg-group__caret,
  .cfg-opt__frame, .cfg-opt__frame img, .cfg-opt__mark::after { transition: none; }
  .cfg-opt:hover .cfg-opt__frame img { transform: none; }
  /* Every answer still arrives — the ring, the filled mark, the figures —
     it just does not move to get there. build.js adds none of the classes. */
  .cfg-opt { transition: none; }
  .cfg-group[open] .cfg-opt, .cfg-opt__frame img.is-just, .cfg-base__img.is-swap, .cfg-delta.is-on, .cfg-line.is-flash,
  .cfg-line.is-new dd, .cfg-group.is-new .cfg-group__chosen > * { animation: none; }
}
