/* The tint builder on /window-tint-killeen-quote: the illustrated car and the four-step
   quote are one object. Desktop (>=1024px): the car sits sticky in the left column, the step
   panel on the right. Below that: the car is pinned under the header at ~38svh and the step
   panel scrolls beneath it. Red is the quote tool's state colour only (progress, the selected
   swatch, the price) and never a surface inside #quoteBuilder. Typography and components come
   from styles.css and window-tint-killeen-quote.css; the rules here are layout, the light
   well, the swatches, the step indicator, and state. */

/* ---- Components the builder used to borrow --------------------------------------------- */
/* Copied from css/window-tint-killeen-quote.css (the paid page's stylesheet, which the
   homepage does not load), rescoped from the paid page's body class to the builder root.
   Each keeps its source line as a comment. That stylesheet still carries the originals: it
   was left as it was when arm A, the old paid page, was deleted. */

/* from window-tint-killeen-quote.css:7-9 */
.tb-builder * {
  box-sizing: border-box;
}

/* from window-tint-killeen-quote.css:11-14 */
.tb-builder img {
  display: block;
  max-width: 100%;
}

/* from window-tint-killeen-quote.css:16-19 */
.tb-builder {
  width: min(100% - 32px, 1152px);
  margin-inline: auto;
}

/* from window-tint-killeen-quote.css:221-228 */
.tb-builder #quoteBuilder {
  display: grid;
  gap: 16px;
  border: 0;
  background: transparent;
  padding: 22px 26px 28px;
  box-shadow: none;
}

/* from window-tint-killeen-quote.css:276-279 */
.tb-builder .qb-section {
  min-width: 0;
  padding: 22px;
}

/* from window-tint-killeen-quote.css:281-283 */
.tb-builder .qb-section[hidden] {
  display: none;
}

/* from window-tint-killeen-quote.css:285-287 */
.tb-builder .qb-section-heading h3 {
  font-size: 1.45rem;
}

/* from window-tint-killeen-quote.css:295-298 */
.tb-builder .q-input {
  min-height: 48px;
  font-size: 1rem;
}

/* from window-tint-killeen-quote.css:300-303 */
.tb-builder textarea.q-input {
  min-height: 98px;
  resize: vertical;
}

/* from window-tint-killeen-quote.css:305-307 */
.tb-builder .q-3 {
  grid-template-columns: 1fr;
}

/* from window-tint-killeen-quote.css:309-311 */
.tb-builder .qpkg-grid {
  grid-template-columns: 1fr;
}

/* from window-tint-killeen-quote.css:313-316 */
.tb-builder .qb-pkg-card {
  min-width: 0;
  padding: 18px 16px;
}

/* from window-tint-killeen-quote.css:318-322 */
.tb-builder .qb-pkg-card .price {
  max-width: 110px;
  font-size: 1.35rem;
  line-height: 1;
}

/* from window-tint-killeen-quote.css:324-326 */
.tb-builder .qb-pkg-card .price-row {
  align-items: center;
}

/* from window-tint-killeen-quote.css:328-330 */
.tb-builder .qchip {
  min-height: 46px;
}

/* from window-tint-killeen-quote.css:332-335 */
.tb-builder #qbProjectSection.has-error .qpkg-grid {
  outline: 2px solid var(--red);
  outline-offset: 3px;
}

/* from window-tint-killeen-quote.css:337-343 */
.tb-builder .lp-step-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 2px;
}

/* from window-tint-killeen-quote.css:345-348 */
.tb-builder .lp-step-actions .cta {
  min-height: 48px;
  border: 0;
}

/* from window-tint-killeen-quote.css:350-352 */
.tb-builder .lp-step-actions .cta:last-child {
  flex: 1;
}

/* from window-tint-killeen-quote.css:354-360 */
.tb-builder .lp-submit-status {
  min-height: 1.4em;
  color: #fca5a5;
  font-size: 0.8rem;
  line-height: 1.45;
  text-align: center;
}

/* The Film step's summary (the builder page): the price, one step stronger than the step subtitles. */
.tb-builder .tb-look-summary {
  margin-top: 14px;
  font-size: .9rem;
  font-weight: 500;
  color: var(--muted);
}

/* from window-tint-killeen-quote.css:362-367 */
.tb-builder .lp-result-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
}

/* from window-tint-killeen-quote.css:369-374 */
.tb-builder .lp-edit-button {
  min-height: 44px;
  flex: none;
  color: var(--muted);
  font-size: 0.8rem;
}

/* from window-tint-killeen-quote.css:376-380 */
.tb-builder .lp-lead-status {
  margin-top: 12px;
  color: var(--muted);
  font-size: 0.78rem;
}

/* from window-tint-killeen-quote.css:382-390 */
.tb-builder .lp-result-note {
  margin-top: 20px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.035);
  padding: 16px;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.55;
}

/* from window-tint-killeen-quote.css:392-394 */
.tb-builder .lp-result-note strong {
  color: var(--text);
}

