/* ═══════════════════════════════════════════════════════════════════════════
   TFP Visualizer — shared shell components  (Plan §2.1)
   ───────────────────────────────────────────────────────────────────────────
   ONE stepper component + ONE price-bar component, shared byte-for-byte across
   the print / frame / mirror SPAs so the customer perceives a single product.
   Served same-origin at /visualizer-shared/shell.css (see configurator.py) and
   paired with /visualizer-shared/stepper.js (the dynamic step-engine).

   The PRINT STUDIO's stepper + price bar are the design reference (the best of
   the three) — these rules are lifted verbatim from it, tokenised with fallbacks
   so any app whose :root defines the "Forest on Air" tokens renders identically,
   and any app that doesn't still gets a sensible default.

   Design tokens expected on :root (all three apps define them):
     --panel-b --line --line-soft --gold --gold-lt --gold-dk --glow
     --dim --faint --text --ease
   Every var() below carries a fallback so a missing token never blanks a rule.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Stepper component ─────────────────────────────────────────────────────
   Markup contract (rendered by stepper.js — do NOT hand-author):
     #stepper[role=list]      → .step-dot[role=listitem]
                                  → .step-circle(.done|.active|.pending)
                                     • done  → role=button, tabindex=0, ✓
                                     • active→ aria-current=step, number
                                     • ahead-but-reachable → role=button, number
                                     • not-yet → number, no role
                                  → .step-line(.done|.pending)   (decorative)
     #step-labels[aria-hidden]→ .step-label(.done|.active|.pending)
   Inapplicable steps are ABSENT from the DOM (never dashed/disabled); the whole
   stepper is display:none while the journey sits on its gateway step. */
