/* ===================================================================
 * Make My — Shared zone editor (D45 slice 2)
 *
 * SECTION 1 — ELEVATION (owned by core-zone-elevation.js)
 *
 * Everything in this section is written by core-zone-elevation.js and by
 * nothing else. Geometry (left/top/width/height) is set INLINE by the
 * renderer, because it is derived from the tree's own millimetres and the
 * one uniform scale; this sheet supplies only chrome and stacking.
 *
 * Stacking is the load-bearing part. The renderer's draw order is
 * shell → boards → hit strips → zones → fronts → selection, so in DOM
 * order the zones sit ABOVE the hit strips — and a 14px hit strip over an
 * 18mm board (about 3px on screen) always overlaps the zones either side.
 * Without the z-index below, those zones would swallow every click meant
 * for the board, which is precisely the bug the 14px floor exists to fix.
 * The strip is fully transparent, so lifting it changes the hit test and
 * nothing about the picture.
 *
 * Theme tokens only. No literal colours, no local token system: the plugin
 * ships as its own release unit but paints on the Theme's :root, exactly as
 * every other Core frontend sheet does.
 * =================================================================== */

.core-zone-stage {
    position: relative;
    margin: 0 auto;
    isolation: isolate;
    background: var(--core-preview-bg);
    color: var(--ink);
    font-family: var(--font-sans);
    letter-spacing: var(--tracking-normal);
    -webkit-user-select: none;
    user-select: none;
}

.core-zone-stage > * {
    position: absolute;
}

/* --- The carcass face --- */

.core-zone-shell {
    z-index: 0;
    background: var(--paper-soft);
    border: 1px solid var(--rule-strong);
    border-radius: var(--r-xs);
    pointer-events: none;
}

/* --- Boards --- */

.core-zone-board {
    z-index: 1;
    background: var(--ink-faint);
    pointer-events: none;
}

/* A doubled board is two boards back to back — a doored bay's hinge host.
   Read it as solid. */
.core-zone-board--doubled {
    background: var(--ink-muted);
}

/*
 * A carcass JOIN (D47) — also two boards, but this is where the wall comes
 * apart into separate boxes that bolt together. It gets the darkest ink and a
 * hairline of the shell down its centre, so the seam between the two carcasses
 * is the thing the eye reads rather than the thickness. Breaks only ever land
 * on a top-level VERTICAL divider, so the seam always runs down the board.
 *
 * It replaces `--doubled` on the same element rather than stacking with it —
 * the renderer stamps one class or the other, never both.
 */
.core-zone-board--break {
    background: var(--ink);
    background-image: linear-gradient(
        to right,
        transparent calc(50% - 0.5px),
        var(--paper-soft) calc(50% - 0.5px),
        var(--paper-soft) calc(50% + 0.5px),
        transparent calc(50% + 0.5px)
    );
}

/*
 * The invisible strip that makes a 3px board clickable. It is grown to at
 * least 14px on its thin axis by the renderer and centred on the board, so
 * it necessarily overhangs the zones either side — hence the z-index above
 * .core-zone. Never give this a background: it would paint a fat band over
 * two zones.
 */
.core-zone-board-hit {
    z-index: 3;
    padding: 0;
    background: none;
    border: 0;
    border-radius: var(--r-xs);
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}

.core-zone-board-hit:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

/* --- Zones --- */

.core-zone {
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sp-1);
    overflow: hidden;
    padding: 0;
    background: var(--paper);
    border: 1px solid var(--rule-interactive);
    border-radius: var(--r-xs);
    color: var(--ink-muted);
    font-family: inherit;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}

.core-zone:hover {
    background: var(--accent-wash);
    color: var(--ink);
}

.core-zone:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

.core-zone__label {
    font-family: var(--font-sans);
    font-size: var(--fs-11);
    letter-spacing: var(--tracking-normal);
    line-height: var(--lh-snug);
    pointer-events: none;
}

.core-zone__key {
    font-family: var(--font-sans);
    font-size: var(--fs-11);
    letter-spacing: var(--tracking-normal);
    line-height: var(--lh-snug);
    color: var(--ink-faint);
    pointer-events: none;
}