/* from window-tint-killeen-quote.css:396-400 */
.tb-builder .lp-result-actions {
  display: grid;
  gap: 12px;
  margin-top: 20px;
}

/* from window-tint-killeen-quote.css:1098-1100 */
@media (max-width: 767px) {
  .tb-builder {
    width: min(100% - 28px, 1152px);
  }
}

/* from window-tint-killeen-quote.css:1176-1178 */
@media (max-width: 767px) {
  .tb-builder #quoteBuilder {
    padding: 18px;
  }
}

/* from window-tint-killeen-quote.css:1180-1183 */
@media (max-width: 767px) {
  .tb-builder .qb-section {
    padding: 17px;
  }
}

/* from window-tint-killeen-quote.css:1185-1187 */
@media (max-width: 767px) {
  .tb-builder .qb-pkg-card .price {
    max-width: none;
  }
}

/* from window-tint-killeen-quote.css:1189-1192 */
@media (max-width: 767px) {
  .tb-builder .lp-step-actions {
    align-items: stretch;
    flex-direction: column-reverse;
  }
}

/* from window-tint-killeen-quote.css:1194-1197 */
@media (max-width: 767px) {
  .tb-builder .lp-step-actions .cta {
    width: calc(100% - 10px);
    margin-left: 5px;
  }
}

/* from window-tint-killeen-quote.css:1384-1390 */
@media (prefers-reduced-motion: reduce) {
  .tb-builder *,
  .tb-builder ::before,
  .tb-builder ::after {
    scroll-behavior: auto !important;
    animation: none !important;
    transition: none !important;
  }
}

/* A label switched off by data-quote-for stays hidden where a rule sets display (.cta > span). */
.tb-builder [data-quote-for][hidden] {
  display: none !important;
}

.tint-builder {
  /* The pinned car and the #quote scroll target must clear the sticky .lp-header. Sourced from
     css/window-tint-killeen-quote.css: .lp-header-inner min-height 68px + its 1px border-bottom
     (the same figure css/comfort-science.css uses for --cs-top). */
  --tb-top: 69px;
  --tb-gutter: 16px;
  /* The pinned car below 1024px: its whole band (tabs rail, car, look caption) is ~38svh. The
     car's height is that band minus the chrome around it (paddings, gap, a two-line caption). */
  --tb-car-h: 38svh;
  --tb-stage-chrome: 62px;
  /* A soft pool of light on --bg that the studio image fades into. No photo. */
  --tb-well:
    radial-gradient(64% 58% at 50% 52%, rgba(226, 229, 234, 0.13), rgba(226, 229, 234, 0.04) 58%, transparent 82%),
    var(--bg);
  position: relative;
  scroll-margin-top: var(--tb-top);
  border-bottom: 1px solid var(--line-soft);
  background: var(--bg);
  padding-block: clamp(22px, 2.6vw, 36px) clamp(44px, 5vw, 72px);
}

/* ---- Layout --------------------------------------------------------------------------- */

.tb-builder {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(400px, 0.85fr);
  grid-template-areas:
    "intro intro"
    "stage panel";
  align-items: start;
  column-gap: clamp(28px, 3.6vw, 52px);
  row-gap: clamp(20px, 2.4vw, 30px);
}

.tb-intro {
  grid-area: intro;
}

.tb-intro h1 {
  margin-top: 16px;
  font-size: clamp(2.6rem, 5.2vw, 4.6rem);
  line-height: 0.9;
  letter-spacing: -0.01em;
}

.tb-intro h1 em {
  color: var(--red-hot);
  font-style: normal;
}

.tb-lead {
  max-width: 62ch;
  margin-top: 14px;
  color: rgba(244, 244, 246, 0.78);
  font-size: clamp(0.98rem, 1.3vw, 1.08rem);
  line-height: 1.6;
}

.tb-stage {
  position: sticky;
  z-index: 5;
  top: calc(var(--tb-top) + 20px);
  grid-area: stage;
  min-width: 0;
}

.tb-panel {
  /* Where a scroll into the panel lands its target: below the sticky header here, below the
     pinned car at <1024px (redefined there and for landscape phones below). */
  --tb-land: calc(var(--tb-top) + 16px);
  position: relative;
  grid-area: panel;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--bg-lift);
  box-shadow: 0 28px 70px rgba(0, 0, 0, 0.5);
  container-type: inline-size;
}

/* ---- The car: the light well ---------------------------------------------------------- */

/* The view tabs and the Stock button share the top row; the car spans the width below. */
.tb-view {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--tb-well);
}

.tb-view .tint-demo-visual {
  grid-column: 1 / -1;
  /* A grid item with auto margins shrinks to its content, and the visual's is all absolute. */
  width: 100%;
  /* Keep the whole sticky car on a short desktop screen. */
  max-width: calc((100svh - var(--tb-top) - 170px) * 1.5);
  margin-inline: auto;
  background: transparent;
}