#stepper{display:flex;align-items:center;justify-content:center;padding:24px 18px 8px;flex-shrink:0;background:var(--panel-b,#FAF5F0);border-bottom:1px solid var(--line-soft,#E9E0D7)}
.step-dot{display:flex;align-items:center}
.step-circle{border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:600;transition:all .5s var(--ease,cubic-bezier(.22,1,.36,1));position:relative}
.step-circle.done{background:#ECE2D8;border:1.5px solid rgba(49,62,40,.4);color:var(--gold-dk,#2E2216);cursor:pointer}
.step-circle.active{background:radial-gradient(circle at 50% 35%,#46543A,#313E28);border:1.5px solid var(--gold,#313E28);color:#F2EAE4;box-shadow:0 0 0 4px rgba(49,62,40,.06),0 0 18px var(--glow,rgba(49,62,40,.18))}
.step-circle.pending{background:#FCF8F4;border:1.5px solid var(--line,#DED2C7);color:#C4B7A6}
/* ahead-but-already-reached steps read as pending but are clickable */
.step-circle.pending[role="button"]{cursor:pointer}
.step-line{height:1px;transition:background .5s var(--ease,cubic-bezier(.22,1,.36,1))}
.step-line.done{background:linear-gradient(90deg,rgba(49,62,40,.5),rgba(49,62,40,.25))}
.step-line.pending{background:var(--line-soft,#E9E0D7)}
#step-labels{display:flex;justify-content:center;padding:6px 18px 12px;flex-shrink:0;background:var(--panel-b,#FAF5F0);border-bottom:1px solid var(--line-soft,#E9E0D7)}
.step-label{text-align:center;text-transform:uppercase;font-weight:500;color:#CCC0B0;transition:color .4s var(--ease,cubic-bezier(.22,1,.36,1))}
.step-label.done{color:#566849}.step-label.active{color:var(--gold-lt,#4A5A3C)}

/* ─── Price-bar component ───────────────────────────────────────────────────
   Markup contract (each app populates its own numbers):
     #bottom
       #price-section[aria-live=polite][aria-atomic]   (display toggled by app)
         .price-row → .price-label + .price-display(#…)
         .price-note
         .bd-toggle[aria-expanded]        (breakdown disclosure)
         .breakdown(.open) → .bd-line[.gst|.tot] → .bl(.d) + .br
       .nav-row → back/next buttons (.btn / .btn-outline, app-local)
       .assist  → phone-order help line
   #bottom is a flex-shrink:0 footer; app supplies the .btn base styles. */
#bottom{padding:14px 22px;border-top:1px solid var(--line,#DED2C7);background:linear-gradient(180deg,#FBF7F2,#F7F5F5);flex-shrink:0}
#price-section{display:none;margin-bottom:12px}
.price-row{display:flex;justify-content:space-between;align-items:flex-end}
.price-label{font-size:9px;color:var(--dim,#8A7D6B);text-transform:uppercase;letter-spacing:1px}
.price-display{font-size:24px;font-weight:700;color:var(--gold,#313E28);font-variant-numeric:tabular-nums;letter-spacing:.3px;line-height:1;transition:opacity .25s}
#bottom.loading .price-display{opacity:.35}
.price-note{font-size:8px;color:var(--faint,#A3957F);letter-spacing:.8px;text-transform:uppercase;margin-top:4px}
.bd-toggle{font-size:10px;color:var(--gold-lt,#4A5A3C);background:none;border:none;cursor:pointer;font-family:inherit;padding:6px 0 0;text-decoration:underline;letter-spacing:.02em}
.breakdown{display:none;margin-top:10px;border-top:1px solid var(--line-soft,#E9E0D7);padding-top:10px}
.breakdown.open{display:block}
.bd-line{display:flex;justify-content:space-between;gap:10px;padding:3px 0;font-size:11px}
.bd-line .bl{color:#8C7357}.bd-line .bl .d{display:block;font-size:9px;color:var(--faint,#A3957F);margin-top:1px}
.bd-line .br{color:var(--text,#2E2216);font-variant-numeric:tabular-nums;font-weight:500}
.bd-line.gst{color:var(--dim,#8A7D6B)}.bd-line.tot{border-top:1px solid var(--line-soft,#E9E0D7);margin-top:4px;padding-top:7px;font-weight:700;color:var(--gold,#313E28)}
.nav-row{display:flex;gap:9px}
.nav-row .btn,.nav-row .btn-outline{flex:1}
.assist{text-align:center;margin-top:12px;font-size:11px;line-height:1.5;opacity:.72}
.assist a{text-decoration:underline}

/* ─── Door / content tiles component ────────────────────────────────────────
   The premium "What are we making?" tile language, lifted verbatim from the
   Design Studio gateway so the frame SPA's step-1 content picker reads as the
   SAME family (owner directive 23 Jul: content selection must be premium tiles,
   not a dropdown). The gateway keeps its own byte-identical inline copy of these
   rules (its inline <style> loads after this file, so it wins there — no visual
   change to the gateway); apps that don't redefine them (the frame SPA) inherit
   this shared component. Tokenised with fallbacks matching the gateway's values. */
.door-grid{display:grid;grid-template-columns:1fr;gap:12px}
.door-card{position:relative;display:flex;gap:15px;align-items:center;padding:20px 18px;border:1px solid var(--line,#DED2C7);border-radius:3px;cursor:pointer;
  background:linear-gradient(158deg,#EFE6DD,#F7F1EA);overflow:hidden;
  transition:transform .4s var(--ease,cubic-bezier(.22,1,.36,1)),border-color .4s var(--ease,cubic-bezier(.22,1,.36,1)),box-shadow .4s var(--ease,cubic-bezier(.22,1,.36,1)),background .4s var(--ease,cubic-bezier(.22,1,.36,1))}
.door-card::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at 82% 12%,rgba(49,62,40,.1),transparent 55%);opacity:0;transition:opacity .4s var(--ease,cubic-bezier(.22,1,.36,1))}
.door-card:hover{transform:translateY(-2px);border-color:var(--gold-dk,#2E2216);box-shadow:0 16px 36px -20px rgba(46,34,22,.28)}
.door-card:hover::before,.door-card.selected::before{opacity:1}
.door-card.selected{border-color:var(--gold,#313E28);background:linear-gradient(158deg,rgba(49,62,40,.12),rgba(49,62,40,.02));box-shadow:0 12px 34px -16px var(--glow,rgba(49,62,40,.18))}
.door-icon{width:52px;height:52px;flex-shrink:0;border-radius:3px;border:1px solid var(--line,#DED2C7);background:radial-gradient(circle at 50% 30%,#fff,#EFE6DD);display:flex;align-items:center;justify-content:center;color:var(--gold,#313E28)}
.door-icon svg{width:30px;height:30px}
.door-body{flex:1;min-width:0}
.door-name{font-size:15px;font-weight:600;color:#2E2216;letter-spacing:.2px}
.door-blurb{font-size:11px;color:var(--dim,#8A7D6B);margin-top:5px;line-height:1.5}
.door-arrow{color:var(--gold-lt,#4A5A3C);flex-shrink:0}

/* ─── Pieces tray component (Plan §4B) ──────────────────────────────────────
   "Add another piece" — one multi-line order built from N configured pieces,
   shared byte-for-byte between the frame and mirror SPAs (each app supplies
   its own thumb/desc/qty/subtotal per row via JS; markup below is the
   contract). Empty (no pieces added) → #pieces-tray-card stays display:none
   and the single-piece payload is completely unaffected — see each app's own
   submit code for the byte-identical-when-empty guarantee. */
.pieces-tray{display:flex;flex-direction:column;gap:10px}
.piece-row{display:flex;gap:12px;align-items:center;padding:10px;border:1px solid var(--line,#DED2C7);border-radius:2px;background:linear-gradient(150deg,#FFFFFF,#F7F1EA)}
.piece-thumb{width:48px;height:48px;border-radius:2px;border:1px solid var(--line,#DED2C7);background:radial-gradient(circle at 50% 35%,#FFFFFF,#E7DDD2);overflow:hidden;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:var(--faint,#A3957F);font-size:7px;letter-spacing:1.6px;text-transform:uppercase}
.piece-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.piece-body{flex:1;min-width:0}
.piece-name{font-size:11.5px;font-weight:600;color:#2E2216}
.piece-desc{font-size:10px;color:var(--dim,#8A7D6B);margin-top:2px;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.piece-meta{display:flex;gap:10px;margin-top:4px;font-size:9.5px;color:var(--faint,#A3957F);letter-spacing:.3px}
.piece-subtotal{font-size:12px;font-weight:600;color:var(--gold,#313E28);font-variant-numeric:tabular-nums;white-space:nowrap}
.piece-actions{display:flex;flex-direction:column;gap:4px;flex-shrink:0;align-items:flex-end}
.piece-edit,.piece-remove{background:none;border:none;padding:0;font-family:inherit;font-size:9.5px;text-decoration:underline;cursor:pointer;letter-spacing:.4px;text-transform:lowercase}
.piece-edit{color:var(--gold-lt,#4A5A3C)}
.piece-edit:hover{color:var(--gold-dk,#2E2216)}
.piece-remove{color:#B3402E}
.piece-remove:hover{color:#8A2F20}
.pieces-count-tag{font-size:8px;color:var(--faint,#A3957F);letter-spacing:1px;text-transform:none;font-weight:400}
.pieces-cap-note{font-size:10px;color:var(--dim,#8A7D6B);margin-top:10px;line-height:1.5}
.pieces-cap-note a{color:var(--gold-dk,#2E2216);text-decoration:underline}
#btn-add-piece{width:100%;margin-bottom:16px}

/* ═══════════════════════════════════════════════════════════════════════════
   CINEMATIC STUDIO SHELL  (Design System v3 · §06 + §07)  — Wave III
   ───────────────────────────────────────────────────────────────────────────
   ONE shared implementation of the "a room you design inside" grammar, consumed
   byte-for-byte by the frame / mirror / print SPAs. The 3D canvas becomes the
   full-bleed room; the config panel becomes a floating frosted-glass panel; the
   stepper becomes a hairline timeline across the top; the running price becomes a
   brass plaque pinned bottom-left. Component look lives HERE; each SPA supplies
   only markup classes + minimal positioning (see the FRAME reference in
   tfp-visualizer/index.html). Engines are untouched — presentation only.

   v3 gallery tokens (with fallbacks to the Forest-on-Air tokens each SPA already
   defines, so a missing token never blanks a rule). Each SPA may set --serif to
   its own display face (frame: Qeraldin); the fallback keeps the plaque legible.
   ═══════════════════════════════════════════════════════════════════════════ */
:root{
  --wall:#FBF8F4; --gesso:#F1E9E1; --forest:#313E28; --walnut:#7C664D;
  --ink:#262019; --brass:#A98D5F;
  --serif:'Cormorant Garamond',Georgia,'Times New Roman',serif;
}

/* ─── The floating frosted-glass panel ──────────────────────────────────────
   Look only — each SPA positions its own panel (inset over the room, internally
   scrollable, 0px radius). See FRAME: #panel gets .studio-glass-panel + inset. */
.studio-glass-panel{
  background:rgba(251,248,244,.68);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border:1px solid rgba(38,32,25,.1);border-radius:0;
  box-shadow:0 30px 80px -34px rgba(38,32,25,.5)}

/* ─── The hairline timeline (restyled shared stepper) ───────────────────────
   BEHAVIOUR IS UNCHANGED: the shared step-engine still renders #stepper (the
   clickable, aria-labelled circles) + #step-labels; here we only recolour and
   shrink them into a timeline. Circles collapse to small nodes (font-size:0 hides
   the glyph but keeps the 44px-safe click target + aria on the element); the caps
   labels carry the reading — active = forest + brass underline, done = walnut,
   upcoming = faded. Each SPA wraps #stepper + #step-labels in .studio-timeline
   and positions it top-centre over the room. Inline geometry from stepper.js is
   overridden with !important (the engine sets width/height/font-size inline). */
.studio-timeline{pointer-events:none;text-align:center;
  background:linear-gradient(180deg,rgba(251,248,244,.92),rgba(251,248,244,0));
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent);
  padding:16px 26px 15px}
.studio-timeline #stepper,.studio-timeline #step-labels{
  background:none!important;border:none!important;padding:2px 0!important}
.studio-timeline #stepper{pointer-events:auto}
/* Keep the engine's circle BOX (so #step-labels, sized off it, stay aligned) but
   render the node as a small centred dot pseudo — glyph hidden, click/aria intact. */
.studio-timeline .step-circle{background:none!important;border:none!important;
  box-shadow:none!important;color:transparent!important;position:relative}
.studio-timeline .step-circle::before{content:'';position:absolute;top:50%;left:50%;
  width:10px;height:10px;transform:translate(-50%,-50%);border-radius:50%;background:#D9CFC3;
  transition:background .4s var(--ease,cubic-bezier(.22,1,.36,1))}
.studio-timeline .step-circle.active::before{background:var(--forest,#313E28);box-shadow:0 0 0 3px rgba(49,62,40,.14)}
.studio-timeline .step-circle.done::before{background:var(--walnut,#7C664D)}
.studio-timeline .step-line.done{background:var(--walnut,#7C664D)!important;opacity:.55}
.studio-timeline .step-line.pending{background:rgba(38,32,25,.14)!important}
.studio-timeline .step-label{font-size:10.5px!important;letter-spacing:.13em!important;
  font-weight:700;text-transform:uppercase;padding-bottom:5px;white-space:nowrap;
  transition:color .4s var(--ease,cubic-bezier(.22,1,.36,1))}
.studio-timeline .step-label.active{color:var(--forest,#313E28)!important;
  border-bottom:1px solid var(--brass,#A98D5F)}
.studio-timeline .step-label.done{color:var(--walnut,#7C664D)!important}
.studio-timeline .step-label.pending{color:rgba(124,102,77,.42)!important}

/* ─── The brass plaque (running price) ──────────────────────────────────────
   Recipe from DESIGN_SYSTEM §03. Each SPA restyles its own price element to this
   markup (eyebrow · serif tabular price · sub-line) and pins it bottom-left over
   the room. See FRAME: #price-section.studio-plaque. */
.studio-plaque{display:inline-block;border-radius:0;
  background:linear-gradient(170deg,#C7AC7C,#A98D5F 55%,#B79A69);padding:2.5px;
  box-shadow:0 12px 30px -12px rgba(38,32,25,.55)}
.studio-plaque .sp-in{background:linear-gradient(180deg,#EFE3C8,#E3D3AF);padding:11px 22px;text-align:left}
.studio-plaque .sp-eyebrow{font-size:9px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:#6E5A35}
.studio-plaque .sp-price{font-family:var(--serif,'Cormorant Garamond',Georgia,serif);
  font-size:34px;line-height:1.05;color:#3D3016;margin:2px 0 1px;font-weight:500;
  font-variant-numeric:tabular-nums;letter-spacing:.5px;transition:opacity .25s}
/* sub-line ("incl. GST"): #84713F measured 4.49:1 on the phone bar and 3.2:1 on the plaque's
   own gradient (audit 1 Oct 2026, P-F14) — #665230 is ≥ 5:1 on both */
.studio-plaque .sp-sub{font-size:9.5px;color:#665230;letter-spacing:.02em;text-transform:none;font-weight:400}

/* ─── Moulding thumbnails (picker) ──────────────────────────────────────────
   These used to be clipped into an L with a drawn 45° mitre seam, on the idea
   that a framer hands you a corner sample. Owner call, 27 Jul: show the
   photographs as they are. The reasoning holds — a good half of the library is
   already photographed as a mitred corner, so the clip was cutting a corner out
   of a corner, and on the plain strip shots it removed the very part of the face
   the customer is trying to judge.
   The sizing hooks and the Forest selection outline stay; the frame picker's
   grid overrides the 44px box (index.html, #frame-catalogue). */
.cs-thumb{position:relative;width:44px;height:44px;flex-shrink:0;overflow:hidden;
  background:var(--gesso,#F1E9E1)}
.cs-thumb .thumb,.cs-thumb img.thumb{width:100%!important;height:100%!important;
  border-radius:0!important;box-shadow:none!important;object-fit:cover}
.item-card.selected .cs-thumb{outline:2px solid var(--forest,#313E28);outline-offset:2px}
.item-card.selected .cs-thumb::before{content:'';position:absolute;inset:0;pointer-events:none;
  box-shadow:0 0 0 1px rgba(49,62,40,.25)}

/* ─── Mobile: bottom-sheet + compressed timeline ────────────────────────────
   The glass panel becomes a bottom sheet (drag-handle affordance); the timeline
   compresses to dots + the current label only; the plaque docks above the sheet.
   Positioning is per-SPA; these are the shared component bits. */
@media(max-width:768px){
  .studio-timeline{padding:12px 16px 10px}
  .studio-timeline .step-label{display:none}
  .studio-timeline .step-label.active{display:block;font-size:10px!important}
  .studio-glass-panel::after{content:'';position:absolute;top:7px;left:50%;transform:translateX(-50%);
    width:40px;height:4px;border-radius:0;background:rgba(38,32,25,.24);z-index:6;pointer-events:none}
}

/* ─── Reduced-motion: collapse all shell motion ─────────────────────────────
   Motion rule (Design System v3): prefers-reduced-motion collapses ALL motion.
   The print SPA already carries a global guard, but the frame + mirror SPAs do
   not — so the cinematic-shell transitions introduced HERE (studio timeline /
   glass panel / plaque / door + piece tiles / corner samples / shared stepper)
   must neutralise themselves in the shared layer. Presentation only; the 3D
   engines animate via requestAnimationFrame, not CSS, so this never touches them. */
@media(prefers-reduced-motion:reduce){
  .studio-timeline,.studio-timeline *,.studio-glass-panel,.studio-glass-panel *,
  .studio-plaque,.studio-plaque *,.door-card,.door-card::before,.door-icon,
  .cs-thumb,.cs-thumb .thumb,.cs-thumb img.thumb,.piece-row,.piece-edit,.piece-remove,
  #stepper,.step-circle,.step-line,.step-label,#price-section,.price-display,.bd-toggle{
    transition-duration:.001ms!important;animation-duration:.001ms!important;
    transition-delay:0ms!important;animation-delay:0ms!important}
}

/* ═══════════════════════════════════════════════════════════════════════════
   WAVE IV — ONE INTERIOR (17 Sep 2026)
   ---------------------------------------------------------------------------
   Gallery Direction v3 reached only the outer shell (timeline, glass panel,
   brass plaque). Every card, button, toggle and field the customer actually
   touches still ran each app's older "Forest on Air" palette at 2px radius.
   All three SPAs declare the SAME local variable names, so re-pointing them
   here — at :root:root, which out-specifies each app's own :root whether this
   sheet loads before or after the inline styles — retints every interior in
   one move. Zero radius is then enforced on the panel's descendants (the
   toggle switch and the stepper circles are the deliberate exceptions), and
   one selection idiom replaces three: a plate with a hairline rule, selected
   = forest left-rule + forest border. No engine, no markup, no per-file hex
   hunt. Presentation only.
   ═══════════════════════════════════════════════════════════════════════════ */
:root:root{
  --bg:#FBF8F4;           /* wall  */
  --panel-a:#FFFFFF;
  --panel-b:#F1E9E1;      /* gesso */
  --line:rgba(38,32,25,.16);
  --line-soft:rgba(38,32,25,.09);
  --gold:#313E28;         /* forest — the only loud colour */
  --gold-lt:#313E28;
  --gold-dk:#262019;      /* ink */
  --text:#262019;
  --dim:#7C664D;          /* walnut — labels & secondary */
  --faint:#8A7F70;
}

/* ── house radius: 2px, measured off the live site ─────────────────────────
   The written spec says "0px everywhere", but the shipped theme does not: the
   site's own primary CTA ("Start a piece") renders at border-radius 2px, and
   2px is the only non-pill radius the homepage and /custom-framing use. The
   configurators sit INSIDE that site, so they follow what the site actually
   does — a door at 0px next to a page at 2px reads as a different product.
   Pills, the toggle switch and the stepper circles keep their own shapes. */
.studio-glass-panel *:not(.switch):not(.track):not(.knob):not(.step-circle):not(.h-trust):not(.toast-act),
.studio-plaque, .studio-plaque *, #toast,
#tfpds-continue, #tfpds-continue *, #tfpproj-sheet, #tfpproj-sheet *{
  border-radius:2px!important;
}

/* ── one selection idiom ───────────────────────────────────────────────────── */
.studio-glass-panel .door-card,
.studio-glass-panel .opt-card,
.studio-glass-panel .mount-card,
.studio-glass-panel .media-card,
.studio-glass-panel .size-card,
.studio-glass-panel .shape-card,
.studio-glass-panel .glass-card,
.studio-glass-panel .lane-card,
.studio-glass-panel .toggle-row,
.studio-glass-panel .review-card{
  background:var(--panel-a,#FFFFFF)!important;
  border:1px solid var(--line,rgba(38,32,25,.16))!important;
  box-shadow:none!important;
  transform:none!important;
}
.studio-glass-panel .door-card::before,
.studio-glass-panel .opt-card::before,
.studio-glass-panel .mount-card::before{ display:none!important; }
.studio-glass-panel .door-card:hover,
.studio-glass-panel .opt-card:hover,
.studio-glass-panel .mount-card:hover,
.studio-glass-panel .media-card:hover,
.studio-glass-panel .size-card:hover,
.studio-glass-panel .shape-card:hover,
.studio-glass-panel .glass-card:hover,
.studio-glass-panel .lane-card:hover{
  border-color:var(--walnut,#7C664D)!important;
  background:var(--panel-a,#FFFFFF)!important;
}
.studio-glass-panel .door-card.selected,
.studio-glass-panel .opt-card.selected,
.studio-glass-panel .mount-card.selected,
.studio-glass-panel .media-card.selected,
.studio-glass-panel .size-card.selected,
.studio-glass-panel .shape-card.selected,
.studio-glass-panel .glass-card.selected,
.studio-glass-panel .lane-card.selected,
.studio-glass-panel .lane-card[aria-checked="true"],
.studio-glass-panel .door-card[aria-pressed="true"]{
  border-color:var(--forest,#313E28)!important;
  box-shadow:inset 3px 0 0 var(--forest,#313E28)!important;
  background:var(--panel-a,#FFFFFF)!important;
}
/* ── the tick badge marks the CHOSEN plate, and only the chosen plate ───────
   Each app draws an empty ring on every card and colours in the tick on the
   selected one (`.media-card.selected .mc-check`, etc). Forcing a fill on the
   bare class — which this block used to do — lit every tick at once, so a
   four-option list read as four things chosen. Hide the mark by default and
   let any selected ancestor reveal it, whatever the card is called. */
.studio-glass-panel .door-check,
.studio-glass-panel .mc-check,
.studio-glass-panel .oc-check{ opacity:0!important; }
.studio-glass-panel .selected .door-check,
.studio-glass-panel .selected .mc-check,
.studio-glass-panel .selected .oc-check,
.studio-glass-panel [aria-pressed="true"] .door-check,
.studio-glass-panel [aria-checked="true"] .oc-check{
  opacity:1!important;
  background:var(--forest,#313E28)!important; color:var(--wall,#FBF8F4)!important;
  border-color:var(--forest,#313E28)!important;
}
/* a chevron promises navigation; these tiles are selections — only the
   gateway's tiles actually navigate, so only there does the arrow stay */
#content-tiles .door-arrow, #type-cards .door-arrow{ display:none!important; }

/* ── copy, labels and plates ───────────────────────────────────────────────── */
.studio-glass-panel .form-label{
  color:var(--walnut,#7C664D)!important; font-weight:600; letter-spacing:.14em;
}
.studio-glass-panel .content-chip{
  background:var(--panel-b,#F1E9E1)!important; border:1px solid var(--line)!important;
  box-shadow:inset 3px 0 0 var(--forest,#313E28)!important;
}
.studio-glass-panel .content-chip .cc-change{ color:var(--walnut,#7C664D)!important; text-decoration:underline; text-underline-offset:3px; }
.studio-glass-panel input[type="number"],
.studio-glass-panel input[type="text"],
.studio-glass-panel input[type="email"],
.studio-glass-panel input[type="tel"],
.studio-glass-panel select,
.studio-glass-panel textarea{
  background:var(--panel-a,#FFFFFF)!important; border:1px solid var(--line)!important;
}
/* Chrome's native number spinner is the loudest "unstyled" tell left in the
   panel (owner, 18 Sep). Every number field here is either typed (dimensions)
   or has its own −/+ pair (quantity), so the stepper earns nothing. */
.studio-glass-panel input[type="number"]{ -moz-appearance:textfield; appearance:textfield; }
.studio-glass-panel input[type="number"]::-webkit-outer-spin-button,
.studio-glass-panel input[type="number"]::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
.studio-glass-panel input:focus, .studio-glass-panel select:focus, .studio-glass-panel textarea:focus{
  border-color:var(--forest,#313E28)!important; box-shadow:none!important;
}
/* buttons: one forest primary, one hairline secondary */
.studio-glass-panel .btn, .studio-glass-panel .gold-btn{
  background:var(--forest,#313E28)!important; color:var(--wall,#FBF8F4)!important;
  box-shadow:none!important; letter-spacing:.12em;
}
.studio-glass-panel .btn:hover:not(:disabled), .studio-glass-panel .gold-btn:hover:not(:disabled){
  background:var(--forest-deep,#232D1C)!important; transform:none!important;
}
.studio-glass-panel .btn-outline{
  background:transparent!important; color:var(--ink,#262019)!important;
  border:1px solid var(--line)!important; box-shadow:none!important;
}
.studio-glass-panel .btn-outline:hover:not(:disabled){ border-color:var(--walnut,#7C664D)!important; }
/* motion: transform/opacity only, and only on the things that move */
.studio-glass-panel .door-card, .studio-glass-panel .opt-card, .studio-glass-panel .mount-card{
  transition:border-color .25s ease, box-shadow .25s ease!important;
}
/* review spec values wrap rather than truncate — a reference cut to "A53701 — Vienna - Black (20H x…"
   is a value the customer cannot read, on the one screen that says "this is what we'll make" */
.studio-glass-panel .rv-row .rv-value{ white-space:normal!important; overflow:visible!important; text-overflow:clip!important; max-width:64%; text-align:right; line-height:1.35; }
/* phone: nothing the customer must read may fall under 11px (Priya round 3: the "/m" unit at
   7.2px, option captions at 7.5–9px, and the sentence saying the quote is not final at 9px) */
@media (max-width:768px){
  .studio-glass-panel .item-card .price small{ font-size:.9em!important; }
  .studio-glass-panel .mc-tag, .studio-glass-panel .mc-desc, .studio-glass-panel .door-blurb,
  .studio-glass-panel .oc-meta, .studio-glass-panel .tr-sub, .studio-glass-panel .rv-detail,
  .studio-glass-panel .rv-fineprint, .studio-glass-panel .upload-hint, .studio-glass-panel .mount-inline-hint,
  .studio-glass-panel .gz-lede, .studio-glass-panel .li-lede, .studio-glass-panel .form-group > div[style*="font-size:9"],
  .studio-glass-panel .step-panel > p[style*="font-size:9"], .studio-glass-panel .assist,
  .studio-glass-panel .glass-card .chip, .studio-glass-panel .oc-price, .studio-glass-panel .rv-warn{ font-size:11px!important; line-height:1.45; }
  .studio-plaque .sp-sub, .studio-plaque .price-note{ font-size:10.5px!important; }
}
.studio-glass-panel .gq-note{ font-size:11px; color:var(--walnut,#7C664D); line-height:1.5; margin:10px 0 0; }
.studio-glass-panel .cat-hint{ font-size:11px; color:var(--walnut,#7C664D); line-height:1.5; margin:0 0 8px; }
@media (max-width:768px){
  .studio-glass-panel .item-card .price small{ font-size:10.5px!important; }
  /* 3 Oct 2026 (studio audit): 11 px is the site's label floor on a phone; 10.5 contradicted the rule above. */
  .studio-glass-panel .rv-group-head span, .studio-glass-panel .rv-section-title, .studio-glass-panel .rv-edit,
  .studio-glass-panel .rv-source-tag, .studio-glass-panel .rv-label{ font-size:11px!important; }
  .studio-glass-panel .step-panel .subtitle, .studio-glass-panel .panel-step .subtitle{ font-size:11px!important; }
  .studio-glass-panel .rv-sum-desc{ font-size:11px!important; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   WAVE V — HOUSE STYLE (17 Sep 2026)
   Measured off the running site, not off the spec sheet:
     ground   #FBF8F4      · headings  Qeraldin 400, ink #262019, tight tracking
     body     Niveau Grotesk 300–400 16px
     primary  Niveau Grotesk 11.5px / 700 / 2.3px tracking / UPPERCASE
              #FBF8F4 on forest #313E28, padding 11px 22px, radius 2px
   The doors were running an older ground (#F2EAE4), a softer heading brown
   (#2E2216) and a lighter, sentence-case CTA — close enough to look like a
   near-miss, which is worse than an obvious difference.
   ═══════════════════════════════════════════════════════════════════════════ */
body{ background:#FBF8F4; }

.studio-glass-panel .step-panel h2, .studio-glass-panel .step-panel h3,
.studio-glass-panel .panel-step h2, .studio-glass-panel .panel-step h3{
  color:var(--ink,#262019)!important; letter-spacing:-.01em!important;
}

.studio-glass-panel .btn, .studio-glass-panel .gold-btn,
.studio-glass-panel .btn-outline, #bottom .btn, #bottom .btn-outline,
#bottom-bar .btn, #bottom-bar .btn-outline{
  font-family:'Niveau Grotesk','Hanken Grotesk',system-ui,sans-serif!important;
  font-size:11.5px!important; font-weight:700!important; letter-spacing:2.3px!important;
  text-transform:uppercase!important; padding:11px 22px!important; border-radius:2px!important;
}
.studio-glass-panel .btn, .studio-glass-panel .gold-btn, #bottom .btn, #bottom-bar .btn{
  background:var(--forest,#313E28)!important; color:#FBF8F4!important; border:1px solid var(--forest,#313E28)!important;
}
.studio-glass-panel .btn-outline, #bottom .btn-outline, #bottom-bar .btn-outline{
  background:transparent!important; color:var(--ink,#262019)!important;
  border:1px solid var(--line,rgba(38,32,25,.16))!important;
}
.studio-glass-panel .btn-outline:hover:not(:disabled){ border-color:var(--walnut,#7C664D)!important; }
/* the two explanatory notes under the Review actions are prose, not chrome */
.studio-glass-panel .gq-note, .studio-glass-panel .cat-hint{ text-transform:none; letter-spacing:normal; }
/* segmented-control icons: the house's 1.4-stroke line language, not emoji —
   an emoji renders in the OS font and is the one thing on the screen the
   studio did not draw */
.studio-glass-panel .seg-ico{display:inline-flex;width:15px;height:15px;margin-right:7px;
  vertical-align:-2px;color:var(--walnut,#7C664D)}
.studio-glass-panel .seg-ico svg{width:100%;height:100%}
.studio-glass-panel .seg-btn.active .seg-ico{color:var(--forest,#313E28)}

/* ═══ PHONE LAYOUT (≤ 768 px) — phase 7, 30 Sep 2026 ═══════════════════════════════════════════
   Owner, 30 Sep (phone + installed app): the step label and the price plaque sat on the
   preview, "2D" floated, the dots sat inside the stage, option cards slid under it and
   Back / Next hid behind the app's tab bar. One layout for the three studios instead:

     ┌ stepper row ─────────── fixed, its own band (dots + the step's name)
     ├ stage ───────────────── sticky, opaque; row + stage = 36 % of the screen
     │  (preview only; the view buttons in its bottom-right corner)
     ├ options ─────────────── the ONE scroll container: this document
     └ bar ─────────────────── fixed: the price (once, "incl. GST" once) + Back / Next

   Host contract (tfp_website_cpq views/configurator_templates.xml sets these on <html> when
   the studio runs inside the site; standalone they fall back):
     --tfp-stage  px  stepper row + stage = 36 % of the SCREEN (inside an iframe vh is the
                      iframe's height, not the screen's)
     --tfp-sab    px  bottom inset the host could not absorb (0 when the host's own chrome,
                      e.g. the installed app's tab bar, already sits below the frame)
   The host sizes the frame to the visible area between its bar and its bottom chrome, so the
   studio's fixed bands are always on screen. */
@media (max-width:768px){
  html{--tfp-row:60px;--tfp-bar:60px;--tfp-sab-v:var(--tfp-sab,env(safe-area-inset-bottom,0px));
    --tfp-stage-v:var(--tfp-stage,36vh);
    scroll-padding-top:var(--tfp-stage-v);
    scroll-padding-bottom:calc(var(--tfp-bar) + var(--tfp-sab-v) + 12px);
    overscroll-behavior-y:contain}
  body{overscroll-behavior-y:contain}
  html #app{padding-top:var(--tfp-row)!important;min-height:0!important}

  /* the stepper: its own band at the top, never on the preview */
  html #studio-timeline.studio-timeline{position:fixed!important;top:0!important;left:0!important;right:0!important;
    width:auto!important;height:var(--tfp-row);transform:none!important;margin:0!important;
    padding:4px 16px 0!important;background:#F7F2EC!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important;border:0!important;-webkit-mask-image:none!important;mask-image:none!important;pointer-events:auto!important;border-bottom:1px solid rgba(38,32,25,.10)!important;box-shadow:none!important;z-index:30;
    display:flex;flex-direction:column;align-items:center;justify-content:flex-start}
  html #studio-timeline #stepper{padding:6px 0 0!important}
  html #studio-timeline .step-label.active{font-size:11px!important;letter-spacing:.12em!important;padding-bottom:2px}

  /* the stage: preview only, opaque, pinned under the stepper */
  html #canvas-container,html #stage{inset:auto!important;position:sticky!important;top:var(--tfp-row)!important;
    width:100%!important;height:calc(var(--tfp-stage-v) - var(--tfp-row))!important;min-height:170px!important;
    flex:none!important;z-index:20;box-shadow:0 12px 16px -16px rgba(46,34,22,.55)}
  html #canvas-container{background:#E9E1D8}
  /* the view buttons: 44 px, in the stage's bottom-right corner */
  html #view-toggle{top:auto!important;left:auto!important;bottom:10px!important;right:10px!important;
    min-width:44px!important;min-height:44px!important}

  /* the bar: Back / Next, fixed at the bottom, above the safe area */
  html #bottom-bar,html #bottom{position:fixed!important;left:0;right:0;bottom:0;z-index:30;
    min-height:var(--tfp-bar);padding:8px 14px calc(8px + var(--tfp-sab-v))!important;margin:0!important;
    background:#FBF8F4!important;border-top:1px solid rgba(38,32,25,.12)!important;box-shadow:0 -10px 18px -16px rgba(46,34,22,.5)}
  html :is(#bottom-bar,#bottom) .nav-row{gap:8px;margin:0}
  html :is(#bottom-bar,#bottom) .nav-row button{min-height:44px;padding-top:0;padding-bottom:0}
  /* the price joins the bar, left of Back / Next: the figure, then "incl. GST" once */
  html #price-section.studio-plaque{position:fixed!important;left:14px!important;right:auto!important;top:auto!important;
    bottom:calc(8px + var(--tfp-sab-v))!important;z-index:31;height:44px;width:112px;padding:0!important;margin:0!important;transform:none!important;background:none!important;box-shadow:none!important;border:0!important}
  html #price-section .sp-in{background:none;padding:0;height:100%;display:grid;align-content:center;gap:1px}
  html #price-section .sp-eyebrow{display:none}
  html #price-section .sp-price{font-size:21px;line-height:1;margin:0;white-space:nowrap}
  html #price-section .sp-sub{font-size:11px!important;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  html:has(#price-section.studio-plaque:not([style*="display: none"]):not([style*="display:none"])) :is(#bottom-bar,#bottom) .nav-row{margin-left:118px}
  /* the options end above the bar */
  html #panel{padding-bottom:calc(var(--tfp-bar) + var(--tfp-sab-v) + 16px)!important}
  html .step-panel{padding-bottom:16px!important}
  html .assist-note{margin:4px 16px 0!important}
}
@media (max-width:768px){
  /* a hand-off card (suspended > 1200 mm) stands where the price would: over the bar, full width */
  html #handoff-card{position:fixed!important;left:0!important;right:0!important;top:auto!important;max-width:none!important;
    bottom:calc(var(--tfp-bar) + var(--tfp-sab-v))!important;z-index:29;margin:0!important;border-radius:0}
  /* the print studio's gateway has no stepper and no stage: the picker is the page */
  html #app:has(#stage-hero.on){padding-top:0!important}
  html #app:has(#stage-hero.on) #studio-timeline{display:none!important}
}

/* ── Every width (phase 7, 30 Sep 2026): the step names read, and touch gets 44 px ──────
   The stepper draws its labels at 8 px inline and the pending ones in a pale sand that
   measured under 3:1 on the wall. 11 px is the site's label floor. */
.studio-timeline .step-label{font-size:11px!important;letter-spacing:.1em!important;white-space:nowrap}
.studio-timeline .step-label.pending{color:#6B5F50!important}
@media (pointer:coarse){
  :is(.dim-input input,#art-width,#art-height,#mir-width,#mir-height){min-height:44px;font-size:16px!important}
  :is(.phone-handoff,#bottom-bar .nav-row button,#bottom .nav-row button){min-height:44px}
  #view-toggle{min-width:44px!important;min-height:44px!important}
  :is(.cc-change,.assist-note a,label.switch){position:relative}
  :is(.cc-change,.assist-note a)::after{content:"";position:absolute;left:-6px;right:-6px;top:50%;height:44px;transform:translateY(-50%)}
  label.switch::after{content:"";position:absolute;inset:-9px -4px}
}

/* ═══ PHONE STUDIO (owner, 20 Oct 2026) ═══════════════════════════════════════════════════════
   Over 60% of visits are phones. Three rounds with the owner, one section (it replaced five
   layered passes that had grown 57 text styles and 15 control heights):
     1. direction A: the picture on top, every choice in a sheet below it with the steps as tabs,
        price · Review › · Next in the bar, Add to cart on the Review step only;
     2. "users will miss it if they don't scroll and just go next": one screen per step, the
        extras behind "More options", long lists scrolling inside the sheet; "the preview needs to
        be half or 3/4 of the screen … expanding like Uber": the sheet rises over the picture;
     3. "text sizes are all different, buttons big and small, no consistency; the size option is
        hidden behind a scroll": seven text styles, one 44 px control, an 8 px grid, and each
        step's main choice visible at rest. Spec: 04_reports/mobile-first-2026-10-20/PHONE-SPEC.md.
   The look is the website's own (Gallery Direction v3 as the product page draws it on a phone).

     ┌ studio top bar ──── the host page's (configurator_templates.xml), 48 px
     ├ picture ─────────── fixed; as large as the step allows at rest (stepper.js keeps 220 px of
     │                     sheet content visible), scaled and centre-cropped as the sheet rises
     ├ sheet band ──────── handle + numbered step tabs (stepper.js)
     ├ options ─────────── this document scrolls under the band
     └ bar ─────────────── price · Review › · Next (Back is the tabs' job here)

   html.tfp-phone is set by stepper.js (loaded in <head>) under 768 px; html.tfp-gateway on a
   journey's gateway step; tfp-sheet-up / tfp-sheet-full as the sheet rises. Presentation only:
   no id, listener, payload or price path changes. Every rule below sits in the phone query. */
/* The phone studio's own pieces are hidden everywhere but a phone: stepper.js adds them to the page
   at every width, and the phone query below is the only place that shows them. (1.17.92–1.17.94 kept
   these rules inside the query, so a desktop showed raw tab buttons and a "Review ›" in its bar.) */
#tfp-band,#tfp-skip,.tfp-more,.tfp-note{display:none}
@media (max-width:768px){
  html.tfp-phone{
    /* tokens */
    --h-wall:#FBF8F4;--h-gesso:#F1E9E1;--h-forest:#313E28;--h-walnut:#7C664D;--h-ink:#262019;--h-brass:#A98D5F;
    --h-line:rgba(38,32,25,.18);--h-muted:#6B5F50;--h-cream:#FBF8F4;
    --h-sans:'Niveau Grotesk','Hanken Grotesk',system-ui,sans-serif;--h-serif:'Cormorant Garamond','Cormorant',Georgia,serif;
    --h-ctl:44px;--h-ctl2:56px;
    /* geometry (stepper.js overwrites the stage figures in px) */
    --m-stage-max:55vh;--m-stage-min:26vh;--m-stage-h:var(--m-stage-max);--m-stage-k:1;
    --m-band:61px;--tfp-row:0px;--tfp-bar:64px;
    scroll-padding-top:calc(var(--m-stage-min) + var(--m-band) + 8px)}
  html.tfp-phone.tfp-gateway{--m-band:17px}
  html.tfp-phone body{background:var(--h-wall)!important}
  html.tfp-phone #studio-timeline.studio-timeline{display:none!important}
  html.tfp-phone #app{padding-top:0!important}
  html.tfp-phone #panel.studio-glass-panel::after{display:none!important}
  html.tfp-phone :is(.tfp-home-pill,.home-pill){display:none!important}

  /* ── the picture: fixed; scaled (≥ 0.6) and centre-cropped as the sheet rises, never resized ── */
  html.tfp-phone #app::before{content:"";position:fixed;left:0;right:0;top:0;height:var(--m-stage-h);z-index:19;background:#ECE5DC}
  html.tfp-phone #canvas-container,html.tfp-phone #stage{position:fixed!important;top:0!important;left:0!important;right:0!important;
    width:100%!important;height:var(--m-stage-max)!important;min-height:0!important;z-index:20;box-shadow:none!important;
    transform:translateY(var(--m-stage-ty,0px)) scale(var(--m-stage-k,1))!important;transform-origin:50% 50%!important;
    clip-path:inset(var(--m-stage-clip,0px) 0 var(--m-stage-clip,0px) 0)}
  html.tfp-phone :is(#zv-pill,#zv-tip,#view-toggle){display:none!important}
  html.tfp-phone.tfp-sheet-up :is(#stage-actions,#ar-wall-btn,.zoom-hint,.tfp-zoom-hint){opacity:0!important;pointer-events:none!important}
  /* hidden is hidden for the keyboard too: no focus stop on a control at opacity 0 (audit 20 Oct, F045) */
  html.tfp-phone.tfp-sheet-up :is(#stage-actions,#ar-wall-btn){visibility:hidden!important}
  html.tfp-phone :is(#stage-actions,#zv-pill){--sc-h:var(--h-ctl)!important}
  html.tfp-phone #ar-wall-btn{min-height:var(--h-ctl)!important;height:var(--h-ctl)!important;padding:0 14px!important;background:rgba(251,248,244,.94)!important;
    border:1px solid var(--h-line)!important;border-radius:0!important;font-family:var(--h-sans)!important;font-size:11px!important;font-weight:600!important;
    letter-spacing:.14em!important;text-transform:uppercase!important;color:var(--h-ink)!important}

  /* ── the sheet band: wall ground, brass hairline, handle, numbered tabs ── */
  html.tfp-phone #tfp-band{display:block;position:fixed;left:0;right:0;top:var(--m-stage-h);z-index:25;background:var(--h-wall);
    border-top:1px solid var(--h-brass);box-shadow:0 -16px 30px -20px rgba(38,32,25,.5);touch-action:none}
  #tfp-handle{display:block;width:100%;height:16px;margin:0;padding:0;border:0;background:none;position:relative;cursor:grab}
  #tfp-handle::before{content:"";position:absolute;left:50%;top:7px;width:36px;height:3px;margin-left:-18px;background:rgba(38,32,25,.24)}
  #tfp-handle::after{content:"";position:absolute;left:0;right:0;top:-10px;bottom:-2px}
  #tfp-handle:focus-visible{outline:2px solid #313E28;outline-offset:-2px}
  #tfp-tabs{display:flex;overflow-x:auto;scrollbar-width:none;border-bottom:1px solid rgba(38,32,25,.18);padding:0 8px}
  #tfp-tabs::-webkit-scrollbar{display:none}
  html.tfp-gateway #tfp-tabs{display:none}
  #tfp-tabs button{flex:1 0 auto;min-width:max-content;height:44px;margin:0;padding:0 8px;border:0;background:none;position:relative;cursor:pointer;
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;white-space:nowrap;
    font-family:'Niveau Grotesk','Hanken Grotesk',system-ui,sans-serif;color:#6B5F50}
  #tfp-tabs .tfp-tab-n{font-size:9.5px;line-height:1;font-weight:500;letter-spacing:.14em}
  #tfp-tabs .tfp-tab-l{font-size:11px;line-height:1;font-weight:600;letter-spacing:.14em;text-transform:uppercase}
  #tfp-tabs button.done{color:#262019}
  #tfp-tabs button[aria-selected="true"]{color:#313E28}
  #tfp-tabs button[aria-selected="true"]::after{content:"";position:absolute;left:14%;right:14%;bottom:-1px;height:2px;background:#313E28}
  #tfp-tabs button:focus-visible{outline:2px solid #313E28;outline-offset:-3px}

  /* ── the options under the band ── */
  html.tfp-phone #panel{background:var(--h-wall)!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important;
    border-radius:0!important;box-shadow:none!important}
  html.tfp-phone #panel{padding-top:calc(var(--m-stage-max) + var(--m-band))!important;margin-top:0!important;
    min-height:calc(100vh + var(--m-stage-max) - var(--m-stage-min))!important}
  html.tfp-phone :is(.step-panel,.panel-step){padding:12px 16px 16px!important}
  /* the tab names the step: its heading and eyebrow stay for screen readers only (not on a gateway) */
  html.tfp-phone:not(.tfp-gateway) :is(.step-panel,.panel-step) > :is(h2,h3):first-of-type,
  html.tfp-phone:not(.tfp-gateway) :is(.step-panel,.panel-step) > .subtitle{position:absolute!important;width:1px!important;height:1px!important;
    overflow:hidden!important;clip:rect(0 0 0 0)!important;white-space:nowrap!important;margin:0!important;padding:0!important}
  html.tfp-phone .step-eyebrow{display:none!important}

  /* Every rule in the sheet is anchored on #panel (all three studios' panel): the shell has #panel …
     !important type rules that out-rank any class-only selector. */
  /* ── TYPE. A reset to T4 Body for everything in a step, then the roles (PHONE-SPEC.md) ── */
  html.tfp-phone #panel :is(.step-panel,.panel-step) *{font-family:var(--h-sans)!important;font-size:13px!important;line-height:1.45!important;
    letter-spacing:0!important;text-transform:none!important;font-weight:400!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(b,strong){font-weight:600!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(p,.studio-note,.oc-meta,.door-blurb,.mc-desc,.mc-surface,.ln-blurb,.hint,.lead,.rv-detail,.rv-fineprint,.tfp-note,.tr-sub){color:var(--h-muted)!important}
  /* T2 Label */
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.form-label,.section-label,.opt-group-label,.mat-group-h,.finish-group-h,.mb-label,label.form-label,
    .door-name,.oc-name,.mc-name,.gc-name,.ln-name,.tr-label,.pill,.seg-btn,.seg > button,.seg-btn *,.cs-n,.rv-section-title,.rv-group-head,.rv-group-head *,
    .review-card h3,.review-card h4,.rv-label,.sc-name,.f3-enq h4,.mat-group-head,.mg-title,.disclose-btn,.tfp-more,.tfp-more *,.mb-adjust,.tfpds-save .btn-outline,.link-btn,.link-btn *,.cc-change,.rv-edit,.bd-toggle){
    font-size:11px!important;font-weight:600!important;letter-spacing:.14em!important;text-transform:uppercase!important;line-height:1.3!important;color:var(--h-ink)!important}
  /* T5 Caption */
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.unit,.mc-tag,.mf-pick,.recess-rec,.tier-badge,.gc-badge,.sc-fit,.sc-tag,.sc-tag *,.oc-price,
    .dim-sep){font-size:9.5px!important;font-weight:500!important;letter-spacing:.14em!important;text-transform:uppercase!important;line-height:1.3!important}
  html.tfp-phone #panel #finish-cards .finish-group .oc-name{font-size:9.5px!important;font-weight:500!important;letter-spacing:.14em!important;text-transform:uppercase!important;line-height:1.3!important}
  /* T4s Small: image-tile captions and fine print */
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.item-card *,.studio-ref-note,.rv-fineprint,.gq-note,.mb-hint){font-size:11px!important;line-height:1.3!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) .item-card :is(.price,.price *){font-weight:600!important;color:var(--h-ink)!important}
  /* T1 Display (Review summary title) */
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.rv-title,.rv-sum-title,.review-card .rv-h,.rv-sum-name){font-family:'Qeraldin',var(--h-serif)!important;font-size:26px!important;line-height:1.1!important;color:var(--h-ink)!important}
  /* Input */
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(input[type=number],input[type=text],input[type=search],input:not([type]),select,textarea){
    font-size:16px!important;font-weight:500!important;color:var(--h-ink)!important;height:var(--h-ctl)!important;min-height:var(--h-ctl)!important;
    border-radius:0!important;box-sizing:border-box!important}
  /* Review's "Notes for our team" is a box, not a one-line control (2 ids outrank the rule above) */
  html.tfp-phone #panel #cust-notes{height:auto!important;min-height:96px!important}

  /* ── CONTROLS. One-line options: 44 px tiles on a hairline, name only; chosen = forest ── */
  html.tfp-phone #panel :is(.door-card,.opt-card,.mount-card,.glass-card,.lane-card){
    min-height:var(--h-ctl)!important;height:auto!important;padding:0 12px!important;gap:10px!important;display:flex;align-items:center!important;
    background:transparent!important;border:1px solid var(--h-line)!important;border-radius:0!important;box-shadow:none!important;outline-offset:2px;position:relative}
  html.tfp-phone #panel :is(.door-card,.opt-card,.mount-card,.glass-card,.lane-card) :is(.door-body,.oc-body,.mc-body,.gc-body){display:flex;
    align-items:center!important;gap:8px!important;min-width:0;flex:1}
  html.tfp-phone #panel :is(.door-card,.opt-card,.mount-card,.glass-card) :is(.door-blurb,.oc-meta,.mc-desc,.gc-chips,.door-check,.oc-check,.mc-check,.gc-swatch,.mc-tag){display:none!important}
  html.tfp-phone #panel :is(.door-card,.opt-card,.mount-card,.glass-card) :is(.door-name,.oc-name,.mc-name,.gc-name){white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  html.tfp-phone #panel :is(.door-icon,.mc-icon,.oc-swatch){width:20px!important;height:20px!important;min-width:20px!important;flex:none;margin:0!important}
  html.tfp-phone #panel :is(.door-icon,.mc-icon,.oc-swatch:has(svg)){background:none!important;border:0!important;box-shadow:none!important;color:var(--h-walnut)!important}
  html.tfp-phone #panel :is(.door-icon,.mc-icon,.oc-swatch) svg{width:20px!important;height:20px!important}
  html.tfp-phone #panel .opt-card .oc-price:empty{display:none!important}
  html.tfp-phone #panel .opt-card .oc-price{margin-left:auto!important;color:var(--h-muted)!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.door-card,.opt-card,.mount-card,.glass-card,.lane-card,.media-card,.size-card):is(.selected,[aria-checked="true"],[aria-pressed="true"]){
    background:var(--h-forest)!important;border-color:var(--h-forest)!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.door-card,.opt-card,.mount-card,.glass-card,.lane-card,.media-card,.size-card):is(.selected,[aria-checked="true"],[aria-pressed="true"]) *{color:var(--h-cream)!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.door-card,.opt-card,.mount-card,.glass-card,.lane-card,.media-card,.size-card):is(.selected,[aria-checked="true"],[aria-pressed="true"]) :is(.mc-surface,.ln-blurb,.sc-tag,.oc-price){color:rgba(251,248,244,.74)!important}
  /* swatch-led tiles (glass tints, light) keep a round colour chip */
  html.tfp-phone #panel :is(#tint-cards,#led-tier-cards) .oc-swatch{border-radius:50%!important;border:1px solid var(--h-line)!important}
  /* two-line options (56 px) only where the second line differs per option: papers, print sizes, gateway cards */
  html.tfp-phone #panel .media-card,html.tfp-phone #panel .size-card,html.tfp-phone #panel #mf-ask-cards .door-card,html.tfp-phone #panel #door-cards > *{min-height:var(--h-ctl2)!important;
    padding:8px 12px!important;background:transparent!important;border:1px solid var(--h-line)!important;border-radius:0!important;box-shadow:none!important;
    display:flex;flex-direction:column!important;align-items:flex-start!important;justify-content:center!important;gap:2px!important}
  html.tfp-phone #panel :is(#mf-ask-cards .door-card,#door-cards .door-card){flex-direction:row!important;align-items:center!important;justify-content:flex-start!important;gap:12px!important}
  html.tfp-phone #panel :is(#mf-ask-cards .door-card,#door-cards .door-card) .door-body{flex-direction:column!important;align-items:flex-start!important;gap:2px!important}
  html.tfp-phone #panel :is(#mf-ask-cards .door-card,#door-cards .door-card) :is(.door-blurb){display:block!important;-webkit-line-clamp:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;max-width:100%}
  html.tfp-phone #panel :is(.media-card,.size-card) :is(.mc-swatch,.mc-check,.sc-in,.sc-lock){display:none!important}
  html.tfp-phone #panel .size-card :is(.sc-name,.sc-dim){display:inline!important}
  html.tfp-phone #panel .size-card .sc-fit{position:absolute;top:6px;right:8px}
  html.tfp-phone #panel .size-card{position:relative}
  html.tfp-phone #panel .lane-card{flex-direction:column!important;align-items:flex-start!important;justify-content:center!important;min-height:var(--h-ctl2)!important;padding:8px 12px!important}

  /* groups: grids on an 8 px gap */
  html.tfp-phone #panel :is(.door-grid,.opt-grid,.mount-grid,.glass-grid,.media-group,.mf-arrival,#size-cards){gap:8px!important;border:0!important}
  html.tfp-phone #panel :is(#tint-cards,#led-tier-cards,#mount-cards,#size-cards){display:grid;grid-template-columns:repeat(2,minmax(0,1fr))!important}
  html.tfp-phone #panel :is(#glass-cards,.media-group,#mf-ask-cards,#door-cards){grid-template-columns:1fr!important}
  /* groups nested inside a block keep a 16 px step; a step's own groups take the column gap (class-only, so the
     step-level margin reset outranks it: an id inside :is() lifted the whole list above it) */
  html.tfp-phone #panel :is(.form-group,.mb-block,.f3-enq,.toggle-row){margin-top:16px!important}
  html.tfp-phone #panel :is(.form-label,.opt-group-label,.mat-group-h,.mb-label){display:block;margin:0 0 8px!important}
  /* segmented: the mirror type, recess presets, orientation, print/frame fork, fulfilment */
  html.tfp-phone #panel :is(#type-cards,#recess-chips){display:grid;gap:0!important;border:1px solid var(--h-line)!important}
  html.tfp-phone #panel #type-cards{grid-template-columns:repeat(4,minmax(0,1fr))!important}
  html.tfp-phone #panel #recess-chips{grid-template-columns:repeat(3,minmax(0,1fr))!important}
  html.tfp-phone #panel :is(#type-cards,#recess-chips) > *{border:0!important;border-left:1px solid var(--h-line)!important;justify-content:center!important;
    padding:0 4px!important;text-align:center}
  html.tfp-phone #panel :is(#type-cards,#recess-chips) > :first-child{border-left:0!important}
  html.tfp-phone #panel :is(#type-cards,#recess-chips) :is(.door-icon,.oc-meta,.recess-rec,.oc-swatch){display:none!important}
  html.tfp-phone #panel :is(#type-cards,#recess-chips) :is(.door-body,.oc-body){justify-content:center!important}
  html.tfp-phone #panel #type-cards .door-name{white-space:normal!important;line-height:1.2!important;text-align:center}
  html.tfp-phone #panel :is(.seg,#orient-seg,#finish-seg){display:flex;gap:0!important;border:1px solid var(--h-line)!important;background:transparent!important;padding:0!important;border-radius:0!important}
  html.tfp-phone #panel :is(.seg,#orient-seg,#finish-seg) > :is(button,.seg-btn){flex:1 1 0!important;min-height:var(--h-ctl)!important;height:var(--h-ctl)!important;padding:0 6px!important;
    margin:0!important;border:0!important;border-left:1px solid var(--h-line)!important;border-radius:0!important;background:transparent!important;box-shadow:none!important;
    display:flex;align-items:center!important;justify-content:center!important;text-align:center;color:var(--h-ink)!important}
  html.tfp-phone #panel :is(.seg,#orient-seg,#finish-seg) > :first-child{border-left:0!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.seg,#orient-seg,#finish-seg) > :is(.on,.active,[aria-selected="true"],[aria-pressed="true"]){background:var(--h-forest)!important;color:var(--h-cream)!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.seg,#orient-seg,#finish-seg) > :is(.on,.active,[aria-selected="true"],[aria-pressed="true"]) *{color:var(--h-cream)!important}
  html.tfp-phone #panel .seg-ico{display:none!important}
  /* chip rows: shapes, what it is, rods, filters */
  html.tfp-phone #panel :is(#shape-cards,#organic-cards,#pole-cards,#content-tiles,.pill-row){display:flex;flex-wrap:nowrap!important;overflow-x:auto;
    gap:8px!important;scrollbar-width:none;margin:0 -16px!important;padding:0 16px!important;border:0!important}
  html.tfp-phone #panel :is(#shape-cards,#organic-cards,#pole-cards,#content-tiles,.pill-row)::-webkit-scrollbar{display:none}
  html.tfp-phone #panel :is(#shape-cards,#organic-cards,#pole-cards,#content-tiles,.pill-row) > *{flex:none!important;width:auto!important}
  html.tfp-phone #panel :is(#shape-cards,#organic-cards) > :not(.opt-card){display:none!important}
  html.tfp-phone #panel .pill{min-height:var(--h-ctl)!important;height:var(--h-ctl)!important;padding:0 14px!important;margin:0!important;
    background:transparent!important;border:1px solid var(--h-line)!important;border-radius:0!important;box-shadow:none!important;color:var(--h-ink)!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) .pill.active{background:var(--h-forest)!important;border-color:var(--h-forest)!important;color:var(--h-cream)!important}
  html.tfp-phone #panel .pill-row + .pill-row{margin-top:8px!important}
  /* round metal swatches, a ring round the chosen one (#finish-cards: the shell's
     .studio-glass-panel :not()… radius rule outweighs a class-only selector) */
  html.tfp-phone #finish-cards .finish-group{display:grid!important;grid-template-columns:repeat(5,minmax(0,1fr))!important;gap:12px 4px!important}
  html.tfp-phone #finish-cards .finish-group .opt-group-label{grid-column:1/-1}
  html.tfp-phone #finish-cards .finish-group .opt-card,html.tfp-phone #finish-cards .finish-group .opt-card.selected{background:none!important;border:0!important;padding:0!important;
    min-height:0!important;flex-direction:column!important;align-items:center!important;text-align:center;gap:6px!important}
  html.tfp-phone #finish-cards .finish-group .opt-card .oc-body{flex-direction:column!important;align-items:center!important}
  html.tfp-phone #finish-cards .finish-group .opt-card .oc-swatch{width:40px!important;height:40px!important;min-width:40px!important;border-radius:50%!important;
    border:1px solid var(--h-line)!important;overflow:hidden!important;position:relative}
  html.tfp-phone #finish-cards .finish-group .opt-card.selected .oc-swatch{box-shadow:0 0 0 3px var(--h-wall),0 0 0 4px var(--h-ink)!important}
  html.tfp-phone #finish-cards .finish-group .opt-card .oc-name,html.tfp-phone #finish-cards .finish-group .opt-card.selected .oc-name{white-space:normal!important;
    color:var(--h-ink)!important;display:-webkit-box!important;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  html.tfp-phone #finish-cards .finish-group + .finish-group{margin-top:16px!important}
  /* image tiles (mouldings, mats): pictures with a small caption */
  html.tfp-phone #panel .item-card{padding:4px!important;gap:4px!important;border-radius:0!important}
  /* links: More options, disclosures, save; a 44 px target, underlined like the product page's */
  html.tfp-phone #panel :is(.disclose-btn,.mb-adjust,.tfpds-save .btn-outline,.link-btn,.cc-change,.bd-toggle,.rv-edit){display:inline-flex!important;align-items:center;
    width:auto!important;min-height:var(--h-ctl)!important;margin:8px 0 0!important;padding:0!important;border:0!important;background:none!important;box-shadow:none!important;
    text-decoration:underline!important;text-decoration-thickness:1px!important;text-underline-offset:6px!important}
  html.tfp-phone #panel .tfpds-save{display:flex;flex-wrap:wrap;gap:0 20px}
  html.tfp-phone #panel :is(.review-card,.rv-card,.summary-card,.selected-preview){box-shadow:none!important;border-radius:0!important;border-color:var(--h-line)!important;background:transparent!important}
  /* the chosen option's description, one line under its group (stepper.js describe) */
  html.tfp-phone .tfp-note{display:block;margin:8px 0 0!important}
  html.tfp-phone #panel .cs-head{min-height:var(--h-ctl)!important;height:var(--h-ctl)!important;padding:0 12px!important}
  /* toggles (extras) and steppers keep the 44 px rhythm */
  html.tfp-phone #panel .toggle-row{min-height:var(--h-ctl)!important;padding:0 12px!important;border:1px solid var(--h-line)!important;background:transparent!important;border-radius:0!important;box-shadow:none!important}
  html.tfp-phone #panel .stepper-num :is(button,input){height:var(--h-ctl)!important;min-height:var(--h-ctl)!important;border-radius:0!important}

  /* ── each step's main choice in view at rest ── */
  /* mirror, Shape: the size, then the shape chips, then the type (owner, 26 Oct 2026: "size shape and frame for mobile as well") */
  html.tfp-phone #panel-type.active{display:flex!important;flex-direction:column}
  html.tfp-phone #panel-type > #size-inline{order:1;display:flex;flex-direction:column}
  html.tfp-phone #panel-type > #type-cards{order:2;margin-top:18px!important}
  html.tfp-phone #panel-type > :not(#type-cards):not(#size-inline){order:3}
  html.tfp-phone #size-inline > .form-group{order:1;margin-top:0!important}
  html.tfp-phone #size-inline > #shape-label{order:2;margin-top:16px!important}
  html.tfp-phone #size-inline > #shape-cards{order:2;margin-top:6px!important}
  /* the named organics: their own strip right under the shape strip (they were nested in it and hidden) */
  html.tfp-phone #size-inline > #organic-cards{order:2;margin-top:8px!important}
  html.tfp-phone #size-inline > :not(.form-group):not(#shape-label):not(#shape-cards):not(#organic-cards){order:3}
  html.tfp-phone #size-inline-label{display:none!important}
  html.tfp-phone #panel :is(#led-entry-row,#tol-note){display:none!important}
  html.tfp-phone #panel #panel-type > p.studio-note{display:none!important}
  /* size inputs: two 44 px boxes, the unit as a caption inside */
  html.tfp-phone #panel .form-row{display:flex;align-items:center!important;gap:8px!important;flex-wrap:nowrap!important}
  html.tfp-phone #panel .dim-input{flex:1 1 0!important;display:flex;align-items:center!important;height:var(--h-ctl)!important;padding:0 10px!important;
    border:1px solid var(--h-line)!important;background:transparent!important;border-radius:0!important;gap:6px!important}
  html.tfp-phone #panel .dim-input input{flex:1 1 auto!important;width:100%!important;min-width:0!important;border:0!important;background:none!important;padding:0!important;height:40px!important;min-height:40px!important}
  html.tfp-phone #panel .dim-input .unit{flex:none;color:var(--h-muted)!important}
  html.tfp-phone #panel .form-row + div[style*="font-size:9.5px"]{display:none!important}
  /* frame, Piece: the chosen start as one 44 px line; the photo box as one line */
  html.tfp-phone #panel #mf-ask-chip.content-chip{min-height:var(--h-ctl)!important;padding:0 12px!important;align-items:center!important;justify-content:space-between!important;
    gap:12px!important;border:1px solid var(--h-line)!important;background:transparent!important;border-radius:0!important;box-shadow:none!important}
  html.tfp-phone #panel #mf-ask-chip:not([style*="none"]){display:flex!important}
  html.tfp-phone #panel #mf-ask-chip .cc-label{font-size:11px!important;font-weight:600!important;letter-spacing:.14em!important;text-transform:uppercase!important;color:var(--h-ink)!important}
  html.tfp-phone #panel #mf-ask-chip .cc-change{margin:0!important}
  html.tfp-phone #panel #content-tiles :is(.door-blurb,.door-check){display:none!important}
  html.tfp-phone #panel #upload-zone{min-height:var(--h-ctl)!important;padding:0 12px!important;display:flex;flex-direction:row!important;align-items:center!important;gap:10px!important;
    border:1px dashed var(--h-line)!important;background:transparent!important}
  html.tfp-phone #panel #upload-zone :is(.icon,svg){width:20px!important;height:20px!important;margin:0!important}
  html.tfp-phone #panel :is(#phone-handoff-btn,#upload-hint){display:none!important}
  /* print, Crop & size: the resolution verdict as one line */
  html.tfp-phone #panel .rv-warn,html.tfp-phone #panel .res-warn{padding:8px 12px!important;border-radius:0!important}
  html.tfp-phone #panel :is(#orient-hint,#step-media > p.lead){display:none!important}

  /* ── extras wait behind "More options" (stepper.js adds the link where a step has any) ── */
  html.tfp-phone :is(.step-panel,.panel-step):not(.tfp-more-open) :is(#suspension-inline,#bevel-upsell,#thickness-block,#recess-group,#profile-group,
    #finish-cards > .finish-group ~ .finish-group:not(:has(.selected)),#rv-extras-card,.finder-row:not(:has(input:not(:placeholder-shown))),#borders-block,
    #mat-brand-pills:not(:has(.pill.active:not(:first-child))),#mat-search:placeholder-shown,#mat-enquiries){display:none!important}
  html.tfp-phone .tfp-more:not([hidden]){display:inline-flex;align-items:center;gap:6px;min-height:var(--h-ctl);margin:8px 0 0;padding:0;border:0;background:none;cursor:pointer;
    text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:6px}
  html.tfp-phone .tfp-more:focus-visible{outline:2px solid #313E28;outline-offset:2px}
  /* helper prose a phone visitor does not need to choose (the (i) in the top bar has the phone number) */
  html.tfp-phone #panel :is(#antique-call-note,.assist-note,.assist-inline,.recess-figure,.cat-hint,.trust-line,.phone-cta,#frame-sort){display:none!important}
  html.tfp-phone #panel :is(#frame-search,#mat-search){flex:1 1 100%!important}

  /* ── long lists fill the open sheet and scroll inside it; still until the sheet is open ── */
  html.tfp-phone .tfp-fit{overflow-y:auto!important;overscroll-behavior:contain}
  html.tfp-phone:not(.tfp-sheet-full) .tfp-fit{overflow-y:hidden!important}

  /* ── Review: the bar carries Add to cart. The panel's own button is visually hidden, never
     display:none: the frame studio shows the bar's Add to cart only while this one is displayed
     (buyBarOn reads offsetParent and display), and the bar's press clicks it ── */
  html.tfp-phone #panel :is(.step-panel,.panel-step) #btn-add-to-cart{position:absolute!important;width:1px!important;height:1px!important;
    padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important;border:0!important;white-space:nowrap!important}

  /* ── the bar: price (T1) · Review › (T2) · Next (T3), all 44 px ── */
  html.tfp-phone :is(#bottom-bar,#bottom){min-height:var(--tfp-bar);background:var(--h-wall)!important;border-top:1px solid var(--h-line)!important;
    box-shadow:0 -10px 20px -18px rgba(38,32,25,.5)!important;padding:10px 16px calc(10px + var(--tfp-sab-v,0px))!important}
  html.tfp-phone :is(#bottom-bar,#bottom) #btn-back{display:none!important}
  html.tfp-phone #bottom .assist{display:none!important}
  html.tfp-phone :is(#bottom-bar,#bottom) .nav-row{justify-content:flex-end;align-items:center;gap:12px}
  html.tfp-phone :is(#bottom-bar,#bottom) .nav-row :is(#btn-next,#btn-toframe,#btn-add-to-cart){flex:0 1 auto;min-width:140px;height:var(--h-ctl)!important;min-height:var(--h-ctl)!important;
    padding:0 18px!important;font-family:var(--h-sans)!important;font-size:11px!important;font-weight:700!important;letter-spacing:.16em!important;text-transform:uppercase!important;border-radius:0!important}
  html.tfp-phone #price-section .sp-price{font-family:var(--h-serif)!important;font-size:26px!important;font-weight:400!important;color:var(--h-ink)!important;letter-spacing:0!important;line-height:1!important}
  html.tfp-phone #price-section .sp-sub{font-family:var(--h-sans)!important;font-size:9.5px!important;font-weight:500!important;letter-spacing:.14em!important;text-transform:uppercase!important;color:var(--h-muted)!important}
  html.tfp-phone #price-section :is(#bd-toggle,.bd-toggle,#breakdown,.breakdown){display:none!important}
  html.tfp-phone #tfp-skip:not([hidden]){display:inline-flex;align-items:center;justify-content:center;height:var(--h-ctl);padding:0 4px;margin:0;border:0;background:none;cursor:pointer;flex:none;
    font-family:var(--h-sans);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--h-ink);white-space:nowrap;
    text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:6px}
  html.tfp-phone #tfp-skip:focus-visible{outline:2px solid #313E28;outline-offset:2px}
  html.tfp-phone .tfp-more{font-family:var(--h-sans);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--h-ink)}

  /* toasts and the saved-design prompt: above the bar, full width, never over Next */
  html.tfp-phone :is(#toast,#tfpproj-toast){left:16px!important;right:16px!important;bottom:calc(var(--tfp-bar) + var(--tfp-sab-v,0px) + 12px)!important;top:auto!important;
    transform:none!important;width:auto!important;max-width:none!important;z-index:60!important;text-align:center;justify-content:center;border-radius:0!important;
    font-family:var(--h-sans)!important;font-size:13px!important;letter-spacing:0!important;padding:12px 16px!important}
  html.tfp-phone #tfpds-continue{bottom:calc(var(--tfp-bar) + var(--tfp-sab-v,0px) + 12px)!important;z-index:60!important}
  /* the print studio's gateway (no picture yet): the start page flows from the top, no reserved stage */
  html.tfp-phone.tfp-gateway #stage{position:relative!important;transform:none!important;clip-path:none!important;height:auto!important;min-height:0!important}
  html.tfp-phone.tfp-gateway:has(#stage) #app::before{display:none}
  html.tfp-phone.tfp-gateway:has(#stage) #panel{padding-top:0!important;min-height:0!important}
  /* ── review round 1 (20 Oct 2026): seven reviewers + sceptics against PHONE-SPEC.md ── */
  /* one rhythm: a step's groups 16 px apart, whatever margins the apps set inline */
  html.tfp-phone #panel :is(.step-panel,.panel-step).active{display:flex!important;flex-direction:column!important;gap:16px!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) > *{margin-top:0!important;margin-bottom:0!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step).active > :is(.tfp-more,.disclose-btn,.link-btn){align-self:flex-start}
  html.tfp-phone #panel #panel-type.active{gap:16px}
  html.tfp-phone #panel #panel-type.active > *{margin-top:0!important}
  html.tfp-phone #panel #size-inline{gap:16px}
  html.tfp-phone #panel #size-inline > *{margin-top:0!important;margin-bottom:0!important}
  html.tfp-phone #panel :is(.finish-group,.mat-group,.media-group) + :is(.finish-group,.mat-group,.media-group){margin-top:16px!important}
  html.tfp-phone #panel :is(.opt-group-label,.mat-group-head,.mg-title){margin:0 0 8px!important;padding:0!important;border:0!important;background:none!important}
  html.tfp-phone #panel .mg-title::after,html.tfp-phone #panel .mg-title::before{display:none!important}
  /* the mirror type: four tiles two by two, every name on one line */
  html.tfp-phone #panel #type-cards{grid-template-columns:repeat(2,minmax(0,1fr))!important;gap:8px!important;border:0!important}
  html.tfp-phone #panel #type-cards > *{border:1px solid var(--h-line)!important;height:var(--h-ctl)!important}
  html.tfp-phone #panel #type-cards .door-name{white-space:nowrap!important}
  /* long names get the full width: light, style */
  html.tfp-phone #panel :is(#led-tier-cards,#mount-cards){grid-template-columns:1fr!important}
  /* size fields: one box each (the input inside loses its own ring), the unit as a caption */
  html.tfp-phone #panel .dim-input input{-webkit-appearance:none!important;appearance:none!important;box-shadow:none!important;outline:none!important;margin:0!important;
    border-radius:0!important;background:transparent!important;border:0!important}
  html.tfp-phone #panel .dim-input:focus-within{outline:2px solid var(--h-forest);outline-offset:-1px}
  html.tfp-phone #panel .dim-sep{flex:none;color:var(--h-muted)!important}
  /* chips: even padding, a fade at the edge that says the row scrolls */
  html.tfp-phone #panel :is(#shape-cards,#organic-cards,#content-tiles) .opt-card,html.tfp-phone #panel #content-tiles .door-card{padding:0 14px!important}
  html.tfp-phone #panel :is(#shape-cards,#organic-cards,#content-tiles) :is(.oc-body,.door-body){flex:none!important}
  html.tfp-phone #panel :is(#shape-cards,#organic-cards,#pole-cards,#content-tiles,.pill-row){-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent);padding-right:32px!important}
  html.tfp-phone #panel .pill-row{margin-bottom:8px!important}
  html.tfp-phone #panel .pill-row + .pill-row{margin-top:0!important}
  /* swatches: centred names under their circles */
  html.tfp-phone #finish-cards .finish-group .opt-card .oc-body{width:100%;justify-content:center!important;text-align:center}
  html.tfp-phone #finish-cards .finish-group .opt-card .oc-name{text-align:center!important;width:100%}
  html.tfp-phone #panel :is(#tint-cards,#led-tier-cards) .oc-swatch:not(:has(svg)){border-radius:50%!important;border:1px solid var(--h-line)!important}
  /* image tiles: a plain grid on the sheet, captions in one weight */
  html.tfp-phone #panel .catalogue-scroll{background:transparent!important;border:0!important;padding:0!important;border-radius:0!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) .item-card :is(.price,.price *){font-weight:400!important}
  html.tfp-phone #panel #mat-preview{display:none!important}
  /* badges in the caption style, square */
  html.tfp-phone #panel .tier-badge{position:static!important;margin-left:auto!important;padding:3px 6px!important;border-radius:0!important;background:transparent!important;
    box-shadow:inset 0 0 0 1px var(--h-brass)!important;color:var(--h-ink)!important}
  /* the reference note: left, small, muted, straight after the step */
  html.tfp-phone #panel #step-content,html.tfp-phone #panel #content{flex:none!important}
  html.tfp-phone #panel .studio-ref-note{text-align:left!important;margin:4px 16px 16px!important;opacity:1!important;color:var(--h-muted)!important;font-family:var(--h-sans)!important;font-size:11px!important;line-height:1.3!important}
  /* Review: the summary lines muted like every note, cards flush with the 16 px gutter, no second picture */
  html.tfp-phone #panel :is(.rv-sum-desc,.rv-sum-meta,.preview-meta,.rv-sub,.mc-note){color:var(--h-muted)!important}
  html.tfp-phone #panel :is(.review-card,.rv-card){border:0!important;padding:0!important}
  html.tfp-phone #panel #rv-thumb{display:none!important}
  /* print: the sharpness verdict as one line; sizes as two-line cards; the size label without its aside */
  html.tfp-phone #panel #size-badge .badge{border-radius:0!important;padding:10px 12px!important;display:flex!important;align-items:center!important;gap:10px!important}
  html.tfp-phone #panel #size-badge :is(.b-cap,.b-ppi){display:none!important}
  html.tfp-phone #panel #size-badge .dot{width:8px!important;height:8px!important;border-radius:50%!important;box-shadow:none!important;flex:none}
  html.tfp-phone #panel .size-card{display:block!important;height:var(--h-ctl2)!important;padding:9px 12px!important}
  html.tfp-phone #panel .size-card .sc-tag{display:flex!important;align-items:center;gap:6px;margin-top:3px!important}
  html.tfp-phone #panel label.form-label.section-gap > span{display:none!important}
  html.tfp-phone #panel .cs-head{padding:0!important}
  html.tfp-phone #result-cap{font-family:var(--h-sans)!important;font-size:9.5px!important;font-weight:500!important;letter-spacing:.14em!important;text-transform:uppercase!important;
    border-radius:0!important;box-shadow:none!important;padding:6px 10px!important}
  /* the picture: one flat chip at the top right, clear of the piece; soft edges when it shrinks */
  html.tfp-phone #stage-actions{top:12px!important;bottom:auto!important;right:12px!important;left:auto!important}
  html.tfp-phone #ar-wall-btn{background-image:none!important;box-shadow:none!important}
  html.tfp-phone.tfp-sheet-up :is(#canvas-container,#stage){-webkit-mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent);mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent)}
  html.tfp-phone:has(#panel-type) #app::before{background:#EFE8DF}
  html.tfp-phone:has(#step-1) #app::before{background:#D0CCC4}
  /* the bar keeps one shape on every step: Review's slot is held, the button one width */
  html.tfp-phone #tfp-skip[hidden]{display:inline-flex!important;visibility:hidden!important}
  html.tfp-phone.tfp-gateway #tfp-skip[hidden]{display:none!important}
  html.tfp-phone :is(#bottom-bar,#bottom) .nav-row :is(#btn-next,#btn-toframe,#btn-add-to-cart){flex:none!important;width:168px!important;min-width:0!important}
  html.tfp-phone :is(#bottom-bar,#bottom) .nav-row #btn-next:disabled{background:transparent!important;border:1px solid var(--h-line)!important;color:var(--h-muted)!important;opacity:1!important}
  html.tfp-phone :is(#tfp-skip,.tfp-more){text-decoration:none!important}
  html.tfp-phone :is(#tfp-skip,.tfp-more) .tfp-u{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:6px}
  /* the price: the site's serif with level figures, as the product page sets "$ 797.81" */
  html.tfp-phone #price-section .sp-price{font-family:'Qeraldin',var(--h-serif)!important;font-variant-numeric:lining-nums tabular-nums!important}
  html.tfp-phone #price-section .sp-price::after{font-size:9.5px!important;font-weight:500!important;letter-spacing:.14em!important;text-transform:uppercase!important;color:var(--h-muted)!important}
  /* tabs: only the step you are on stands out */
  #tfp-tabs button.done{color:#6B5F50}
  /* ── code review (20 Oct 2026) ── */
  /* the description note sits 8 px under its group; nothing reserves space for the screen-reader-only heading */
  html.tfp-phone #panel :is(.step-panel,.panel-step) > .tfp-note{margin-top:-8px!important}
  html.tfp-phone .tfp-note[hidden]{display:none!important}
  /* a reveal's own notes ("needs the 40 mm deep bar" changes the bar and the price) and an unavailable option's reason stay readable */
  html.tfp-phone #panel #recess-chips > *{height:auto!important;min-height:var(--h-ctl2)!important;padding:6px 4px!important;flex-direction:column!important}
  html.tfp-phone #panel #recess-chips :is(.oc-body){flex-direction:column!important;gap:2px!important}
  html.tfp-phone #panel #recess-chips .oc-meta{display:block!important;font-size:11px!important;line-height:1.25!important;white-space:normal!important}
  html.tfp-phone #panel .opt-card:is(.disabled,[aria-disabled="true"]) .oc-meta{display:block!important}
  /* the price note may take two short lines in the plaque rather than be cut */
  html.tfp-phone #price-section .sp-sub{white-space:normal!important;letter-spacing:.06em!important;display:-webkit-box!important;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden!important;text-overflow:clip!important}
  /* the cutouts counter matches the other numbers; its buttons are 44 px square */
  html.tfp-phone #panel :is(.step-panel,.panel-step) .stepper-num .val{font-size:16px!important;font-weight:500!important}
  html.tfp-phone #panel .stepper-num button{width:var(--h-ctl)!important}
  /* the mirror's manual-quote card (suspended over 1200 mm) lives on <body> on a phone (stepper.js) and sits on the picture's lower edge */
  html.tfp-phone body #handoff-card{top:calc(var(--m-stage-h) - 14px)!important;max-height:calc(var(--m-stage-h) - 70px)!important;z-index:22!important;border-radius:0!important}
  /* round 1 strays: the frame Review summary line in body text; print's breakdown link in the caption style; papers two lines */
  html.tfp-phone #panel #rv-sum-desc{font-size:13px!important;color:var(--h-muted)!important}
  html.tfp-phone #price-section #bd-toggle{font-family:var(--h-sans)!important;font-size:9.5px!important;font-weight:500!important;letter-spacing:.14em!important;
    text-transform:uppercase!important;color:var(--h-ink)!important;padding:0!important;min-height:0!important;text-decoration:underline;text-underline-offset:4px}
  html.tfp-phone #panel .media-card .mc-note{display:none!important}
  /* ── review round 2 (20 Oct 2026) ── */
  /* the frame's two filter rows: 8 px apart (ids, so it outranks the shared chip-row rule) */
  html.tfp-phone #panel :is(#frame-supplier-pills,#frame-series-pills,#mat-brand-pills).pill-row{margin-bottom:8px!important}
  /* the Frameless tile keeps its left edge (the segmented strip's first-child rule outranked the 2x2 tiles) */
  html.tfp-phone #panel #type-cards > :first-child{border-left:1px solid var(--h-line)!important}
  /* timber finish tiles: a round 20 px swatch like every other tile swatch; group labels 16 above, 8 below */
  html.tfp-phone #panel #finish-cards > .opt-card .oc-swatch{border-radius:50%!important;border:1px solid var(--h-line)!important}
  html.tfp-phone #panel #finish-cards > .opt-group-label{margin:8px 0 0!important}
  html.tfp-phone #panel #finish-cards > .opt-group-label:first-child{margin-top:0!important}
  html.tfp-phone #finish-cards .finish-group{grid-template-columns:repeat(4,minmax(0,1fr))!important}
  html.tfp-phone #finish-cards .finish-group > .opt-group-label{margin:0!important}
  /* the White light swatch is visible on a cream tile */
  html.tfp-phone #panel #led-tier-cards .oc-swatch{border:1px solid rgba(38,32,25,.3)!important}
  /* mats four to a row so their names fit; picture tiles square, no card, no shadow */
  html.tfp-phone #panel #mat-catalogue .mat-group{display:grid!important;grid-template-columns:repeat(4,minmax(0,1fr))!important;gap:8px!important}
  html.tfp-phone #panel #mat-catalogue .mat-group > .mat-group-head{grid-column:1/-1;margin:0!important}
  html.tfp-phone #panel #mat-catalogue .mat-group + .mat-group{margin-top:16px!important}
  html.tfp-phone #panel .item-card,html.tfp-phone #panel .item-card *{border-radius:0!important}
  html.tfp-phone #panel .item-card{background:transparent!important;box-shadow:none!important;border:0!important}
  /* one chosen mark on a picture tile: a 2 px forest ring drawn inside the picture (the app's own double line goes) */
  html.tfp-phone #panel .item-card :is(.cs-thumb,.thumb,img){border:0!important;box-shadow:none!important;outline:0!important}
  html.tfp-phone #panel :is(.item-card.selected,.item-card[aria-selected="true"]){outline:0!important;box-shadow:none!important}
  html.tfp-phone #panel :is(.item-card.selected,.item-card[aria-selected="true"]) :is(.cs-thumb,.thumb:not(.cs-thumb *)){box-shadow:inset 0 0 0 2px var(--h-forest)!important;outline:2px solid var(--h-forest)!important;outline-offset:-2px}
  /* one badge style, after the name */
  html.tfp-phone #panel :is(.step-panel,.panel-step) :is(.mf-pick,.tier-badge){position:static!important;order:3;margin-left:auto!important;padding:3px 6px!important;border:0!important;border-radius:0!important;
    background:transparent!important;box-shadow:inset 0 0 0 1px var(--h-brass)!important;color:var(--h-ink)!important;white-space:nowrap}
  html.tfp-phone #panel :is(.glass-card,.mount-card) :is(.gc-body,.mc-body){order:1}
  /* the picture's chip: the secondary style, 44 px, narrower so it clears the piece */
  html.tfp-phone #stage-actions #ar-wall-btn{height:var(--h-ctl)!important;min-height:var(--h-ctl)!important;padding:0 10px!important;letter-spacing:.1em!important;
    background:rgba(251,248,244,.94)!important;border:1px solid var(--h-line)!important;box-shadow:none!important;background-image:none!important}
  /* the bar's links keep a space before their arrow */
  html.tfp-phone :is(#tfp-skip,.tfp-more){gap:4px}
  /* the price's thousands comma reads as one */
  html.tfp-phone #price-section .sp-price{letter-spacing:.01em!important}
  /* softer edges when the picture shrinks (the wide fade read as a smear on a close view) */
  html.tfp-phone.tfp-sheet-up :is(#canvas-container,#stage){-webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
  /* ── review round 2, print and chrome (20 Oct 2026) ── */
  /* the bar says "incl. GST" once (print drew it after the figure as well as under it) */
  html.tfp-phone #price-section .sp-price::after{content:none!important}
  /* print sizes: one line for the size (cut with an ellipsis, never wrapped), the sharpness under it */
  html.tfp-phone #panel .size-card .sc-tag{white-space:normal!important}
  html.tfp-phone #panel .size-card .sc-fit{position:absolute!important;top:10px!important;bottom:auto!important;right:10px!important}
  html.tfp-phone #panel .size-card:has(.sc-fit){padding-right:84px!important}
  /* the sharpness verdict: a calm sentence with a coloured dot, no pink box */
  html.tfp-phone #panel #size-badge .badge{background:transparent!important;border:0!important;box-shadow:none!important;padding:0!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) #size-badge .b-head{font-size:13px!important;font-weight:400!important;letter-spacing:0!important;text-transform:none!important;color:var(--h-ink)!important}
  /* the crop tool: no band of padding left over from the old step strip; its buttons 44 px */
  html.tfp-phone #stage-crop{padding-top:12px!important;padding-bottom:12px!important}
  html.tfp-phone .crop-toolbar :is(#zoom-out,#zoom-in,#crop-reset){width:var(--h-ctl)!important;height:var(--h-ctl)!important;min-width:var(--h-ctl)!important;border-radius:0!important}
  html.tfp-phone .crop-toolbar .zlabel{font-family:var(--h-sans)!important;font-size:9.5px!important;font-weight:500!important;letter-spacing:.14em!important;text-transform:uppercase!important}
  /* The Paper: the print-or-frame choice first, then the papers (the list is long) */
  html.tfp-phone #panel #step-media.active > #finish-label{order:-3}
  html.tfp-phone #panel #step-media.active > #finish-seg{order:-2;margin-top:-8px!important}
  html.tfp-phone #panel #step-media.active > #finish-hint{order:-1;margin-top:-8px!important}
  html.tfp-phone #panel #step-media.active > #finish-hint:empty{display:none!important}
  /* the print gateway: no sheet edge over the start cards; their line may take two lines */
  html.tfp-phone.tfp-gateway:has(#stage) #tfp-band{display:none!important}
  html.tfp-phone #panel #door-cards .door-blurb{white-space:normal!important;-webkit-line-clamp:2!important;display:-webkit-box!important;-webkit-box-orient:vertical}
  /* toasts in the house's colours: cream, warm hairline, body text */
  html.tfp-phone :is(#toast,#tfpproj-toast){background:#FBF8F4!important;color:var(--h-ink)!important;border:1px solid var(--h-line)!important;box-shadow:0 10px 24px -14px rgba(38,32,25,.45)!important;font-weight:400!important}
  /* the breakdown link in the bar: a 44 px target around its small caption */
  html.tfp-phone #price-section #bd-toggle{position:relative!important}
  html.tfp-phone #price-section #bd-toggle::after{content:"";position:absolute;left:-8px;right:-8px;top:-17px;bottom:-17px}
  /* review round 3: the filter rows one group (8 px apart, 16 px to the grid); the chosen start line without extra space */
  html.tfp-phone #panel :is(#frame-supplier-pills,#frame-series-pills,#mat-brand-pills).pill-row{margin-bottom:0!important}
  html.tfp-phone #panel #step-3.active > #frame-series-pills{margin-top:-8px!important}
  html.tfp-phone #panel #mf-ask{display:flex;flex-direction:column;gap:0!important}
  html.tfp-phone #panel #mf-ask > *{margin:0!important}
  html.tfp-phone #panel .rv-sum-thumb,html.tfp-phone #panel .rv-sum-thumb *{border-radius:0!important}
  /* the photo box reads as the other controls: a 44 px row on a solid hairline, its words a label */
  html.tfp-phone #panel #upload-zone{border-style:solid!important}
  html.tfp-phone #panel :is(.step-panel,.panel-step) #upload-zone :is(.text,#upload-text,span){font-size:11px!important;font-weight:600!important;letter-spacing:.14em!important;text-transform:uppercase!important;color:var(--h-ink)!important}
  /* ── review round 3 (20 Oct 2026) ── */
  /* print sizes: the size on line one (never cut), the name and its sharpness on line two */
  html.tfp-phone #panel .size-card{display:grid!important;grid-template-columns:auto minmax(0,1fr)!important;grid-template-rows:auto auto!important;column-gap:8px!important;
    row-gap:3px!important;align-content:center!important;white-space:normal!important}
  html.tfp-phone #panel .size-card .sc-dim{grid-row:1;grid-column:1/-1;font-size:13px!important;font-weight:500!important;letter-spacing:0!important;text-transform:none!important;color:var(--h-ink)!important}
  html.tfp-phone #panel .size-card .sc-name{grid-row:2;grid-column:1;font-size:9.5px!important;font-weight:500!important;letter-spacing:.14em!important;margin:0!important;line-height:1.3!important}
  html.tfp-phone #panel .size-card .sc-tag{grid-row:2;grid-column:2;margin:0!important;min-width:0}
  html.tfp-phone #panel .size-card .sc-fit{position:absolute!important;top:9px!important;right:10px!important;bottom:auto!important}
  html.tfp-phone #panel .size-card:is(.selected,[aria-pressed="true"]) .sc-dim{color:var(--h-cream)!important}
  /* the print picture's layers: no band of padding left over from the old step strip */
  html.tfp-phone #stage .stage-layer{padding-top:12px!important;padding-bottom:12px!important}
  /* timber finish names may take two lines in their tile (no "Dark metall…") */
  html.tfp-phone #panel #finish-cards > .opt-card :is(.oc-name){white-space:normal!important;overflow:visible!important;text-overflow:clip!important;line-height:1.25!important}
  html.tfp-phone #panel #finish-cards > .opt-card{height:auto!important;padding-top:6px!important;padding-bottom:6px!important}
  html.tfp-phone #panel #finish-cards > .opt-card.selected .oc-swatch{box-shadow:0 0 0 1px rgba(251,248,244,.7)!important}
  /* a swatch caption's trailing letter-space balanced, so it sits centred under its circle */
  html.tfp-phone #finish-cards .finish-group .opt-card .oc-name{text-indent:.14em}
  /* every option tile names itself from the left, the type tiles too */
  html.tfp-phone #panel #type-cards > *{justify-content:flex-start!important;padding:0 12px!important;text-align:left!important}
  html.tfp-phone #panel #type-cards :is(.door-body){justify-content:flex-start!important}
  html.tfp-phone #panel #type-cards .door-name{text-align:left!important}
  /* "On your wall": a 44 px icon in the picture's corner, clear of the piece (the name stays for screen readers) */
  html.tfp-phone #stage-actions #ar-wall-btn{width:var(--h-ctl)!important;min-width:var(--h-ctl)!important;padding:0!important;font-size:0!important;letter-spacing:0!important;
    background:rgba(251,248,244,.94) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23262019' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 21h18'/%3E%3Crect x='6' y='5' width='12' height='12'/%3E%3Cpath d='M9 5l3-3 3 3'/%3E%3C/svg%3E") center/22px 22px no-repeat!important}
  /* the More link sits in the rhythm, its 44 px target not doubling the gap */
  html.tfp-phone #panel :is(.step-panel,.panel-step) .tfp-more{margin-top:-12px!important;margin-bottom:-12px!important}
  /* the price's comma reads as a comma */
  html.tfp-phone #price-section .sp-price{letter-spacing:.03em!important}
  /* a long list in the open sheet fades at its foot, so the cut reads as "more below" */
  html.tfp-phone .catalogue-scroll.tfp-fit{-webkit-mask-image:linear-gradient(#000 calc(100% - 28px),transparent);mask-image:linear-gradient(#000 calc(100% - 28px),transparent)}
  /* print's breakdown, moved into its Review page on a phone (stepper.js house): a link and its list in the sheet */
  html.tfp-phone #panel #tfp-bd-home #bd-toggle{display:inline-flex!important}
  html.tfp-phone #panel #tfp-bd-home{display:flex;flex-direction:column;align-items:flex-start;gap:8px}
  /* swatch captions centred under their circles: the text itself, not just its box (a flex row, so no inherited
     text-align can pull it left; measured 11 px off in round 3) */
  html.tfp-phone #panel #finish-cards .finish-group .opt-card .oc-body{display:flex!important;justify-content:center!important;align-items:flex-start!important;width:100%!important}
  html.tfp-phone #panel #finish-cards .finish-group .opt-card .oc-name{display:flex!important;justify-content:center!important;text-align:center!important;width:auto!important;max-width:100%!important;
    margin:0 auto!important;padding:0 0 0 .14em!important;text-indent:0!important}
  /* the print studio's picture holds controls (the file chooser, the crop tool): when the sheet rises it crops, it never
     shrinks them under 44 px */
  html.tfp-phone #stage{transform:translateY(var(--m-stage-ty,0px))!important}
  html.tfp-phone.tfp-sheet-up #stage{-webkit-mask-image:none!important;mask-image:none!important}
  /* print size tiles, final: line one the size with its short name (or "Perfect fit") at the right, line two the
     sharpness, never wrapped (round 3: "30 cm square" pushed "low resolution" out of the tile) */
  html.tfp-phone #panel .size-card .sc-dim{grid-row:1!important;grid-column:1!important}
  html.tfp-phone #panel .size-card .sc-name{grid-row:1!important;grid-column:2!important;justify-self:end;min-width:0;max-width:100%;white-space:nowrap!important;overflow:hidden!important;
    text-overflow:ellipsis!important;color:var(--h-muted)!important;align-self:center}
  html.tfp-phone #panel .size-card .sc-fit{position:static!important;grid-row:1;grid-column:2;justify-self:end;align-self:center;white-space:nowrap}
  html.tfp-phone #panel .size-card:has(.sc-fit) .sc-name{display:none!important}
  html.tfp-phone #panel .size-card .sc-tag{grid-row:2!important;grid-column:1/-1!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}
  html.tfp-phone #panel .size-card:has(.sc-fit){padding-right:12px!important}
  /* a label that starts a new group inside a block (print's "Standard sizes" under the orientation) keeps the 16 px gap */
  html.tfp-phone #panel :is(.step-panel,.panel-step) label.form-label.section-gap{margin-top:16px!important}
  /* ── audit 20 Oct 2026, fixes (F043, F044, F049, F050) ── */
  /* F043: the bar never spills left under the price. Next gives up width first; the price is smaller under
     390 px; under 340 px "Review ›" steps aside (the sheet's tabs end on Review). The price never takes a
     tap meant for the bar (its breakdown link lives in Review on a phone). Extra body/id weight: the print
     studio's own plaque rules come after this sheet. */
  html.tfp-phone body #price-section.studio-plaque{pointer-events:none}
  html.tfp-phone body :is(#bottom-bar,#bottom) .nav-row{min-width:0}
  html.tfp-phone body :is(#bottom-bar,#bottom) .nav-row :is(#btn-next,#btn-toframe,#btn-add-to-cart){flex:0 1 168px!important;width:auto!important;min-width:0!important}
  /* F049: eight tabs scroll sideways, never run into each other; the edge fades say so */
  #tfp-tabs{-webkit-mask-image:linear-gradient(90deg,transparent 0,#000 12px,#000 calc(100% - 12px),transparent);mask-image:linear-gradient(90deg,transparent 0,#000 12px,#000 calc(100% - 12px),transparent)}
  /* F038: Notes for our team reads as its own block, not another row of the spec list above it */
  html.tfp-phone #panel #rv-notes{padding-top:16px!important;border-top:1px solid var(--h-line)!important}
  /* F039: Save and Add to project are one block, last: the same link style, side by side from the left edge */
  html.tfp-phone #panel [data-tfpproj-inline]{display:flex;flex-wrap:wrap;align-items:center;gap:0 20px}
  html.tfp-phone #panel [data-tfpproj-inline] > .tfpds-save:not([hidden]){display:contents}
  /* R3e: a save block the studio hid (no design sessions on this server) stays hidden; the link rules above out-ranked [hidden] */
  html.tfp-phone #panel .tfpds-save[hidden]{display:none!important}
  html.tfp-phone #panel .tfpproj-addlink-inline{display:inline-flex!important;align-items:center;justify-content:flex-start!important;width:auto!important;
    min-height:var(--h-ctl)!important;margin:8px 0 0!important;padding:0!important;font-family:var(--h-sans)!important;font-size:11px!important;font-weight:600!important;
    letter-spacing:.14em!important;text-transform:uppercase!important;line-height:1.3!important;color:var(--h-ink)!important;
    text-decoration:underline!important;text-decoration-thickness:1px!important;text-underline-offset:6px!important}
  /* F044: a step's heading takes the keyboard's focus on a step change (stepper.js); on a phone it is
     screen-reader-only, so while it holds keyboard focus it shows, over the top of the step */
  html.tfp-phone:not(.tfp-gateway) :is(.step-panel,.panel-step) > :is(h2,h3):first-of-type:focus-visible{width:auto!important;height:auto!important;
    clip:auto!important;overflow:visible!important;white-space:normal!important;z-index:5;padding:6px 10px!important;background:var(--h-wall)!important;
    outline:2px solid #313E28!important;outline-offset:0;font-family:var(--h-sans)!important;font-size:11px!important;font-weight:600!important;
    letter-spacing:.14em!important;text-transform:uppercase!important;color:var(--h-ink)!important;line-height:1.3!important}
}
@media (max-width:768px) and (max-width:389px){
  html.tfp-phone body #price-section.studio-plaque{width:96px}
  html.tfp-phone body #price-section .sp-price{font-size:22px!important}
  html.tfp-phone:has(#price-section.studio-plaque:not([style*="display: none"]):not([style*="display:none"])) body :is(#bottom-bar,#bottom) .nav-row{margin-left:100px!important}
  html.tfp-phone body :is(#bottom-bar,#bottom) .nav-row{gap:8px}
  html.tfp-phone body :is(#bottom-bar,#bottom) .nav-row :is(#btn-next,#btn-toframe,#btn-add-to-cart){padding:0 10px!important;letter-spacing:.08em!important}
}
@media (max-width:768px) and (max-width:339px){
  html.tfp-phone body #tfp-skip,html.tfp-phone body #tfp-skip[hidden]{display:none!important}
}

/* Owner, 26 Oct 2026: "make these both cream grey from our homepage ... across all 3 visualizer": the choice cards in the
   frame, mirror and print studios sit on the homepage's cream band (#F2EAE4, home.css --home-band), not white. On a phone
   only the unchosen tiles change: a chosen tile stays forest. */
.studio-glass-panel :is(.door-card,.opt-card,.mount-card,.glass-card,.lane-card,.media-card),
.studio-glass-panel :is(.door-card,.opt-card,.mount-card,.glass-card,.lane-card,.media-card).selected{background:#F2EAE4!important}
html.tfp-phone #panel :is(.door-card,.opt-card,.mount-card,.glass-card,.lane-card,.media-card):not(.selected):not([aria-pressed="true"]):not([aria-checked="true"]){background:#F2EAE4!important}