/*
 * Fitting line-art. The ART ITSELF is the product's, because the slug is the
 * palette's fitting id and no shared file may name a wardrobe fitting or a
 * frame member: a module adds its own `.core-zone-fit--<its slug>` rules.
 * This is only the box they draw inside.
 */
.core-zone-fit {
    position: absolute;
    inset: 0;
    color: var(--ink-faint);
    pointer-events: none;
}

/* --- Fronts --- */

.core-zone-front {
    z-index: 4;
    padding: 0;
    background: color-mix(in oklch, var(--paper-sunk) 55%, transparent);
    border: 1px solid var(--rule-strong);
    border-radius: var(--r-xs);
    font-family: inherit;
    appearance: none;
    -webkit-appearance: none;
}

/*
 * Decoration on any step but Fronts: the renderer disables it, and taking its
 * pointer events away is what keeps the zone underneath clickable — a
 * disabled button still swallows the click that lands on it.
 */
.core-zone-front:not(.core-zone-front--pickable) {
    pointer-events: none;
}

.core-zone-front--pickable {
    cursor: pointer;
}

.core-zone-front--pickable:hover {
    background: color-mix(in oklch, var(--accent) 14%, transparent);
    border-color: var(--rule-interactive);
}

.core-zone-front--pickable:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

/* --- Selection --- */

/*
 * Drawn over whatever is selected, never under it, and never in the way: the
 * thing beneath keeps its own click. Outline rather than border so it sits
 * outside the box and cannot shift what it marks by a pixel.
 */
.core-zone-selection {
    z-index: 5;
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-radius: var(--r-xs);
    background: var(--accent-tint);
    pointer-events: none;
}

/*
 * A selected board is a few pixels wide, so a tint inside it reads as
 * nothing. The outline does the whole job there.
 */
.core-zone-selection--board {
    background: var(--accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: no-preference) {
    .core-zone,
    .core-zone-front--pickable {
        transition: background-color var(--dur-fast) var(--ease),
                    border-color var(--dur-fast) var(--ease);
    }
}

/* ===== End of SECTION 1 (elevation) ================================= */

/* ===================================================================
 * SECTION 2 — POPOVER + STEP RAIL (owned by core-zone-editor.js)
 *
 * Placement and layout only. The chrome comes from the shared primitives
 * the shell's markup already carries — `.core-popover` (core-modal.css)
 * for the raised sheet, `.core-input` / `.core-select` / `.core-segmented`
 * / `.core-btn` (core-controls.css) for every control, and
 * `.core-validation-messages` (core-validation-messages.css) for the
 * issue card. Nothing below restates a background, border, radius,
 * shadow or font size that one of those already owns; a surface that
 * did is exactly the drift efficiencies #228/#229 and inconsistency #95
 * closed.
 *
 * Theme tokens only — no literal hex, no second token system.
 * =================================================================== */

/* Wraps rather than keying on the viewport. The editor is mounted inside a
   stepper panel a few hundred px wide on EVERY screen size, so a viewport
   media query asked the wrong question: on a desktop configurator it never
   fired, and the pane was left sharing ~470px with a 360px rail. Wrapping
   asks the container instead — the two sit side by side when there is room
   for both and stack when there is not. */
.core-zone-editor {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-5);
    align-items: flex-start;
}

/* The clipping box. The popover is positioned against THIS, so it must be
   the containing block — and it is `overflow: hidden`, which is why
   positionPopover() measures and pulls back rather than trusting a
   preferred placement. */
.core-zone-editor__pane {
    position: relative;
    /* A basis, not `auto`: the pane's content is absolutely positioned, so
       `auto` resolves to zero and the rail takes the whole row. */
    flex: 1 1 320px;
    min-width: 0;
    overflow: hidden;
}

/* A transparent sheet over the stage that owns nothing but the popover, so
   appending one never disturbs the elevation's own layout or draw order. It
   must not swallow clicks meant for the boards underneath it. */
.core-zone-popover-layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.core-zone-popover-layer > * {
    pointer-events: auto;
}