/* Which car: Sedan / Coupe / SUV / Pickup. The toggle is a sibling of .tb-view (it cannot live inside the
   visual, whose role="img" hides its children from assistive tech). On desktop it is laid
   over the car's top-left corner, the one corner no view of either car puts glass in: top =
   .tb-view's 1px border + the 45px angle-tab row (44px tabs + 1px rule) + 12px; left follows
   the visual when a short screen narrows it (the same cap as its max-width above).
   js/tint-slider.js moves aria-pressed. */
.tb-body-tabs {
  position: absolute;
  z-index: 4;
  top: 58px;
  left: calc(1px + max(0px, (100% - 2px - (100svh - var(--tb-top) - 170px) * 1.5) / 2) + 12px);
  display: flex;
  border: 1px solid rgba(255, 255, 255, 0.17);
  border-radius: 2px;
  background: rgba(7, 8, 11, 0.72);
  backdrop-filter: blur(8px);
}

.tb-body-tab {
  min-height: 32px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  padding: 0 11px;
  color: var(--muted);
  font: 700 0.66rem/1 var(--body);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.tb-body-tab + .tb-body-tab {
  border-left: 1px solid rgba(255, 255, 255, 0.12);
}

.tb-body-tab:hover {
  color: var(--text);
}

.tb-body-tab[aria-pressed="true"] {
  border-bottom-color: var(--red);
  color: #fff;
}

.tb-body-tab:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: -2px;
}

/* Stock: a toggle, not a fourth view, so it sits behind a rule at the end of the tab row and
   fills when pressed instead of taking the tabs' underline; the dot is its switch. Its 44px
   plus the row's 1px rule keep the row at the 45px .tb-body-tabs' top is measured from.
   js/tint-slider.js moves aria-pressed. */
