/* =============================================================
   Core Stepper — shared stepper shell styles.
   Source: Design Claude handoff — lifted from the prototype HTML's
   inline <style> block (Make My - Header, Configurator & Checkout.html,
   lines 239-456), not from design/configurator.css (that file targets
   the old sidebar+preview layout, not the stepper).
   Token dependency: Theme/assets/css/main.css must be loaded first
   (provides --paper, --ink, --accent, --sp-*, etc.).
   ============================================================= */

/* ===== Outer shell (title row → card → summary bar) =====
   Shell redesign, 2026-09-25 (maintainer-approved mock-up): the shell itself
   is frameless. Its three rows are the title row (.config-hero), one bordered
   card holding the step tabs and the panel + preview (.config-card), and the
   summary bar sitting below the card (.config-summary). The room planner
   reuses these classes on its own root and no longer restates its own frame
   — .config-card owns the border/radius/clip the same way it does for the
   standalone configurators — see the "Room planner" block at the foot of
   this file. */

.config-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    gap: var(--sp-4);
    background: var(--paper);
}

/* The card. `clip`, not `hidden`. Both clip the rounded corners identically,
   but `hidden` creates a scroll container — and a scroll container silently
   neutralises `position: sticky` on every descendant (the mobile steps rail
   and step-nav). `clip` does not create one. The `hidden` line stays first as
   a fallback for engines without `clip`. */
.config-card {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    min-width: 0;
    border: 1px solid var(--rule-strong);
    border-radius: var(--r-md);
    overflow: hidden;
    overflow: clip;
    background: var(--paper);
}

/* ===== Title row (product title + the Advanced options switch) =====
   Core_Stepper prints the page's <h1> here — the product title, its module
   noun in the accent, which is only scoped inside the configurator root — and
   core-input-mode.js appends the switch after it, pushed right. With neither
   (no page title, no Advanced controls) the strip is :empty and collapses. */

.config-hero {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-end;
    gap: var(--sp-3);
}

.config-hero:empty {
    display: none;
}

.config-hero__title {
    margin: 0;
    font-size: clamp(var(--fs-28), 5vw, var(--fs-36));
    font-weight: var(--fw-semibold);
    letter-spacing: var(--tracking-tight);
    line-height: 1.1;
    color: var(--accent);
}

/* A configurator's product title reads on from the lowercase "make my" logo:
   the product in Ink, the module noun (Core_Stepper::title_html()) in the
   accent, all lowercase — except an L-/U-shape letter, which only names the
   shape as a capital. Lowercased here, not in PHP, so the page title, tab
   title and basket names keep their capitals. */
.config-hero__title--product {
    color: var(--ink);
    text-transform: lowercase;
}

.config-hero__module {
    color: var(--accent);
}

.config-hero__keep-case {
    text-transform: none;
}

/* ===== Input-mode switch (Standard ⇄ Advanced) =====
   core-input-mode.js appends this into .config-hero as
       <div class="config-hero__mode">
         <button class="core-switch core-input-mode-toggle" role="switch"
                 data-input-mode-toggle aria-checked="true|false">
           <span class="core-input-mode-toggle__label">Advanced options</span>
         </button>
       </div>
   The switch state is read off the button's aria-checked alone
   (true = Advanced/on). The track + knob are pure pseudo-elements
   (::before = track, ::after = knob, so the knob paints over the track) — no
   extra DOM, no JS styling hooks. */

.config-hero__mode {
    flex: none;
    /* Right-aligned whether or not a title precedes it. */
    margin-left: auto;
}

/* The Advanced options switch wears the shared `.core-switch` primitive
   (core-controls.css, a dep of this sheet); `.core-input-mode-toggle` stays
   on the button as its JS hook and carries no rules of its own. */

/* ===== Step tabs =====
   Equal columns of centred Ink labels divided by 1px Rule Strong rules, the
   current tab's label in the accent. Each tab also wears the shared
   `.core-tab` primitive (core-controls.css), which owns the progress
   underline, the hover wash and the focus ring — the room planner's sub-step
   bar wears the same class, so the two bars can't drift. Only the bar's own
   sizing, type and divider colour live here. The underline follows
   aria-current, never data-done (which core-stepper.js never clears, so it
   would leave steps underlined after going Back). */

