/* ============================================================
   CrispSign — Halo-Lit Channel Letter Preview
   Brand palette only. No improvising.
   ============================================================ */

:root {
  /* Brand */
  --cream:        #FAF7F2;
  --cream-2:      #F4F0E8;   /* alternate brick */
  --navy:         #0A1226;
  --navy-deep:    #050912;
  --orange:       #E81820;
  --ink-muted:    #5C6273;
  --border:       #E5DFD3;
  /* Primary "Add to Cart" CTA — Signal Red, matching the approved Lobby Vinyl /
     LobbyPanel builder (panel.css --panel-red / --panel-red-deep). The buy box
     itself is brand navy with white text; the CTA inside is this red. */
  --signal:       #E81820;
  --signal-deep:  #B8121A;

  /* Night-mode derivations (same family as navy, never a new hue) */
  --night-wall:   #1A1F2E;
  --night-surf:   #0F141F;

  /* Type */
  --font-body:    'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  --font-display: 'Space Grotesk', var(--font-body);
  --font-sign:    'Bebas Neue', sans-serif;

  /* Motion */
  --ease:         cubic-bezier(0.4, 0, 0.2, 1);
  --dur:          600ms;
  --dur-fast:     220ms;

  /* Global UI scale. The builder read ~16% small after the right-rail
     redesign; this multiplier drives the spacing tokens, preview height,
     page width, and the structurally-dominant font sizes via calc() so the
     whole builder scales up uniformly without a transform/zoom hack (which
     would break the sticky preview + buy box). Only styles.css consumes the
     --gap-* tokens, so the learn/index pages are unaffected. */
  --ui-scale: 1.16;

  /* Rhythm */
  --gap-1: calc(8px  * var(--ui-scale));
  --gap-2: calc(16px * var(--ui-scale));
  --gap-3: calc(24px * var(--ui-scale));
  --gap-4: calc(32px * var(--ui-scale));
  --gap-5: calc(48px * var(--ui-scale));
  --gap-6: calc(64px * var(--ui-scale));

  /* ── Live-preview camera (channel letters on storefront photo) ──
     Customers were complaining the letters felt "far away" inside the
     1100×600 viewBox: the photo has a lot of sky/sidewalk filler around
     the sign band. We crop in with a CSS scale on the SVG so the
     storefront context is preserved (you still see the door for scale)
     but the sign band fills more of the preview window.

     This is a CSS-only camera zoom — the SVG's internal coordinate
     system, letter-vs-door scaling math (PR #8), and cabinet geometry
     are all untouched. Cabinet mode opts out via a selector below so
     its 3/4 framing isn't double-cropped. */
  --preview-zoom:          1.18;   /* desktop crop strength (channel letters) */
  --preview-zoom-mobile:   1.10;   /* mobile is already small — gentler zoom */
  --preview-zoom-origin-x: 50%;
  --preview-zoom-origin-y: 42%;    /* sign band sits above middle in v2/v3/v4/brick scenes */
  --preview-max-h:         calc(680px * var(--ui-scale));  /* up from 600px, then scaled with --ui-scale */

  /* Cabinet-mode camera. The cabinet body sits at ~x=260-900, y=170-400
     in the 1100×600 SVG viewBox (centered around 580,285). A 4'×8'
     cabinet is large in real life and the customer is designing artwork
     on its face, so we crop in tighter than the channel-letter scene to
     make the face fill more of the live design area. Origin is biased
     slightly above geometric center to keep the cabinet body centered
     in the cropped window. Side-view / double-faced is opted out below
     so its wider scene isn't double-cropped. */
  --cab-camera-zoom:        1.28;
  --cab-camera-zoom-mobile: 1.15;
  --cab-camera-origin-x:    52%;
  --cab-camera-origin-y:    48%;
}

* { box-sizing: border-box; }

/* The `hidden` attribute must always win — guard against display: flex etc. */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--cream);
  color: var(--navy);
  font-family: var(--font-body);
  font-size: calc(15px * var(--ui-scale));
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* ── Page shell ───────────────────────────────────────────── */

.page {
  max-width: calc(1100px * var(--ui-scale));
  margin: 0 auto;
  padding: var(--gap-6) var(--gap-4) var(--gap-6);
  display: flex;
  flex-direction: column;
  gap: var(--gap-5);
}

/* ── Brand bar ────────────────────────────────────────────── */

/* Brand bar spacing mirrors the Lobby Vinyl header (panel.css .panel-header):
   tight top, 14px below, a hairline rule, and an 18px gap between clusters. */
.brand-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  /* Trimmed vertical padding so the header band sits closer to the other
     builders' header height — the logo/title keep their prominent Vinyl
     sizing; only the surrounding whitespace shrinks. */
  padding: 6px 0 14px;
  border-bottom: 1px solid var(--border);
}

/* Left cluster: logo + a thin divider + the title/subtitle stack, all grouped
   so the builder identity reads as one unit next to the mark (Lobby Vinyl
   header standard). */
.brand-lead {
  display: flex;
  align-items: center;
  gap: 20px;
  min-width: 0;
}
.brand-divider {
  width: 1px;
  align-self: stretch;
  background: var(--border);
  margin: 3px 0;
}
.brand-title-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.brand-subtitle {
  margin: 0;
  font-family: var(--font-body);
  font-size: calc(16px * var(--ui-scale));
  line-height: 1.35;
  letter-spacing: 0.005em;
  color: var(--ink-muted);
}

/* Right cluster: account state + cart control. */
.brand-actions {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  flex: 0 0 auto;
}
/* Outer pill wrapping the shared account-control.js pill, matching the
   approved /lobby/panel header (panel.css .panel-header-account): white
   surface, 1px hairline border, full pill radius. Keeps the BeaconLetters
   and LobbyLogo builder headers visually identical to every other builder. */
.brand-actions-account {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  background: #fff;
  border: 1px solid var(--line-strong, rgba(10, 18, 38, 0.18));
  border-radius: 999px;
  line-height: 1;
}
/* Empty (loading) state: don't render an empty pill before account-control.js
   paints content into it. */
.brand-actions-account:empty {
  display: none;
}
/* Circular cart control, matching the approved Lobby Vinyl header
   (panel.css .panel-header-cart): 44px round pill, white surface, red count. */
.header-cart {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: 1px solid var(--line-strong, rgba(10, 18, 38, 0.18));
  background: #fff;
  color: var(--navy);
  text-decoration: none;
  transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.header-cart:hover,
.header-cart:focus-visible {
  border-color: var(--navy);
  background: #F1ECE3;
}
.header-cart-icon { display: block; }
.header-cart-count {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--orange);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11px;
  line-height: 18px;
  text-align: center;
}
.header-cart-count[hidden] { display: none; }

.brand-mark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: inherit;
}

.brand-logo { width: 30px; height: auto; display: block; }

/* v2 brand mark — full-color SVG with embedded wordmark (1043 × 340).
   Sized to match the prominent Lobby Vinyl / LobbyPanel header (the large
   "is-lg" title lockup): a 48px desktop mark, 38px on narrow screens, so the
   three builders share one mark and the identity fills the left header area. */
.brand-logo-v2 {
  display: block;
  height: calc(56px * var(--ui-scale));
  width: auto;
  max-width: 100%;
  object-fit: contain;
}
@media (max-width: 720px) {
  .brand-logo-v2 { height: calc(42px * var(--ui-scale)); }
}

/* Visually hide a label/wordmark while keeping it accessible to AT */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.brand-wordmark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -0.02em;
  color: var(--navy);
}

/* Header title lockup — mirrors the approved Lobby Vinyl / LobbyPanel header's
   large "is-lg" title: a prominent product title in brand navy (800) with a
   muted "/ descriptor" following it, so the builder identity fills the left
   header area instead of reading as a tiny eyebrow. Beacon and Lobby Logo share
   this exact treatment so the three builders read as one. */
.brand-eyebrow {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(26px * var(--ui-scale));
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--ink-soft, rgba(10, 18, 38, 0.66));
}
.brand-eyebrow strong {
  font-weight: 800;
  font-size: calc(26px * var(--ui-scale));
  letter-spacing: -0.02em;
  color: var(--navy);
  margin-right: 7px;
}
.brand-eyebrow .muted {
  color: var(--ink-faint, rgba(10, 18, 38, 0.48));
  font-weight: 500;
  font-size: calc(21px * var(--ui-scale));
}

/* ── Checkout CTA ────────────────────────────── */
.checkout-bar {
  margin-top: 32px;
  padding: 24px;
  background: #fff;
  border: 1px solid rgba(10, 18, 38, 0.12);
  border-radius: 14px;
  display: grid;
  gap: 14px;
  align-items: center;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "summary cta"
    "summary save"
    "status  status"
    "link    link"
    "fine    fine";
}
.checkout-summary {
  grid-area: summary;
  display: flex;
  flex-direction: column;
}
.checkout-label {
  font-family: var(--font-body);
  font-size: calc(12px * var(--ui-scale));
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.checkout-price {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(28px * var(--ui-scale));
  letter-spacing: -0.02em;
  color: var(--navy);
}
.checkout-summary-line {
  margin-top: 4px;
  font-family: var(--font-body);
  font-size: calc(13px * var(--ui-scale));
  line-height: 1.4;
  color: var(--ink-muted);
}
.checkout-summary-line[hidden] { display: none; }
/* Itemized split shown above the headline total when a preset shape is priced.
   Always visible (no toggle/collapse) so live QA reads it in the same card. */
.checkout-itemized {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 8px;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--ink);
}
.checkout-itemized[hidden] { display: none; }
.checkout-itemized-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}
.checkout-itemized-total {
  font-weight: 700;
  border-top: 1px solid var(--line, rgba(0,0,0,0.12));
  padding-top: 3px;
  margin-top: 1px;
}
.checkout-itemized-note {
  font-size: 11px;
  color: var(--ink-muted);
}
.cta-primary {
  grid-area: cta;
  appearance: none;
  border: 0;
  background: var(--signal);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: calc(16px * var(--ui-scale));
  letter-spacing: 0.01em;
  padding: 14px 26px;
  border-radius: 10px;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(232, 24, 32, 0.32);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.cta-primary:hover {
  background: var(--signal-deep);
  box-shadow: 0 8px 22px rgba(232, 24, 32, 0.34);
  transform: translateY(-1px);
}
.cta-primary:active { transform: translateY(0); }
.cta-primary[disabled] {
  background: var(--ink-muted);
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}
.cta-secondary {
  grid-area: save;
  appearance: none;
  background: transparent;
  color: var(--navy);
  border: 1.5px solid rgba(10, 18, 38, 0.22);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(15px * var(--ui-scale));
  letter-spacing: -0.01em;
  padding: 11px 24px;
  border-radius: 10px;
  cursor: pointer;
  justify-self: end;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.cta-secondary:hover {
  border-color: var(--navy);
  background: rgba(10, 18, 38, 0.04);
  transform: translateY(-1px);
}
.cta-secondary:active { transform: translateY(0); }
.cta-secondary[disabled] {
  color: var(--ink-muted);
  border-color: rgba(10, 18, 38, 0.12);
  cursor: not-allowed;
  transform: none;
}
.save-design-status {
  grid-area: status;
  margin: 0;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--ink-muted);
}
.save-design-status[data-kind="success"] { color: #1B7F3B; font-weight: 600; }
.save-design-status[data-kind="error"]   { color: #C8401B; font-weight: 600; }
.save-design-status[data-kind="pending"] { color: var(--ink-muted); }
.save-design-link {
  grid-area: link;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--orange);
  text-decoration: none;
}
.save-design-link:hover { text-decoration: underline; }
.checkout-fineprint {
  grid-area: fine;
  margin: 0;
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--ink-muted);
}
.checkout-fineprint-save { display: block; margin-top: 2px; }
@media (max-width: 600px) {
  .checkout-bar {
    grid-template-columns: 1fr;
    grid-template-areas: "summary" "cta" "save" "status" "link" "fine";
  }
  .cta-secondary { justify-self: stretch; text-align: center; }
}

/* ── Footer brand chrome ───────────────────────────── */
.brand-footer {
  padding-top: 28px;
  border-top: 1px solid rgba(10, 18, 38, 0.08);
  margin-top: 36px;
}
.brand-slogan {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(30px * var(--ui-scale));
  letter-spacing: -0.02em;
  color: var(--navy);
  margin: 18px 0 6px;
  line-height: 1.15;
}
.brand-slogan em {
  font-style: italic;
  color: var(--orange);
  font-weight: 700;
}
.brand-fineprint {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--ink-muted);
  margin: 4px 0 0;
}

/* ── Canvas ───────────────────────────────────────────────── */

/* ── Live preview card ──────────────────────────────────────────────
   White card/wrapper around the live design area, matching the Lobby
   Vinyl/Panel treatment (panel.css .panel-canvas): a small uppercase
   "YOUR LIVE PREVIEW" pill at the top, then the preview underneath. The
   card carries the surface chrome (white bg, border, radius, shadow) so
   the inner .canvas-wrap drops its own outer shadow and reads as the
   framed stage inside the card. Shared by Beacon + Lobby Logo. */
.preview-card {
  background: #fff;
  border: 1px solid rgba(10, 18, 38, 0.10);
  border-radius: 14px;
  padding: 14px 14px 12px;
  box-shadow:
    0 4px 14px rgba(10, 18, 38, 0.08),
    0 1px 3px rgba(10, 18, 38, 0.06);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.preview-card-pill {
  align-self: flex-start;
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: 0.18em;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--ink-soft, rgba(10, 18, 38, 0.66));
  background: #F1ECE3;
  padding: 5px 10px;
  border-radius: 999px;
}

.canvas-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 1100 / 600;
  max-height: var(--preview-max-h, 680px);
  border-radius: 10px;
  overflow: hidden;
  background: var(--cream);
  border: 1px solid var(--border);
  /* The .preview-card now provides the outer margin/spacing; the canvas is
     the framed stage inside it. */
  margin-bottom: 0;
  box-shadow: inset 0 1px 0 rgba(10, 18, 38, 0.03);
  transition:
    border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

.canvas-wrap[data-mode="night"] {
  border-color: var(--night-surf);
  box-shadow: inset 0 1px 0 rgba(10, 18, 38, 0.08);
}

.wall-canvas { display: block; width: 100%; height: 100%; }

/* ── Live-preview camera zoom ───────────────────────────────────────
   Crops in on the storefront sign band so the customer sees their
   letters at a more useful size. Applied only to channel-letter /
   sandblasted scenes on the photo backdrop. Cabinet mode keeps its
   own 3/4-view framing (its preview is already centered on the box),
   so we explicitly opt cabinet out via BOTH data-style and
   data-product — depending on the entry path the user took, one or
   the other (or both) will be set:
     • ?style=cabinet                → data-style="cabinet"
     • Cabinet Sign product button   → data-product="cabinet" (style
                                       attribute is left at its prior
                                       channel-letter value).

   transform-origin is biased upward (42%) because every storefront
   scene puts the sign band above the geometric center of the photo.
   The SVG's internal coordinate system is unchanged — door-reference
   scaling from PR #8 still drives the letter-vs-door proportion. */
.canvas-wrap[data-bg="photo"]:not([data-style="cabinet"]):not([data-product="cabinet"]) .wall-canvas {
  transform: scale(var(--preview-zoom, 1));
  transform-origin: var(--preview-zoom-origin-x, 50%) var(--preview-zoom-origin-y, 42%);
  transition: transform var(--dur) var(--ease);
}

/* Cabinet camera — pulls the customer closer to the cabinet face so a
   4'×8' (or larger) cabinet feels appropriately big in the live design
   area. Single-faced front view only. The double-faced side view paints
   its own wide scene, so we opt that out by gating on the JS-managed
   data-cabinet-view="front" attribute on the wrap. */
.canvas-wrap[data-product="cabinet"][data-cabinet-view="front"] .wall-canvas {
  transform: scale(var(--cab-camera-zoom, 1.28));
  transform-origin: var(--cab-camera-origin-x, 52%) var(--cab-camera-origin-y, 48%);
  transition: transform var(--dur) var(--ease);
}

.wall-bg { transition: fill var(--dur) var(--ease); }
.canvas-wrap[data-mode="night"] .wall-bg { fill: var(--night-wall); }

.wall-bricks { transition: opacity var(--dur) var(--ease); }

.vignette-rect {
  opacity: 0.25;
  transition: opacity var(--dur) var(--ease);
  pointer-events: none;
}
.canvas-wrap[data-mode="night"] .vignette-rect { opacity: 0.85; }

/* ── Live measurement ruler ──────────────────────────────────────────
   Vertical scale showing actual letter height. Updates from JS
   based on the rendered face text bbox (so it matches what the
   customer actually sees). */