.tb-stock {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  border-left: 1px solid rgba(255, 255, 255, 0.12);
  background: transparent;
  padding: 0 18px;
  color: var(--muted);
  font: 700 0.78rem/1 var(--body);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.tb-stock::before {
  content: "";
  flex: none;
  box-sizing: border-box;
  width: 8px;
  height: 8px;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.tb-stock:hover {
  color: var(--text);
}

.tb-stock[aria-pressed="true"] {
  background: var(--red-dim);
  color: #fff;
}

.tb-stock[aria-pressed="true"]::before {
  border-color: var(--red);
  background: var(--red);
}

.tb-stock:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: -2px;
}

/* Step 1 already shows the stock glass. Hidden, not removed, so the row keeps its shape. */
[data-tint-demo].is-clear .tb-stock {
  visibility: hidden;
}

/* Under the rear swatches, only for bodies with factory privacy glass. */
.tb-privacy-note {
  margin-top: 8px;
  color: var(--muted);
  font-size: 0.74rem;
  line-height: 1.45;
}

/* The studio image falls off into the well like a pool of light. The ellipse keeps every
   window, mirror and wheel of all three views fully lit and only darkens the empty corners.
   The mask sits on each .tint-demo-stage, the parent its image and glass masks share, so it
   can never shift one against the other; the "Illustration" caption is a sibling of the
   stages and stays sharp. */
.tb-view .tint-demo-stage {
  -webkit-mask-image: radial-gradient(ellipse 70% 72% at 50% 50%, #000 66%, rgba(0, 0, 0, 0.6) 82%, transparent 100%);
  mask-image: radial-gradient(ellipse 70% 72% at 50% 50%, #000 66%, rgba(0, 0, 0, 0.6) 82%, transparent 100%);
}

/* Film fades on and off. Step 1 shows the glass as it left the factory: tint-builder.js sets
   .is-clear on the [data-tint-demo] root (.tb-builder), which out-specifies the per-zone
   opacity rules. The Stock button (.is-stock, tint-slider.js) shows the same glass from any
   later step. The factory layer (an SUV's rear privacy glass) is not film, so it stays. */
.tb-builder .tint-demo-film {
  transition: opacity 0.45s ease;
}

[data-tint-demo].is-clear .tint-demo-film:not(.tint-demo-film-factory),
[data-tint-demo].is-stock .tint-demo-film:not(.tint-demo-film-factory) {
  opacity: 0;
}

/* A two-door job tints only the front pair (tint-builder.js sets .is-front-only): the rear
   glass shows as it left the factory, privacy glass included. */
[data-tint-demo].is-front-only .tint-demo-film-rear {
  opacity: 0;
}

/* With no film on the glass, the caption's shade summary ("30% front · 15% rear") would
   describe film that isn't there. Hide it and its leading separator; step 1 reads
   "Side · Illustration", Stock reads "Side · Illustration · Stock". */
[data-tint-demo].is-front-only .tint-demo-caption [data-tint-demo-summary],
[data-tint-demo].is-front-only .tint-demo-caption .tb-caption-sep,
[data-tint-demo].is-clear .tint-demo-caption [data-tint-demo-summary],
[data-tint-demo].is-clear .tint-demo-caption .tb-caption-sep,
[data-tint-demo].is-stock .tint-demo-caption [data-tint-demo-summary],
[data-tint-demo].is-stock .tint-demo-caption .tb-caption-sep,
[data-tint-demo]:not(.is-stock) .tint-demo-caption [data-tint-demo-stock],
[data-tint-demo].is-clear .tint-demo-caption [data-tint-demo-stock] {
  display: none;
}

/* The look caption: what the visitor has built so far. */
.tb-caption {
  min-height: calc(2 * 1.45em);
  margin-top: 12px;
  color: var(--text);
  font-size: 0.84rem;
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: 0.02em;
  overflow-wrap: anywhere;
}

/* ---- The step panel ------------------------------------------------------------------- */

.tb-progress {
  display: grid;
  gap: 12px;
  border-bottom: 1px solid var(--line-soft);
  padding-bottom: 16px;
}

.tb-indicator {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.tb-indicator span {
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--faint);
  font: 600 0.66rem/1.1 var(--body);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}

.tb-indicator span::before {
  width: 9px;
  height: 9px;
  flex: none;
  border: 1.5px solid rgba(255, 255, 255, 0.34);
  transform: skewX(-14deg);
  content: "";
  transition: background 0.2s ease, border-color 0.2s ease;
}

/* Steps already passed. */
.tb-indicator li:has(~ li [aria-current="step"]) span {
  color: var(--muted);
}

.tb-indicator li:has(~ li [aria-current="step"]) span::before {
  border-color: rgba(255, 255, 255, 0.62);
  background: rgba(255, 255, 255, 0.62);
}

.tb-indicator [aria-current="step"] {
  color: var(--text);
}

.tb-indicator [aria-current="step"]::before {
  border-color: var(--red);
  background: var(--red);
}

.tb-progress-meta {
  display: flex;
  min-height: 1.6rem;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

#qbProgressText {
  color: var(--faint);
  font: 600 0.68rem/1 var(--body);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.tb-estimate {
  display: flex;
  align-items: baseline;
  gap: 9px;
  color: var(--faint);
  font: 600 0.62rem/1 var(--body);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* tint-builder.js keeps the price hidden until the Film step is reached. */
.tb-estimate[hidden] {
  display: none;
}

.tb-estimate strong {
  color: var(--red-hot);
  font: 700 1.35rem/1 var(--disp);
  letter-spacing: 0.02em;
}

.tb-progress .qb-progress {
  height: 3px;
  margin-top: 0;
}

/* The four steps: one visible at a time, flat inside the panel's single surface. */
.tb-panel .tb-steps > .qb-section {
  border: 0;
  background: transparent;
  padding: 0;
  box-shadow: none;
  animation: tb-step-in 0.3s ease both;
}

.tb-panel .tb-steps > .qb-section[hidden] {
  display: none;
}

@keyframes tb-step-in {
  from {
    opacity: 0;
    transform: translateX(14px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.tb-steps .qb-section-heading {
  align-items: center;
  gap: 16px;
}

/* Ghost numerals 01-04, as on the Lab Standard timeline. */
.tb-steps .qb-section-number {
  padding-left: 0;
  color: transparent;
  font: 700 2.6rem/1 var(--disp);
  letter-spacing: 0.02em;
  -webkit-text-stroke: 1px rgba(255, 255, 255, 0.3);
}

.tb-steps .qb-section-number::before {
  display: none;
}

.tb-steps .qb-section-heading h3:focus {
  outline: none;
}

.tb-steps .qb-section-heading h3:focus-visible {
  outline: 2px solid rgba(220, 38, 38, 0.7);
  outline-offset: 4px;
}

/* ---- Shade: glass swatches ------------------------------------------------------------ */

.tb-shade-group {
  min-width: 0;
  margin: 0;
  border: 0;
  padding: 0;
}

.tb-shade-group[hidden] {
  display: none;
}

.tb-shade-group > legend {
  padding: 0;
}

.tb-swatches {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
  margin-top: 10px;
}

.tb-swatch {
  position: relative;
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
}

/* A literal glass tile: a bright scene seen through film at the same opacity the car uses
   (alphaForVlt() in js/tint-slider.js), with a diagonal sheen across the glass. */
.tb-swatch-glass {
  --tb-film: 0.665;
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 3px;
  background:
    linear-gradient(118deg, transparent 32%, rgba(255, 255, 255, 0.2) 40%, transparent 50%),
    linear-gradient(rgba(5, 8, 12, var(--tb-film)), rgba(5, 8, 12, var(--tb-film))),
    linear-gradient(160deg, #eef0f3 0%, #cfd4db 56%, #a9b0ba 100%);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.tb-swatch[data-shade="5"] .tb-swatch-glass { --tb-film: 0.934; }
.tb-swatch[data-shade="15"] .tb-swatch-glass { --tb-film: 0.822; }
.tb-swatch[data-shade="30"] .tb-swatch-glass { --tb-film: 0.665; }
.tb-swatch[data-shade="50"] .tb-swatch-glass { --tb-film: 0.468; }
.tb-swatch[data-shade="70"] .tb-swatch-glass { --tb-film: 0.276; }

/* The selected-state tick. */
.tb-swatch-glass::after {
  position: absolute;
  top: 5px;
  right: 5px;
  display: flex;
  width: 17px;
  height: 17px;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
  background: var(--red);
  color: #fff;
  content: "\2713";
  font: 700 0.62rem/1 var(--body);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.tb-swatch-value {
  color: var(--muted);
  font: 700 0.98rem/1 var(--disp);
  letter-spacing: 0.04em;
}

.tb-swatch:hover .tb-swatch-glass {
  border-color: rgba(255, 255, 255, 0.38);
  transform: translateY(-2px);
}

/* The radio sits directly before its tile, so the states need no :has(). */
.tb-swatch input:checked + .tb-swatch-glass {
  border-color: var(--red);
  box-shadow: 0 0 0 1px var(--red), 0 0 18px rgba(220, 38, 38, 0.22);
}

.tb-swatch input:checked + .tb-swatch-glass::after {
  opacity: 1;
  transform: none;
}

.tb-swatch input:checked ~ .tb-swatch-value {
  color: #fff;
}

/* Keyboard focus is white so it stays distinct from the red selected ring it usually sits on. */
.tb-swatch input:focus-visible + .tb-swatch-glass {
  outline: 2px solid var(--text);
  outline-offset: 3px;
}

/* Opens the Front view, where the windshield options live. */
.tb-show-front {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  justify-self: start;
  gap: 8px;
  color: var(--muted);
  font: 600 0.74rem/1 var(--body);
  letter-spacing: 0.12em;
  text-decoration: underline;
  text-transform: uppercase;
  text-underline-offset: 5px;
  cursor: pointer;
  transition: color 0.15s ease;
}

.tb-show-front:hover {
  color: var(--text);
}

.tb-show-front[hidden] {
  display: none;
}

/* ---- Film + contact: fit the reused components to the panel width --------------------- */

/* Year and Make share a row and Model takes the next, which keeps step 1's Next button above
   the fold on a 900px-tall desktop. */
@container (min-width: 300px) {
  .tb-builder .tb-panel .q-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .tb-builder .tb-panel .q-3 > :last-child {
    grid-column: 1 / -1;
  }
}

@container (min-width: 560px) {
  .tb-builder .tb-panel .qpkg-grid {
    grid-template-columns: 1fr 1fr;
  }

  .tb-builder .tb-panel .q-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .tb-builder .tb-panel .q-3 > :last-child {
    grid-column: auto;
  }
}

/* ---- The full builder (data-quote-services: the homepage) ------------------------------
   Elements only a form that offers more than tint carries: the service switch, the named step
   tabs, the colour swatches, the film rows and the price line. Every selector here needs a hook
   the builder page does not have (scripts/test-tint-builder-services.js proves it matches nothing
   there). Selected is the brand red, hover red-500, the keyboard ring white. */

.tb-builder .tb-service {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  min-width: 0;
  margin: 0;
  border: 0;
  padding: 0;
}

.tb-builder .tb-service-option {
  position: relative;
  display: grid;
  align-content: start;
  gap: 5px;
  min-height: 56px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.02);
  padding: 11px 12px 10px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.tb-builder .tb-service-option b {
  color: var(--text);
  font: 700 1.02rem/1 var(--disp);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.tb-builder .tb-service-option small {
  color: var(--muted);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
}

.tb-builder .tb-service-option:hover {
  border-color: var(--red-hot);
}

.tb-builder .tb-service-option:has(input:checked) {
  border-color: var(--red);
  background: rgba(220, 38, 38, 0.12);
  box-shadow: inset 0 2px 0 var(--red);
}

.tb-builder .tb-service-option:has(input:checked) small {
  color: var(--text);
}

.tb-builder .tb-service-option:has(input:focus-visible) {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* On phones the switch is one line of name and one of what it gets, so the Year select still
   lands in the first screen under the pinned car (measured at 375x548). */
@media (max-width: 767px) {
  .tb-builder .tb-service-option {
    gap: 3px;
    min-height: 44px;
    padding: 7px 9px 6px;
  }

  .tb-builder .tb-service-option b {
    font-size: 0.9rem;
  }

  .tb-builder .tb-service-option small {
    font-size: 0.68rem;
    letter-spacing: 0.04em;
  }
}

/* Three across down to 360px wide; below that, one per row (owner decision 5). */
@media (max-width: 359px) {
  .tb-builder .tb-service {
    grid-template-columns: minmax(0, 1fr);
  }

  .tb-builder .tb-service-option {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    min-height: 44px;
  }
}

/* The step tabs: names only, never numbers. A step reached and left is a button back to it. */
.tb-builder .tb-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 18px;
  margin: 0;
  border-bottom: 1px solid var(--line-soft);
  padding: 0;
  list-style: none;
}

.tb-builder .tb-tabs button {
  min-height: 34px;
  border: 0;
  background: none;
  padding: 0;
  color: var(--faint);
  font: 600 0.7rem/1 var(--body);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
}

.tb-builder .tb-tabs button:disabled {
  cursor: default;
}

.tb-builder .tb-tabs button:not(:disabled) {
  color: var(--muted);
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.3);
  text-underline-offset: 5px;
}

.tb-builder .tb-tabs button:not(:disabled):hover {
  color: var(--text);
}

.tb-builder .tb-tabs [aria-current="step"] {
  color: var(--text);
  box-shadow: inset 0 -2px 0 var(--red);
}

.tb-builder .tb-tabs button:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* The wrap colours (built by tint-builder.js from js/wrap-colors.js). */
.tb-builder .tb-colors {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 10px 8px;
  margin-top: 10px;
}

.tb-builder .tb-color {
  display: grid;
  justify-items: center;
  gap: 6px;
  min-width: 0;
  min-height: 44px;
  border: 0;
  background: none;
  padding: 0;
  color: var(--muted);
  font: 500 0.7rem/1.2 var(--body);
  cursor: pointer;
}

.tb-builder .tb-color-chip {
  width: 100%;
  max-width: 44px;
  aspect-ratio: 1;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 3px;
}

/* "Not sure" has no colour: a dashed, empty chip. */
.tb-builder .tb-color-chip.is-unsure {
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.45);
  background: none;
}

.tb-builder .tb-color[aria-checked="true"] {
  color: var(--text);
}

.tb-builder .tb-color[aria-checked="true"] .tb-color-chip {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.tb-builder .tb-color:hover .tb-color-chip {
  border-color: var(--red-hot);
}

.tb-builder .tb-color:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

@container (max-width: 459px) {
  .tb-builder .tb-colors {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* The film rows (owner decision 3): name, one film line, the price on the right. */
.tb-builder .tb-films {
  display: grid;
  gap: 8px;
}

.tb-builder .tb-film {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 14px;
  min-height: 56px;
  border: 1.5px solid var(--line-soft);
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.02);
  padding: 11px 14px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.tb-builder .tb-film b {
  color: var(--text);
  font: 700 1.12rem/1.05 var(--disp);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.tb-builder .tb-film small {
  grid-column: 1;
  color: var(--muted);
  font-size: 0.78rem;
}

.tb-builder .tb-film-tag {
  margin-left: 8px;
  color: var(--red-hot);
  font: 600 0.64rem/1 var(--body);
  letter-spacing: 0.16em;
  vertical-align: middle;
}

.tb-builder .tb-film-price {
  grid-row: 1 / span 2;
  grid-column: 2;
  color: var(--text);
  font: 700 1.2rem/1 var(--disp);
  white-space: nowrap;
}

.tb-builder .tb-film:hover {
  border-color: var(--red-hot);
}

.tb-builder .tb-film:has(input:checked) {
  border-color: var(--red);
  background: rgba(220, 38, 38, 0.1);
  box-shadow: inset 0 2px 0 var(--red);
}

.tb-builder .tb-film:has(input:focus-visible) {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* The price line, just above the active step's Back/Next row (tint-builder.js moves it). */
.tb-builder .tb-price {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 3px 16px;
  border-top: 1px solid var(--line-soft);
  padding-top: 14px;
}

.tb-builder .tb-price-key {
  color: var(--faint);
  font: 600 0.66rem/1.2 var(--body);
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.tb-builder .tb-price-value {
  grid-column: 1;
  overflow-wrap: anywhere;
  color: var(--text);
  font: 700 1.05rem/1.2 var(--disp);
  text-transform: uppercase;
}

.tb-builder .tb-price-amount {
  grid-row: 1 / span 3;
  grid-column: 2;
  color: var(--text);
  font: 700 2.2rem/1 var(--disp);
}

.tb-builder .tb-price-amount:empty {
  display: none;
}

.tb-builder .tb-price.is-consult .tb-price-amount {
  color: var(--red-hot);
  font-size: 1.4rem;
}

.tb-builder .tb-price-note {
  grid-column: 1;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.4;
}

@media (prefers-reduced-motion: reduce) {
  .tb-builder .tb-service-option,
  .tb-builder .tb-film {
    transition: none;
  }
}

/* ---- End of the full builder ---------------------------------------------------------- */


/* ---- Results: they replace the form inside the same surface --------------------------- */

/* main.js hides the form with Tailwind's .hidden on success, but the
   `.tb-builder #quoteBuilder { display: grid }` rule above out-specifies it, which would leave
   the form showing above the result. */
.tb-panel > #quoteBuilder.hidden {
  display: none;
}

/* main.js scrolls the result panel to the top of the viewport after a submit, and the browser
   scrolls a control that fails native validation into view; both have to clear the header and
   the pinned car. A control also keeps its label above it in view. */
.tb-panel > .quote-result-panel {
  scroll-margin-top: var(--tb-land);
}

.tb-panel #quoteBuilder :is(input, select, textarea) {
  scroll-margin-top: calc(var(--tb-land) + 1.5rem);
}

.tb-panel > .quote-result-panel {
  border-top: 0;
  border-right: 0;
  border-bottom: 0;
  border-radius: 3px;
  background: transparent;
  animation: tb-step-in 0.3s ease both;
}

/* ---- Below 1024px: the car pinned above the panel ------------------------------------- */

@media (max-width: 1023px) {
  /* A block-level flex column, not a grid, so the sticky stage is bounded by the whole
     builder rather than by its own grid row (which would leave it nowhere to stick). */
  .tb-builder {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 18px;
  }

  .tb-stage {
    top: var(--tb-top);
    margin-inline: calc(-1 * var(--tb-gutter));
    border-bottom: 1px solid var(--line);
    background: var(--tb-well);
    padding: 8px var(--tb-gutter) 10px;
    box-shadow: 0 14px 26px rgba(0, 0, 0, 0.45);
  }

  /* The car band is a grid: the car and its tabs rail across the top, then the body toggle
     and the look caption share the caption's row, so the toggle costs the pinned band no
     height (a car this small has no corner free of glass in every view for the desktop
     pill, and a row of its own would push the Year select out of the first viewport). */
  .tb-stage {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: 12px;
  }

  .tb-stage > .tb-view {
    grid-column: 1 / -1;
  }

  /* The tabs become a rail beside the car, using the width the height-bound car leaves, so
     the car itself can be larger. Stock closes the rail. Its four rows share the car's
     height rather than add to it: at 375x548 the car is 124px tall, so a fourth 40px row
     would make the pinned band taller; the rows are 31px there and 41px from 390x664. */
  .tb-view {
    display: grid;
    grid-template-columns:
      min(calc(100% - 76px), calc((var(--tb-car-h) - var(--tb-stage-chrome)) * 1.5))
      68px;
    grid-template-rows: repeat(4, minmax(0, 1fr));
    justify-content: center;
    column-gap: 8px;
    overflow: visible;
    border: 0;
    border-radius: 0;
    background: none;
  }

  .tb-view .tint-demo-visual {
    grid-column: 1;
    grid-row: 1 / -1;
    width: 100%;
    max-width: none;
    border-radius: 2px;
  }

  .tb-body-tabs {
    position: static;
    margin-top: 8px;
  }

  .tb-body-tab {
    min-height: 28px;
    padding: 0 9px;
    font-size: 0.62rem;
    letter-spacing: 0.1em;
  }

  .tb-view .tint-demo-tabs {
    grid-column: 2;
    grid-row: 1 / span 3;
    grid-template-columns: 1fr;
    grid-auto-rows: minmax(30px, 1fr);
    border-bottom: 0;
    border-left: 1px solid var(--line);
  }

  .tb-view .tint-demo-tab {
    min-height: 30px;
    margin-left: -1px;
    border-bottom: 0;
    border-left: 2px solid transparent;
    padding: 0 0 0 11px;
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    text-align: left;
  }

  .tb-view .tint-demo-tab[aria-selected="true"] {
    border-left-color: var(--red);
  }

  .tb-stock {
    grid-column: 2;
    grid-row: 4;
    justify-content: flex-start;
    gap: 6px;
    min-height: 30px;
    border-top: 1px solid var(--line);
    border-bottom: 0;
    border-left: 1px solid var(--line);
    padding: 0 0 0 11px;
    font-size: 0.7rem;
    letter-spacing: 0.12em;
  }

  .tb-caption {
    margin-top: 8px;
    font-size: 0.8rem;
    text-align: center;
  }

  /* Lands a scroll to the panel just below the pinned car (tint-builder.js scrolls .tb-panel
     on Next/Back below 1024px, because scrolling #quote there brings back the intro and
     leaves only the progress header in view). --tb-car-h is the band's *nominal* height
     (tabs rail + car + a 2-line caption, per --tb-stage-chrome above); a longer vehicle
     name with both shades and both add-ons wraps #qbLookCaption to a 3rd line, a 56px box
     that is 19px taller than that reserve at both 375px and 390px. --tb-band-h adds a line
     and a half of the caption's own metrics (0.8rem/1.45 ≈ 18.56px a line) as headroom so
     the target still clears the band: measured, the panel then lands 8px below the pinned
     car at 375x548 (scroll-margin-top 277px there, 317px at 390x664). */
  .tb-panel {
    --tb-band-h: calc(var(--tb-car-h) + 1.74rem); /* 1.5 * 0.8rem * 1.45 line-height */
    --tb-land: calc(var(--tb-top) + var(--tb-band-h));
    scroll-margin-top: var(--tb-land);
  }
}

@media (max-width: 767px) {
  .tint-builder {
    /* .lp-header-inner min-height 62px + 1px border-bottom = 63px. */
    --tb-top: 63px;
    --tb-gutter: 14px;
    /* Tightened along with everything else below it so the Year select's full box sits
       inside the first viewport at 390x664 and 375x548: measured, its bottom edge lands at
       579px (85px to spare) and 538px (10px to spare). The car is the last lever pulled —
       34svh is the floor below the 38svh default; the intro/panel tightening alone gets
       390x664 there, but 375x548 needs this too. */
    --tb-car-h: 34svh;
    padding-block: 10px calc(40px + env(safe-area-inset-bottom));
  }

  /* Tighter than the >=768px column gap so the first viewport reaches the Year select. */
  .tb-builder {
    gap: 8px;
  }

  .tb-intro h1 {
    margin-top: 6px;
    font-size: clamp(1.9rem, 8vw, 2.6rem);
  }

  /* The lead sentence is the first thing to go: the car preview and the vehicle picker
     say what the page is for without it, and it's the only intro element with no other
     job (the H1 sets the page's message; the lead just restates it in longer form). */
  .tb-lead {
    display: none;
  }

  /* "· pick your vehicle to start." goes too: the Vehicle step's own heading says it just
     below, and beside the body toggle it wrapped the look caption to a third line. */
  .tb-caption-hint {
    display: none;
  }

  .tb-stage {
    padding-top: 6px;
    padding-bottom: 6px;
  }

  /* Everything below tightens the step panel's own chrome (progress block, section
     heading, field padding) toward the phone's cramped vertical budget; none of it
     changes at >=768px. */
  .tb-panel #quoteBuilder {
    padding: 4px 14px 16px;
    gap: 6px;
  }

  .tb-progress {
    gap: 8px;
    padding-bottom: 6px;
  }

  .tb-steps .qb-section-heading {
    gap: 10px;
    padding-bottom: 6px;
  }

  .tb-steps .qb-section-fields {
    padding-top: 4px;
  }

  .tb-panel .q-3 > div {
    gap: 4px;
  }

  .tb-panel .q-input {
    min-height: 44px;
  }

  /* Keep "Side · Illustration · 30% front · 15% rear" on one line over the small car. */
  .tb-view .tint-demo-caption {
    right: 6px;
    bottom: 6px;
    padding: 4px 6px;
    font-size: 0.56rem;
    letter-spacing: 0.02em;
    text-transform: none;
    white-space: nowrap;
  }

  /* An SUV's read-through takes a second line rather than running off the car: the first
     line stays "… · 15% rear", the second reads "≈3% through factory glass". */
  .tb-view .tint-demo-caption [data-tint-demo-factory] {
    display: block;
    text-align: right;
  }

  .tb-view .tint-demo-caption [data-tint-demo-factory] .tint-demo-sep {
    display: none;
  }

  .tb-view .tint-demo-tab {
    padding-left: 9px;
    font-size: 0.66rem;
    letter-spacing: 0.08em;
  }

  .tb-stock {
    gap: 5px;
    padding-left: 9px;
    font-size: 0.66rem;
    letter-spacing: 0.08em;
  }

  .tb-indicator {
    gap: 4px;
  }

  .tb-indicator span {
    gap: 5px;
    font-size: 0.6rem;
    letter-spacing: 0.06em;
  }

  .tb-indicator span::before {
    width: 7px;
    height: 7px;
  }

  .tb-steps .qb-section-number {
    font-size: 2.1rem;
  }

  .tb-swatches {
    gap: 6px;
  }

  .tb-swatch-value {
    font-size: 0.9rem;
  }
}

/* Browsers without svh (Safari < 15.4). A custom property holding 34svh is still valid where
   it is declared; it only fails where it is used, dropping .tb-panel's scroll-margin-top to 0
   (panels land under the pinned car) and the pinned car's sizing. So this must come after every rule that sets
   --tb-car-h in svh, or the later rule wins. */
@supports not (height: 1svh) {
  .tint-builder {
    --tb-car-h: 38vh;
  }

  @media (max-width: 767px) {
    .tint-builder {
      --tb-car-h: 34vh;
    }
  }
}

/* Landscape phones with the toolbars hidden: too short to pin the car above the form. */
@media (max-width: 1023px) and (max-height: 420px) {
  .tb-stage {
    position: relative;
    top: auto;
    box-shadow: none;
  }

  .tb-view {
    grid-template-columns: min(calc(100% - 76px), 360px) 68px;
  }

  /* Nothing is pinned, so a scroll into the panel only has to clear the header. Next and Back
     scroll the step itself here (tint-builder.js), leaving the progress block above. */
  .tb-panel {
    --tb-land: calc(var(--tb-top) + 8px);
  }

  .tb-panel .tb-steps > .qb-section {
    scroll-margin-top: var(--tb-land);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tb-builder .tint-demo-film,
  .tb-body-tab,
  .tb-stock,
  .tb-stock::before,
  .tb-indicator span::before,
  .tb-swatch-glass,
  .tb-swatch-glass::after,
  .tb-show-front {
    transition: none;
  }

  .tb-panel .tb-steps > .qb-section,
  .tb-panel > .quote-result-panel {
    animation: none;
  }

  .tb-swatch:hover .tb-swatch-glass {
    transform: none;
  }
}