.steps-bar {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    background: var(--paper);
    border-bottom: 1px solid var(--rule-strong);
}

.steps-bar__step {
    min-width: 0;
    padding: var(--sp-3) var(--sp-2);
    text-align: center;
}

.steps-bar__step + .steps-bar__step {
    border-left: 1px solid var(--rule-strong);
}

.steps-bar__label {
    font-size: var(--fs-13);
    font-weight: var(--fw-regular);
    color: var(--ink);
    line-height: 1.3;
    transition: color var(--dur-fast) var(--ease);
}

.steps-bar__step[aria-current="step"] .steps-bar__label {
    color: var(--accent);               /* current — the delivered accent, at every size (§3.5) */
}

/* Live value carrier — kept in the DOM so the summary spec line can read it,
   never shown on the bar. */
.steps-bar__value {
    display: none;
}

/* ===== Body: step content (left) + preview (right) ===== */
/* Markup uses .config-panel as the step container; prototype uses
   .config-step directly. We target .config-panel (ours) for ordering. */

.config-body {
    display: grid;
    grid-template-columns: 525px 1fr;
    min-height: 480px;
}

.config-body .config-panel {
    order: 1;
}

.config-body .config-preview {
    order: 2;
}

/* Tablet landscape / narrow desktop. The single-column collapse used to start
   at 1100px while the preview-first order swap only started at 900px — so
   901-1100px (iPad landscape is 1024px) got a full-width step panel with the
   preview stranded below it, on viewports with ample room for side-by-side.
   Two columns now hold down to 901px, on a narrower panel track so the preview
   keeps a usable width at the low end (901px gives 440 + 461, 1100px gives
   440 + 660). The ≤900px collapse to 1fr lives in the mobile block below. */
@media (min-width: 901px) and (max-width: 1100px) {
    .config-body {
        grid-template-columns: 440px 1fr;
    }
}

/* Step panels (we render all; JS toggles .is-active to show one).
   Without the display: none override here, all N sections stack vertically. */

.config-panel {
    min-width: 0;
}

.config-step {
    display: none;
    padding: var(--sp-6) var(--sp-6) var(--sp-8);
    gap: var(--sp-5);
    align-content: start;
    overflow-y: auto;
}

.config-step.is-active {
    display: grid;
}

/* "02 Material" — the zero-padded step number in the accent, then the title,
   on one line at regular weight. Replaced the "Step 02 of 05" kicker. */
.config-step__title {
    font-size: var(--fs-22);
    font-weight: var(--fw-regular);
    letter-spacing: var(--tracking-tight);
    line-height: 1.2;
    margin: 0;
}

.config-step__num {
    color: var(--accent); /* the delivered accent, at every size (§3.5) */
}

.config-step__desc {
    color: var(--ink-soft);
    font-size: var(--fs-12);
    max-width: 48ch;
    /* Sits close under its heading rather than a full row-gap away. */
    margin: calc(-1 * var(--sp-3)) 0 0;
}

.config-step__body {
    display: grid;
    gap: var(--sp-4);
}

/* Back / Continue — one compact joined pair on the Small rung: grey Back,
   Coal Continue, only the pair's outer corners rounded. Scoped here so it
   outranks the single-class `.core-btn` variants whichever order the sheets
   print in. */
.config-step__nav {
    display: flex;
    gap: 0;
    margin-top: var(--sp-2);
}

.config-step__nav .core-btn {
    min-height: var(--h-btn-sm);
    padding: 0 var(--sp-4);
    font-size: var(--fs-13);
    border: 0;
}

.config-step__nav .config-step__nav__back {
    background: var(--paper-soft);
    color: var(--ink);
    border-radius: var(--r-sm) 0 0 var(--r-sm);
}

.config-step__nav .config-step__nav__back:hover:not(:disabled) {
    background: var(--paper-sunk);
}

.config-step__nav .config-step__nav__back:disabled {
    color: var(--ink-muted);
}