.measure-ruler { pointer-events: none; transition: opacity var(--dur) var(--ease); }
.measure-line,
.measure-cap-top,
.measure-cap-bot {
  stroke: var(--orange, #E81820);
  stroke-width: 2.5;
  stroke-linecap: round;
}
.measure-ticks line {
  stroke: var(--orange, #E81820);
  stroke-width: 1.6;
  stroke-linecap: round;
  opacity: 0.7;
}
.measure-label-bg {
  fill: var(--cream, #FAF7F2);
  stroke: var(--orange, #E81820);
  stroke-width: 1.5;
}
.measure-label {
  fill: var(--navy, #0A1226);
  font: 700 16px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0.02em;
}
/* Night mode: keep ruler readable on dark wall */
.canvas-wrap[data-mode="night"] .measure-line,
.canvas-wrap[data-mode="night"] .measure-cap-top,
.canvas-wrap[data-mode="night"] .measure-cap-bot { stroke: #FF8A4D; }
.canvas-wrap[data-mode="night"] .measure-ticks line { stroke: #FF8A4D; }
.canvas-wrap[data-mode="night"] .measure-label-bg {
  fill: #0F141F;
  stroke: #FF8A4D;
}
.canvas-wrap[data-mode="night"] .measure-label { fill: #FAF7F2; }

/* ── Shape width ruler ────────────────────────────────────────────────
   The additive shape's OWN width scale, painted RED (matching the red
   shape resize handle) so it reads as distinct from the orange text
   width ruler beneath the letters. */
.shape-width-ruler .measure-line,
.shape-width-ruler .measure-cap-top,
.shape-width-ruler .measure-cap-bot { stroke: #E11D1D; }
.shape-width-ruler .measure-ticks line { stroke: #E11D1D; }
.shape-width-ruler .measure-label-bg { stroke: #E11D1D; }
.canvas-wrap[data-mode="night"] .shape-width-ruler .measure-line,
.canvas-wrap[data-mode="night"] .shape-width-ruler .measure-cap-top,
.canvas-wrap[data-mode="night"] .shape-width-ruler .measure-cap-bot { stroke: #FF5A5A; }
.canvas-wrap[data-mode="night"] .shape-width-ruler .measure-ticks line { stroke: #FF5A5A; }
.canvas-wrap[data-mode="night"] .shape-width-ruler .measure-label-bg { stroke: #FF5A5A; }

/* ── Traveling artwork measurement scale ─────────────────────────────
   Glued to the uploaded channel-letter artwork (lives inside
   #logoOverlayGroup so it inherits the drag-offset transform and moves
   with the design). Shows overall width + a per-line height label for
   each detected text line. Deliberately lighter than the typed-text
   ruler so it reads as an annotation, not a control. */
.cl-artwork-scale { pointer-events: none; }
.cl-artwork-scale-line {
  stroke: var(--orange, #E8521B);
  stroke-width: 1.6;
  stroke-linecap: round;
  opacity: 0.85;
}
.cl-artwork-scale-pill {
  fill: var(--cream, #FAF7F2);
  stroke: var(--orange, #E8521B);
  stroke-width: 1.2;
  opacity: 0.96;
}
.cl-artwork-scale-label {
  fill: var(--navy, #0A1226);
  font: 700 12px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0.01em;
}
.canvas-wrap[data-mode="night"] .cl-artwork-scale-line { stroke: #FF8A4D; }
.canvas-wrap[data-mode="night"] .cl-artwork-scale-pill {
  fill: #0F141F;
  stroke: #FF8A4D;
}
.canvas-wrap[data-mode="night"] .cl-artwork-scale-label { fill: #FAF7F2; }

/* ── Sign letter layers ──────────────────────────────────── */
/*
   Layer visibility is driven by [data-style] on .canvas-wrap.
   Each letter type opts in only the layers it needs.

   Default rule: hide every optional layer; per-style blocks below
   re-enable them. .face, .side-return, .cast-shadow are common to all.
*/

.sign-text { user-select: none; transition: fill var(--dur) var(--ease), opacity var(--dur) var(--ease), stroke var(--dur) var(--ease); }

/* Optional layers default OFF — turned on per style */
.halo-outer,
.face-glow,
.trim-cap,
.depth-slice {
  display: none;
}

/* Cast shadow visible in both modes; pulled back at night where halo dominates */
.cast-shadow { opacity: 1; }
.canvas-wrap[data-mode="night"] .cast-shadow { opacity: 0.4; }

/* ── Style: REVERSE HALO-LIT ─────────────────────
   Solid face + return + halo behind. At night the face goes dark and
   only the warm-white halo remains visible. */
/* Day: halo not visible (reflected light needs a dark wall to see). Night: halo lights up. */
.canvas-wrap[data-style="halolit"] .halo-outer  { display: block; opacity: 0; }
.canvas-wrap[data-style="halolit"] .depth-slice { display: block; }

.canvas-wrap[data-mode="night"][data-style="halolit"] .halo-outer  { opacity: 1; }
.canvas-wrap[data-mode="night"][data-style="halolit"] .face        { fill: var(--night-wall) !important; }
.canvas-wrap[data-mode="night"][data-style="halolit"] .side-return { fill: var(--night-surf) !important; }
.canvas-wrap[data-mode="night"][data-style="halolit"] .depth-slice { fill: var(--night-surf) !important; }

/* ── Style: STANDARD FRONT-LIT ────────────────────
   Translucent acrylic face glows from inside. No halo behind. Trim cap
   draws a thin edge stroke. Side return is the painted aluminum side. */
.canvas-wrap[data-style="frontlit"] .face-glow   { display: block; }
.canvas-wrap[data-style="frontlit"] .trim-cap    { display: block; }
.canvas-wrap[data-style="frontlit"] .depth-slice { display: block; }

/* Day: glow subtle. Night: face stays bright (acrylic lit by LEDs inside). */
.canvas-wrap[data-mode="day"][data-style="frontlit"]   .face-glow { opacity: 0.45; }
.canvas-wrap[data-mode="night"][data-style="frontlit"] .face-glow { opacity: 1; }
/* At night the side return goes dark — only the front face is illuminated. */
.canvas-wrap[data-mode="night"][data-style="frontlit"] .side-return { fill: var(--night-surf) !important; }
.canvas-wrap[data-mode="night"][data-style="frontlit"] .depth-slice { fill: var(--night-surf) !important; }

/* ── Style: DUAL-LIT (Front + Halo) ───────────────
   Both the front face glows AND a halo blooms behind. Most expensive look. */
.canvas-wrap[data-style="duallit"] .halo-outer  { display: block; opacity: 0; }
.canvas-wrap[data-style="duallit"] .face-glow   { display: block; }
.canvas-wrap[data-style="duallit"] .trim-cap    { display: block; }
.canvas-wrap[data-style="duallit"] .depth-slice { display: block; }

.canvas-wrap[data-mode="day"][data-style="duallit"]   .face-glow  { opacity: 0.40; }
.canvas-wrap[data-mode="night"][data-style="duallit"] .face-glow  { opacity: 1; }
.canvas-wrap[data-mode="night"][data-style="duallit"] .halo-outer { opacity: 1; }
.canvas-wrap[data-mode="night"][data-style="duallit"] .side-return { fill: var(--night-surf) !important; }
.canvas-wrap[data-mode="night"][data-style="duallit"] .depth-slice { fill: var(--night-surf) !important; }

/* ── Style: SANDBLASTED ───────────────────────────
   Carved & sandblasted wood panel. A wood-grain panel sits behind the
   letters; the letter face appears recessed (carved into the wood) via
   an inner-shadow filter. There is no glow — at night a small spot light
   illuminates the panel from above. */
#sandPanelGroup        { display: none; }
#cabinetGroup          { display: none; }
/* The legacy lightbox-style #cabinetGroup is only ever appropriate when
   the active letter style is "cabinet". The new top-level Cabinet
   product owns its own preview group (#cabinetProductGroup), so when a
   customer is in channel-letter mode we MUST keep #cabinetGroup hidden
   even if a previous session left data-style="cabinet" on the wrap. */
.canvas-wrap[data-product="channel"] #cabinetGroup,
.canvas-wrap[data-product="cabinet"] #cabinetGroup {
  display: none !important;
}

/* Hard-hide #cabinetProductGroup whenever the channel-letter product is
   active. The element gets [hidden] toggled by setProduct() in JS, but
   SVG `<g hidden>` is not universally honored — Safari renders the
   children regardless. Force it off via CSS so the cabinet face / white
   polycarb rect can never leak into a channel-letter scene. Conversely,
   force #signGroup off in cabinet mode for the same reason. */
.canvas-wrap[data-product="channel"] #cabinetProductGroup {
  display: none !important;
}
.canvas-wrap[data-product="cabinet"] #signGroup {
  display: none !important;
}
.canvas-wrap[data-style="sandblasted"] #sandPanelGroup { display: block; }
.canvas-wrap[data-style="sandblasted"] .wall-bricks   { opacity: 0; }
.canvas-wrap[data-style="sandblasted"] .wall-bg       { fill: #2A1810; transition: fill var(--dur) var(--ease); }
.canvas-wrap[data-style="sandblasted"] .halo-outer    { display: none; }
.canvas-wrap[data-style="sandblasted"] .face-glow     { display: none; }
.canvas-wrap[data-style="sandblasted"] .depth-slice   { display: none; }
.canvas-wrap[data-style="sandblasted"] .side-return   { display: none; }
.canvas-wrap[data-style="sandblasted"] .cast-shadow   { display: none; }
.canvas-wrap[data-style="sandblasted"] .trim-cap      { display: none; }
.canvas-wrap[data-mode="day"][data-style="sandblasted"]   #sandPanelSpot { opacity: 0; }
.canvas-wrap[data-mode="night"][data-style="sandblasted"] #sandPanelSpot { opacity: 0.55; }
.canvas-wrap[data-mode="night"][data-style="sandblasted"] #sandPanel    { filter: brightness(0.55); }
.canvas-wrap[data-mode="night"][data-style="sandblasted"] .face         { opacity: 0.85; }

/* ── Style: TRIMLESS ──────────────────────────────
   Trimless front-lit channel letters. No visible trim cap; the face
   appears as a clean lit panel that bleeds light around its edge. */
.canvas-wrap[data-style="trimless"] .halo-outer  { display: none; }
.canvas-wrap[data-style="trimless"] .face-glow   { display: block; opacity: 0.55; }
.canvas-wrap[data-style="trimless"] .trim-cap    { display: none; }
.canvas-wrap[data-style="trimless"] .depth-slice { display: block; opacity: 0.6; }
.canvas-wrap[data-style="trimless"] .side-return { display: block; opacity: 0.7; }
.canvas-wrap[data-style="trimless"] .cast-shadow { opacity: 0.4; }
.canvas-wrap[data-mode="day"][data-style="trimless"]   .face-glow { opacity: 0.30; }
.canvas-wrap[data-mode="night"][data-style="trimless"] .face-glow { opacity: 1; }
.canvas-wrap[data-mode="night"][data-style="trimless"] .face      { filter: url(#trimlessGlow); }

/* ── Style: CABINET ───────────────────────────────
   Lightbox cabinet sign. A rectangular box (sized to the text bbox plus
   padding) sits behind the letters; at night it glows from within and the
   letters read as translucent cutouts. */
.canvas-wrap[data-style="cabinet"] #cabinetGroup { display: block; }
.canvas-wrap[data-style="cabinet"] .halo-outer  { display: none; }
.canvas-wrap[data-style="cabinet"] .face-glow   { display: none; }
.canvas-wrap[data-style="cabinet"] .depth-slice { display: none; }
.canvas-wrap[data-style="cabinet"] .side-return { display: none; }
.canvas-wrap[data-style="cabinet"] .trim-cap    { display: none; }
.canvas-wrap[data-style="cabinet"] .cast-shadow { opacity: 0.6; }
.canvas-wrap[data-mode="day"][data-style="cabinet"]   #cabinetGlow { opacity: 0; }
.canvas-wrap[data-mode="night"][data-style="cabinet"] #cabinetGlow { opacity: 1; filter: url(#cabinetGlowFilter); }
.canvas-wrap[data-mode="night"][data-style="cabinet"] #cabinetBox  { filter: brightness(1.4); }

/* ── Style picker (top-level) ───────────────────── */
.style-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
@media (min-width: 900px) {
  .style-cards { grid-template-columns: repeat(6, 1fr); }
}
.style-card {
  appearance: none;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  padding: 12px 12px 14px;
  background: #FFFFFF;
  border: 1.5px solid var(--border);
  border-radius: 12px;
  cursor: pointer;
  text-align: left;
  font-family: 'Inter', system-ui, sans-serif;
  color: var(--navy);
  transition:
    border-color 140ms ease,
    background   140ms ease,
    transform    140ms ease,
    box-shadow   140ms ease;
}
.style-card:hover {
  border-color: #C4BBA6;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(10, 18, 38, 0.06);
}
.style-card.is-active {
  border-color: var(--orange);
  background: #FFF7F2;
  box-shadow: 0 0 0 3px rgba(232, 24, 32, 0.10);
}
.style-card:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.15);
}
.style-card-thumb {
  display: block;
  width: 100%;
  border-radius: 6px;
  overflow: hidden;
  line-height: 0;
}
.style-card-thumb svg { width: 100%; height: 40px; display: block; }
.style-card-title {
  font-weight: 700;
  font-size: 13px;
  letter-spacing: -0.005em;
  color: var(--navy);
}
.style-card-desc {
  font-weight: 500;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--ink-muted);
}
@media (max-width: 900px) {
  .style-cards { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 560px) {
  .style-cards { grid-template-columns: repeat(2, 1fr); }
}
/* Lighting price-tier captions (Economy / Premium). Non-clickable rows that
   span the full grid width and bucket the lighting cards below them. */
.style-cards .style-tier-label {
  grid-column: 1 / -1;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted, #5C6273);
  margin: 2px 0 -2px;
}
.rail-style-block .style-cards .style-tier-label { margin: 4px 0 0; }

/* ── Sub-pickers (Return color + Trim cap inside colorBlock) ──── */
.sub-picker {
  margin-top: var(--gap-3);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.swatch-grid-sm {
  grid-template-columns: repeat(auto-fill, 22px);
  gap: 6px;
}
.swatch-grid-sm .swatch { width: 22px; height: 22px; }

/* ── Controls ─────────────────────────────────────────────── */

.controls {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.control-block {
  display: flex;
  flex-direction: column;
  gap: 10px;
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.control-header {
  display: flex;
  align-items: baseline;
  gap: var(--gap-2);
  flex-wrap: wrap;
}

.control-label {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: calc(11px * var(--ui-scale));
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
  padding: 0;
  margin: 0;
}

.control-hint {
  font-family: var(--font-body);
  font-size: calc(12px * var(--ui-scale));
  font-weight: 400;
  color: var(--ink-muted);
  letter-spacing: 0;
  text-transform: none;
}

/* ─────────────────────────────────────────────────────────────
   Right-rail sectioned cards
   Mirrors the LobbyPanel builder's .panel-rail / .rail-section
   treatment (crispsign-builders/panel.css): each logical control
   section is its own discrete white card with a soft drop-shadow,
   a 14px radius, clear gutters between cards, and a vibrant navy
   uppercase section heading — instead of one flowing scroll.

   Card chrome values are copied verbatim from panel.css .rail-section
   (background #fff · 1px border rgba(10,18,38,.10) · 14px radius ·
   16/18px padding · the panel --shadow-sm). The 14px gutter is the
   .panel-rail flex gap.
   ───────────────────────────────────────────────────────────── */
.rail-card,
.builder-controls-col > .controls > .control-block:not(#colorBlock),
.builder-controls-col > .controls > .controls-row {
  background: #fff;
  border: 1px solid rgba(10, 18, 38, 0.10);
  border-radius: 14px;
  padding: 16px 16px 18px;
  box-shadow:
    0 1px 2px rgba(10, 18, 38, 0.06),
    0 1px 1px rgba(10, 18, 38, 0.04);
}

/* The dynamic color block is a transparent group: its Acrylic/Face,
   Returns, and Trim Cap children each render as their own card. */
#colorBlock {
  gap: 14px;
  background: transparent;
  border: 0;
  padding: 0;
  box-shadow: none;
}
/* The Returns / Trim Cap sub-pickers are now sibling cards; the flex
   gutter handles their spacing, so drop the legacy stacking margin. */
#colorBlock > .sub-picker { margin-top: 0; }

/* Vibrant section heading — panel.css .rail-label (13px / 700 /
   uppercase / 0.02em / brand navy). Excludes nested sub-headers
   (.control-header.sub) which stay as quiet captions. */
.builder-controls-col > .controls .control-header:not(.sub) > .control-label,
.builder-controls-col > .controls legend.control-label,
.builder-controls-col > .controls > .control-block > label.control-label {
  font-size: calc(13px * var(--ui-scale));
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--navy);
}

/* Numbered section prefix — mirrors the LobbyPanel rail headings
   ("1 · Size"). Injected by app.js renumberSections() as the first child of
   each visible section card's heading label, so it inherits the rail-label
   type above; the renumber pass recomputes the sequence whenever a card
   hides, so the numbers never gap. tabular-nums keeps the digits aligned. */
.rail-card__num {
  font-variant-numeric: tabular-nums;
  color: var(--navy);
}

/* Text input */

.text-input {
  appearance: none;
  width: 100%;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: calc(16px * var(--ui-scale));
  color: var(--navy);
  text-transform: none;
  letter-spacing: 0.04em;
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}

.text-input::placeholder {
  color: var(--ink-muted);
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}

.text-input:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.08);
}

/* ── Body-color swatch grid (40 colors) ──────────────────── */

.swatch-grid {
  display: grid;
  grid-template-columns: repeat(20, 24px);
  gap: 8px;
  padding: 4px 0;
}

.swatch {
  --sw: #000;
  appearance: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--sw);
  border: 1px solid var(--border);
  padding: 0;
  cursor: pointer;
  position: relative;
  transition:
    transform 160ms var(--ease),
    border-color 160ms var(--ease),
    box-shadow 160ms var(--ease);
}

.swatch:hover { transform: translateY(-1px); }

.swatch:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.12);
}

/* Selected ring: 1px navy ring with 2px cream gap */
.swatch.is-active {
  border-color: var(--navy);
  box-shadow:
    0 0 0 2px var(--cream),
    0 0 0 3px var(--navy);
  z-index: 1;
}

/* "Custom Color" swatch — checkerboard so users see it's a wildcard */
.swatch.is-custom {
  background:
    linear-gradient(135deg,
      var(--orange) 0 25%,
      var(--cream) 25% 50%,
      var(--orange) 50% 75%,
      var(--cream) 75% 100%);
  background-size: 12px 12px;
}

/* Selection meta line under the grid */

.selection-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-3);
  flex-wrap: wrap;
  min-height: 22px;
}

.selection-name {
  margin: 0;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--navy);
}

/* ── Font picker grid ───────────────────────────────────── */
.font-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: 10px;
}

.font-chip {
  appearance: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 12px 10px 10px;
  min-height: 90px;
  height: auto;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
  transition:
    border-color 180ms var(--ease),
    background    180ms var(--ease),
    transform     180ms var(--ease),
    box-shadow    180ms var(--ease);
}

.font-chip:hover {
  transform: translateY(-1px);
  border-color: rgba(10, 18, 38, 0.35);
}

.font-chip:focus-visible {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.08);
}

.font-chip.is-active {
  background: #fff;
  border-color: var(--navy);
  box-shadow: 0 1px 0 rgba(10, 18, 38, 0.06), 0 0 0 1px var(--navy);
}

.font-chip-sample {
  font-size: 22px;
  line-height: 1.05;
  color: var(--navy);
  letter-spacing: 0.01em;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  display: block;
}

.font-chip-name {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-muted);
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  text-align: center;
}

.font-chip.is-active .font-chip-name { color: var(--navy); }

/* "Upload My Font" — dashed border to read as an action, not a font */
.font-chip.is-custom {
  border-style: dashed;
  border-color: rgba(10, 18, 38, 0.35);
  background: transparent;
}

.font-chip.is-custom .font-chip-icon {
  font-family: var(--font-body);
  font-size: 24px;
  font-weight: 400;
  line-height: 1;
  color: var(--ink-muted);
  margin-top: 2px;
}

.font-chip.is-custom.is-active {
  border-style: solid;
  border-color: var(--orange);
  box-shadow: 0 0 0 1px var(--orange);
  background: #fff;
}

.font-chip.is-custom.is-active .font-chip-icon { color: var(--orange); }

.custom-font-note-body {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--ink-muted);
  line-height: 1.4;
  max-width: 380px;
}

/* Custom hex input */

.custom-hex {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.custom-hex-label {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.custom-hex-input {
  appearance: none;
  width: 100px;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--navy);
  text-transform: uppercase;
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}

.custom-hex-input:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.08);
}

/* ── Row of three control blocks (return depth + lighting + estimate) ── */

.controls-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-4);
  align-items: flex-end;
}
.controls-row > .control-block {
  flex: 0 0 auto;
  min-width: 0;
}
.controls-row > .estimate-block {
  flex: 1 1 100%;          /* estimate always gets its own row — prevents return-depth/lighting/estimate triple collision when right column is narrow */
  align-self: stretch;
}
@media (min-width: 1280px) {
  /* Wide desktop: bring estimate back inline alongside the toggles */
  .controls-row > .estimate-block {
    flex: 1 1 auto;
    margin-left: auto;
  }
}

/* ── Segmented control (return depth) ────────────────────── */

.segment {
  display: inline-flex;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px;
  position: relative;
  height: 36px;
}

.segment-btn {
  appearance: none;
  background: transparent;
  border: 0;
  margin: 0;
  padding: 0 18px;
  height: 100%;
  border-radius: 999px;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
  white-space: nowrap;
}

.segment-btn:hover { color: var(--navy); }

.segment-btn.is-active {
  background: var(--navy);
  color: var(--cream);
}

.segment-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.12);
}

/* ── Return-depth cards (replaces flat pill chips) ──────────
   Each card shows a small section-view extrusion diagram so the
   depth difference (3" vs 5") is immediately legible.            */
.return-depth-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
  height: auto;
}
.return-depth-card {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 8px 12px 8px 8px;
  min-height: 56px;
  cursor: pointer;
  font-family: var(--font-body);
  color: var(--navy);
  transition: border-color var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
.return-depth-card:hover {
  border-color: var(--navy);
}
.return-depth-card.is-active {
  background: #FFFFFF;
  border-color: var(--orange, #E8521B);
  box-shadow: 0 0 0 2px rgba(232, 82, 27, 0.18);
}
.return-depth-card-svg {
  display: inline-flex;
  width: 44px;
  height: 30px;
  background: #FFFFFF;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 2px;
}
.return-depth-card.is-active .return-depth-card-svg {
  border-color: var(--orange, #E8521B);
}
.return-depth-card-text {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  line-height: 1.1;
}
.return-depth-card-inches {
  font-weight: 800;
  font-size: 15px;
  letter-spacing: -0.01em;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}
.return-depth-card-tag {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.return-depth-card.is-active .return-depth-card-tag {
  color: var(--orange, #E8521B);
}
.return-depth-card:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(232, 82, 27, 0.22);
}

/* ── Letter height slider ─────────────────────────── */
.slider-row {
  display: flex;
  align-items: center;
  gap: 14px;
}
.slider-val {
  min-width: 56px;
  text-align: right;
  font-family: 'Inter', system-ui, sans-serif;
  font-weight: 800;
  font-size: 18px;
  font-variant-numeric: tabular-nums;
  color: var(--navy, #0A1226);
  letter-spacing: -0.01em;
}
.form-slider {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(to right,
    var(--orange, #E81820) 0%,
    var(--orange, #E81820) var(--slider-fill, 40%),
    #E5DFD3 var(--slider-fill, 40%),
    #E5DFD3 100%);
  outline: none;
  cursor: pointer;
}
.form-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #FFFFFF;
  border: 2px solid var(--navy, #0A1226);
  box-shadow: 0 2px 6px rgba(10, 18, 38, 0.18);
  cursor: grab;
  transition: transform 120ms ease;
}
.form-slider::-webkit-slider-thumb:active { cursor: grabbing; transform: scale(1.08); }
.form-slider::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #FFFFFF;
  border: 2px solid var(--navy, #0A1226);
  box-shadow: 0 2px 6px rgba(10, 18, 38, 0.18);
  cursor: grab;
}
.form-slider:focus-visible { box-shadow: 0 0 0 4px rgba(10, 18, 38, 0.10); }

.height-max-note {
  margin: 8px 0 0;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11.5px;
  color: var(--ink-muted, #5C6273);
  line-height: 1.4;
}
.height-max-note a {
  color: var(--orange, #E81820);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px dashed currentColor;
}
.height-max-note a:hover { color: #B73E12; }

/* ── Installation cards (DIY vs. Pro) ───────────────── */
.install-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.install-card {
  appearance: none;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px 16px 14px;
  border-radius: 14px;
  background: #FFFFFF;
  border: 1.5px solid var(--border, #E5DFD3);
  cursor: pointer;
  font-family: 'Inter', system-ui, sans-serif;
  color: var(--navy, #0A1226);
  transition:
    border-color 140ms ease,
    background   140ms ease,
    transform    140ms ease,
    box-shadow   140ms ease;
}
.install-card:hover {
  border-color: #C4BBA6;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(10, 18, 38, 0.06);
}
.install-card.is-active {
  border-color: var(--orange, #E81820);
  background: #FFF7F2;
  box-shadow: 0 0 0 3px rgba(232, 24, 32, 0.10);
}
.install-card:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.15);
}
.install-card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(10, 18, 38, 0.06);
  color: var(--navy, #0A1226);
  margin-bottom: 4px;
}
.install-card.is-active .install-card-icon {
  background: rgba(232, 24, 32, 0.12);
  color: var(--orange, #E81820);
}
.install-card-title {
  font-weight: 700;
  font-size: 14px;
  letter-spacing: -0.005em;
}
.install-card-desc {
  font-weight: 500;
  font-size: 12px;
  color: var(--ink-muted, #5C6273);
  line-height: 1.4;
}
.install-card-meta {
  margin-top: 4px;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--orange, #E81820);
}
.install-card:not(.is-active) .install-card-meta {
  color: var(--ink-muted, #5C6273);
}

@media (max-width: 640px) {
  .install-cards { grid-template-columns: 1fr; }
}

/* ── Day/Night pill toggle ───────────────────────────────── */

.toggle-block   { align-self: end; }
.estimate-block { align-self: end; }

/* ── Estimate pill (sits next to the Day/Night toggle) ───── */
.estimate {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  min-height: 44px;
  padding: 8px 14px;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 10px;
  background: #FFFFFF;
  line-height: 1.1;
  white-space: nowrap;
}
.estimate-amount {
  font-family: 'Inter', system-ui, sans-serif;
  font-weight: 800;
  font-size: 20px;
  color: var(--navy, #0A1226);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.estimate-meta {
  margin-top: 2px;
  font-family: 'Inter', system-ui, sans-serif;
  font-weight: 500;
  font-size: 11px;
  color: var(--ink-muted, #5C6273);
  letter-spacing: 0.02em;
}
/* Itemized rows injected into the estimate meta line when a priced preset shape
   is present. They stack and span the card width so Channel letters / Shape
   add-on / Estimated total are always visible right under the headline total. */
.estimate-meta-itemized {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  align-self: stretch;
  width: 100%;
  white-space: normal;
}
.estimate-itemized-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  width: 100%;
  min-width: 180px;
  margin-top: 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--navy, #0A1226);
  white-space: nowrap;
}
.estimate-itemized-row > span:last-child { font-variant-numeric: tabular-nums; }
.estimate-itemized-total {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border, #E5DFD3);
  font-weight: 800;
  font-size: 14px;
}
.estimate-itemized-note {
  display: block;
  width: 100%;
  margin-top: 3px;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-muted, #5C6273);
  white-space: nowrap;
}
.estimate-disclaimer {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px dashed rgba(229, 223, 211, 0.9);
  font-family: 'Inter', system-ui, sans-serif;
  font-weight: 500;
  font-style: italic;
  font-size: 10px;
  color: var(--ink-muted, #5C6273);
  opacity: 0.85;
  letter-spacing: 0.01em;
  white-space: normal;
  max-width: 260px;
  text-align: right;
  line-height: 1.35;
}
.estimate.is-quote .estimate-amount {
  color: var(--orange, #E81820);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.mode-toggle {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

.mode-toggle:focus-visible .toggle-pill {
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.12);
}

.toggle-pill {
  position: relative;
  display: inline-grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  width: 132px;
  height: 36px;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition:
    background var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    box-shadow 160ms var(--ease);
  overflow: hidden;
}

.toggle-option {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--ink-muted);
  transition: color var(--dur) var(--ease);
  user-select: none;
}

.toggle-thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: calc(50% - 3px);
  height: calc(100% - 6px);
  background: var(--navy);
  border-radius: 999px;
  z-index: 1;
  transition:
    transform var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

.mode-toggle[aria-checked="false"] .toggle-option-day  { color: var(--cream); }
.mode-toggle[aria-checked="true"]  .toggle-option-night { color: var(--cream); }

.mode-toggle[aria-checked="true"] .toggle-thumb {
  transform: translateX(100%);
}

/* ── Quote callout (custom color selected) ───────────────── */

.quote-callout {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--cream);
  border: 1px solid var(--border);
  border-left: 3px solid var(--orange);
  border-radius: 8px;
  padding: 12px 14px;
}

.quote-callout p {
  margin: 0;
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.5;
  color: var(--navy);
}

.quote-dot {
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: 6px;
  border-radius: 50%;
  background: var(--orange);
}

/* ── Notes ────────────────────────────────────────────────── */

.notes {
  border-top: 1px solid var(--border);
  padding-top: var(--gap-3);
}

.notes p {
  margin: 0;
  max-width: 72ch;
  color: var(--ink-muted);
  font-size: 14px;
  line-height: 1.6;
}

/* ── Responsive ───────────────────────────────────────────── */

/* Below 1100px the swatch grid relaxes its rigid 20-col layout */
@media (max-width: 1100px) {
  .swatch-grid {
    grid-template-columns: repeat(auto-fill, 24px);
  }
}

@media (max-width: 720px) {
  .page {
    padding: var(--gap-4) var(--gap-3) var(--gap-5);
    gap: var(--gap-4);
  }

  .brand-bar {
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 12px;
  }
  .brand-lead { flex: 1 1 auto; }
  .brand-actions { flex: 0 0 auto; }
  .brand-subtitle { display: none; }
  /* Scale the prominent title down a step on narrow screens so the wrapped
     header stays tidy while still reading larger than the old compact pass. */
  .brand-eyebrow,
  .brand-eyebrow strong { font-size: calc(21px * var(--ui-scale)); }
  .brand-eyebrow .muted { font-size: calc(17px * var(--ui-scale)); }

  .controls-row {
    gap: var(--gap-3);
  }
  .controls-row > .control-block { flex: 1 1 100%; }
  .controls-row > .estimate-block { flex: 1 1 100%; }
  .estimate { align-items: flex-start; }
  .estimate-disclaimer { text-align: left; max-width: 100%; }

  .toggle-block   { align-self: stretch; }
  .estimate-block { align-self: stretch; }

  .canvas-wrap { border-radius: 10px; }

  .swatch-grid {
    grid-template-columns: repeat(auto-fill, 22px);
    gap: 7px;
  }

  .swatch {
    width: 22px;
    height: 22px;
  }
}

@media (max-width: 400px) {
  .text-input { font-size: calc(15px * var(--ui-scale)); }
  .toggle-pill { width: 124px; }
}

/* ==========================================================
   Additive: Mounting style picker (sibling of install picker)
   ========================================================== */
.mount-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
@media (max-width: 720px) {
  .mount-cards { grid-template-columns: 1fr; }
}
.mount-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 14px 14px 12px;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 10px;
  background: #fff;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
  font-family: inherit;
  color: inherit;
}
.mount-card:hover { border-color: var(--orange, #E81820); }
.mount-card.is-active {
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232,24,32,0.18);
}
.mount-card-icon {
  display: block;
  width: 100%;
  aspect-ratio: 240 / 130;
  border-radius: 8px;
  overflow: hidden;
  background: #FBF6EC;
  border: 1px solid var(--border, #E5DFD3);
  color: var(--navy, #0A1226);
  margin-bottom: 4px;
}
.mount-card-icon svg {
  display: block;
  width: 100%;
  height: 100%;
}
.mount-card.is-active .mount-card-icon {
  border-color: var(--orange, #E81820);
}
.mount-card-title {
  font-weight: 700;
  font-size: 14px;
  color: var(--navy, #0A1226);
  line-height: 1.2;
}
.mount-card-desc {
  font-size: 12.5px;
  color: var(--ink-muted, #5C6273);
  line-height: 1.4;
}
.mount-card-meta {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--orange, #E81820);
  margin-top: 4px;
}

/* Raceway visual (in-canvas) */
.raceway-group { transition: opacity .25s ease; }
/* The raceway is a free-moving object the customer drags independently of the
   letters. Make the bar + its hardware grabbable (touch-action:none keeps a
   drag from scrolling the page on touch) and hint draggability with a move
   cursor + a subtle hover/active outline. */
.raceway-group:not([hidden]) { cursor: move; touch-action: none; }
.raceway-bar {
  fill: #1F2937;          /* default dark powder-coat */
  stroke: #0A1226;
  stroke-width: 1.5;
  pointer-events: all;
}
.raceway-shadow {
  fill: #050912;
  pointer-events: all;
}
.raceway-screws circle {
  fill: #6B7280;
  stroke: #1F2937;
  stroke-width: 0.8;
  pointer-events: all;
}
.raceway-group:not([hidden]):hover .raceway-bar { stroke: var(--orange, #E8521B); stroke-width: 2; }
.raceway-group.is-dragging .raceway-bar { stroke: var(--orange, #E8521B); stroke-width: 2.5; }
.canvas-wrap[data-mode="night"] .raceway-bar  { fill: #0F141F; stroke: #050912; }
.canvas-wrap[data-mode="night"] .raceway-shadow { fill: #000; opacity: .55; }

/* Logo overlay in canvas */
.logo-overlay-group .logo-shape {
  fill: #FAF7F2;
  stroke: #0A1226;
  stroke-width: 4;
}
.canvas-wrap[data-mode="night"] .logo-overlay-group .logo-shape {
  fill: #1A1F2E;
  stroke: #FAF7F2;
}

/* ── Raceway color sub-picker (Sherwin-Williams powder-coat) ───────── */
.raceway-color-block {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px dashed var(--border, #E5DFD3);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.control-header.sub .control-label {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted, #5C6273);
}
.control-header.sub .control-hint {
  font-size: 12px;
  color: var(--ink-muted, #5C6273);
  display: block;
  margin-top: 2px;
}
.raceway-color-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
  gap: 8px;
}
.raceway-swatch {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  padding: 4px;
  border: 1.5px solid var(--border, #E5DFD3);
  border-radius: 8px;
  background: #FFF;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.raceway-swatch:hover { border-color: var(--orange, #E81820); }
.raceway-swatch.is-active {
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232,24,32,0.18);
}
.raceway-swatch .chip {
  height: 28px;
  border-radius: 4px;
  border: 1px solid rgba(10,18,38,0.10);
}
.raceway-swatch .sw {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--navy, #0A1226);
  text-align: center;
}
.raceway-swatch .nm {
  font-size: 10px;
  color: var(--ink-muted, #5C6273);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.raceway-swatch.custom .chip {
  background: repeating-linear-gradient(45deg, #C9C5BC, #C9C5BC 5px, #E5DFD3 5px, #E5DFD3 10px);
}
.raceway-color-meta {
  font-size: 11px;
  color: var(--ink-muted, #5C6273);
  margin: 0;
  font-style: italic;
}

/* ── Floating quick-controls bar (additive) ──────────────── */
/* Pinned inside the canvas-wrap so height + color + day/night
   stay reachable while designing. Doesn't touch original markup. */
.quick-controls {
  position: relative;
  /* Dock now lives OUTSIDE .canvas-wrap (sibling, not child) so overflow:hidden
     no longer clips it. Pull up slightly into the reserved 64px gap so the
     dock visually anchors to the canvas without overlapping the storefront. */
  margin: -28px auto 12px auto;
  width: max-content;
  max-width: calc(100% - 16px);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 999px;
  background: rgba(10, 18, 38, 0.86);
  color: #FAF7F2;
  backdrop-filter: blur(10px) saturate(1.05);
  -webkit-backdrop-filter: blur(10px) saturate(1.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow:
    0 6px 18px -8px rgba(0, 0, 0, 0.55),
    0 2px 6px -2px rgba(0, 0, 0, 0.35);
  z-index: 5;
  font: 500 13px/1 'Inter', system-ui, sans-serif;
  user-select: none;
  pointer-events: auto;
}
.canvas-wrap[data-mode="night"] .quick-controls {
  background: rgba(15, 20, 31, 0.92);
  border-color: rgba(255, 138, 77, 0.18);
}

.quick-controls .qc-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: inherit;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.quick-controls .qc-item:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.18);
}

.quick-controls .qc-icon {
  font-size: 13px;
  opacity: 0.75;
}
.quick-controls .qc-height {
  padding-right: 12px;
}
.quick-controls .qc-height input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 130px;
  height: 4px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  outline: none;
  cursor: pointer;
}
.quick-controls .qc-height input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #E81820;
  border: 2px solid #FAF7F2;
  cursor: grab;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}
.quick-controls .qc-height input[type="range"]::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #E81820;
  border: 2px solid #FAF7F2;
  cursor: grab;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}
.quick-controls .qc-val {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  min-width: 30px;
  text-align: right;
}

.quick-controls .qc-color-chip {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
  flex: 0 0 18px;
}
.quick-controls .qc-color-name {
  max-width: 110px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.quick-controls .qc-mode-pill {
  position: relative;
  display: inline-block;
  width: 28px;
  height: 16px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
  transition: background 0.2s ease;
}
.quick-controls .qc-mode-pill .qc-mode-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #FAF7F2;
  transition: left 0.2s ease, background 0.2s ease;
}
.quick-controls .qc-mode[data-mode="night"] .qc-mode-pill {
  background: rgba(255, 138, 77, 0.55);
}
.quick-controls .qc-mode[data-mode="night"] .qc-mode-pill .qc-mode-thumb {
  left: 14px;
  background: #FFF5E0;
}

/* ── Scene picker (storefront backdrop chooser) ───────────────── */
.quick-controls .qc-scene {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.quick-controls .qc-scene-thumb {
  width: 22px;
  height: 16px;
  border-radius: 3px;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border: 1px solid rgba(255, 255, 255, 0.20);
  flex-shrink: 0;
}
.quick-controls .qc-scene-label { font: inherit; }

.qc-popover.qc-scene-popover {
  /* Override the default .qc-popover hidden state — this popover positions itself
     via inline styles (fixed + computed left/bottom) so the color-popover transition
     and translateX hooks don't apply. Higher specificity (two classes) needed to
     beat the .qc-popover { opacity:0 } rule that comes later in the file. */
  opacity: 1 !important;
  transform: none !important;
  width: 340px;
  background: #FFFFFF;
  color: #0A1226;
  border-radius: 12px;
  box-shadow:
    0 18px 40px -12px rgba(10, 18, 38, 0.30),
    0 6px 14px -4px rgba(10, 18, 38, 0.18);
  border: 1px solid rgba(10, 18, 38, 0.10);
  padding: 12px;
  width: 340px;
  max-width: calc(100vw - 16px);
}
.qc-scene-popover::after { display: none; content: none; }
.qc-scene-popover .qc-pop-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.qc-scene-popover .qc-pop-title {
  font: 600 13px/1 'Space Grotesk', system-ui, sans-serif;
  letter-spacing: 0.01em;
  color: #0A1226;
}
.qc-scene-popover .qc-pop-close {
  appearance: none;
  background: transparent;
  border: 0;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  font-size: 18px;
  line-height: 1;
  color: #5C6273;
  cursor: pointer;
}
.qc-scene-popover .qc-pop-close:hover { background: rgba(10, 18, 38, 0.06); }
.qc-scene-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.qc-scene-tile {
  appearance: none;
  background: #FAF7F2;
  border: 2px solid transparent;
  border-radius: 10px;
  padding: 0;
  overflow: hidden;
  cursor: pointer;
  text-align: left;
  display: flex;
  flex-direction: column;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.qc-scene-tile:hover { transform: translateY(-1px); border-color: rgba(232, 24, 32, 0.30); }
.qc-scene-tile.is-active { border-color: #E81820; }
.qc-scene-tile-img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border-bottom: 1px solid rgba(10, 18, 38, 0.06);
}
.qc-scene-tile-meta {
  display: flex;
  flex-direction: column;
  padding: 6px 8px 8px;
  gap: 1px;
}
.qc-scene-tile-label {
  font: 600 12px/1.2 'Inter', system-ui, sans-serif;
  color: #0A1226;
}
.qc-scene-tile-desc {
  font: 400 10px/1.3 'Inter', system-ui, sans-serif;
  color: #5C6273;
}

@media (max-width: 640px) {
  .quick-controls {
    gap: 6px;
    padding: 6px 8px;
    bottom: 8px;
  }
  .quick-controls .qc-item {
    padding: 5px 8px;
    font-size: 12px;
  }
  .quick-controls .qc-height input[type="range"] {
    width: 80px;
  }
  .quick-controls .qc-color-name {
    display: none;
  }
}

/* ── Logo overlay drag affordance ─────────────────────────── */
#logoOverlayGroup {
  cursor: grab;
  touch-action: none;
}
#logoOverlayGroup.is-dragging {
  cursor: grabbing;
}
#logoOverlayGroup.is-resizing {
  cursor: nwse-resize;
}
/* Subtle hover halo so the user discovers it's draggable */
#logoOverlayGroup:hover .logo-shape,
#logoOverlayGroup:hover .logo-upload-img {
  filter: drop-shadow(0 0 4px rgba(232, 24, 32, 0.45));
}

/* ── Uploaded-artwork resize handle ───────────────────────── */
/* A grab dot at the artwork's bottom-right corner. Dragging it resizes the
   artwork by upright height (width stays locked to the aspect ratio). */
/* Invisible, enlarged hit target so a real pointer reliably grabs the handle
   rather than the artwork beside it (live QA: corner drags were missing). */
.cl-artwork-handle-hit {
  fill: transparent;
  cursor: nwse-resize;
  pointer-events: all;
}
.cl-artwork-handle {
  fill: var(--signal-orange, #E8521B);
  stroke: var(--cream, #FAF7F2);
  stroke-width: 2;
  cursor: nwse-resize;
  pointer-events: all;
  filter: drop-shadow(0 1px 2px rgba(10, 18, 38, 0.45));
  transition: r var(--dur, 180ms) var(--ease, ease);
}
#logoOverlayGroup:hover .cl-artwork-handle {
  r: 11;
}
/* Lobby typed-text resize handle reuses the Beacon grab-dot visual. Grows on
   hover so it reads as grabbable, same as the upload-mode handle. */
.lobby-resize-handle-group:hover .cl-artwork-handle,
.lobby-resize-handle-group.is-resizing .cl-artwork-handle {
  r: 11;
}
.lobby-resize-handle-group[hidden] { display: none; }
.cl-artwork-handle-glyph {
  fill: none;
  stroke: var(--cream, #FAF7F2);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

/* ── Shape resize handle ─────────────────────────────────────
   A distinct RED grab dot on the additive shape's bottom-right corner.
   Independent of the (orange) letter-height handle so the customer can tell
   them apart and resize the shape without touching letter height. */
.shape-resize-handle-hit {
  fill: transparent;
  cursor: nwse-resize;
  pointer-events: all;
}
.shape-resize-handle {
  fill: #E11D1D;
  stroke: var(--cream, #FAF7F2);
  stroke-width: 2;
  cursor: nwse-resize;
  pointer-events: all;
  filter: drop-shadow(0 1px 2px rgba(10, 18, 38, 0.45));
  transition: r var(--dur, 180ms) var(--ease, ease);
}
.shape-resize-handle-group:hover .shape-resize-handle,
.shape-resize-handle-group.is-resizing .shape-resize-handle {
  r: 11;
}
.shape-resize-handle-group[hidden] { display: none; }
.shape-resize-handle-glyph {
  fill: none;
  stroke: var(--cream, #FAF7F2);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

/* Shape size live readout (height / width / sq ft) under the shape slider. */
.shape-size-block[hidden] { display: none; }
.shape-size-readout {
  display: flex;
  gap: 1.25rem;
  margin: 0.6rem 0 0;
  padding: 0;
}
.shape-size-readout > div { display: flex; flex-direction: column; }
.shape-size-readout dt {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-muted, #5C6273);
  margin: 0;
}
.shape-size-readout dd {
  margin: 0.1rem 0 0;
  font-weight: 600;
  color: var(--navy, #0A1226);
}

/* ── Shape lighting + drag affordance ────────────────────── */
.sign-shape {
  user-select: none;
  transition: fill var(--dur) var(--ease), opacity var(--dur) var(--ease), stroke var(--dur) var(--ease);
}
/* Sandblasted: hide the conventional sign-shape, the wood panel replaces it */
.canvas-wrap[data-style="sandblasted"] .sign-shape { display: none; }
/* Cabinet: hide the sign-shape, the cabinet box replaces it */
.canvas-wrap[data-style="cabinet"] .sign-shape { display: none; }
/* Reverse-halo at night: shape face goes dark like the letters */
.canvas-wrap[data-mode="night"][data-style="halolit"] .sign-shape.face        { fill: var(--night-wall) !important; }
.canvas-wrap[data-mode="night"][data-style="halolit"] .sign-shape.side-return { fill: var(--night-surf) !important; }
.canvas-wrap[data-mode="night"][data-style="frontlit"] .sign-shape.side-return { fill: var(--night-surf) !important; }
.canvas-wrap[data-mode="night"][data-style="duallit"]       .sign-shape.side-return { fill: var(--night-surf) !important; }
/* Trimless: keep side-return visible (front-lit channel letters have depth) */

/* ── Quick controls — color popover ───────────────────────── */
.qc-popover {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  width: 280px;
  max-width: calc(100vw - 32px);
  padding: 12px;
  border-radius: 14px;
  background: rgba(10, 18, 38, 0.96);
  color: #FAF7F2;
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow:
    0 12px 36px -12px rgba(0, 0, 0, 0.55),
    0 4px 12px -4px rgba(0, 0, 0, 0.40);
  backdrop-filter: blur(14px) saturate(1.05);
  -webkit-backdrop-filter: blur(14px) saturate(1.05);
  opacity: 0;
  transition: opacity 0.18s ease, transform 0.18s ease;
  z-index: 6;
}
.qc-popover.is-open {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.qc-popover::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: rgba(10, 18, 38, 0.96);
}
.canvas-wrap[data-mode="night"] .qc-popover {
  background: rgba(15, 20, 31, 0.96);
  border-color: rgba(255, 138, 77, 0.20);
}
.canvas-wrap[data-mode="night"] .qc-popover::after {
  border-top-color: rgba(15, 20, 31, 0.96);
}

.qc-pop-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.qc-pop-title {
  font: 600 12px/1.2 'Inter', system-ui, sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(250, 247, 242, 0.78);
}
.qc-pop-close {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.10);
  color: #FAF7F2;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease;
}
.qc-pop-close:hover { background: rgba(255, 255, 255, 0.20); }

.qc-pop-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin-bottom: 10px;
}
.qc-swatch {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.18);
  background: var(--sw, #888);
  cursor: pointer;
  padding: 0;
  transition: transform 0.12s ease, border-color 0.15s ease, box-shadow 0.15s ease;
  position: relative;
}
.qc-swatch:hover { transform: scale(1.08); border-color: rgba(255, 255, 255, 0.55); }
.qc-swatch.is-active {
  border-color: #E81820;
  box-shadow: 0 0 0 2px rgba(232, 24, 32, 0.35);
}
.qc-swatch.is-custom {
  background: conic-gradient(from 90deg,
    #E81820, #F4D03F, #2ECC71, #3498DB, #9B59B6, #E81820);
}
.qc-swatch.is-custom::after {
  content: "+";
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: #FAF7F2;
  font: 700 14px/1 'Inter', system-ui, sans-serif;
  text-shadow: 0 1px 2px rgba(0,0,0,0.45);
}

.qc-pop-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.qc-pop-name {
  font: 500 13px/1.2 'Inter', system-ui, sans-serif;
  color: #FAF7F2;
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.qc-pop-hex {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: rgba(250, 247, 242, 0.70);
}
.qc-pop-hex-input {
  width: 76px;
  padding: 4px 6px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.06);
  color: #FAF7F2;
  font: 500 12px/1 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.04em;
  outline: none;
}
.qc-pop-hex-input:focus {
  border-color: rgba(232, 24, 32, 0.55);
  background: rgba(255, 255, 255, 0.10);
}

@media (max-width: 640px) {
  .qc-popover {
    width: 240px;
    padding: 10px;
  }
  .qc-pop-grid { grid-template-columns: repeat(6, 1fr); }
}

/* ============================================================
   Per-block drag — each .word-block is a draggable group
   Hovering shows a grab cursor; dragging shows a subtle outline.
   ============================================================ */
.word-block {
  cursor: grab;
  /* Pointer events on the group itself — even the transparent gaps
     between letters won't capture, but text fills will. */
}
.word-block.is-dragging {
  cursor: grabbing;
}
.word-block.is-dragging .face,
.word-block.is-dragging .halo-outer {
  /* faint emphasis on the block being dragged */
  filter: drop-shadow(0 0 6px rgba(232, 24, 32, 0.35));
}
[data-mode="night"] .word-block.is-dragging .face,
[data-mode="night"] .word-block.is-dragging .halo-outer {
  filter: drop-shadow(0 0 8px rgba(255, 138, 77, 0.55));
}

/* ============================================================
   "+ Add Word" button — sits next to the SIGN TEXT label
   ============================================================ */
.add-word-btn {
  appearance: none;
  border: 1px solid #E5DFD3;
  background: #FAF7F2;
  color: #0A1226;
  font: 600 12px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0.02em;
  padding: 6px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease, transform 120ms ease;
  margin-left: auto;
}
.add-word-btn:hover {
  background: #FFFFFF;
  border-color: #E81820;
  color: #E81820;
}
.add-word-btn:active {
  transform: translateY(1px);
}
.add-word-btn:focus-visible {
  outline: 2px solid #E81820;
  outline-offset: 2px;
}

/* ── Hide vertical (height) ruler ───────────────────────────
   Per customer feedback: only the horizontal width ruler should
   be visible, since they only care about total sign length.
   The vertical ruler markup is kept in builder.html in case we
   re-introduce it later, but it is hidden here and the JS that
   updates it short-circuits. */
#measureRuler { display: none !important; }

/* ── Quick-controls: 3-color chip group + responsive stacking ─────────
   Per customer request: Front-Lit and Dual Front+Halo expose three
   color chips (acrylic / return / trim cap) right inside the floating
   "design wizard" so the customer can edit each layer without leaving
   the canvas. On narrow screens the bar wraps to two rows. */
.quick-controls {
  flex-wrap: wrap;
  justify-content: center;
  max-width: calc(100% - 24px);
  row-gap: 6px;
}
.quick-controls .qc-color-group {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.quick-controls .qc-color {
  /* Slightly tighter padding when there are three side-by-side chips. */
  padding-left: 8px;
  padding-right: 10px;
}
.quick-controls .qc-color .qc-color-name {
  max-width: 9ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Mobile / narrow canvas: stack the bar into 2 rows.
   Row 1: height + day/night.  Row 2: color chips. */
@media (max-width: 720px) {
  .quick-controls {
    flex-direction: row;
    flex-wrap: wrap;
    border-radius: 22px;
    padding: 8px 12px;
    gap: 8px 10px;
    width: max-content;
    max-width: calc(100% - 16px);
  }
  /* Row order: height first, then day/night, then color group on its own row */
  .quick-controls .qc-height { order: 1; }
  .quick-controls .qc-mode   { order: 2; }
  .quick-controls .qc-color-group {
    order: 3;
    flex-basis: 100%;
    justify-content: center;
  }
  .quick-controls .qc-color .qc-color-name { max-width: 7ch; }
}

/* Active-popover ring on the chip that opened the popover */
.quick-controls .qc-color.is-open {
  outline: 2px solid #E81820;
  outline-offset: 2px;
}

/* ============================================================
   SANDBLASTED TEMPLATE SYSTEM — v2
   3-path picker, template gallery, custom controls, modals,
   color popover, shape/border pickers.
   Brand palette: navy #0A1226, orange #E81820, cream #FAF7F2
   Cedar accent: #A87649 / #6B3410
   ============================================================ */

/* ── 3-Path Picker ─────────────────────────────────────────── */

.sb-path-picker {
  padding: 0;
}

.sb-path-header {
  margin-bottom: 20px;
}

.sb-path-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.02em;
  color: var(--navy);
  margin: 0 0 6px;
}

.sb-path-sub {
  margin: 0;
  font-size: 14px;
  color: var(--ink-muted);
}

.sb-path-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

@media (max-width: 767px) {
  .sb-path-cards {
    grid-template-columns: 1fr;
  }
}

.sb-path-card {
  appearance: none;
  border: 2px solid var(--border);
  background: #fff;
  border-radius: 14px;
  padding: 20px 18px 18px;
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: border-color 0.18s, box-shadow 0.18s, transform 0.12s;
  position: relative;
}

.sb-path-card:hover {
  border-color: #A87649;
  box-shadow: 0 4px 18px rgba(168, 118, 73, 0.14);
  transform: translateY(-2px);
}

.sb-path-card.is-active {
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.08), 0 4px 18px rgba(10, 18, 38, 0.10);
}

.sb-path-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 10px;
  background: var(--cream);
  margin-bottom: 2px;
}

.sb-path-label {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.01em;
  color: var(--navy);
}

.sb-path-badge {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 8px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
  width: fit-content;
}

.sb-path-badge--free    { background: #E8F5E9; color: #2E7D32; }
.sb-path-badge--paid    { background: #FFF3E0; color: #E65100; }
.sb-path-badge--premium { background: #EDE7F6; color: #4527A0; }

.sb-path-desc {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-muted);
  margin-top: 2px;
}

/* ── Template Gallery ──────────────────────────────────────── */

.sb-gallery-section {
  padding: 0;
}

.sb-gallery-header {
  margin-bottom: 16px;
}

.sb-gallery-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.02em;
  color: var(--navy);
  margin: 0 0 4px;
}

.sb-gallery-hint {
  margin: 0;
  font-size: 13px;
  color: var(--ink-muted);
}

.sb-gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}

@media (max-width: 900px) {
  .sb-gallery-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
  .sb-gallery-grid { grid-template-columns: 1fr; }
}

.sb-tpl-card {
  appearance: none;
  background: #fff;
  border: 2px solid var(--border);
  border-radius: 12px;
  padding: 0;
  cursor: pointer;
  text-align: left;
  transition: border-color 0.18s, box-shadow 0.18s, transform 0.12s;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.sb-tpl-card:hover {
  border-color: #A87649;
  box-shadow: 0 4px 16px rgba(168, 118, 73, 0.16);
  transform: translateY(-2px);
}

.sb-tpl-card.is-active {
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.10);
}

.sb-tpl-thumb {
  width: 100%;
  aspect-ratio: 4/3;
  overflow: hidden;
  background: var(--cream);
}

.sb-tpl-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.sb-tpl-info {
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
}

.sb-tpl-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  color: var(--navy);
  letter-spacing: -0.01em;
}

.sb-tpl-sub {
  font-size: 11px;
  color: var(--ink-muted);
  line-height: 1.4;
}

.sb-tpl-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 4px;
}

.sb-tpl-tag {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--cream);
  border: 1px solid var(--border);
  font-size: 10px;
  color: var(--ink-muted);
  text-transform: lowercase;
}

/* ── Sandblasted Controls ──────────────────────────────────── */

.sb-controls {
  display: flex;
  flex-direction: column;
  gap: 24px;
  border-top: 1px solid var(--border);
  padding-top: 24px;
  margin-top: 8px;
}

.sb-controls-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  align-items: start;
}

/* Shape picker */
.sb-shape-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.sb-shape-card,
.sb-border-card {
  appearance: none;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  padding: 8px 4px 5px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-muted);
  transition: border-color 0.15s, background 0.15s;
}

.sb-shape-card:hover,
.sb-border-card:hover {
  border-color: #A87649;
  color: #6B3410;
}

.sb-shape-card.is-active,
.sb-border-card.is-active {
  border-color: var(--navy);
  background: rgba(10, 18, 38, 0.04);
  color: var(--navy);
  font-weight: 700;
}

.sb-shape-card svg,
.sb-border-card svg {
  color: currentColor;
}

/* Border picker */
.sb-border-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

/* Segmented controls (Material, Sides) */
.sb-seg {
  display: flex;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  width: fit-content;
}

.sb-seg-btn {
  appearance: none;
  background: #fff;
  border: none;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  border-right: 1px solid var(--border);
}

.sb-seg-btn:last-child { border-right: none; }

.sb-seg-btn.is-active {
  background: var(--navy);
  color: #fff;
  font-weight: 700;
}

/* Depth hint */
.sb-depth-hint {
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--ink-muted);
}

/* Text lines */
.sb-lines-block {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.sb-line-row {
  display: grid;
  grid-template-columns: 72px 1fr 130px 36px;
  gap: 8px;
  align-items: center;
}

@media (max-width: 640px) {
  .sb-line-row {
    grid-template-columns: 72px 1fr;
    grid-template-rows: auto auto;
  }
  .sb-font-select { grid-column: 1; }
  .sb-color-btn   { grid-column: 2; justify-self: start; }
}

.sb-line-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.sb-line-text {
  /* inherits .text-input */
}

.sb-font-select {
  appearance: none;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24'%3E%3Cpath fill='%235C6273' d='M7 10l5 5 5-5z'/%3E%3C/svg%3E") no-repeat right 8px center;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  padding: 8px 28px 8px 10px;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--navy);
  cursor: pointer;
}

.sb-color-btn {
  appearance: none;
  border: 1.5px solid var(--border);
  background: #fff;
  border-radius: 8px;
  width: 36px;
  height: 36px;
  padding: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.15s;
}

.sb-color-btn:hover { border-color: var(--navy); }

.sb-color-chip {
  display: block;
  width: 22px;
  height: 22px;
  border-radius: 4px;
  border: 1px solid rgba(0,0,0,0.12);
}

.sb-color-count {
  font-size: 12px;
  color: var(--orange);
  font-weight: 600;
  margin: 4px 0 0;
}

/* ── 1 Shot Color Popover ──────────────────────────────────── */

.sb-color-popover {
  position: absolute;
  z-index: 1000;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 40px rgba(10, 18, 38, 0.18);
  padding: 12px;
  max-width: 300px;
  max-height: 360px;
  overflow-y: auto;
}

.sb-color-popover-inner {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sb-color-family {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.sb-color-family-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.sb-color-swatch-row {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.sb-color-swatch {
  appearance: none;
  border: 1.5px solid transparent;
  border-radius: 4px;
  width: 22px;
  height: 22px;
  cursor: pointer;
  padding: 0;
  transition: border-color 0.12s, transform 0.10s;
}

.sb-color-swatch:hover { transform: scale(1.2); border-color: var(--navy); }
.sb-color-swatch.is-active { border-color: var(--navy); box-shadow: 0 0 0 2px rgba(10,18,38,0.25); }

/* ── Modals ─────────────────────────────────────────────────── */

.sb-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 900;
  background: rgba(10, 18, 38, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  backdrop-filter: blur(3px);
}

.sb-modal {
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 24px 80px rgba(10, 18, 38, 0.25);
  padding: 32px;
  max-width: 640px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  position: relative;
}

.sb-modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  appearance: none;
  background: var(--cream);
  border: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
}

.sb-modal-close:hover { background: var(--border); }

.sb-modal-header {
  margin-bottom: 24px;
  padding-right: 32px;
}

.sb-modal-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: -0.02em;
  color: var(--navy);
  margin: 0 0 6px;
}

.sb-modal-sub {
  font-size: 14px;
  color: var(--ink-muted);
  margin: 0;
  line-height: 1.55;
}

/* AI Modal form */
.ai-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 20px;
}

@media (max-width: 540px) {
  .ai-form-grid { grid-template-columns: 1fr; }
}

.ai-form-field--full {
  grid-column: 1 / -1;
}

.ai-form-label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 5px;
}

.ai-required {
  color: var(--orange);
}

.ai-textarea {
  width: 100%;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--navy);
  line-height: 1.55;
  resize: vertical;
  transition: border-color 0.15s;
}

.ai-textarea:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.06);
}

.ai-select {
  width: 100%;
  padding: 9px 28px 9px 10px;
}

.ai-generate-btn {
  width: 100%;
  font-size: 15px;
}

/* AI Step 2 */
.ai-preview-wrap {
  margin-bottom: 16px;
}

.ai-preview-img-wrap {
  width: 100%;
  aspect-ratio: 16/9;
  border-radius: 10px;
  overflow: hidden;
  background: var(--cream);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.ai-preview-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.ai-preview-spinner {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: var(--cream);
  font-size: 13px;
  color: var(--ink-muted);
}

.ai-spinner-ring {
  width: 36px;
  height: 36px;
  border: 3px solid var(--border);
  border-top-color: var(--orange);
  border-radius: 50%;
  animation: spinRing 0.8s linear infinite;
}

@keyframes spinRing {
  to { transform: rotate(360deg); }
}

.ai-step2-actions {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.ai-regen-btn {
  appearance: none;
  border: 1.5px solid var(--border);
  background: #fff;
  border-radius: 9px;
  padding: 10px 16px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--navy);
  cursor: pointer;
  transition: border-color 0.15s;
}
.ai-regen-btn:hover:not(:disabled) { border-color: var(--navy); }
.ai-regen-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.ai-use-btn { flex: 1; }

.ai-back-btn {
  appearance: none;
  background: none;
  border: none;
  font-size: 13px;
  color: var(--ink-muted);
  cursor: pointer;
  text-decoration: underline;
  padding: 10px 0;
}

.ai-regen-upsell {
  margin-top: 10px;
  font-size: 13px;
  color: var(--ink-muted);
}

.ai-upsell-btn {
  appearance: none;
  background: none;
  border: none;
  color: var(--orange);
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
  text-decoration: underline;
}

/* Custom $99 modal form */
.custom-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 20px;
}

@media (max-width: 540px) {
  .custom-form-grid { grid-template-columns: 1fr; }
}

.custom-form-field--full {
  grid-column: 1 / -1;
}

.custom-submit-btn {
  width: 100%;
  font-size: 15px;
}

.custom-submit-note {
  font-size: 12px;
  color: var(--ink-muted);
  text-align: center;
  margin: 10px 0 0;
}

/* sb-field-error */
.sb-field-error {
  border-color: #D32F2F !important;
  box-shadow: 0 0 0 2px rgba(211, 47, 47, 0.15) !important;
}

/* ── Canvas: studio-white override for sandblasted mode ─────── */
/* (JS toggles .wall-bricks opacity and .wall-bg fill directly) */

/* Hide channel-letter-only controls when sandblasted is active.
   The actual toggling is done by JS setting display:none, but we add
   class-based hiding as a fallback.  */
.is-sandblasted .channel-only { display: none !important; }

/* Sandblasted estimate box */
#sbEstimate {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 20px;
  background: #fff;
}

/* ── Responsive tweaks for sb-controls-row ──────────────────── */
@media (max-width: 640px) {
  .sb-controls-row {
    grid-template-columns: 1fr;
  }
  .sb-shape-grid {
    grid-template-columns: repeat(3, 1fr);
  }
  .sb-border-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}


/* ═══════════════════════════════════════════════════════════════
   SANDBLASTED v3 — Questionnaire-First Lead-Gen Flow
   All classes prefixed with sbv3- to avoid any collision with
   existing channel-letter or v2 sandblasted styles.
   ═══════════════════════════════════════════════════════════════ */

/* ── Shell ──────────────────────────────────────────────────── */
.sbv3-shell {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* ── Steps (each step is individually shown/hidden) ─────────── */
.sbv3-step {
  animation: sbv3FadeIn 280ms var(--ease) both;
}
@keyframes sbv3FadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Buttons ─────────────────────────────────────────────────── */
.sbv3-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 28px;
  border-radius: 10px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  cursor: pointer;
  border: 2px solid transparent;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
  text-decoration: none;
  white-space: nowrap;
}
.sbv3-btn:disabled {
  opacity: 0.48;
  cursor: not-allowed;
  pointer-events: none;
}
.sbv3-btn--primary {
  background: var(--orange);
  color: #fff;
  border-color: var(--orange);
}
.sbv3-btn--primary:hover {
  background: #c93f0f;
  border-color: #c93f0f;
  box-shadow: 0 4px 16px rgba(232,24,32,0.30);
  transform: translateY(-1px);
}
.sbv3-btn--primary:active { transform: translateY(0); }
.sbv3-btn--secondary {
  background: var(--navy);
  color: #fff;
  border-color: var(--navy);
}
.sbv3-btn--secondary:hover {
  background: #1e2e55;
  border-color: #1e2e55;
  transform: translateY(-1px);
}
.sbv3-btn--ghost {
  background: transparent;
  color: var(--navy);
  border-color: var(--border);
}
.sbv3-btn--ghost:hover {
  background: rgba(10,18,38,0.06);
  border-color: #c5c0b8;
}
.sbv3-btn--sm {
  padding: 8px 16px;
  font-size: 13px;
}

/* ── Progress bar ────────────────────────────────────────────── */
.sbv3-progress-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0 4px;
}
.sbv3-progress-track {
  flex: 1;
  height: 6px;
  background: var(--border);
  border-radius: 9999px;
  overflow: hidden;
}
.sbv3-progress-fill {
  height: 100%;
  background: var(--orange);
  border-radius: 9999px;
  transition: width 400ms var(--ease);
}
.sbv3-progress-label {
  font-size: 12px;
  color: var(--ink-muted);
  white-space: nowrap;
  min-width: 80px;
  text-align: right;
}

/* ── Landing ─────────────────────────────────────────────────── */
.sbv3-landing {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  align-items: center;
  padding: 40px 0;
}
@media (max-width: 720px) {
  .sbv3-landing { grid-template-columns: 1fr; gap: 32px; }
}
.sbv3-landing-badge {
  display: inline-block;
  background: rgba(168,118,73,0.12);
  color: #7a4c20;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 12px;
  border-radius: 9999px;
  margin-bottom: 16px;
}
.sbv3-landing-headline {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1rem + 3vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--navy);
  line-height: 1.1;
  margin-bottom: 16px;
}
.sbv3-landing-body {
  font-size: 16px;
  color: var(--ink-muted);
  line-height: 1.65;
  margin-bottom: 24px;
  max-width: 46ch;
}
.sbv3-landing-features {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 32px;
}
.sbv3-feature {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--navy);
}
.sbv3-feature svg { color: #437a22; flex-shrink: 0; }
.sbv3-landing-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}
.sbv3-landing-slogan {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-muted);
  letter-spacing: -0.01em;
}
.sbv3-landing-slogan em {
  font-style: italic;
  color: var(--orange);
  font-weight: 700;
}
.sbv3-landing-imgs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto;
  gap: 10px;
  align-items: stretch;
}
.sbv3-landing-img {
  width: 100%;
  border-radius: 10px;
  object-fit: cover;
  aspect-ratio: 4/3;
  box-shadow: 0 8px 24px rgba(10,18,38,0.13);
}
.sbv3-landing-img--1 { grid-column: 1 / 3; grid-row: 1; aspect-ratio: 16/9; }
.sbv3-landing-img--2 { grid-column: 3;     grid-row: 1; aspect-ratio: 4/5; }
.sbv3-landing-img--3 { grid-column: 1 / 4; grid-row: 2; aspect-ratio: 21/7; }

/* ── Questionnaire ───────────────────────────────────────────── */
.sbv3-questionnaire {
  padding: 8px 0 100px;
}
.sbv3-q-header {
  margin-bottom: 28px;
}
.sbv3-q-title {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 1rem + 1.5vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--navy);
  margin-bottom: 6px;
}
.sbv3-q-sub {
  color: var(--ink-muted);
  font-size: 14px;
}

/* Section accordion */
.sbv3-q-section {
  border: 1px solid var(--border);
  border-radius: 12px;
  margin-bottom: 12px;
  overflow: hidden;
  background: #fff;
}
.sbv3-q-sec-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 20px;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  transition: background var(--dur-fast) var(--ease);
  user-select: none;
}
.sbv3-q-sec-toggle:hover { background: rgba(10,18,38,0.03); }
.sbv3-q-sec-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--navy);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
}
.sbv3-q-sec-title {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--navy);
  flex: 1;
}
.sbv3-q-sec-req,
.sbv3-q-sec-opt {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 9999px;
}
.sbv3-q-sec-req {
  background: rgba(232,24,32,0.10);
  color: #c93f0f;
}
.sbv3-q-sec-opt {
  background: rgba(10,18,38,0.07);
  color: var(--ink-muted);
}
.sbv3-q-sec-check {
  font-size: 14px;
  color: #437a22;
  font-weight: 700;
  min-width: 16px;
}
.sbv3-q-sec-toggle[aria-expanded="true"] .sbv3-q-sec-chevron {
  transform: rotate(180deg);
}
.sbv3-q-sec-chevron {
  color: var(--ink-muted);
  transition: transform 200ms var(--ease);
  flex-shrink: 0;
}

.sbv3-q-sec-body {
  padding: 8px 20px 24px;
  border-top: 1px solid var(--border);
}
.sbv3-q-sec-body[hidden] { display: none !important; }

/* ── Form grid & fields ───────────────────────────────────────── */
.sbv3-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
@media (max-width: 580px) {
  .sbv3-form-grid { grid-template-columns: 1fr; }
}
.sbv3-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.sbv3-field--full { grid-column: 1 / -1; }
.sbv3-field label {
  font-size: 13px;
  font-weight: 600;
  color: var(--navy);
  letter-spacing: 0.01em;
}
.sbv3-field-hint {
  font-weight: 400;
  color: var(--ink-muted);
}
.sbv3-req { color: var(--orange); }
.sbv3-field input[type="text"],
.sbv3-field input[type="email"],
.sbv3-field input[type="tel"],
.sbv3-field input[type="number"],
.sbv3-field input[type="date"],
.sbv3-field select,
.sbv3-field textarea {
  width: 100%;
  padding: 11px 14px;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--navy);
  background: #fff;
  transition: border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
  appearance: auto;
}
.sbv3-field input:focus,
.sbv3-field select:focus,
.sbv3-field textarea:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(10,18,38,0.10);
}
.sbv3-field input.sbv3-input-error,
.sbv3-field select.sbv3-input-error {
  border-color: #c93f0f;
  box-shadow: 0 0 0 3px rgba(232,24,32,0.15);
}
.sbv3-field textarea { resize: vertical; min-height: 90px; }
.sbv3-field input[type="file"] {
  padding: 8px;
  font-size: 13px;
}

/* Radio rows */
.sbv3-radio-row {
  display: flex;
  gap: 20px;
  padding: 8px 0;
}
.sbv3-radio-label {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 14px;
  cursor: pointer;
  user-select: none;
}
.sbv3-radio-label input[type="radio"] {
  width: 16px;
  height: 16px;
  accent-color: var(--orange);
}

/* Checkbox group */
.sbv3-check-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.sbv3-check-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  cursor: pointer;
  padding: 7px 14px;
  border: 1.5px solid var(--border);
  border-radius: 9999px;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
  user-select: none;
}
.sbv3-check-label:has(input:checked) {
  background: rgba(232,24,32,0.08);
  border-color: var(--orange);
  color: var(--orange);
  font-weight: 600;
}
.sbv3-check-label input[type="checkbox"] {
  width: 14px;
  height: 14px;
  accent-color: var(--orange);
}

/* 1 Shot color families */
.sbv3-color-families {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.sbv3-color-family-group {}
.sbv3-color-family-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--ink-muted);
  margin-bottom: 6px;
  display: block;
}
.sbv3-color-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.sbv3-color-swatch-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2.5px solid transparent;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
  position: relative;
  background: none;
  padding: 0;
}
.sbv3-color-swatch-btn:hover {
  transform: scale(1.15);
  box-shadow: 0 2px 8px rgba(10,18,38,0.18);
}
.sbv3-color-swatch-btn.is-selected {
  border-color: var(--navy);
  box-shadow: 0 0 0 2px var(--navy);
  transform: scale(1.15);
}
.sbv3-color-swatch-btn[title] { cursor: pointer; }

/* Questionnaire footer */
.sbv3-q-footer {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  background: rgba(250,247,242,0.96);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--border);
  margin-top: 24px;
  border-radius: 0 0 12px 12px;
  gap: 12px;
  z-index: 10;
}
.sbv3-q-footer-right {
  display: flex;
  align-items: center;
  gap: 12px;
}
.sbv3-q-validation-msg {
  font-size: 13px;
  color: #c93f0f;
  font-weight: 500;
}

/* ── Path Picker ─────────────────────────────────────────────── */
.sbv3-path-picker {
  padding: 8px 0 32px;
}
.sbv3-pp-header {
  text-align: center;
  margin-bottom: 36px;
}
.sbv3-pp-title {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 1rem + 2vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--navy);
  margin-bottom: 8px;
}
.sbv3-pp-sub { color: var(--ink-muted); font-size: 15px; }

.sbv3-pp-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
@media (max-width: 800px) {
  .sbv3-pp-cards { grid-template-columns: 1fr; }
}

/* 3-path cards — large, photographic feel, hover lift */
.sbv3-pp-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 32px 28px 28px;
  background: #fff;
  border: 2px solid var(--border);
  border-radius: 16px;
  cursor: pointer;
  text-align: left;
  transition: border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
  gap: 16px;
}
.sbv3-pp-card:hover {
  border-color: var(--navy);
  box-shadow: 0 16px 48px rgba(10,18,38,0.13);
  transform: translateY(-4px);
}
.sbv3-pp-card--featured {
  border-color: var(--orange);
  background: linear-gradient(145deg, #fff 70%, rgba(232,24,32,0.04));
}
.sbv3-pp-card--featured:hover {
  border-color: #c93f0f;
  box-shadow: 0 16px 48px rgba(232,24,32,0.20);
}

/* Price chip — top right corner */
.sbv3-pp-price-chip {
  position: absolute;
  top: 16px;
  right: 16px;
  background: var(--navy);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 4px 10px;
  border-radius: 9999px;
  text-transform: uppercase;
}
.sbv3-pp-price-chip--paid { background: var(--orange); }
.sbv3-pp-price-chip--premium { background: #5a3490; }

.sbv3-pp-icon {
  color: var(--navy);
  margin-bottom: 4px;
}
.sbv3-pp-card--featured .sbv3-pp-icon { color: var(--orange); }

.sbv3-pp-card-body { flex: 1; }
.sbv3-pp-card-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--navy);
  margin-bottom: 10px;
}
.sbv3-pp-card-desc {
  font-size: 14px;
  color: var(--ink-muted);
  line-height: 1.6;
  margin-bottom: 20px;
  max-width: 30ch;
}
.sbv3-pp-card-cta {
  display: inline-block;
  font-size: 13px;
  font-weight: 700;
  color: var(--navy);
  letter-spacing: 0.01em;
  border-bottom: 2px solid currentColor;
  padding-bottom: 1px;
  transition: color var(--dur-fast) var(--ease);
}
.sbv3-pp-card--featured .sbv3-pp-card-cta { color: var(--orange); }
.sbv3-pp-card:hover .sbv3-pp-card-cta { color: var(--orange); }

.sbv3-pp-footer {
  display: flex;
  justify-content: flex-start;
  padding-top: 24px;
}

/* ── Path screen shared ──────────────────────────────────────── */
.sbv3-path-header {
  padding: 8px 0 28px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 32px;
}
.sbv3-back-inline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-muted);
  background: none;
  border: none;
  cursor: pointer;
  margin-bottom: 16px;
  padding: 0;
  transition: color var(--dur-fast) var(--ease);
}
.sbv3-back-inline:hover { color: var(--navy); }
.sbv3-path-title {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 1rem + 1.5vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--navy);
  margin-bottom: 8px;
}
.sbv3-path-sub {
  font-size: 15px;
  color: var(--ink-muted);
  max-width: 62ch;
}
.sbv3-path-footer {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding-top: 32px;
  border-top: 1px solid var(--border);
  margin-top: 32px;
}
.sbv3-path-footer-note {
  font-size: 12px;
  color: var(--ink-muted);
}

/* ── Upload path ─────────────────────────────────────────────── */
.sbv3-upload-zone {
  border: 2.5px dashed var(--border);
  border-radius: 14px;
  padding: 40px 24px;
  text-align: center;
  background: rgba(250,247,242,0.6);
  transition: border-color var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease);
  position: relative;
}
.sbv3-upload-zone.is-dragover {
  border-color: var(--orange);
  background: rgba(232,24,32,0.05);
}
.sbv3-upload-input {
  position: absolute;
  inset: 0;
  opacity: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
  z-index: 1;
}
.sbv3-upload-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  color: var(--ink-muted);
  pointer-events: none;
}
.sbv3-upload-text { font-size: 16px; color: var(--navy); font-weight: 500; }
.sbv3-upload-link { color: var(--orange); text-decoration: underline; font-weight: 700; }
.sbv3-upload-hint { font-size: 12px; color: var(--ink-muted); }
.sbv3-upload-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 600;
  color: #437a22;
  margin-top: 12px;
  padding: 10px 16px;
  background: rgba(67,122,34,0.08);
  border-radius: 8px;
}
.sbv3-upload-clear {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--ink-muted);
  font-size: 14px;
  line-height: 1;
  padding: 2px 4px;
  margin-left: 4px;
}
.sbv3-upload-clear:hover { color: #c93f0f; }

/* ── AI Designer path ────────────────────────────────────────── */
.sbv3-gallery { margin-bottom: 32px; }
.sbv3-gallery-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  color: var(--navy);
  margin-bottom: 16px;
}
.sbv3-gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
@media (max-width: 700px) {
  .sbv3-gallery-grid { grid-template-columns: repeat(2, 1fr); }
}
.sbv3-gallery-card {
  border: 2.5px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
  background: #fff;
}
.sbv3-gallery-card:hover {
  border-color: var(--navy);
  box-shadow: 0 8px 24px rgba(10,18,38,0.12);
  transform: translateY(-2px);
}
.sbv3-gallery-card.is-selected {
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(232,24,32,0.20);
}
.sbv3-gallery-card img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  display: block;
}
.sbv3-gallery-card-label {
  padding: 8px 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--navy);
  text-align: center;
  background: #fff;
}