/* --- The popover ---
   `.core-popover` supplies paper, rule, radius and the rung-2 shadow; this
   adds only where it sits and how wide it is. `--z-raised` is the canonical
   scale's rung for a popover — there is no `--z-popover`, and the old
   vocabulary aliases were deleted in the 2026-08-10 token migration. */
.core-zone-popover {
    position: absolute;
    z-index: var(--z-raised);
    width: 260px;
    max-width: calc(100% - 16px);
    padding: var(--sp-4);
    box-sizing: border-box;
}

.core-zone-popover .core-input-group:last-of-type {
    margin-bottom: var(--sp-3);
}

/* The cost of removing, stated before the button that does it. Quiet, but
   at reading weight — it is the sentence the customer decides on. */
.core-zone-popover__note {
    margin: 0 0 var(--sp-3);
    font-size: var(--fs-12);
    color: var(--ink-soft);
    line-height: 1.4;
}

.core-zone-popover__actions {
    display: flex;
    gap: var(--sp-2);
    margin-top: var(--sp-3);
}

.core-zone-popover__actions:first-child {
    margin-top: 0;
}

.core-zone-popover__actions .core-btn {
    flex: 1 1 auto;
}

/* --- The step rail ---
   The 360px control rail every configurator's controls column already is,
   so its buttons keep the full-width default the `.core-btn` base sets. */
.core-zone-rail {
    flex: 0 0 360px;
    max-width: 360px;
    box-sizing: border-box;
}

.core-zone-rail .core-segmented {
    margin-bottom: var(--sp-4);
}

/* How many carcasses this design is built as (D47) — a statement of fact
   about the order, not a warning, so it takes the same quiet register as the
   popover's cost note rather than the issue card's. */
.core-zone-rail__note {
    margin: 0 0 var(--sp-4);
    font-size: var(--fs-12);
    color: var(--ink-soft);
    line-height: 1.4;
}

/* Width and placement only — the card's own colour, border, radius and
   type come from `.core-validation-messages` (inconsistency #95). */
.core-zone-rail__issues {
    margin-bottom: var(--sp-4);
}

.core-zone-rail__actions {
    display: flex;
    gap: var(--sp-2);
}

/* ===================================================================
 * SECTION 3 — PRESET PICKER (owned by core-zone-editor.js; the sketch is
 * drawn by core-zone-editor-presets.js)
 *
 * "Start from" — a starting point the customer picks and then edits, as a
 * grid of choice cards. The card box (border, picked,
 * hover, focus, name/sub type) is `.core-choice-card` in core-controls.css;
 * this section is the grid, the sketch and spacing only. The sketch shows
 * how one column reads, never how many columns — a preset re-derives that
 * from the carcass width when it is applied.
 * =================================================================== */

.core-zone-presets {
    display: grid;
    gap: var(--sp-2);
    padding-bottom: var(--sp-4);
    border-bottom: 1px solid var(--rule);
}

.core-zone-presets__label {
    font-family: var(--font-sans);
    font-size: var(--fs-11);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--ink-muted);
}

.core-zone-presets__list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-2);
}

@media (max-width: 420px) {
    .core-zone-presets__list {
        grid-template-columns: minmax(0, 1fr);
    }
}

.core-zone-presets__confirm {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

/* --- The fittings sketch: 26×36, strokes and fills from the tokens --- */

.core-zone-sketch {
    display: block;
    width: 26px;
    height: 36px;
    overflow: visible;
}

.core-zone-sketch__frame {
    fill: var(--paper);
    stroke: var(--rule-interactive);
    stroke-width: 1;
}

/* What a door covers — the whole column, or one row of it. */
.core-zone-sketch__door {
    fill: var(--paper-soft);
}

.core-zone-sketch__divider,
.core-zone-sketch__line {
    stroke: var(--ink);
    stroke-width: 1;
}

.core-zone-sketch__rail {
    stroke: var(--ink);
    stroke-width: 1.5;
}

.core-zone-sketch__box {
    fill: var(--paper);
    stroke: var(--ink);
    stroke-width: 1;
}

/* The cost of replacing an edited layout, stated before the click — the same
   rule the board-removal popover follows. */
.core-zone-presets__cost {
    margin: 0;
    font-size: var(--fs-12);
    line-height: 1.5;
    color: var(--ink-soft);
}