.config-step__nav .config-step__nav__continue {
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
}

/* Last step: Back stands alone, so it takes all four corners. */
.config-step__nav .config-step__nav__back:last-child {
    border-radius: var(--r-sm);
}

/* Step 1: Continue stands alone (no Back), so it takes all four corners
   too — the mirror of the lone-Back rule above. */
.config-step__nav .config-step__nav__continue:first-child,
.config-step__nav .config-step__nav__back[hidden] + .config-step__nav__continue {
    border-radius: var(--r-sm);
}

/* `.core-btn { display: flex }` outranks the UA [hidden] rule. */
.config-step__nav .config-step__nav__back[hidden] {
    display: none;
}

/* ===== Preview pane ===== */

.config-preview {
    position: relative;
    display: flex;
    overflow: hidden;
    /* The panel/preview divider inside the card. */
    border-left: 1px solid var(--rule-strong);
}

/* No stacked-preview rule here any more. It only ever applied below 1100px,
   and every declaration in it is re-set by the ≤900px mobile block (which
   zeroes border-top, sets border-bottom, and clamps min-height). With 901-1100px
   now side-by-side, the preview wants the base rule's border-left in that band —
   so the override had no remaining audience. */

/* A floating toolbar over the preview — §6.1 rung 2, same tier as the
 * popovers. Nothing in the codebase currently emits this class (the live
 * preview controls are `.core-preview-toggle` and `.core-3d-reset-btn`),
 * so its chrome was stripped rather than folded onto `.core-popover`
 * (efficiency #230): it used to paint --shadow-1, a rung below its tier.
 * Placement only now — WHOEVER MOUNTS THIS must add `core-popover` to the
 * element and `core-modal` to this sheet's style deps, and bring its own
 * buttons (`.core-btn--overlay-icon`): the `.config-preview__tool` rules that
 * sat below, and the `.config-preview__status` pill, were deleted as dead
 * (efficiency #245). */
.config-preview__tools {
    position: absolute;
    top: var(--sp-4);
    right: var(--sp-4);
    display: flex;
    gap: 2px;
    padding: 3px;
}

/* ===== Summary bar — below the card =====
   Left: Save / Open / Help as small grey chips, plus "Review Tutorial"
   (rendered `hidden`; the tutorial JS reveals it where a tour exists).
   Right: the total — label centred over the amount — then the Coal primary. */

.config-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3) var(--sp-4);
}

.config-summary__design-actions:empty {
    display: none;
}

.config-summary__design-actions .csd-config-btn,
.config-summary__design-actions .config-summary__tutorial {
    /* The same 32px as Staff tools and Add to basket — one button height
       across the bar. */
    height: var(--h-btn-sm);
    min-height: 0;
    padding: 0 var(--sp-3);
    border: 0;
    border-radius: var(--r-sm);
    background: var(--paper-sunk);
    color: var(--ink);
}

/* Every button in the bar reads at 14px — one step up from the small rung's
   13px, so the bar's labels hold their own beside the 28px total. */
.config-summary .core-btn {
    font-size: var(--fs-14);
}

/* Review Tutorial is a text button: no box, an underline, and the same 32px
   height as its neighbours so the row keeps one height (Design.md §5.4). */
.config-summary__design-actions .config-summary__tutorial {
    background: transparent;
    padding: 0 var(--sp-2);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.config-summary__design-actions .csd-config-btn:hover {
    background: color-mix(in oklch, var(--paper-sunk) 85%, var(--ink));
}

.config-summary__design-actions .config-summary__tutorial:hover {
    background: transparent;
    color: var(--ink-soft);
}

/* `.core-btn--inline` is `display: inline-flex`, which beats the UA's
   [hidden] rule — restate it so the replay button stays hidden until a tour
   claims it. */
.config-summary__tutorial[hidden] {
    display: none;
}

.config-summary__price {
    /* Push the price + primary action to the right edge. Works whether or not
       the left-hand design actions are present. The label sits to the LEFT of
       the amount, on its baseline. */
    margin-left: auto;
    display: flex;
    align-items: baseline;
    gap: var(--sp-3);
    text-align: left;
}

.config-summary__price__label {
    font-size: var(--fs-11);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--ink-soft);
    line-height: 1.2;
}