/* Advanced details */
.sbv3-advanced {
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 24px;
  overflow: hidden;
}
.sbv3-advanced-toggle {
  padding: 14px 18px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  color: var(--navy);
  cursor: pointer;
  user-select: none;
  list-style: none;
}
.sbv3-advanced-toggle::-webkit-details-marker { display: none; }
.sbv3-advanced-body {
  padding: 16px 18px 20px;
  border-top: 1px solid var(--border);
}
.sbv3-advanced-note {
  font-size: 13px;
  color: var(--ink-muted);
  margin-bottom: 16px;
}

/* AI preview area */
.sbv3-ai-preview {
  border: 1.5px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  background: rgba(250,247,242,0.5);
  min-height: 280px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin-bottom: 24px;
  position: relative;
}
.sbv3-ai-preview-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 48px 24px;
  color: var(--ink-muted);
  text-align: center;
}
.sbv3-ai-preview-placeholder p { font-size: 14px; max-width: 28ch; }
.sbv3-ai-spinner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 48px 24px;
  color: var(--ink-muted);
  font-size: 14px;
}
.sbv3-spinner-ring {
  width: 40px;
  height: 40px;
  border: 3px solid var(--border);
  border-top-color: var(--orange);
  border-radius: 50%;
  animation: sbv3Spin 0.7s linear infinite;
}
@keyframes sbv3Spin { to { transform: rotate(360deg); } }
.sbv3-ai-image {
  width: 100%;
  max-height: 420px;
  object-fit: contain;
  display: block;
  padding: 16px;
}
.sbv3-ai-regen-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  width: 100%;
  background: #fff;
}
.sbv3-regen-count { font-size: 13px; color: var(--ink-muted); }
.sbv3-regen-count strong { color: var(--navy); }