.config-summary__price__amount {
    font-size: var(--fs-28);
    font-weight: var(--fw-regular);
    line-height: 1;
    white-space: nowrap;
}

/* Quantity > 1 renders "£per × qty = £total": the working stays small and
   only the total takes the 28px lead size. */
.config-summary__price__amount:has(.mm-price--inline) {
    font-size: var(--fs-16);
}
.config-summary__price__amount:has(.mm-price--inline) > .mm-price--inline:last-child {
    font-size: var(--fs-28);
}

/* Ex VAT mode (the header's VAT switch, <html data-vat="ex">): the ex figure
   leads at the same 28px, and the inc figure rides beside it, smaller —
   rather than dropping beneath it as it does in the Theme's default. */
html[data-vat="ex"] .config-summary__price__amount > .mm-price:not(.mm-price--inline) .mm-price__inc {
    display: inline;
    margin-left: var(--sp-3);
    font-family: var(--font-sans);
    font-size: var(--fs-16);
    color: var(--ink-soft);
}

/* `align-items: center` because `.core-btn` sizes with `min-height`, not a
   fixed `height`. */
.config-summary__actions {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
}

.config-summary__actions [data-add-to-cart] {
    padding: 0 var(--sp-4);
    border-radius: var(--r-sm);
}

/* ===== Side-by-side layouts — lock shell height; menu scrolls inside =====
   Without this, the body row's 1fr grows to match the taller of panel/preview,
   so menu-heavy steps stretched the 3D preview vertically. Locking the shell
   height pins the preview to a stable size; the panel becomes the scroll
   container instead. Defusing .core-3d-container's 500px min-height inside
   this scope prevents it from silently pushing the row past the lock.
   Extended down to 901px alongside the two-column body above — the panel
   scroll only works against a definite shell height, so the band needs this
   same lock, not just the grid. Known trade-off: on a 768px-tall viewport
   (iPad landscape) an 860px shell puts the summary bar just below the fold,
   exactly as it already does on a 1366x768 laptop. */

@media (min-width: 901px) {
    .config-card {
        height: 760px;
    }
    .config-panel {
        min-height: 0;
        overflow-y: auto;
        scrollbar-gutter: stable;
    }
    .core-3d-container {
        min-height: 0;
    }
}

/* ===== Mobile =====
   Locked-in pattern from the Cabinet-pilot design: horizontally-scrolling
   step rail, preview that scrolls inline (not sticky), sticky step-nav
   pinned above a fixed summary bar. The summary is safe-area + keyboard
   aware — core-mobile-keyboard.js toggles [data-kb="open"] when the soft
   keyboard is up, and writes --core-summary-h so step-nav sits flush above
   whichever footer height is actually rendered.
*/