/* ── Custom $99 path ─────────────────────────────────────────── */
.sbv3-custom-summary {
  background: rgba(10,18,38,0.04);
  border-radius: 12px;
  padding: 20px 24px;
  margin-bottom: 24px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 24px;
}
@media (max-width: 580px) { .sbv3-custom-summary { grid-template-columns: 1fr; } }
.sbv3-summary-row { display: flex; flex-direction: column; gap: 2px; }
.sbv3-summary-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-muted); }
.sbv3-summary-val { font-size: 15px; font-weight: 600; color: var(--navy); }

.sbv3-custom-includes {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px 24px;
  background: #fff;
  margin-bottom: 8px;
}
.sbv3-custom-includes-title {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--navy);
  margin-bottom: 12px;
}
.sbv3-includes-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sbv3-includes-list li {
  font-size: 14px;
  color: var(--ink-muted);
  padding-left: 20px;
  position: relative;
}
.sbv3-includes-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 7px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--orange);
}

/* ── Thank-you screens ───────────────────────────────────────── */
.sbv3-thankyou {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 48px 24px 64px;
  gap: 20px;
}
.sbv3-ty-icon {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #fff;
}
.sbv3-ty-icon--upload  { background: #437a22; }
.sbv3-ty-icon--ai      { background: var(--orange); }
.sbv3-ty-icon--custom  { background: #5a3490; }
.sbv3-ty-title {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 1rem + 2vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--navy);
  margin: 0;
}
.sbv3-ty-body {
  font-size: 16px;
  color: var(--ink-muted);
  max-width: 50ch;
  line-height: 1.65;
}
.sbv3-ty-summary {
  width: 100%;
  max-width: 480px;
  background: rgba(10,18,38,0.04);
  border-radius: 12px;
  padding: 20px 24px;
  text-align: left;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 20px;
}
@media (max-width: 480px) { .sbv3-ty-summary { grid-template-columns: 1fr; } }
.sbv3-ty-booking {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.sbv3-ty-booking p { font-size: 15px; color: var(--navy); font-weight: 600; margin: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   SANDBLASTED v4 — Material Education + Pricing Engine Styles
   All selectors prefixed sbv3-mat-edu-, sbv3-color-count-, sbv3-price-
══════════════════════════════════════════════════════════════════════════════ */

/* ── Material Education Section ───────────────────────────────────────── */
.sbv3-material-edu {
  padding: 16px 0 40px;
}
.sbv3-mat-edu-header {
  text-align: center;
  margin-bottom: 36px;
}
.sbv3-mat-edu-title {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 1rem + 2vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--navy);
  margin-bottom: 10px;
}
.sbv3-mat-edu-sub {
  font-size: 16px;
  color: var(--ink-muted);
  max-width: 52ch;
  margin: 0 auto;
  line-height: 1.6;
}

.sbv3-mat-edu-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-bottom: 36px;
}
@media (max-width: 720px) {
  .sbv3-mat-edu-cards { grid-template-columns: 1fr; }
}

.sbv3-mat-edu-card {
  background: #fff;
  border: 1.5px solid rgba(10,18,38,0.09);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 4px 18px rgba(10,18,38,0.08);
  display: flex;
  flex-direction: column;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.sbv3-mat-edu-card:hover {
  box-shadow: 0 8px 32px rgba(10,18,38,0.14);
  transform: translateY(-2px);
}

.sbv3-mat-edu-img-wrap {
  width: 100%;
  aspect-ratio: 16/9;
  overflow: hidden;
  flex-shrink: 0;
}
.sbv3-mat-edu-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.35s ease;
}
.sbv3-mat-edu-card:hover .sbv3-mat-edu-img {
  transform: scale(1.03);
}

.sbv3-mat-edu-card-body {
  padding: 24px;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.sbv3-mat-edu-card-title {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--navy);
  margin-bottom: 14px;
}
.sbv3-mat-edu-bullets {
  list-style: none;
  padding: 0;
  margin: 0 0 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sbv3-mat-edu-bullets li {
  font-size: 14px;
  color: var(--navy);
  padding-left: 18px;
  position: relative;
  line-height: 1.5;
}
.sbv3-mat-edu-bullets li::before {
  content: '✓';
  position: absolute;
  left: 0;
  color: #437a22;
  font-weight: 700;
  font-size: 12px;
  top: 1px;
}
.sbv3-mat-edu-footer {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-top: 1px solid rgba(10,18,38,0.08);
  padding-top: 12px;
  margin-top: auto;
  margin-bottom: 0;
}
.sbv3-mat-edu-spec-link {
  display: inline-block;
  margin-top: 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--orange);
  text-decoration: none;
  letter-spacing: -0.01em;
  transition: opacity 0.15s;
}
.sbv3-mat-edu-spec-link:hover { opacity: 0.75; text-decoration: underline; }

.sbv3-mat-edu-cta {
  display: flex;
  justify-content: center;
}

/* ── Thickness note helper ────────────────────────────────────────────── */
.sbv3-thickness-note {
  margin-top: 6px;
  font-size: 12px;
  color: var(--ink-muted);
  line-height: 1.5;
}

/* ── Color Count Picker ───────────────────────────────────────────────── */
.sbv3-color-count-picker {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.sbv3-color-count-btn {
  min-width: 44px;
  height: 40px;
  padding: 0 14px;
  border: 1.5px solid rgba(10,18,38,0.18);
  border-radius: 8px;
  background: #fff;
  color: var(--navy);
  font-size: 15px;
  font-weight: 600;
  font-family: var(--font-body);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  line-height: 1;
}
.sbv3-color-count-btn:hover {
  border-color: var(--orange);
  background: rgba(232,24,32,0.06);
}
.sbv3-color-count-btn--active,
.sbv3-color-count-btn[aria-pressed="true"] {
  background: var(--navy);
  border-color: var(--navy);
  color: #fff;
}

/* ── Questionnaire 2-col grid (form + sticky aside) ─────────────────────── */
.sbv3-q-grid {
  display: block;
}
@media (min-width: 900px) {
  .sbv3-q-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 28px;
    align-items: start;
  }
}
.sbv3-q-aside {
  margin-top: 20px;
}
@media (min-width: 900px) {
  .sbv3-q-aside {
    margin-top: 0;
    position: sticky;
    top: 24px;
  }
}

/* ── Live Price Card ──────────────────────────────────────────────────── */
.sbv3-price-card {
  background: #fff;
  border: 1.5px solid rgba(10,18,38,0.12);
  border-radius: 14px;
  padding: 20px 22px;
  margin: 20px 0 0;
  box-shadow: 0 4px 20px rgba(10,18,38,0.09);
  position: relative;
}
@media (min-width: 900px) {
  .sbv3-price-card {
    position: sticky;
    top: 24px;
    width: 100%;
    z-index: 10;
    margin: 0;
  }
}
@media (max-width: 899px) {
  .sbv3-price-card {
    position: sticky;
    bottom: 72px;
    z-index: 10;
    margin: 12px -2px 0;
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -4px 20px rgba(10,18,38,0.12);
  }
}
.sbv3-price-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.sbv3-price-card-title {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
}
.sbv3-price-card-badge {
  font-size: 11px;
  font-weight: 700;
  padding: 2px 9px;
  border-radius: 9999px;
  background: rgba(168,118,73,0.13);
  color: #7a4c20;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  empty-cells: show;
}
.sbv3-price-card-total {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 1.2rem + 1.5vw, 2.2rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  color: var(--navy);
  margin-bottom: 12px;
  line-height: 1;
}
.sbv3-price-card-breakdown {
  font-size: 12.5px;
  color: var(--ink-muted);
  line-height: 1.7;
  margin-bottom: 12px;
  min-height: 0;
}
.sbv3-price-card-breakdown-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.sbv3-price-card-breakdown-row .label { flex: 1; }
.sbv3-price-card-breakdown-row .amt { font-weight: 600; color: var(--navy); white-space: nowrap; }
.sbv3-price-card-note {
  font-size: 11px;
  color: var(--ink-muted);
  line-height: 1.5;
  margin: 0;
  border-top: 1px solid rgba(10,18,38,0.08);
  padding-top: 10px;
}

/* ── Path estimate display (AI designer + Custom paths) ───────────────── */
.sbv3-path-estimate {
  display: inline-block;
  margin-top: 8px;
  padding: 5px 14px;
  background: rgba(168,118,73,0.10);
  border-radius: 20px;
  font-size: 13px;
  font-weight: 600;
  color: #7a4c20;
  letter-spacing: -0.01em;
  min-height: 0;
}
.sbv3-path-estimate:empty { display: none; }

/* ==========================================================
   Product type picker (Channel / Cabinet / Sandblasted)
   ========================================================== */
.product-block .product-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
@media (max-width: 720px) {
  .product-block .product-cards { grid-template-columns: 1fr; }
}
.product-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 14px 14px 12px;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 10px;
  background: #fff;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  color: inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.product-card:hover { border-color: var(--orange, #E81820); }
.product-card.is-active {
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232,24,32,0.18);
}
.product-card[disabled],
.product-card[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}
.product-card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  border-radius: 8px;
  background: #FAF7F2;
  color: var(--navy, #0A1226);
}
.product-card.is-active .product-card-icon {
  background: #FFEEE3;
  color: var(--orange, #E81820);
}
.product-card-title {
  font-weight: 700;
  font-size: 14px;
  color: var(--navy, #0A1226);
  line-height: 1.2;
}
.product-card-desc {
  font-size: 12.5px;
  color: var(--ink-muted, #5C6273);
  line-height: 1.4;
}
.product-card-desc em {
  font-style: italic;
  color: var(--orange, #E81820);
}

/* ==========================================================
   Cabinet field set
   ========================================================== */
.cab-size-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.cab-size-field {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 6px;
  padding: 10px 12px;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 8px;
  background: #fff;
}
.cab-size-label {
  grid-column: 1 / -1;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--ink-muted, #5C6273);
}
.cab-size-input {
  font: 700 18px/1.2 inherit;
  color: var(--navy, #0A1226);
  border: none;
  outline: none;
  background: transparent;
  width: 100%;
  padding: 0;
  -moz-appearance: textfield;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}
.cab-size-input::-webkit-outer-spin-button,
.cab-size-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* Selects: keep the same compact look as the old number inputs, but show
   a small chevron on the right so it reads as a dropdown. */
select.cab-size-input {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%235C6273' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='1 1.5 6 6.5 11 1.5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0 center;
  background-size: 12px 8px;
  padding-right: 18px;
}
select.cab-size-input::-ms-expand { display: none; }
.cab-size-unit {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-muted, #5C6273);
}
.cab-size-note {
  margin: 8px 0 0;
  font-size: 12.5px;
  color: var(--ink-muted, #5C6273);
}

.cab-config-cards,
.cab-color-grid,
.cab-face-cards {
  display: grid;
  gap: 8px;
}
.cab-config-cards { grid-template-columns: 1fr 1fr; }
.cab-color-grid   { grid-template-columns: repeat(3, 1fr); }
.cab-face-cards   { grid-template-columns: 1fr; }
.cab-face-cards-2up { grid-template-columns: 1fr 1fr; }
@media (max-width: 720px) {
  .cab-face-cards-2up { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  .cab-config-cards { grid-template-columns: 1fr; }
}

.cab-config-card,
.cab-color-card,
.cab-face-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 10px 12px;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 8px;
  background: #fff;
  font-family: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.cab-config-card:hover,
.cab-color-card:hover,
.cab-face-card:hover { border-color: var(--orange, #E81820); }
.cab-config-card.is-active,
.cab-color-card.is-active,
.cab-face-card.is-active {
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232,24,32,0.18);
}
.cab-config-title,
.cab-face-title { font-weight: 700; font-size: 14px; color: var(--navy, #0A1226); }
.cab-config-desc,
.cab-face-desc { font-size: 12.5px; color: var(--ink-muted, #5C6273); line-height: 1.4; }
.cab-face-meta {
  font-size: 11.5px; font-weight: 600; color: var(--orange, #E81820); margin-top: 2px;
}

.cab-color-card {
  align-items: center;
  flex-direction: column;
  text-align: center;
  padding: 12px 8px;
}
.cab-color-swatch {
  width: 100%;
  aspect-ratio: 3 / 1;
  border-radius: 6px;
  display: block;
}
.cab-color-swatch-custom {
  background: conic-gradient(
    from 0deg,
    #c8323a, #e8b04e, #4f9c5a, #4470b6, #6c4ea0, #c8323a
  );
}
.cab-color-name { font-weight: 600; font-size: 13px; color: var(--navy, #0A1226); margin-top: 6px; }
.cab-color-meta { font-size: 11px; font-weight: 600; color: var(--ink-muted, #5C6273); margin-top: 2px; }
.cab-color-card.is-active .cab-color-meta { color: var(--orange, #E81820); }

/* ----- Face card body (collapsed unless card is active) ----- */
.cab-face-card-head { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.cab-face-card-body {
  width: 100%;
  margin-top: 0;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height .25s ease, opacity .2s ease, margin-top .2s ease;
  pointer-events: none;
}
.cab-face-card.is-active .cab-face-card-body {
  max-height: 720px;
  opacity: 1;
  margin-top: 12px;
  pointer-events: auto;
  overflow: visible;
}
.cab-face-card-body { border-top: 1px solid transparent; padding-top: 0; }
.cab-face-card.is-active .cab-face-card-body { border-top-color: rgba(232,24,32,0.2); padding-top: 10px; }

.cab-face-clear {
  margin-top: 10px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-muted, #5C6273);
  background: none;
  border: 1px dashed var(--border, #E5DFD3);
  cursor: pointer;
  padding: 6px 12px;
  border-radius: 6px;
  align-self: flex-start;
}
.cab-face-clear:hover { color: var(--orange, #E81820); border-color: var(--orange, #E81820); }

/* ----- Cut vinyl color-count picker ----- */
.cab-vinyl-count {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 12px;
}
.cab-vinyl-count-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 8px;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 8px;
  background: #fff;
  font: inherit;
  font-weight: 600;
  font-size: 13px;
  color: var(--navy, #0A1226);
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.cab-vinyl-count-btn:hover { border-color: var(--orange, #E81820); }
.cab-vinyl-count-btn.is-active {
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232,24,32,0.18);
}
.cab-vinyl-count-meta {
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-muted, #5C6273);
}
.cab-vinyl-count-btn.is-active .cab-vinyl-count-meta {
  color: var(--orange, #E81820);
}

/* ----- Per-slot Briteline color picker ----- */
.cab-vinyl-pickers {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cab-vinyl-slot {
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 8px;
  padding: 10px 12px;
  background: #fff;
}
.cab-vinyl-slot-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 700;
  font-size: 12.5px;
  color: var(--navy, #0A1226);
  margin-bottom: 8px;
}
.cab-vinyl-slot-pick {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink-muted, #5C6273);
}
.cab-vinyl-swatches {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 5px;
}
@media (max-width: 720px) {
  .cab-vinyl-swatches { grid-template-columns: repeat(5, 1fr); }
}
.cab-vinyl-swatch-btn {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 6px;
  cursor: pointer;
  padding: 0;
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.cab-vinyl-swatch-btn:hover { transform: scale(1.06); border-color: var(--orange, #E81820); }
.cab-vinyl-swatch-btn.is-active {
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232,24,32,0.18);
}
.cab-vinyl-swatch-btn[title]::after { display: none; }

/* ----- Per-slot chip that opens a click-to-open swatch popover ----- */
.cab-vinyl-chip {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px 6px 6px;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 999px;
  background: #fff;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--navy, #0A1226);
  cursor: pointer;
  transition: border-color .15s ease;
}
.cab-vinyl-chip:hover { border-color: var(--orange, #E81820); }
.cab-vinyl-chip[aria-expanded="true"] {
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232,24,32,0.18);
}
.cab-vinyl-chip-swatch {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid rgba(0,0,0,0.12);
  flex: none;
}
.cab-vinyl-chip-name { line-height: 1.1; }
.cab-vinyl-chip-meta {
  display: block;
  font-size: 10.5px;
  font-weight: 500;
  color: var(--ink-muted, #5C6273);
  margin-top: 2px;
}
.cab-vinyl-slot-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
}
.cab-vinyl-slot-row + .cab-vinyl-slot-row { border-top: 1px dashed var(--border, #E5DFD3); }
.cab-vinyl-slot-num {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted, #5C6273);
}

/* Click-to-open vinyl popover */
.cab-vinyl-popover {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 50;
  background: #fff;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(10,18,38,0.18);
  padding: 14px;
  width: min(360px, calc(100vw - 24px));
  display: none;
}
.cab-vinyl-popover.is-open { display: block; }
.cab-vinyl-popover-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--navy, #0A1226);
  margin-bottom: 10px;
}
.cab-vinyl-popover-close {
  background: none;
  border: none;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-muted, #5C6273);
  padding: 0 4px;
}
.cab-vinyl-popover-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
}
.cab-vinyl-popover-grid .cab-vinyl-swatch-btn {
  aspect-ratio: 1 / 1;
}

/* ----- Digital print uploader ----- */
.cab-print-uploader {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.cab-print-upload-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 8px;
  background: #fff;
  font: inherit;
  font-weight: 600;
  font-size: 13px;
  color: var(--navy, #0A1226);
  cursor: pointer;
  transition: border-color .15s ease;
}
.cab-print-upload-btn:hover { border-color: var(--orange, #E81820); }
.cab-print-filename {
  font-size: 12.5px;
  color: var(--ink-muted, #5C6273);
  font-style: italic;
}
.cab-print-clear {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--orange, #E81820);
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 6px;
}
.cab-print-clear:hover { background: rgba(232,24,32,0.08); }
.cab-print-note {
  margin: 10px 0 0;
  font-size: 11.5px;
  color: var(--ink-muted, #5C6273);
  line-height: 1.4;
}

/* Hidden when product != cabinet (handled in JS via hidden attr too) */
[data-only][hidden] { display: none !important; }

/* Cabinet mount picker — 2-card layout (Direct / Blade) */
.mount-cards.mount-cards-2up { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 720px) {
  .mount-cards.mount-cards-2up { grid-template-columns: 1fr; }
}
.cab-mount-hint {
  margin: 10px 0 0;
  font-size: 12px;
  font-weight: 500;
  color: var(--orange, #E81820);
  background: rgba(232,24,32,0.08);
  border: 1px solid rgba(232,24,32,0.22);
  border-radius: 8px;
  padding: 8px 12px;
}

/* ====================================================================
   v6: Hide channel-letter slider quick-control when product=cabinet.
   Cabinet has its own L × H number inputs in the form panel.
   ==================================================================== */
#canvasWrap[data-product="cabinet"] .quick-controls .qc-height {
  display: none !important;
}

/* ====================================================================
   v8: Cabinet Text Styling fieldset
   --------------------------------------------------------------------
   Lives only when product=cabinet (data-only="cabinet"). Lets the user
   pick font, layout (straight / arch up / arch down), size scale, and
   text color. Preview-only — pricing isn't impacted.
   ==================================================================== */

.cab-text-block {
  border-top: 1px dashed #E5DFD3;
  padding-top: 14px;
  margin-top: 6px;
}

.cab-text-row {
  display: grid;
  grid-template-columns: 56px 1fr;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
}
.cab-text-row:first-of-type { margin-top: 0; }

.cab-text-row-label {
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted, #5C6273);
}

/* ── Font chips (compact) ─────────────────────────── */
.cab-font-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.cab-font-chip {
  appearance: none;
  border: 1px solid #E5DFD3;
  background: #FAF7F2;
  color: #0A1226;
  padding: 7px 11px;
  border-radius: 8px;
  font-size: 12px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
  white-space: nowrap;
  line-height: 1;
}
.cab-font-chip:hover {
  background: #FFFFFF;
  border-color: #C8C0AE;
}
.cab-font-chip.is-active {
  background: #0A1226;
  color: #FFFFFF;
  border-color: #0A1226;
  box-shadow: 0 1px 3px rgba(10,18,38,0.18);
}
.cab-font-chip:focus-visible {
  outline: 2px solid #E81820;
  outline-offset: 2px;
}

/* ── Layout (straight / arch up / arch down) ─────────────────────── */
.cab-text-curve {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.cab-curve-btn {
  appearance: none;
  border: 1px solid #E5DFD3;
  background: #FAF7F2;
  color: #0A1226;
  padding: 6px 10px;
  border-radius: 8px;
  font: 600 11.5px/1 'Inter', system-ui, sans-serif;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}
.cab-curve-btn svg { display: block; }
.cab-curve-btn:hover {
  background: #FFFFFF;
  border-color: #C8C0AE;
}
.cab-curve-btn.is-active {
  background: #0A1226;
  color: #FFFFFF;
  border-color: #0A1226;
}
.cab-curve-btn:focus-visible {
  outline: 2px solid #E81820;
  outline-offset: 2px;
}

/* ── Size slider row ─────────────────────── */
.cab-text-size {
  display: flex;
  align-items: center;
  gap: 12px;
}
.cab-text-size .form-slider { flex: 1; }
.cab-text-size .slider-val {
  min-width: 48px;
  font-size: 13px;
  font-weight: 700;
}

/* ── Color row (preset swatches + custom color picker) ─────────── */
.cab-text-colors {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.cab-text-color {
  appearance: none;
  position: relative;
  border: 1px solid #E5DFD3;
  background: #FAF7F2;
  color: #0A1226;
  padding: 5px 9px 5px 5px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: 600 11.5px/1 'Inter', system-ui, sans-serif;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}
.cab-text-color:hover {
  background: #FFFFFF;
  border-color: #C8C0AE;
}
.cab-text-color.is-active {
  background: #0A1226;
  color: #FFFFFF;
  border-color: #0A1226;
  box-shadow: 0 1px 3px rgba(10,18,38,0.18);
}
.cab-text-color:focus-visible {
  outline: 2px solid #E81820;
  outline-offset: 2px;
}
.cab-text-color-sw {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  display: inline-block;
  border: 1px solid rgba(10,18,38,0.18);
  flex-shrink: 0;
}
.cab-text-color-sw-white {
  border-color: #C8C0AE;
}
/* Auto = gradient implying it follows whatever the face/vinyl color is */
.cab-text-color-sw-auto {
  background: conic-gradient(from 0deg, #C8202B, #0E5BA8, #0A1226, #157C42, #F4D200, #C8202B);
}
/* Custom = hidden native color input + rainbow swatch */
.cab-text-color-custom {
  cursor: pointer;
  padding: 5px 9px 5px 5px;
}
.cab-text-color-custom input[type="color"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: 0;
  padding: 0;
  margin: 0;
}
.cab-text-color-sw-custom {
  background: conic-gradient(from 0deg, #FF3B30, #FF9500, #FFCC00, #34C759, #00C7BE, #007AFF, #5856D6, #AF52DE, #FF3B30);
  border-color: rgba(10,18,38,0.18);
}

/* ── Mobile tweaks ───────────────────────── */
@media (max-width: 720px) {
  .cab-text-row {
    grid-template-columns: 1fr;
    gap: 6px;
  }
  .cab-text-row-label { letter-spacing: 0.12em; }
  .cab-font-chip { font-size: 11.5px; padding: 6px 9px; }
}

/* Hide "+ Add Word" when on cabinet (cabinet uses a single sign-text line) */
#canvasWrap[data-product="cabinet"] ~ * #addWordBtn,
body:has(#canvasWrap[data-product="cabinet"]) #addWordBtn {
  display: none !important;
}

/* v8: brief flash on the SIGN TEXT input when "+ Add Word" is clicked
   without any text in the input (helps the user notice). */
@keyframes inputFlashPulse {
  0%   { box-shadow: 0 0 0 0 rgba(232,24,32,0.0); border-color: #E5DFD3; }
  40%  { box-shadow: 0 0 0 4px rgba(232,24,32,0.18); border-color: #E81820; }
  100% { box-shadow: 0 0 0 0 rgba(232,24,32,0.0); border-color: #E5DFD3; }
}
.text-input.input-flash,
input.input-flash {
  animation: inputFlashPulse 380ms ease-out;
}

/* ====================================================================
   v9 — Floating cabinet TEXT-STYLING overlay panel (#cabTextPanel)
   Sits inside #canvasWrap so customers see live changes while editing.
   Vertical, compact, glass-style card. Collapsible header.
   ==================================================================== */

.cab-text-panel {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 5;
  width: 252px;
  max-width: calc(100% - 28px);
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  color: #0A1226;
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(10, 18, 38, 0.10);
  border-radius: 12px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.65) inset,
    0 12px 32px -12px rgba(10, 18, 38, 0.30),
    0 4px 10px -4px rgba(10, 18, 38, 0.18);
  overflow: hidden;
  transition: box-shadow 200ms ease, transform 200ms ease, opacity 200ms ease;
}
.canvas-wrap[data-mode="night"] .cab-text-panel {
  background: rgba(20, 26, 42, 0.86);
  color: #F4F0E8;
  border-color: rgba(255, 255, 255, 0.12);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 12px 32px -12px rgba(0, 0, 0, 0.55),
    0 4px 10px -4px rgba(0, 0, 0, 0.40);
}

/* Header / collapse toggle */
.cab-text-panel-header {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 12px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(10, 18, 38, 0.08);
  cursor: pointer;
  color: inherit;
  font: 700 12px/1 var(--font-body, 'Inter', system-ui, sans-serif);
  letter-spacing: 0.04em;
  text-align: left;
  transition: background 120ms ease;
}
.canvas-wrap[data-mode="night"] .cab-text-panel-header {
  border-bottom-color: rgba(255, 255, 255, 0.10);
}
.cab-text-panel-header:hover {
  background: rgba(10, 18, 38, 0.04);
}
.canvas-wrap[data-mode="night"] .cab-text-panel-header:hover {
  background: rgba(255, 255, 255, 0.05);
}
.cab-text-panel-icon { display: inline-flex; opacity: 0.85; }
.cab-text-panel-title { flex: 1; }
.cab-text-panel-chev {
  display: inline-flex;
  opacity: 0.6;
  transition: transform 200ms ease;
}
.cab-text-panel[data-collapsed="true"] .cab-text-panel-chev {
  transform: rotate(-90deg);
}
.cab-text-panel[data-collapsed="true"] .cab-text-panel-header {
  border-bottom-color: transparent;
}

/* Body — vertical stack of rows */
.cab-text-panel-body {
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 60vh;
  overflow-y: auto;
  transition: max-height 220ms ease, padding 220ms ease, opacity 180ms ease;
}
.cab-text-panel[data-collapsed="true"] .cab-text-panel-body {
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  opacity: 0;
  pointer-events: none;
  overflow: hidden;
}

.cab-text-panel-body::-webkit-scrollbar { width: 6px; }
.cab-text-panel-body::-webkit-scrollbar-thumb {
  background: rgba(10, 18, 38, 0.18);
  border-radius: 6px;
}
.canvas-wrap[data-mode="night"] .cab-text-panel-body::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.18);
}

/* Row layout — label on top, controls below (vertical) */
.cab-text-prow {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cab-text-prow-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted, #5C6273);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.canvas-wrap[data-mode="night"] .cab-text-prow-label {
  color: rgba(244, 240, 232, 0.65);
}
.cab-text-prow-val {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0;
  color: #0A1226;
}
.canvas-wrap[data-mode="night"] .cab-text-prow-val { color: #F4F0E8; }

/* Scoped overrides — make controls compact & vertical inside the panel */
.cab-text-panel .cab-font-chips {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  max-height: 168px;
  overflow-y: auto;
  padding-right: 2px;
}
.cab-text-panel .cab-font-chip {
  padding: 6px 4px;
  font-size: 10.5px;
  border-radius: 6px;
  text-align: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.7);
  border-color: rgba(10, 18, 38, 0.12);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: block;
  line-height: 1.1;
}
.cab-text-panel .cab-font-chip-script {
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  padding-top: 4px;
  padding-bottom: 4px;
}
.canvas-wrap[data-mode="night"] .cab-text-panel .cab-font-chip {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.14);
  color: #F4F0E8;
}
.cab-text-panel .cab-font-chip.is-active {
  background: #0A1226;
  color: #FFFFFF;
  border-color: #0A1226;
}
.canvas-wrap[data-mode="night"] .cab-text-panel .cab-font-chip.is-active {
  background: #E81820;
  border-color: #E81820;
}

.cab-text-panel .cab-text-curve {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
}
.cab-text-panel .cab-curve-btn {
  flex-direction: column;
  gap: 2px;
  padding: 6px 4px;
  font-size: 10px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.7);
  border-color: rgba(10, 18, 38, 0.12);
  text-align: center;
  justify-content: center;
}
.cab-text-panel .cab-curve-btn.is-active {
  background: #0A1226;
  color: #FFFFFF;
  border-color: #0A1226;
}
.canvas-wrap[data-mode="night"] .cab-text-panel .cab-curve-btn {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.14);
  color: #F4F0E8;
}
.canvas-wrap[data-mode="night"] .cab-text-panel .cab-curve-btn.is-active {
  background: #E81820;
  border-color: #E81820;
}

.cab-text-panel .cab-text-size-slider {
  width: 100%;
}

.cab-text-panel .cab-text-colors {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 5px;
}
.cab-text-panel .cab-text-color {
  font-size: 10.5px;
  padding: 4px 7px 4px 4px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.7);
  border-color: rgba(10, 18, 38, 0.12);
}
.cab-text-panel .cab-text-color.is-active {
  background: #0A1226;
  color: #FFFFFF;
  border-color: #0A1226;
}
.canvas-wrap[data-mode="night"] .cab-text-panel .cab-text-color {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.14);
  color: #F4F0E8;
}
.cab-text-panel .cab-text-color-sw {
  width: 14px;
  height: 14px;
  border-radius: 4px;
}
.canvas-wrap[data-mode="night"] .cab-text-panel .cab-text-color.is-active {
  background: #E81820;
  border-color: #E81820;
}

/* Mobile / narrow artboard — keep panel on top so it doesn't overlap the
   bottom-anchored .quick-controls bar. Default-collapsed on mobile to give
   the user the artboard real-estate; they tap the header to expand. */
@media (max-width: 720px) {
  .cab-text-panel {
    top: 10px;
    right: 10px;
    left: auto;
    bottom: auto;
    width: 200px;
    max-width: calc(100% - 20px);
  }
  .cab-text-panel-body {
    max-height: 50vh;
  }
  .cab-text-panel .cab-font-chips,
  .cab-text-panel .cab-text-colors {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ============================================================
   v9 — Photographic storefront backdrop (replaces brick wall)
   Always on. Day/night cross-fade keys off [data-mode]
   ============================================================ */
.channel-photo-bg { display: none; }

#canvasWrap[data-bg="photo"] .channel-photo-bg {
  display: block;
}
/* When photo is on, hide the flat brick + cream wall */
#canvasWrap[data-bg="photo"] .wall-bg,
#canvasWrap[data-bg="photo"] .wall-bricks {
  display: none;
}
/* Day/night cross-fade for the channel-letter backdrop */
#canvasWrap[data-bg="photo"][data-mode="night"] #chBackdropDay   { opacity: 0; }
#canvasWrap[data-bg="photo"][data-mode="night"] #chBackdropNight { opacity: 1; }
#canvasWrap[data-bg="photo"]:not([data-mode="night"]) #chBackdropDay   { opacity: 1; }
#canvasWrap[data-bg="photo"]:not([data-mode="night"]) #chBackdropNight { opacity: 0; }
.channel-photo-bg { transition: opacity 240ms ease; }

/* ==========================================================
   Builder top bar (Product + Letter type, above the canvas)
   Compact horizontal pill strip. Keeps the live preview in
   view while the customer edits specs underneath the canvas.
   ========================================================== */
/* The top selector band is now empty in BOTH modes — relocateTopbarToRail()
   moves the Product-type + Letter-type pickers into the right spec rail so the
   live design area can expand upward to match Lobby Panel / Vinyl. The band
   itself is hidden; the .topbar-* rules below only style the cards while they
   still carry those classes during the (synchronous) relocation, and remain as
   a safety net should the relocation ever be skipped. */
.builder-topbar {
  display: none;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr);
  gap: 12px;
  padding: 10px 12px;
  background: #fff;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(10,18,38,0.04);
}
.builder-topbar .topbar-block {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.builder-topbar .topbar-block .control-header {
  margin: 0 0 6px 2px;
}
.builder-topbar .topbar-block .control-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted, #5C6273);
}
.builder-topbar .topbar-block[data-only]:not([data-only="channel"]) { display: none; }
/* Hide letter-type strip when current product isn't channel.
   The body's data-only attr handling already toggles this on
   non-channel products via existing JS. We add an extra rule below
   targeting the topbar specifically so it collapses cleanly. */
body[data-product="cabinet"]      .builder-topbar .topbar-block[data-only="channel"],
body[data-product="sandblasted"]  .builder-topbar .topbar-block[data-only="channel"] {
  display: none;
}
body[data-product="cabinet"]      .builder-topbar,
body[data-product="sandblasted"]  .builder-topbar {
  grid-template-columns: 1fr;
}

/* Compact horizontal strips */
.builder-topbar .topbar-cards {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.builder-topbar .topbar-cards::-webkit-scrollbar { display: none; }

.builder-topbar .topbar-cards .product-card,
.builder-topbar .topbar-cards .style-card {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  padding: 7px 8px;
  border-radius: 10px;
  text-align: left;
}
/* Drop icons in topbar product cards — titles alone are clearest. */
.builder-topbar .topbar-cards .product-card-icon { display: none; }
.builder-topbar .topbar-cards .product-card { justify-content: center; }
.builder-topbar .topbar-cards .product-card-title,
.builder-topbar .topbar-cards .style-card-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
/* Drop the long descriptions and big style thumbnails in the topbar */
.builder-topbar .topbar-cards .product-card-desc,
.builder-topbar .topbar-cards .style-card-desc { display: none; }
.builder-topbar .topbar-cards .style-card-thumb {
  flex: 0 0 36px;
  width: 36px;
  height: 24px;
}
.builder-topbar .topbar-cards .style-card-thumb svg { height: 24px; }

/* Day/night surface treatment so the bar reads at any time */
.builder-topbar .topbar-cards .product-card,
.builder-topbar .topbar-cards .style-card {
  background: #FAF7F2;
  border: 1px solid var(--border, #E5DFD3);
}
.builder-topbar .topbar-cards .product-card.is-active,
.builder-topbar .topbar-cards .style-card.is-active {
  background: #FFF7F2;
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232, 24, 32, 0.18);
}

/* Mobile: stack two strips vertically, allow horizontal scroll within each */
@media (max-width: 720px) {
  .builder-topbar {
    grid-template-columns: 1fr;
    gap: 8px;
    padding: 8px 10px;
  }
  .builder-topbar .topbar-cards .product-card,
  .builder-topbar .topbar-cards .style-card {
    flex: 0 0 auto;
    min-width: 132px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   DAY-1 P0 PATCH — May 9 2026
   - Mobile sticky buy bar (P0-6)
   - Mobile picker overflow + scroll-snap + fade hint (P0-7)
   - Cabinet size: native select hidden, chip group visible (P0-8)
   - Desktop B2Sign-style layout: canvas sticky, controls scroll alongside
   ═══════════════════════════════════════════════════════════════════════════ */

/* P0-8 — hide native cabinet selects (kept for JS state); show chip group */
.cab-size-input--hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.cab-size-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
}
.cab-size-chip {
  appearance: none;
  min-width: 44px;
  min-height: 44px;
  padding: 8px 12px;
  background: #FFFFFF;
  border: 1.5px solid var(--border, #E5DFD3);
  border-radius: 10px;
  font-family: 'Inter', system-ui, sans-serif;
  font-weight: 700;
  font-size: 14px;
  color: var(--navy, #0A1226);
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease, box-shadow 140ms ease;
}
.cab-size-chip:hover { border-color: #C4BBA6; }
.cab-size-chip.is-active {
  border-color: var(--orange, #E81820);
  background: #FFF7F2;
  box-shadow: 0 0 0 2px rgba(232, 24, 32, 0.18);
}
.cab-size-chip:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.18);
}

/* P0-7 — Mobile picker overflow: scroll-snap + fade-right hint */
@media (max-width: 720px) {
  .builder-topbar .topbar-cards {
    scroll-snap-type: x mandatory;
    -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%);
            mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%);
    padding-right: 24px;
  }
  .builder-topbar .topbar-cards .product-card,
  .builder-topbar .topbar-cards .style-card {
    scroll-snap-align: start;
    min-height: 44px;
  }
  /* Reduce min-width so 3 product cards fit on 390px without scroll;
     style-cards (4 letter types) keep scroll for graceful overflow. */
  .builder-topbar .topbar-cards.product-cards .product-card {
    min-width: 0;
    flex: 1 1 0;
  }
  .builder-topbar .topbar-cards.style-cards .style-card {
    flex: 0 0 auto;
    min-width: 110px;
  }
}

/* P0-6 — Mobile sticky buy bar */
.mobile-buy-bar {
  display: none;
}
@media (max-width: 900px) {
  .mobile-buy-bar {
    display: block;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
    background: rgba(255, 255, 255, 0.96);
    -webkit-backdrop-filter: blur(10px);
            backdrop-filter: blur(10px);
    border-top: 1px solid rgba(10, 18, 38, 0.10);
    box-shadow: 0 -8px 24px rgba(10, 18, 38, 0.10);
    padding: 10px max(12px, env(safe-area-inset-left)) calc(10px + env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-right));
  }
  .mobile-buy-bar[aria-hidden="false"] {
    transform: translateY(0);
  }
  .mobile-buy-bar-inner {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 12px;
    align-items: center;
    max-width: 720px;
    margin: 0 auto;
  }
  .mobile-buy-bar-price {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
    min-width: 0;
  }
  .mobile-buy-bar-label {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: calc(10px * var(--ui-scale));
    letter-spacing: 0.10em;
    text-transform: uppercase;
    color: var(--ink-muted, #5C6273);
  }
  .mobile-buy-bar-amount {
    font-family: 'Space Grotesk', system-ui, sans-serif;
    font-weight: 700;
    font-size: calc(22px * var(--ui-scale));
    letter-spacing: -0.02em;
    color: var(--navy, #0A1226);
  }
  .mobile-buy-bar-cta {
    appearance: none;
    border: 0;
    background: var(--signal, #E81820);
    color: #FFFFFF;
    font-family: 'Inter', system-ui, sans-serif;
    font-weight: 800;
    font-size: calc(14px * var(--ui-scale));
    letter-spacing: 0.01em;
    padding: 0 18px;
    min-height: 48px;
    border-radius: 10px;
    cursor: pointer;
    box-shadow: 0 6px 14px rgba(232, 24, 32, 0.30);
    transition: transform 120ms ease, box-shadow 120ms ease, opacity 120ms ease;
  }
  .mobile-buy-bar-cta:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 18px rgba(232, 24, 32, 0.34);
  }
  .mobile-buy-bar-cta:active { transform: translateY(0); }
  .mobile-buy-bar-cta:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    box-shadow: none;
  }
  /* Body padding so bottom content isn't hidden behind the bar */
  body.has-mobile-buy-bar {
    padding-bottom: calc(76px + env(safe-area-inset-bottom));
  }
}

/* P1-12 — Universal 44px touch target on mobile */
@media (max-width: 720px) {
  .swatch,
  .product-card,
  .style-card,
  .cab-config-card,
  .mount-card,
  .install-card,
  .topbar-cards .product-card,
  .topbar-cards .style-card {
    min-height: 44px;
  }
}

/* Legacy desktop layout removed — the new .builder-stage-grid below now
   owns the two-column / sticky-preview behavior on desktop. We keep the
   cabinet text panel z-index here so it still layers above the canvas. */
@media (min-width: 1280px) {
  .canvas-wrap .cab-text-panel { z-index: 5; }
}

/* ════════════════════════════════════════════════════════════════════
   Day 2 P1 — Buyer-blocker fixes
   Premium upgrades, breakdown panel, trust strip, modal, expanders,
   global touch targets, mobile sticky preview.
   ════════════════════════════════════════════════════════════════════ */

/* ── P1-2: Style card "custom quote" badge ─────────────────────── */
.style-card-badge {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cream);
  background: var(--orange);
  padding: 3px 8px;
  border-radius: 999px;
  margin-top: 4px;
  white-space: nowrap;
}
.builder-topbar .topbar-cards .style-card-badge {
  font-size: 9px;
  padding: 2px 6px;
  margin-top: 2px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── P1-4: Font picker — Upload Vector subtext ─────────────────── */
.font-chip-sub {
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  margin-top: 2px;
}
.font-chip.is-active .font-chip-sub { color: var(--navy); }

/* Upload-vector chip occupies its own row in the font grid */
.font-chip.is-custom { grid-column: 1 / -1; }

/* ── P1-3: Itemized price breakdown panel ──────────────────────── */
.estimate-breakdown {
  list-style: none;
  margin: 8px 0 0 0;
  padding: 12px 14px;
  background: rgba(10, 18, 38, 0.03);
  border: 1px solid var(--border);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.estimate-breakdown li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--navy);
}
.estimate-line-label { color: var(--navy); }
.estimate-line-amt {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--navy);
  white-space: nowrap;
}
.estimate-line-amt.is-quote {
  font-weight: 500;
  font-style: italic;
  color: var(--orange);
  font-size: 12px;
}
.estimate-line-amt.is-included {
  font-weight: 500;
  color: var(--ink-muted);
  font-size: 12px;
}
.estimate-line-sub {
  padding-left: 14px;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-muted);
}
.estimate-line-sub .estimate-line-label,
.estimate-line-sub .estimate-line-amt {
  color: var(--ink-muted);
  font-weight: 500;
}
.estimate-line-total {
  margin-top: 6px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-weight: 700;
}
.estimate-line-total .estimate-line-label,
.estimate-line-total .estimate-line-amt {
  font-weight: 700;
  font-size: 14px;
}

.estimate-breakdown-toggle {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 8px 0;
  margin: 4px 0 0 0;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--navy);
  cursor: pointer;
  text-align: left;
  min-height: 44px;
}
.estimate-breakdown-toggle:hover { text-decoration: underline; }
.estimate-breakdown-toggle:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ── P1-11: Trust strip near CTA ───────────────────────────────── */
.estimate-trust {
  list-style: none;
  margin: 12px 0 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--ink-muted);
}
.estimate-trust li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.estimate-trust li::before {
  content: "✓";
  color: var(--orange);
  font-weight: 700;
  font-size: 13px;
}
@media (max-width: 600px) {
  .estimate-trust { gap: 6px 12px; font-size: 11px; }
}

/* ── P1-7: Quote email modal ──────────────────────────────────── */
.quote-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(10, 18, 38, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9000;
  padding: 24px;
  animation: quote-modal-fadein 200ms var(--ease, ease) both;
}
.quote-modal-overlay[hidden] { display: none; }
@keyframes quote-modal-fadein { from { opacity: 0 } to { opacity: 1 } }
.quote-modal {
  position: relative;
  background: var(--cream);
  border-radius: 16px;
  padding: 28px 24px 24px;
  width: 100%;
  max-width: 440px;
  box-shadow: 0 30px 80px -20px rgba(10, 18, 38, 0.5);
  animation: quote-modal-pop 220ms var(--ease, ease) both;
}
@keyframes quote-modal-pop {
  from { transform: translateY(8px) scale(0.98); opacity: 0; }
  to   { transform: translateY(0)   scale(1);    opacity: 1; }
}
.quote-modal-close {
  position: absolute;
  top: 8px;
  right: 10px;
  appearance: none;
  background: transparent;
  border: 0;
  font-size: 28px;
  line-height: 1;
  color: var(--ink-muted);
  cursor: pointer;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.quote-modal-close:hover { color: var(--navy); background: rgba(10, 18, 38, 0.06); }
.quote-modal-title {
  margin: 0 0 6px 0;
  font-family: var(--font-display, var(--font-body));
  font-size: 20px;
  font-weight: 600;
  color: var(--navy);
}
.quote-modal-sub {
  margin: 0 0 18px 0;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--ink-muted);
  line-height: 1.5;
}
.quote-modal-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.quote-modal-label {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.quote-modal-input {
  appearance: none;
  width: 100%;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--navy);
  min-height: 48px;
}
.quote-modal-input:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(10, 18, 38, 0.08);
}
.quote-modal-error {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--orange);
  margin: 4px 0 0;
}
.quote-modal-actions {
  display: flex;
  gap: 10px;
  margin-top: 16px;
  justify-content: flex-end;
}
.quote-modal-cancel,
.quote-modal-submit {
  appearance: none;
  border-radius: 10px;
  padding: 12px 18px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  min-height: 44px;
  border: 1px solid transparent;
}
.quote-modal-cancel {
  background: transparent;
  border-color: var(--border);
  color: var(--navy);
}
.quote-modal-cancel:hover { background: rgba(10, 18, 38, 0.06); }
.quote-modal-submit {
  background: var(--navy);
  color: var(--cream);
}
.quote-modal-submit:hover { background: #1a2a55; }
.quote-modal-submit:focus-visible,
.quote-modal-cancel:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

/* ── P1-1: Letter-type "What's the difference?" expander ──────── */
.letter-type-help-toggle {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 8px 0;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--navy);
  text-align: left;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  min-height: 44px;
  align-self: flex-start;
}
.letter-type-help-toggle:hover { color: var(--orange); }
.letter-type-help-toggle:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
  border-radius: 4px;
}
.letter-type-help {
  margin-top: 6px;
  padding: 14px 16px;
  background: rgba(10, 18, 38, 0.03);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.letter-type-help-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.5;
  color: var(--navy);
}
.letter-type-help-list strong {
  font-weight: 700;
  color: var(--navy);
}

/* ── P1-12: Global 44px min touch targets + 48px swatches ─────── */
.controls button,
.controls input[type="text"],
.controls input[type="email"],
.controls input[type="number"],
.controls select,
.mobile-buy-bar button,
.brand-bar button {
  min-height: 44px;
}
@media (max-width: 900px) {
  /* Promote color swatches to comfortable touch size on mobile */
  .swatch { width: 48px; height: 48px; }
  .swatch-grid-sm .swatch { width: 36px; height: 36px; }
  .swatch-grid { gap: 10px; }
}

/* ── P1-6: Mobile sticky preview ──────────────────────────────── */
@media (max-width: 900px) {
  .canvas-wrap {
    position: sticky;
    top: 0;
    /* Slightly taller window so the zoomed-in sign band is the
       hero of the mobile builder. Controls still scroll naturally
       beneath the sticky preview. */
    max-height: 52vh;
    z-index: 5;
  }
  /* On mobile the screen is already small, so apply a gentler crop —
     too aggressive a zoom hides the door context. Same opt-out logic
     as desktop (see above) — cabinet keeps its own framing. */
  .canvas-wrap[data-bg="photo"]:not([data-style="cabinet"]):not([data-product="cabinet"]) .wall-canvas {
    transform: scale(var(--preview-zoom-mobile, 1.10));
  }
  /* Cabinet camera mirrors the desktop rule with a gentler mobile crop. */
  .canvas-wrap[data-product="cabinet"][data-cabinet-view="front"] .wall-canvas {
    transform: scale(var(--cab-camera-zoom-mobile, 1.15));
  }
  /* Mobile dock: stick to bottom of canvas-wrap area (sticky preview pins
     to viewport top up to 52vh; dock sits just below in normal flow). The
     mobile buy bar is fixed at viewport bottom — dock should NOT be sticky
     on mobile to avoid colliding with it. */
  .quick-controls {
    margin: 8px auto 12px auto;
  }
}

/* ==========================================================
   Builder stage grid — sticky preview + scrolling controls
   ==========================================================
   Desktop (≥1024px): two columns. Left holds the canvas inside
   a position:sticky wrapper so the live preview stays visible
   while the customer scrolls through the right-hand control
   column. Mirrors the redesigned Lobby/Auto builder flow so
   users no longer have to scroll back up after every change.

   Tablet / mobile (<1024px): collapses to a single column with
   the canvas above the controls (preserves the original stack).
   ========================================================== */
.builder-stage-grid {
  display: flex;
  flex-direction: column;
  gap: var(--gap-4);
  min-width: 0;
}

.builder-preview-col,
.builder-controls-col {
  min-width: 0;
}

/* Sandblasted v3 flow has its own full-bleed shell; suppress the
   grid columns so the questionnaire/AI/upload steps render as
   intended without a stray empty preview column on the side. */
body[data-product="sandblasted"] .builder-stage-grid {
  display: block;
}

@media (min-width: 1024px) {
  /* Widen the page shell so two columns have room to breathe.
     Brand-bar and topbar still center inside .page; the stage
     grid uses the additional width for the controls column. */
  .page {
    max-width: calc(1320px * var(--ui-scale));
  }

  .builder-stage-grid {
    display: grid;
    /* Preview gets a larger share of the row so the sign band reads
       like a real design surface instead of a thumbnail. Controls
       column keeps its 360px floor so every existing control stays
       comfortably reachable — we are widening the preview, not
       shrinking the controls. */
    grid-template-columns: minmax(0, 1.6fr) minmax(360px, 1fr);
    align-items: start;
    gap: var(--gap-4);
  }

  /* Sandblasted v3 flow renders inside its own shell — let it
     keep full width when active. */
  body[data-product="sandblasted"] .builder-stage-grid {
    display: block;
  }

  .builder-preview-col {
    /* Stick the live preview to the top of the viewport so it
       stays in view while the customer scrolls the controls
       column on the right. Top offset accounts for breathing
       room above the canvas. */
    position: sticky;
    top: var(--gap-3);
    align-self: start;
    z-index: 2;
  }

  /* Drop the legacy floating-dock spacer when the canvas is
     stacked next to the controls — controls live to the right
     now, not below. */
  .builder-preview-col .canvas-wrap {
    margin-bottom: 0;
  }

  /* Controls column scrolls naturally with the page. No fixed
     height — using sticky on the preview keeps the design
     visible without trapping scroll inside a small pane, which
     scales better for long control lists (cabinet, install,
     mount, etc.). */
  .builder-controls-col {
    min-height: 100%;
  }
}

/* Larger desktops: a touch more breathing room. */
@media (min-width: 1440px) {
  .page {
    max-width: calc(1440px * var(--ui-scale));
  }
  .builder-stage-grid {
    gap: var(--gap-5);
  }
}

/* ----------------------------------------------------------
   Builder packaging — matches Lobby/Auto visual rhythm:
   canvas as a card, controls in a paired card surface with
   thin section dividers between blocks. No copy or option
   changes — purely visual chrome around the existing layout.
   ---------------------------------------------------------- */
@media (min-width: 1024px) {
  /* Wrap the right-side controls in a single paneled card so the
     scroll column reads as one packaged surface (the Lobby/Auto
     builders pair their floating-panel chrome with a sidebar
     mirror of the same visual weight). */
  /* The rail is a transparent flex column; each section is now its
     own discrete white card (see .rail-card above), matching the
     LobbyPanel .panel-rail — not one packaged panel. The 14px gap
     is the panel.css .panel-rail gutter. */
  .builder-controls-col > .controls {
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: 0;
    box-shadow: none;
    gap: 14px;
  }

  /* Hidden blocks must not occupy a card slot / gutter. */
  .builder-controls-col > .controls > [hidden] {
    display: none !important;
  }

  /* Anchor the checkout bar to the bottom of the controls card
     with a clear separator — matches the "summary at bottom" feel
     of Lobby's controls panel. */
  .builder-controls-col > .controls > .checkout-bar {
    margin-top: 8px;
    border-top: 1px solid rgba(10, 18, 38, 0.10);
    padding-top: 22px;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
  }

  /* Strengthen the preview card shadow to match the paired control
     card, so the two surfaces read as a set. */
  .builder-preview-col .preview-card {
    box-shadow:
      0 1px 0 rgba(10, 18, 38, 0.04),
      0 30px 60px -30px rgba(10, 18, 38, 0.22);
  }
}

/* Tablet (<1024px): keep the original spacing — the controls
   already read fine in a single column without the card frame. */
@media (max-width: 1023px) {
  .builder-stage-grid { gap: var(--gap-4); }
}

/* ============================================================
   Builder polish pass — handwritten-notes fixes
   ============================================================
   1) Color palette must wrap within its panel (was fixed 20-col,
      overflowed the narrow right column).
   2) Mounting style must render directly below Letter height
      (was wedged after Return depth / Lighting / Estimate).
   3) Estimate / total displayed as a contained red pill at the
      bottom of the controls card — matches the Lobby/Auto buy bar.
   4) Tighten the secondary buttons (mount / install / cab-config
      / product / style cards) so they read consistently with the
      Lobby/Auto button language.
   No content, copy, options, pricing, or step logic changed.
   ============================================================ */

/* 1) Color palette — wrap to whatever width the column allows. */
.swatch-grid {
  grid-template-columns: repeat(auto-fill, 24px);
  justify-content: start;
  max-width: 100%;
}

/* 2) Mounting style reorder — use flex order on direct children
      of .controls. Letter height fieldset → 1, both mount-blocks
      → 2, the Return depth / Lighting / Estimate row → 3. Other
      blocks keep their natural source order via the order:0 reset
      on first-child runs (we only re-order this small range; the
      rest of .controls children keep order: 0 which sits before
      these three regardless because they appear earlier in the
      source). To prevent later blocks from being pulled up, we
      pin them to a higher order. */
.controls > .control-block:has(#heightSlider) { order: 1; }
.controls > .mount-block { order: 2; }
.controls > .controls-row { order: 3; }
.controls > .install-block,
.controls > .checkout-bar { order: 4; }

/* ── Beacon (channel, non-lobby) section order ──────────────────
   Enforces the approved sectioned-card order top-to-bottom:
     1 Letter Type      (relocated .rail-style-block)
     2 Letter Height    (.control-block with #heightSlider)
     3 Sign Text        (.signtext-block + its Design toggle/upload)
     4 Font             (.font-block)
     5 Acrylic / Face   ┐
     6 Returns Color    ├ the three cards inside #colorBlock
     7 Trim Cap Color   ┘
     8 Raceway / Mounting (.mount-block)
   The product-type selector is pinned on top; the Return depth /
   Lighting / Estimate row, Install, and the buy box follow. These
   rules carry an ID inside :has() (or body[data-product]) so they
   out-rank the generic order rules above; cabinet / sandblasted /
   lobby keep the generic order untouched. */
body[data-product="channel"]:not([data-lobby="true"]) .controls > .rail-product-block { order: 1; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .rail-style-block { order: 2; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .control-block:has(#heightSlider) { order: 3; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .shape-size-block { order: 4; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .cl-mode-block { order: 5; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .signtext-block { order: 6; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .cl-upload-block { order: 7; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .font-block { order: 8; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > #colorBlock { order: 9; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .mount-block { order: 10; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .controls-row { order: 11; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .quote-callout { order: 12; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .install-block { order: 13; }
body[data-product="channel"]:not([data-lobby="true"]) .controls > .checkout-bar { order: 14; }

/* 3) Estimate / total — red pill packaging.
      We keep the existing #estimateAmount inside .estimate-block
      so JS doesn't lose its hook, but on desktop the breakdown is
      collapsed inline. The hero "total" is the red bar at the
      bottom of the controls card (checkout-bar) — the desktop
      sibling of the existing mobile-buy-bar pill. */
@media (min-width: 1024px) {
  /* Desktop: the bottom checkout-bar becomes the navy "buy box" from the
     approved Lobby Vinyl / LobbyPanel builder (panel.css .rail-buy) — brand
     navy surface, white price/labels, and a Signal-Red Add-to-Cart CTA. */
  .builder-controls-col > .controls > .checkout-bar {
    background: var(--navy, #0A1226);
    color: #FFFFFF;
    border-radius: 16px;
    padding: 20px 22px 18px;
    /* Single column so the buy box stacks exactly like the Lobby Vinyl
       .rail-buy: cap → price → summary line → full-width CTA → footer. */
    grid-template-columns: 1fr;
    grid-template-areas:
      "summary"
      "cta"
      "save"
      "fine";
    gap: 12px;
    align-items: stretch;
    justify-items: stretch;
    border: 0;
    box-shadow:
      0 18px 48px rgba(10, 18, 38, 0.22),
      0 4px 12px rgba(10, 18, 38, 0.10);
    /* Float in the right rail: the box sticks to the BOTTOM of the viewport so
       it stays in the customer's field of vision while the spec controls above
       it scroll past — mirroring Lobby Vinyl's sticky rail-buy. As the last
       child of the controls column, sticky-bottom glues it to the viewport
       floor from the moment its natural position would scroll off, instead of
       only pinning after the customer has already scrolled to the very end. */
    position: sticky;
    bottom: var(--gap-3, 16px);
    margin-top: 24px;
    z-index: 3;
  }
  .builder-controls-col > .controls > .checkout-bar .checkout-label {
    color: rgba(255, 255, 255, 0.62);
    font-weight: 700;
    letter-spacing: 0.12em;
  }
  .builder-controls-col > .controls > .checkout-bar .checkout-price {
    color: #FFFFFF;
    font-size: calc(34px * var(--ui-scale));
    font-weight: 800;
    line-height: 1.05;
  }
  /* Product summary line directly under the price — material/product + the
     live dimensions, mirroring Lobby Vinyl's "13oz Vinyl Banner · 96" × 48"". */
  .builder-controls-col > .controls > .checkout-bar .checkout-summary-line {
    margin-top: 6px;
    font-family: var(--font-body);
    font-size: calc(13px * var(--ui-scale));
    line-height: 1.4;
    color: rgba(255, 255, 255, 0.74);
  }
  .builder-controls-col > .controls > .checkout-bar .checkout-summary-line[hidden] {
    display: none;
  }
  .builder-controls-col > .controls > .checkout-bar .checkout-fineprint {
    color: rgba(255, 255, 255, 0.55);
    font-size: 11.5px;
    margin-top: 4px;
  }
  /* The navy buy box hosts the live itemized split — lighten the rows so the
     Channel letters / Shape add-on / Estimated total stay legible on navy. */
  .builder-controls-col > .controls > .checkout-bar .checkout-itemized {
    color: rgba(255, 255, 255, 0.92);
  }
  .builder-controls-col > .controls > .checkout-bar .checkout-itemized-total {
    border-top-color: rgba(255, 255, 255, 0.30);
  }
  .builder-controls-col > .controls > .checkout-bar .checkout-itemized-note {
    color: rgba(255, 255, 255, 0.70);
  }
  /* CTA stays Signal Red on the navy box (matches Lobby Vinyl .rail-buy-cta),
     now full-width across the box like the screenshots. */
  .builder-controls-col > .controls > .checkout-bar .cta-primary {
    grid-area: cta;
    width: 100%;
    justify-self: stretch;
    text-align: center;
    background: var(--signal, #E81820);
    color: #FFFFFF;
    font-size: calc(17px * var(--ui-scale));
    padding: 15px 26px;
    box-shadow: 0 6px 18px rgba(232, 24, 32, 0.32);
  }
  .builder-controls-col > .controls > .checkout-bar .cta-primary:hover {
    background: var(--signal-deep, #B8121A);
    box-shadow: 0 8px 22px rgba(232, 24, 32, 0.36);
  }
  /* Secondary "Save Design" control + its status/link sit below the CTA inside
     the navy box, full width and de-emphasized so the red CTA stays the focus. */
  .builder-controls-col > .controls > .checkout-bar .cta-secondary {
    grid-area: save;
    width: 100%;
    justify-self: stretch;
    text-align: center;
    color: rgba(255, 255, 255, 0.92);
    border-color: rgba(255, 255, 255, 0.28);
    background: transparent;
  }
  .builder-controls-col > .controls > .checkout-bar .cta-secondary:hover {
    border-color: rgba(255, 255, 255, 0.55);
    background: rgba(255, 255, 255, 0.06);
  }
  .builder-controls-col > .controls > .checkout-bar .save-design-status,
  .builder-controls-col > .controls > .checkout-bar .save-design-link {
    grid-area: auto;
    color: rgba(255, 255, 255, 0.80);
  }

  /* Hide the inline estimate-block on desktop so the live total
     reads from one place (the red bar) instead of two crowded
     locations. The JS still updates #estimateAmount, so when the
     customer scrolls back the values stay coherent for the
     breakdown popover; we just don't render it as a wedged box. */
  .builder-controls-col > .controls .controls-row > .estimate-block {
    display: none;
  }

  /* With the estimate gone from the row, give Return depth and
     Lighting comfortable breathing room. */
  .builder-controls-col > .controls > .controls-row {
    gap: var(--gap-4);
    align-items: flex-end;
  }
  .builder-controls-col > .controls > .controls-row > .control-block {
    flex: 1 1 0;
  }
}

/* 4) Button cleanup — normalize the secondary "card" buttons used
      across product/style/mount/install/cab-config groups. We
      keep the existing copy + structure; only the visual chrome
      is tightened so they read as one consistent family
      (matches the Lobby/Auto button language). */
.mount-card,
.install-card,
.cab-config-card {
  background: #FFFFFF;
  border: 1px solid rgba(10, 18, 38, 0.10);
  border-radius: 12px;
  transition:
    border-color 160ms var(--ease),
    box-shadow 160ms var(--ease),
    background 160ms var(--ease),
    transform 160ms var(--ease);
}
.mount-card:hover,
.install-card:hover,
.cab-config-card:hover {
  border-color: rgba(10, 18, 38, 0.22);
  box-shadow: 0 6px 18px -10px rgba(10, 18, 38, 0.18);
}
.mount-card.is-active,
.install-card.is-active,
.cab-config-card.is-active {
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232, 24, 32, 0.18);
  background: #FFF7F2;
}

/* Day/Night toggle: align baseline with the segment row next to
   it so Return depth and Lighting feel like siblings, not a
   step. */
.controls-row .toggle-block .toggle-pill {
  height: 38px;
}

/* ── Cabinet design workflow (PR #8 update) ─────────────────────
   Cabinet customers lead with artwork, not typed text. These
   styles support the design-path card row, the primary Upload
   Artwork drop zone, and the design notes textarea.            */
.cab-design-block { display: block; }
.cab-design-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 14px;
}
@media (max-width: 720px) {
  .cab-design-cards { grid-template-columns: 1fr; }
}
.cab-design-card {
  appearance: none;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 12px 12px 10px;
  background: #FFFFFF;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 10px;
  cursor: pointer;
  font-family: inherit;
  color: inherit;
  text-align: left;
  transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.cab-design-card:hover { border-color: var(--orange, #E8521B); }
.cab-design-card.is-active {
  border-color: var(--orange, #E8521B);
  background: #FFF7F2;
  box-shadow: 0 0 0 2px rgba(232, 82, 27, 0.22);
}
.cab-design-card-icon {
  display: inline-flex;
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--cream, #FAF7F2);
  color: var(--navy, #0A1226);
}
.cab-design-card.is-active .cab-design-card-icon {
  background: #FFE6D8;
  color: var(--orange, #E8521B);
}
.cab-design-card-title {
  font-weight: 700;
  font-size: 14px;
  color: var(--navy, #0A1226);
  letter-spacing: -0.01em;
}
.cab-design-card-desc {
  font-size: 12.5px;
  color: var(--ink-muted, #5C6273);
  line-height: 1.4;
}
.cab-design-card-meta {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--orange, #E8521B);
  margin-top: 2px;
}

/* Cabinet live-preview upload button — sits centered on the polycarb face
   when no artwork is uploaded yet. Brand V2 primary-button styling (matches
   .sbv3-btn--primary language used elsewhere in the builder/funnel). */
/* foreignObject wrapper that flex-centers the Upload Artwork button
   over the cabinet face. The foreignObject itself is an SVG element and
   does not honor flex layout on its own — the button needs to live
   inside an XHTML <div> with the centering rules. pointer-events on the
   wrap pass clicks through to the cabinet behind it (only the button
   itself is interactive). */
.cab-face-upload-wrap {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.cab-face-upload-wrap > .cab-face-upload-btn {
  pointer-events: auto;
}

.cab-face-upload-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* Sized smaller than the channel-letter primary button — the cabinet
     camera zoom (~1.28×) magnifies everything inside the wall canvas, so
     a normal-sized button would dominate the face. These dimensions land
     ~ a third of the polycarb face width at default 4'×8'. */
  padding: 8px 16px;
  border-radius: 999px;
  border: 1.5px solid var(--orange, #E81820);
  background: var(--orange, #E81820);
  color: #fff;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(10, 18, 38, 0.18), 0 1px 2px rgba(10, 18, 38, 0.12);
  transition: background .15s ease, border-color .15s ease, transform .12s ease, box-shadow .15s ease;
  white-space: nowrap;
  line-height: 1;
}
.cab-face-upload-btn-icon svg {
  width: 14px;
  height: 14px;
}
.cab-face-upload-btn:hover {
  background: #c93f0f;
  border-color: #c93f0f;
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(232, 24, 32, 0.35), 0 2px 4px rgba(10, 18, 38, 0.18);
}
.cab-face-upload-btn:active { transform: translateY(0); }
.cab-face-upload-btn:focus-visible {
  outline: 2px solid #0A1226;
  outline-offset: 2px;
}
.cab-face-upload-btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}
.cab-face-upload-btn-label { line-height: 1; }

/* ── Vector-artwork-received card on the cabinet face ───────────────────
   Shown when a production vector/handoff file (AI/EPS/PDF) is attached.
   The browser can't render those inline, so this card confirms receipt
   instead of showing a broken-image icon. Centered on the polycarb face. */
.cab-face-vector-wrap {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  box-sizing: border-box;
  pointer-events: none;
}
.cab-face-vector-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  max-width: 82%;
  max-height: 100%;
  padding: 8px 14px;
  border-radius: 9px;
  border: 1.5px dashed rgba(10, 18, 38, 0.28);
  background: rgba(250, 247, 242, 0.94);
  box-shadow: 0 4px 14px rgba(10, 18, 38, 0.14);
  text-align: center;
  font-family: 'Inter', sans-serif;
  overflow: hidden;
}
.cab-face-vector-badge {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.08em;
  color: #fff;
  background: var(--orange, #E81820);
  padding: 1px 7px;
  border-radius: 999px;
}
.cab-face-vector-icon {
  display: inline-flex;
  color: #0A1226;
}
.cab-face-vector-icon svg { width: 18px; height: 18px; }
.cab-face-vector-name {
  font-size: 11px;
  font-weight: 700;
  color: #0A1226;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cab-face-vector-msg {
  font-size: 9.5px;
  font-weight: 600;
  line-height: 1.25;
  color: #5C6273;
}

/* ── Channel-letter uploaded-artwork conversion states ──────────────────────
   The AI/EPS/PDF design-area card is never a permanent placeholder. It shows a
   temporary "Converting preview…" state with a spinner, or a failure state with
   retry/replace actions, until the backend-rendered preview image swaps in. */
.cl-artwork-card.is-converting {
  border-color: rgba(232, 24, 32, 0.35);
  background: rgba(250, 247, 242, 0.97);
}
.cl-artwork-card.is-error {
  border-style: solid;
  border-color: rgba(232, 24, 32, 0.55);
  background: rgba(255, 245, 245, 0.97);
}
.cl-artwork-msg-error { color: #B42318; }
.cl-artwork-spinner {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2.5px solid rgba(10, 18, 38, 0.18);
  border-top-color: var(--orange, #E81820);
  animation: cl-artwork-spin 0.8s linear infinite;
}
@keyframes cl-artwork-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .cl-artwork-spinner { animation-duration: 2.4s; }
}
.cl-artwork-card-actions {
  display: flex;
  gap: 6px;
  margin-top: 5px;
}
.cl-artwork-card-btn {
  font-family: 'Inter', sans-serif;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.01em;
  padding: 4px 9px;
  border-radius: 6px;
  border: 1px solid var(--orange, #E81820);
  background: var(--orange, #E81820);
  color: #fff;
  cursor: pointer;
}
.cl-artwork-card-btn.is-secondary {
  background: #fff;
  color: #0A1226;
  border-color: rgba(10, 18, 38, 0.3);
}
.cl-artwork-card-btn:hover { filter: brightness(0.96); }

.cab-artwork-uploader {
  margin-top: 4px;
  margin-bottom: 14px;
}
.cab-artwork-uploader[data-active="false"] { display: none; }
.cab-artwork-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 6px;
  padding: 26px 16px;
  border: 2px dashed var(--border, #E5DFD3);
  border-radius: 12px;
  background: #FFFFFF;
  cursor: pointer;
  color: var(--navy, #0A1226);
  transition: border-color .15s ease, background .15s ease;
}
.cab-artwork-drop:hover {
  border-color: var(--orange, #E8521B);
  background: #FFF7F2;
}
.cab-artwork-drop-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--orange, #E8521B);
}
.cab-artwork-drop-primary {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.01em;
}
.cab-artwork-drop-secondary {
  font-size: 12px;
  color: var(--ink-muted, #5C6273);
  max-width: 380px;
  line-height: 1.4;
}
.cab-artwork-drop-tertiary {
  font-size: 11px;
  color: var(--ink-muted, #8C8779);
  letter-spacing: 0.02em;
}
.cab-artwork-drop-gate {
  display: block;
  font-size: 11px;
  margin-top: 4px;
  color: var(--orange, #E8521B);
  letter-spacing: 0.02em;
}
/* Once the customer is signed in (a real handoff grant / resolved account —
   set by reflectUploadAuthState in upload-panel-state.js), the dropzone is
   unlocked: drop the "Sign in or create an account…" gate line so the panel
   no longer reads as locked. Signed-out (guest, the default) keeps it visible. */
.cab-artwork-drop[data-upload-auth="authed"] .cab-artwork-drop-gate {
  display: none;
}
.cab-artwork-drop.is-drag-over {
  border-color: var(--orange, #E8521B);
  background: #FFF1E6;
}

/* Inline upload error — shown when the customer picks an unsupported
   type or an over-sized file. Sits directly under the drop label. */
.cab-artwork-error {
  margin: 8px 0 0;
  padding: 8px 12px;
  border-radius: 8px;
  background: #FDECEC;
  border: 1px solid #F1B7B7;
  color: #8A1F1F;
  font-size: 12.5px;
  line-height: 1.4;
}

/* Non-blocking backend design-upload status note (control panel). Distinct
   tones for in-flight / saved-to-account / local-only fallback so a working
   local preview never reads as an error while the backend persists the file. */
.cab-artwork-upload-status {
  margin: 8px 0 0;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.4;
  background: #EEF3FB;
  border: 1px solid #C6D8F0;
  color: #234876;
}
.cab-artwork-upload-status[data-tone="success"] {
  background: #EAF6EE;
  border-color: #BFE3CC;
  color: #1E5B33;
}
.cab-artwork-upload-status[data-tone="local"] {
  background: #FBF3E2;
  border-color: #EAD7A8;
  color: #6B5316;
}

/* Live design-area echo of the upload status. Anchored bottom-left over the
   preview so production-file progress sits near the floating controls dock
   (centered just below the canvas) without covering the controls or blocking
   the raster/vector preview underneath. */
.cab-face-upload-status {
  position: absolute;
  bottom: 12px;
  left: 12px;
  z-index: 6;
  max-width: min(78%, 360px);
  padding: 7px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.14);
  background: #EEF3FB;
  border: 1px solid #C6D8F0;
  color: #234876;
  pointer-events: none;
}
.cab-face-upload-status[data-tone="success"] {
  background: #EAF6EE;
  border-color: #BFE3CC;
  color: #1E5B33;
}
.cab-face-upload-status[data-tone="local"] {
  background: #FBF3E2;
  border-color: #EAD7A8;
  color: #6B5316;
}
/* The cabinet face status badge is only meaningful on the cabinet preview.
   The channel-letter variant (.cl-face-upload-status) is exempt — it has its
   own product-scoped visibility rule further down. */
.canvas-wrap:not([data-product="cabinet"]) .cab-face-upload-status:not(.cl-face-upload-status) { display: none; }
/* The channel-letter upload status badge only shows on the channel preview
   while in upload mode (JS unhides it; hide everywhere else). */
.canvas-wrap[data-product="cabinet"] .cl-face-upload-status,
.canvas-wrap:not([data-cl-mode="upload"]) .cl-face-upload-status { display: none; }

/* Fit / Fill / Stretch chip row — only visible after a previewable
   upload (cabArtworkFitRow.hidden is toggled by JS). */
.cab-artwork-fit {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 12px;
}
.cab-artwork-fit-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-muted, #5C6273);
  letter-spacing: 0.02em;
}
.cab-artwork-fit-chips {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
}
.cab-artwork-fit-chip {
  appearance: none;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border, #E5DFD3);
  background: #FFFFFF;
  color: var(--navy, #0A1226);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.cab-artwork-fit-chip:hover { border-color: var(--orange, #E8521B); }
.cab-artwork-fit-chip.is-active {
  background: var(--navy, #0A1226);
  border-color: var(--navy, #0A1226);
  color: #FFFFFF;
}
.cab-artwork-thumb {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 12px;
  padding: 10px;
  background: #FFFFFF;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 10px;
}
.cab-artwork-thumb img {
  width: 80px;
  height: 60px;
  object-fit: contain;
  background: #F4F2EC;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 6px;
}
/* File-type chip — shown in place of <img> when the upload is not a
   browser-previewable raster/vector (e.g. PDF, AI, EPS). The <img>
   element is set to hidden by JS in this state; this ::before paints a
   small extension badge in the same 80×60 footprint so the layout never
   collapses or shows the broken-image chrome. */
.cab-artwork-thumb[data-has-preview="false"]::before {
  content: attr(data-ext);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 60px;
  background: #F4F2EC;
  border: 1px dashed var(--border, #C8C2B0);
  border-radius: 6px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--navy, #0A1226);
  flex-shrink: 0;
}
.cab-artwork-thumb-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  flex: 1;
}
.cab-artwork-thumb-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--navy, #0A1226);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cab-artwork-thumb-remove {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--orange, #E8521B);
  cursor: pointer;
  text-align: left;
  width: max-content;
}
.cab-artwork-thumb-remove:hover { text-decoration: underline; }

.cab-design-notes {
  margin-top: 6px;
}
.cab-design-notes-label {
  display: block;
  margin-bottom: 6px;
}
.cab-design-notes-hint {
  font-weight: 500;
  font-size: 12px;
  color: var(--ink-muted, #5C6273);
  margin-left: 4px;
  letter-spacing: 0;
  text-transform: none;
}
.cab-design-notes-input {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 14px;
  line-height: 1.45;
  color: var(--navy, #0A1226);
  background: #FFFFFF;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 10px;
  padding: 10px 12px;
  resize: vertical;
  min-height: 72px;
}
.cab-design-notes-input:focus {
  outline: none;
  border-color: var(--orange, #E8521B);
  box-shadow: 0 0 0 3px rgba(232, 82, 27, 0.18);
}
.cab-design-notes-counter {
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--ink-muted, #5C6273);
  text-align: right;
}

/* When the customer is on cabinet mode, the channel-letter "Sign text"
   row is suppressed — typed text isn't the primary input for cabinets.
   The cabTextPanel (text styling overlay) is now gated to only appear
   if the customer explicitly opens it via the new toggle. */
body[data-product="cabinet"] #textInputLabel,
body[data-product="cabinet"] #textInput {
  display: none;
}
/* Cabinet mode is artwork-first: there is no typed-text on the cabinet
   face, so the floating Text styling overlay is hidden entirely. The
   element stays in the DOM so non-cabinet code paths that reference it
   still resolve. */
body[data-product="cabinet"] #cabTextPanel {
  display: none !important;
}

/* ════════════════════════════════════════════════════════════════
   Channel-letter Upload Logo / Vector Art mode
   Mode toggle, upload panel, sizing controls, and the rules that hide
   the typed-letter preview layers while in upload mode.
   ════════════════════════════════════════════════════════════════ */

/* Segmented Use Text / Upload toggle */
.cl-mode-toggle {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  padding: 4px;
  border-radius: 12px;
  background: #F2EEE4;
  border: 1px solid var(--border, #E5DFD3);
}
.cl-mode-btn {
  flex: 1 1 0;
  padding: 9px 10px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  font: inherit;
  font-weight: 600;
  font-size: 13px;
  color: var(--ink-muted, #5C6273);
  cursor: pointer;
  transition: background .15s ease, color .15s ease, box-shadow .15s ease;
}
.cl-mode-btn:hover { color: var(--navy, #0A1226); }
.cl-mode-btn.is-active {
  background: #FFFFFF;
  color: var(--navy, #0A1226);
  box-shadow: 0 1px 3px rgba(10, 18, 38, 0.12);
}

/* Upload panel */
.cl-upload-block .cl-artwork-uploader {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cl-artwork-error {
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  color: #9B1C1C;
}
.cl-artwork-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.cl-artwork-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--navy, #0A1226);
  word-break: break-all;
}
.cl-artwork-status {
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  padding: 7px 11px;
  border-radius: 8px;
  background: #EEF3FB;
  border: 1px solid #C6D8F0;
  color: #234876;
}
.cl-artwork-status[data-tone="success"] {
  background: #EAF6EE; border-color: #BFE3CC; color: #1E5B33;
}
.cl-artwork-status[data-tone="local"] {
  background: #FBF3E2; border-color: #EAD7A8; color: #6B5316;
}

/* "Use My Files" reuse picker — sits under the dropzone */
.cl-myfiles {
  margin-top: 10px;
}
.cl-myfiles-btn {
  width: 100%;
  padding: 9px 12px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--cs-navy, #0A1226);
  background: #fff;
  border: 1px solid #C6D8F0;
  border-radius: 9px;
  cursor: pointer;
}
.cl-myfiles-btn:hover {
  border-color: var(--cs-orange, #E8521B);
  color: var(--cs-orange, #E8521B);
}
.cl-myfiles-panel {
  margin-top: 8px;
}
.cl-myfiles-status {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 600;
  color: #5C6273;
}
.cl-myfiles-status[data-tone="local"] { color: #6B5316; }
.cl-myfiles-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 220px;
  overflow-y: auto;
}
.cl-myfiles-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 8px 11px;
  font: inherit;
  font-size: 13px;
  text-align: left;
  background: #F7F9FD;
  border: 1px solid #DCE6F4;
  border-radius: 8px;
  cursor: pointer;
}
.cl-myfiles-item:hover {
  border-color: var(--cs-orange, #E8521B);
  background: #fff;
}
.cl-myfiles-item-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cl-myfiles-item-ext {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: #5C6273;
}

/* Sizing row — upright height + locked-aspect width */
.cl-artwork-size {
  display: flex;
  align-items: flex-end;
  gap: 10px;
}
.cl-artwork-size-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 0;
}
.cl-artwork-size-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-muted, #5C6273);
}
.cl-artwork-size-input-wrap {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px 10px;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 9px;
  background: #FFFFFF;
}
.cl-artwork-size-input {
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  font-weight: 600;
  color: var(--navy, #0A1226);
  outline: none;
}
.cl-artwork-size-input[readonly] { color: var(--ink-muted, #5C6273); }
.cl-artwork-size-unit {
  font-size: 12px;
  color: var(--ink-muted, #8C8779);
}
.cl-artwork-size-x {
  padding-bottom: 12px;
  color: var(--ink-muted, #8C8779);
  font-weight: 700;
}
.cl-artwork-proof {
  margin: 0;
  font-size: 11px;
  line-height: 1.4;
  color: var(--ink-muted, #6B5316);
  background: #FBF3E2;
  border: 1px solid #EAD7A8;
  border-radius: 8px;
  padding: 7px 10px;
}
.cl-artwork-count {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  margin-top: 10px;
}
.cl-artwork-count .cl-artwork-size-field { flex: 0 0 auto; min-width: 96px; }
.cl-artwork-count-detail {
  padding-bottom: 12px;
  font-size: 12px;
  color: var(--ink-muted, #5C6273);
}

/* In upload mode the uploaded artwork is the primary design, so the typed
   word-block, raceway, and the text-driven measure rulers are hidden. The
   logo-overlay group is driven by updateClArtwork() instead. */
.canvas-wrap[data-cl-mode="upload"] #signGroup,
.canvas-wrap[data-cl-mode="upload"] #racewayGroup,
.canvas-wrap[data-cl-mode="upload"] #measureRuler,
.canvas-wrap[data-cl-mode="upload"] #measureWidthRuler {
  display: none !important;
}

/* ── Account state (builder header) ───────────────────────────
   Populated by app.js initAccountState(). Sits at the end of the
   .brand-bar flex row; baseline-aligned with the eyebrow. Empty
   while the session probe resolves so there's no wrong-state flash. */
.account-state {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.account-state[data-state="loading"] { visibility: hidden; }
.account-state .account-who {
  color: var(--ink-muted);
}
/* Sign-in / My Files reads as a pill control, matching the approved Lobby
   Vinyl header (panel.css .panel-header-account / .panel-header-link). */
.account-state .account-link {
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--line-strong, rgba(10, 18, 38, 0.18));
  background: #fff;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.account-state .account-link:hover,
.account-state .account-link:focus-visible {
  background: #F1ECE3;
  border-color: var(--navy);
}

/* ─────────────────────────────────────────────────────────────────────────
   Lobby Logo (interior) mode
   The same Beacon builder, constrained for interior channel letters. Scoped to
   body[data-lobby="true"] / #canvasWrap[data-lobby="true"] so Beacon mode is
   completely unaffected. See app.js applyLobbyMode().
   ───────────────────────────────────────────────────────────────────────── */

/* Lobby Logo hides the entire top band. The header already establishes the
   product (interior channel letters), so the exterior product picker and the
   letter-type cards no longer belong above the canvas. applyLobbyMode() moves
   the Halo-Lit / Trimless style picker into the right spec rail (.lobby-style-block)
   and this hides the now-empty band so the live design area expands upward to
   match the other builders (Lobby Panel / Vinyl). Beacon does the same via the
   universal .builder-topbar { display:none } rule below — this lobby-scoped rule
   is kept as a defensive belt-and-braces. */
body[data-lobby="true"] .builder-topbar { display: none; }

/* Relocated Lobby Logo style picker — Halo-Lit / Trimless now reads as a
   right-rail spec section like every other control block, not a top band.
   Cards sit side-by-side and fill the rail width. */
.lobby-style-block .style-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
  margin: 0;
}
/* Lead with the visual: each card is a large letter-style preview with a small,
   de-emphasized label underneath. The thumbnail communicates the Halo-Lit /
   Trimless look; the word is secondary confirmation, not the main signal. */
.lobby-style-block .style-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.5rem;
  padding: 0.7rem 0.7rem 0.55rem;
  text-align: center;
}
.lobby-style-block .style-card-desc { display: none; }
/* Hero thumbnail — fills the card width and dominates the card height so the
   letter style reads at a glance. */
.lobby-style-block .style-card-thumb {
  display: block;
  width: 100%;
  border-radius: 9px;
  overflow: hidden;
  line-height: 0;
}
.lobby-style-block .style-card-thumb svg {
  width: 100%;
  height: 72px;
  display: block;
}
/* De-emphasized label: smaller, muted, uppercase tracking so it reads as a
   caption beneath the visual rather than competing with it. */
.lobby-style-block .style-card-title {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.lobby-style-block .style-card.is-active .style-card-title {
  color: var(--navy);
  font-weight: 700;
}

/* ─────────────────────────────────────────────────────────────────────────
   Beacon: relocated Product-type + Letter-type pickers in the right rail
   relocateTopbarToRail() moves these out of the (now-hidden) top band so the
   live preview expands upward. They read as ordinary right-rail control
   blocks; the cards lead with the visual (icon / letter-style thumb) and a
   compact label, matching the approved Lobby Logo style-card treatment.
   Scoped to .rail-product-block / .rail-style-block so Beacon-only.
   ───────────────────────────────────────────────────────────────────────── */
.rail-product-block,
.rail-style-block {
  margin: 0 0 1rem;
  padding: 0;
  border: 0;
  min-width: 0;
}
.rail-product-block .control-header,
.rail-style-block .control-header {
  margin: 0 0 0.5rem;
}

/* Both pickers: a responsive grid of visual-led cards that fill the rail. */
.rail-product-block .product-cards,
.rail-style-block .style-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
  margin: 0;
}
.rail-product-block .product-card,
.rail-style-block .style-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.45rem;
  padding: 0.7rem 0.6rem 0.55rem;
  text-align: center;
  background: #FAF7F2;
  border: 1px solid var(--border, #E5DFD3);
  border-radius: 11px;
  transition: border-color 140ms ease, background 140ms ease, box-shadow 140ms ease;
}
.rail-product-block .product-card.is-active,
.rail-style-block .style-card.is-active {
  background: #FFF7F2;
  border-color: var(--orange, #E81820);
  box-shadow: 0 0 0 2px rgba(232, 24, 32, 0.18);
}

/* Product cards: lead with the line icon, label beneath. */
.rail-product-block .product-card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 34px;
  color: var(--navy, #0A1226);
}
.rail-product-block .product-card-icon svg { width: 26px; height: 26px; }
.rail-product-block .product-card-title {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: -0.005em;
  color: var(--ink, #0A1226);
}
.rail-product-block .product-card-desc { display: none; }

/* Hero-image product cards: the artwork IS the label. The image is scaled
   to fit inside the card with comfortable padding so the full word reads
   without clipping. Used for Channel Letters + Cabinet Sign in the
   product picker. The .product-card-title is kept as .sr-only for screen
   readers and click-target labelling. */
.rail-product-block .product-card.product-card--hero {
  padding: 10px;
  gap: 0;
  overflow: hidden;
  background: #FAF7F2;
  min-height: 96px;
}
.rail-product-block .product-card.product-card--hero.is-active {
  background: #FFF7F2;
}
.product-card-hero {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  max-height: 88px;
  object-fit: contain;
  object-position: center;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
}
/* Screen-reader-only utility (no visible space, still announced). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Letter-type cards: lead with the letter-style thumbnail hero, compact
   uppercase caption beneath — mirrors the Lobby Logo style cards. */
.rail-style-block .style-card-desc { display: none; }
.rail-style-block .style-card-thumb {
  display: block;
  width: 100%;
  border-radius: 9px;
  overflow: hidden;
  line-height: 0;
}
.rail-style-block .style-card-thumb svg {
  width: 100%;
  height: 60px;
  display: block;
}
.rail-style-block .style-card-title {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-muted, #5C6273);
}
.rail-style-block .style-card.is-active .style-card-title {
  color: var(--navy, #0A1226);
  font-weight: 700;
}
/* "Trimless $22/in" style badge stays legible as a small pill in the corner. */
.rail-style-block .style-card { position: relative; }
.rail-style-block .style-card-badge {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0.12rem 0.4rem;
  border-radius: 999px;
  background: var(--navy, #0A1226);
  color: #fff;
}
.rail-style-block .letter-type-help-toggle { margin-top: 0.6rem; }

/* Font picker: in Beacon mode the chip renders the live sign text at 22px,
   which ellipsizes to "SIGN ..." in the narrower interior layout and reads as
   unfinished. Lobby mode shrinks the specimen and tightens tracking so the
   sample word fits the chip without clipping; the font name below is unchanged.
   Beacon mode is untouched. */
body[data-lobby="true"] .font-chip-sample {
  font-size: 17px;
  letter-spacing: 0;
}

/* The premium Halo acrylic insert option is interior-only and Halo-Lit-only.
   JS sets [hidden] when the active style isn't Halo-Lit; this just styles it. */
.lobby-insert-block { margin-top: 0.5rem; }
.lobby-insert-label {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  cursor: pointer;
}
.lobby-insert-label input[type="checkbox"] {
  margin-top: 0.2rem;
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--orange, #E8521B);
  flex: 0 0 auto;
}
.lobby-insert-text { display: flex; flex-direction: column; gap: 0.15rem; }
.lobby-insert-text .control-hint { font-size: 0.8rem; }

/* ── Header (Lobby) ───────────────────────────────────────────────────────
   Lobby Logo shares the identical header with Beacon — same logo size, title
   lockup, divider, subtitle, and right-side pill controls — so the two modes
   read as one consistent visual language (Lobby Vinyl standard). Only the
   builder identity text differs, and that is set in JS (applyLobbyMode()). No
   mode-specific header sizing overrides remain. */

/* ── Illuminated letters in a lit room (Lobby only) ───────────────────────
   Lobby mode is a BRIGHT, lights-on daytime interior: the canvas stays in DAY
   mode (data-mode="day") so the photo backdrop never darkens, and there is no
   Day/Night toggle. But the sign should still read as illuminated — Halo-Lit
   must show its warm halo and Trimless its lit face glow. Those effects are
   normally gated on data-mode="night", so we re-enable them here for DAY mode,
   scoped to [data-lobby]. We deliberately do NOT apply the night dark-face /
   dark-return fills (those are for a dark exterior wall); in a lit room the
   letters keep their painted faces and just gain glow. */
body[data-lobby="true"] .toggle-block,
body[data-lobby="true"] #qcModeBtn { display: none; }

/* Halo-Lit: bloom the halo behind the letters even in day/lit mode. */
body[data-lobby="true"] .canvas-wrap[data-mode="day"][data-style="halolit"] .halo-outer { opacity: 1; }

/* Trimless: full lit-face glow + the trimless edge-bleed filter in day mode. */
body[data-lobby="true"] .canvas-wrap[data-mode="day"][data-style="trimless"] .face-glow { opacity: 1; }
body[data-lobby="true"] .canvas-wrap[data-mode="day"][data-style="trimless"] .face      { filter: url(#trimlessGlow); }

/* Keep the room bright: hold the daytime vignette low even if some other rule
   tries to darken it, and let the photo backdrop carry the wall. */
body[data-lobby="true"] .canvas-wrap .vignette-rect { opacity: 0.18; }

/* ── Font picker → compact dropdown (Lobby only) ──────────────────────────
   Replaces the Beacon card grid with a space-saving dropdown. Each option
   shows a live mixed-case specimen (uppercase + lowercase) in its own family
   so scripts/serifs are distinguishable at a glance. */
.font-dropdown { position: relative; }
.font-dropdown-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  padding: 0.6rem 0.85rem;
  border: 1px solid var(--line, #E2DED4);
  border-radius: 12px;
  background: var(--surface-2, #FBFAF6);
  color: var(--ink, #1B1B1B);
  cursor: pointer;
  text-align: left;
}
.font-dropdown-trigger:hover,
.font-dropdown-trigger[aria-expanded="true"] {
  border-color: var(--orange, #E8521B);
}
.font-dropdown-current {
  display: flex;
  align-items: baseline;
  gap: 0.65rem;
  min-width: 0;
}
.font-dropdown-caret { color: var(--muted, #6B6B6B); flex: 0 0 auto; }
.font-dropdown-list {
  position: absolute;
  z-index: 30;
  left: 0;
  right: 0;
  margin-top: 0.35rem;
  max-height: 320px;
  overflow-y: auto;
  list-style: none;
  padding: 0.3rem;
  border: 1px solid var(--line, #E2DED4);
  border-radius: 12px;
  background: var(--surface, #FFF);
  box-shadow: 0 18px 40px -22px rgba(10, 18, 38, 0.55);
}
.font-option {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  padding: 0.5rem 0.6rem;
  border-radius: 9px;
  cursor: pointer;
}
.font-option:hover { background: var(--surface-2, #F4F1EA); }
.font-option.is-active { background: rgba(232, 82, 27, 0.10); }
.font-option-sample {
  font-size: 22px;
  line-height: 1.05;
  color: var(--ink, #1B1B1B);
  flex: 0 0 auto;
}
.font-option-name {
  font-size: 0.85rem;
  color: var(--muted, #6B6B6B);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Upload Vector File entry (Beacon only) — not a real typeface, so it shows an
   upload glyph in place of a font specimen and a small format hint beneath the
   label. */
.font-option-sample--upload {
  font-size: 18px;
  line-height: 1.05;
  width: 1.4em;
  text-align: center;
  color: var(--orange, #E8521B);
  font-weight: 700;
}
.font-option--upload { border-top: 1px solid var(--line, #E2DED4); margin-top: 0.25rem; padding-top: 0.6rem; }
.font-option--upload .font-option-name { display: flex; flex-direction: column; gap: 1px; }
.font-option-sub {
  font-size: 0.7rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted, #6B6B6B);
}

/* ── Mounting (Lobby only): no Raceway ────────────────────────────────────
   Raceway is an exterior facade-penetration workaround; interior lobby letters
   mount Direct or on standoff studs. Hide the Raceway card and its color
   sub-picker. applyLobbyMode() also resets state.mountStyle off raceway. */
body[data-lobby="true"] .mount-card[data-value="raceway"] { display: none; }
body[data-lobby="true"] #racewayColorBlock { display: none; }

/* ── Proof Hub "Edit this item" edit-mode notice ──────────────────────────────
   Shown at the top of the controls rail only when the builder is opened from the
   Proof Hub edit deep-link (?cart=<token>&edit_item_id=<id>); app.js un-hides
   #editModeNotice and relabels the Add to Cart CTA to "Save changes". Small navy
   bordered note in the brand palette. */
.edit-mode-notice {
  margin: 0 0 16px;
  padding: 10px 14px;
  border: 1px solid var(--navy);
  border-left: 4px solid var(--navy);
  border-radius: 8px;
  background: var(--cream-2);
  color: var(--navy);
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.35;
}
.edit-mode-notice[hidden] { display: none; }