@media (max-width: 900px) {
    /* Shell — keeps the desktop rows (title / card / summary), tighter.
       The summary is position:sticky inside the shell (see .config-summary
       below) so it pins to the viewport bottom while the shell is in view
       and scrolls away cleanly when the user scrolls past into page
       content below the configurator. */
    .config-shell {
        min-height: 100vh;
        gap: var(--sp-3);
    }

    /* Title wraps above the switch when the row runs out. */
    .config-hero {
        gap: var(--sp-2);
    }

    /* Steps rail — flex + horizontal snap-scroll. Override desktop's
       grid-auto-flow so the track becomes a flex row. */
    .steps-bar {
        position: sticky;
        top: 0;
        z-index: var(--z-sticky);
        display: flex;
        grid-auto-flow: initial;
        grid-auto-columns: initial;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        scrollbar-width: none;
    }
    .steps-bar::-webkit-scrollbar {
        display: none;
    }
    .steps-bar__step {
        flex: 0 0 auto;
        min-width: 128px;
        max-width: 170px;
        scroll-snap-align: start;
        padding: var(--sp-3) var(--sp-3);
    }

    /* Body — single column. Preview first, then the step panel. */
    .config-body {
        grid-template-columns: 1fr;
        min-height: 0;
    }
    .config-body .config-panel { order: 2; }
    .config-body .config-preview { order: 1; }

    /* Preview — short, scrolls with content (not sticky). */
    .config-preview {
        min-height: clamp(180px, 28vh, 260px);
        border-left: 0;
        border-top: 0;
        border-bottom: 1px solid var(--rule-strong);
    }

    .config-step {
        padding: var(--sp-4) var(--sp-4) var(--sp-5);
        /* The base rule's `overflow-y: auto` makes this a scroll container,
           which traps .config-step__nav's `position: sticky` inside a box
           that never scrolls — so the nav never pinned above the summary.
           On mobile the page itself is the scroll container; hand it back.
           Desktop keeps `auto` (the ≥901px panel owns its own scrolling). */
        overflow-y: visible;
    }
    /* Step nav — sticky just above the fixed summary, still one joined pair.
       1fr 2fr so Continue dominates. The pair keeps the desktop 32px Small
       rung: every configurator button is one height (§5.4), so the phone
       layout doesn't get an off-ladder 42px pair of its own. */
    .config-step__nav {
        position: sticky;
        bottom: var(--core-summary-h, 64px);
        z-index: calc(var(--z-sticky) + 1);
        display: grid;
        grid-template-columns: 1fr 2fr;
        gap: 0;
        padding: var(--sp-3) var(--sp-4);
        margin: 0;
        background: var(--paper);
        border-top: 1px solid var(--rule);
    }
    /* Summary — sticky to the bottom of the shell's scroll region.
       Pins to viewport bottom while the shell is on screen; scrolls away
       when the user enters page content below. Safe-area aware on iOS. */
    .config-summary {
        position: sticky;
        bottom: 0;
        z-index: calc(var(--z-sticky) + 2);
        justify-content: space-between;
        gap: var(--sp-3);
        padding: var(--sp-3) var(--sp-4) max(var(--sp-3), env(safe-area-inset-bottom, 0));
        border-top: 1px solid var(--rule-strong);
        background: var(--paper);
    }
    /* Save / Load design is a secondary action — keep the cramped sticky
       footer to just the price and the primary button. */
    .config-summary__design-actions {
        display: none;
    }
    .config-summary__price {
        /* space-between handles alignment here: price left, action right. */
        margin-left: 0;
        text-align: left;
    }
    /* The sticky phone bar has no room for the 28px desktop total. */
    .config-summary__price__amount,
    .config-summary__price__amount:has(.mm-price--inline) > .mm-price--inline:last-child {
        font-size: var(--fs-22);
    }
    /* A touch-sized primary in the sticky bar. */
    .config-summary__actions [data-add-to-cart] {
        min-height: var(--h-control);
    }

    /* Keyboard open — core-mobile-keyboard.js sets data-kb="open" on the
       shell. Price collapses; Continue stretches full-width directly
       above the keyboard inset. */
    .config-shell[data-kb="open"] .config-summary {
        padding-bottom: env(keyboard-inset-height, 0);
    }
    .config-shell[data-kb="open"] .config-summary__price {
        display: none;
    }
    /* Price hidden — let the lone primary action stretch full-width. */
    .config-shell[data-kb="open"] .config-summary__actions {
        flex: 1;
    }
    .config-shell[data-kb="open"] .config-summary__actions .core-btn {
        width: 100%;
    }
    .config-shell[data-kb="open"] .config-step__nav {
        bottom: 0;
    }
}

/* ===== Room planner — card now owns the frame (Task 2, 2026-09-25
   redesign) =====
   The planner root reuses .config-shell / .core-stepper the same way the
   standalone configurators do: .config-card (below) owns the border/
   radius/clip, and the action bar (.config-summary) sits outside it. The
   restated frame this block used to carry (border/radius/clip on the root,
   the hero strip's own padding/rule, the summary strip's padding/top rule)
   is gone — the shared .config-card / .config-hero / .config-summary rules
   above apply unmodified. See core-room-shape-form.css / core-room-rail.css
   for what still differs (the planner's own two-pane grid on __main). */
