/* =========================================================================
   Core — shared bulk cut-list table skeleton
   Used by Sheet and Trim only (dep of their product stylesheets).

   Every rule here targets the slug-free `core-bulk-*` styling classes the two
   configurators' markup carries (efficiency #488). The `{slug}-*` classes
   beside them are the JS field hooks (`.sheet-material`, `.trim-dim-a`, …) and
   are never styled here. The few product-only fields (Sheet's grain select and
   Handle cell, Trim's type select) keep their slug class in the selector —
   that name IS the field — and the one genuinely per-product layout rule (the
   card-layout Qty slot) reads the `core-bulk-table--{slug}` modifier on the
   table root. Each selector keeps the specificity its old slug pair had, so
   the cascade against sheet-configurator.css / trim-configurator.css (which
   load after this sheet) is unchanged.
   ========================================================================= */

/* -----------------------------------------------------------------------
   Configurator wrapper
   -----------------------------------------------------------------------
   Deliberately NOT a scroll container. The table wrapper below owns the one
   horizontal scroller; having both made the wide table sit inside two nested
   horizontal scrollers, so a swipe moved whichever one the touch happened to
   land on. */

.core-bulk-configurator {
    max-width: 100%;
}

/* -----------------------------------------------------------------------
   Project meta fieldset
   -----------------------------------------------------------------------
   Both bulk tables collect a project name / client / notes above the table;
   the values ride on every row's line item so the basket can group a cut list
   by project. */

.core-bulk-project-meta {
    border: 1px solid var(--rule);
    border-radius: var(--r-md);
    padding: 16px 20px;
    margin-bottom: 24px;
}

/* The legend treatment is NOT here — it is shared with the labelled-subsection
   fieldset in core-controls.css, which this sheet reaches through
   core-bulk-table → core-configurator → core-controls. Only the box above is
   local, because the bulk tables' fieldset is wider-set than a control-rail
   subsection. */

.core-bulk-field-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
}

.core-bulk-field-row:last-child {
    margin-bottom: 0;
}

.core-bulk-field-row label {
    flex: 0 0 120px;
    font-size: var(--fs-13);
    font-weight: var(--fw-regular);
    color: var(--ink-soft);
}

.core-bulk-project-name,
.core-bulk-project-client,
.core-bulk-project-notes {
    box-sizing: border-box;
    flex: 1 1 200px;
    min-width: 140px;
    padding: 6px 10px;
    border: 1px solid var(--rule-strong);
    border-radius: var(--r-sm);
    font-size: var(--fs-13);
    line-height: 1.4;
}

.core-bulk-project-notes {
    resize: vertical;
}

/* Below 640 px the label stacks above its field. */
@media (max-width: 640px) {
    .core-bulk-field-row label {
        flex: 0 0 100%;
    }
}

/* -----------------------------------------------------------------------
   Table wrapper + table
   -----------------------------------------------------------------------
   The table is intrinsically far wider than any phone viewport (17 columns,
   ~1330 px on Sheet), so it scrolls horizontally inside this wrapper at table
   widths and is replaced outright by the card layout below the breakpoint. No
   min-width is declared: the intrinsic width always exceeds anything worth
   pinning, so a min-width would be a number that never applies. */

.core-bulk-table-wrap {
    overflow-x: auto;
    margin-bottom: 16px;
}

.core-bulk-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-13);
    table-layout: auto;
}

/* Header type, colour and rule come from the shared `.core-table th`
   (core-controls.css); only the padding is this table's. */
.core-bulk-table th {
    padding: 8px 10px;
}

.core-bulk-table td {
    padding: 6px 8px;
    vertical-align: middle;
    border-bottom: 1px solid var(--rule);
}

/* -----------------------------------------------------------------------
   Row inputs
   ----------------------------------------------------------------------- */

/* Shared box model for every row control (`.core-bulk-control`) so selects,
   number fields and text inputs all render at the same height with the same
   text size. */
.core-bulk-control {
    box-sizing: border-box;
    height: var(--h-btn-sm);
    padding: 4px 8px;
    border: 1px solid var(--rule-interactive);
    border-radius: var(--r-sm);
    font-size: var(--fs-13);
    line-height: 1.4;
    background: var(--paper);
    vertical-align: middle;
}

.core-bulk-material,
.core-bulk-thickness,
.core-bulk-edgeband-id {
    width: 100%;
    min-width: 100px;
}

/* Room for the stock mark beside the thickness select (D53): 16px mark +
   its 6px gap, so the pair still fills the cell without wrapping. */
.core-bulk-thickness:has( + .core-stock-mark ) {
    width: calc(100% - 22px);
}

/* The two dimension inputs are Length/Width on Sheet, Dimension A/B on Trim. */
.core-bulk-dim-a,
.core-bulk-dim-b,
.core-bulk-quantity {
    width: 72px;
    text-align: right;
}

.core-bulk-label {
    width: 100%;
    min-width: 80px;
}

/* -----------------------------------------------------------------------
   Material / edgeband swatch widgets (CoreMaterialSwatch)
   -----------------------------------------------------------------------
   CoreMaterialSwatch hides the native material / edge banding
   <select data-swatch> and builds a .cms-wrap + .cms-button trigger. Match the
   button's box model to the sibling row controls (32px / 13px) so every cell
   aligns, and pin each wrap to a fixed width so the trigger no longer grows
   with the selected name — the .cms-button__label already truncates with an
   ellipsis, and the popup keeps its own min-width so full names stay readable. */

/* The trigger also wears `.core-select`, whose 44px min-height would beat a
   plain `height` — so the dense row's 32px rung is stated as both. */
.core-bulk-table .cms-button {
    height: var(--h-btn-sm);
    min-height: var(--h-btn-sm);
    padding: 4px 8px;
    font-size: var(--fs-13);
    border-radius: var(--r-sm);
}

.core-bulk-table .cms-wrap:has( .core-bulk-material ) {
    width: 200px;
    max-width: 200px;
}

.core-bulk-table .cms-wrap:has( .core-bulk-edgeband-id ) {
    width: 160px;
    max-width: 160px;
}

/* -----------------------------------------------------------------------
   Row price cell
   ----------------------------------------------------------------------- */

.core-bulk-row-price {
    display: block;
    white-space: nowrap;
    font-weight: var(--fw-semibold);
    color: var(--ink);
    font-size: var(--fs-13);
    min-width: 60px;
    text-align: right;
}

/* -----------------------------------------------------------------------
   Remove-row button
   ----------------------------------------------------------------------- */

/* The round "×" body comes from `.core-btn--close` (core-controls.css,
   efficiency #229), which the markup carries — the same primitive as the
   configurator popup's dismiss and the saved-designs modal close. Only the
   Error hover is local, and deliberately so: removing a priced row is a
   destructive act, not a dismissal. */
/* Design.md §5.4 "One height per row": a remove-row × takes its row's
   height, so in a bulk row it is a 32px square beside the 32px controls
   instead of `.core-btn--close`'s 24px corner size (that size is kept for a
   lone close × in a corner). Table-qualified to outrank `.core-btn--close`;
   the card layout below lifts it to 44. `.core-btn` already centres the glyph. */
.core-bulk-table .core-bulk-remove-row {
    width: var(--h-btn-sm);
    height: var(--h-btn-sm);
    min-height: var(--h-btn-sm);
}

.core-bulk-remove-row:hover,
.core-bulk-remove-row:focus {
    color: var(--err);
    background: color-mix(in oklch, var(--err) 10%, var(--paper));
    outline: none;
}

/* -----------------------------------------------------------------------
   SVG thumbnail cell (v2 — not in v1 template, no-ops if absent)
   ----------------------------------------------------------------------- */

.core-bulk-row-thumb {
    width: 216px;
    text-align: center;
    vertical-align: middle;
}

.core-bulk-row-thumb svg {
    display: block;
    margin: 0 auto;
}

/* Edge checkbox columns — keep them narrow and centred so the four sit
   compactly next to the Edging picker they belong to. */
.core-bulk-edge-col {
    width: 34px;
    text-align: center;
}

/* The checkboxes themselves. Core_Edge_Grid stamps `.core-bulk-edge-cb` on the
   All master and on every per-edge box, Sheet's L1/L2/S1/S2 and Trim's
   A1/A2/B1/B2 alike. */
.core-bulk-edge-cb {
    width: 18px;
    height: 18px;
    cursor: pointer;
    accent-color: var(--accent);
    display: block;
    margin: 0 auto;
}

/* Touch pointers get the WCAG 2.5.8 minimum (24 × 24 CSS px). Mouse pointers
   keep the tighter 18 px box that lets the four edge columns stay narrow. This
   matters at table widths on a tablet; below the card breakpoint these
   checkboxes are hidden entirely and the edge picker takes over. */
@media (pointer: coarse) {
    .core-bulk-edge-cb {
        width: 24px;
        height: 24px;
    }

    .core-bulk-edge-col {
        width: 40px;
    }
}

/* The card-layout edge picker's column. Hidden at table widths — the five
   checkbox columns are the control there. Table-qualified to match the card
   block's counterpart, which has to outrank `.core-bulk-table td`. */
.core-bulk-table .core-bulk-edge-picker-cell {
    display: none;
}

/* -----------------------------------------------------------------------
   Footer controls row
   ----------------------------------------------------------------------- */

.core-bulk-controls {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 16px;
    margin-bottom: 16px;
}

.core-bulk-total-wrap {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--fs-14);
    color: var(--ink-soft);
}

.core-bulk-total {
    font-weight: var(--fw-semibold);
    font-size: var(--fs-16);
    color: var(--ink);
}

/* -----------------------------------------------------------------------
   Submit wrapper
   ----------------------------------------------------------------------- */

.core-bulk-submit-wrap {
    margin-top: 8px;
}

/* =========================================================================
   Card layout — below 900 px each row becomes a bordered card
   =========================================================================
   The table's intrinsic width is ~3.5× a phone viewport, so at these sizes it
   stops being a table: the <thead> is dropped, each <tr> becomes a two-column
   grid card, and each <td> becomes a labelled field captioned from its
   data-card-label. The markup and every JS selector are untouched — the whole
   switch is presentational, which is why desktop behaviour is unchanged.

   Field order is set with `order` rather than by moving DOM nodes: the two
   wide swatch pickers (Material, Edge banding) and the edge picker take full
   width, the small numeric fields pair up two-across, and Price + Remove sit
   in a footer row.

   (The old rule here dropped the table to 12 px below 640 px. It shrank text
   on a table that scrolled horizontally regardless, and is meaningless now the
   card layout covers those widths.) */

@media (max-width: 900px) {

    /* ---- Shell: stop being a table ---- */

    .core-bulk-table-wrap {
        /* Nothing overflows once rows are cards, and a scroll container here
           would clip the Sheet cut-out popover. */
        overflow: visible;
    }

    .core-bulk-table,
    .core-bulk-table tbody {
        display: block;
        width: 100%;
    }

    .core-bulk-table thead {
        /* Column headers can't caption a card; data-card-label does. */
        display: none;
    }

    /* ---- The card ---- */

    .core-bulk-row {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 12px;
        align-items: end;
        padding: 14px;
        margin-bottom: 14px;
        border: 1px solid var(--rule-strong);
        border-radius: var(--r-md);
        background: var(--paper);
    }

    .core-bulk-table td {
        display: block;
        grid-column: span 2;
        padding: 0;
        border-bottom: 0;
    }

    .core-bulk-table td[data-card-label]::before {
        content: attr(data-card-label);
        display: block;
        margin-bottom: 5px;
        font-size: var(--fs-12);
        font-weight: var(--fw-semibold);
        color: var(--ink-soft);
    }

    /* ---- Field order + which fields pair two-across ----
       Every cell selector below is qualified with the table class. The base
       `.core-bulk-table td` rule above is (0,1,1), so a bare
       `.core-bulk-edge-col` (0,1,0) would lose to it and the hidden columns
       would reappear. */

    .core-bulk-table .core-bulk-row-thumb { order: 1; }

    .core-bulk-table td:has( .trim-type ) { order: 2; }

    .core-bulk-table td:has( .core-bulk-material ) { order: 3; }

    .core-bulk-table td:has( .core-bulk-thickness ) { order: 4; grid-column: span 1; }

    .core-bulk-table td:has( .sheet-grain ) { order: 5; grid-column: span 1; }

    .core-bulk-table td:has( .core-bulk-dim-a ) { order: 6; grid-column: span 1; }

    .core-bulk-table td:has( .core-bulk-dim-b ) { order: 7; grid-column: span 1; }

    .core-bulk-table td:has( .core-bulk-quantity ) { order: 8; grid-column: span 1; }

    /* Trim has no Grain field, so Qty moves up to partner Thickness and the two
       dimensions get their own clean row. Same specificity as the rule above,
       so source order decides. */
    .core-bulk-table--trim td:has( .core-bulk-quantity ) { order: 5; }

    .core-bulk-table td:has( .core-bulk-edgeband-id ) { order: 9; }

    .core-bulk-table .core-bulk-edge-picker-cell { display: block; order: 10; }

    .core-bulk-table .sheet-cell-handle { order: 11; }

    /* A hidden trigger (material not cut-out eligible) would leave the card
       showing a bare "Handle" caption over nothing, so drop the whole cell.
       Desktop keeps its column and simply renders the cell empty. */
    .core-bulk-table .sheet-cell-handle:has( .sheet-cutout-trigger[hidden] ) { display: none; }

    .core-bulk-table td:has( .core-bulk-label ) { order: 12; }

    .core-bulk-table td:has( .core-bulk-row-price ),
    .core-bulk-table .core-bulk-cell-remove {
        grid-column: span 1;
        padding-top: 10px;
        border-top: 1px solid var(--rule);
    }

    .core-bulk-table td:has( .core-bulk-row-price ) { order: 13; }

    .core-bulk-table .core-bulk-cell-remove {
        order: 14;
        justify-self: end;
        align-self: center;
    }

    /* The five checkbox columns are replaced by the edge picker. They stay in
       the DOM — they are still the state every reader looks at. */
    .core-bulk-table .core-bulk-edge-col {
        display: none;
    }

    /* ---- Controls: full width, touch height ---- */

    /* Row-class prefixed so these beat the per-product fixed widths
       (.sheet-grain, .trim-type), whose stylesheets load after this one. */
    .core-bulk-row .core-bulk-control {
        width: 100%;
        min-width: 0;
        height: var(--h-control);
        /* 16 px keeps iOS Safari from zooming the viewport on focus. */
        font-size: var(--fs-16);
        text-align: left;
    }

    .core-bulk-table .cms-button {
        height: var(--h-control);
        font-size: 15px;
    }

    .core-bulk-table .cms-wrap:has( .core-bulk-material ),
    .core-bulk-table .cms-wrap:has( .core-bulk-edgeband-id ) {
        width: 100%;
        max-width: none;
    }

    .core-bulk-row .sheet-cutout-trigger {
        width: 100%;
        min-height: var(--h-control);
        font-size: 15px;
    }

    /* ---- Preview, price, remove ---- */

    .core-bulk-table .core-bulk-row-thumb {
        width: auto;
        padding: 6px 0 2px;
    }

    .core-bulk-row .core-bulk-row-price {
        text-align: left;
        font-size: var(--fs-18);
    }

    .core-bulk-row .core-bulk-remove-row {
        width: var(--h-control);
        height: var(--h-control);
        min-width: var(--h-control);
        min-height: var(--h-control);
        font-size: var(--fs-22);
    }

    /* ---- Footer controls ---- */

    .core-bulk-controls {
        justify-content: space-between;
    }

    .core-bulk-submit-wrap .core-btn,
    .core-bulk-controls .core-btn {
        min-height: var(--h-control);
    }
}

/* =========================================================================
   Card-layout edge picker (core-rect-panel-table.js)
   =========================================================================
   One tappable rectangle replaces the five 18 px checkboxes. It mirrors the row
   thumbnail — longest side horizontal — so the strip a customer taps is the
   edge they can see banded in the preview. Built and kept in sync by JS; the
   real checkboxes remain the state. */

.core-edge-picker__frame {
    position: relative;
    display: grid;
    /* 44 px strips — the touch-target guideline, comfortably above the WCAG
       2.5.8 minimum of 24 px that the checkboxes they replace only just met. */
    grid-template-columns: 44px 1fr 44px;
    grid-template-rows: 44px 1fr 44px;
    width: 100%;
    max-width: 280px;
    aspect-ratio: 5 / 3;
    border-radius: var(--r-sm);
    background: var(--paper-soft);
}

.core-edge-picker__edge,
.core-edge-picker__all {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    padding: 2px;
    border: 1px dashed var(--rule-interactive);
    background: var(--paper);
    color: var(--ink-soft);
    font-size: var(--fs-11);
    font-weight: var(--fw-semibold);
    line-height: 1.2;
    cursor: pointer;
    transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
        border-color var(--dur-fast) var(--ease);
}

.core-edge-picker__edge--top    { grid-area: 1 / 1 / 2 / 4; border-radius: var(--r-sm) var(--r-sm) 0 0; }
.core-edge-picker__edge--bottom { grid-area: 3 / 1 / 4 / 4; border-radius: 0 0 var(--r-sm) var(--r-sm); }
.core-edge-picker__edge--left   { grid-area: 2 / 1 / 3 / 2; }
.core-edge-picker__edge--right  { grid-area: 2 / 3 / 3 / 4; }

/* The two upright strips are ~38 px wide, so their captions run vertically. */
.core-edge-picker__edge--left .core-edge-picker__tag,
.core-edge-picker__edge--right .core-edge-picker__tag {
    writing-mode: vertical-rl;
}

.core-edge-picker__edge--left .core-edge-picker__tag {
    transform: rotate(180deg);
}

.core-edge-picker__all {
    grid-area: 2 / 2 / 3 / 3;
    border-style: solid;
    border-color: var(--rule);
    font-size: var(--fs-13);
    font-weight: var(--fw-regular);
}

/* Banded reads as the same solid dark edge the preview SVG draws. */
.core-edge-picker__edge[aria-checked="true"],
.core-edge-picker__all[aria-checked="true"],
.core-edge-picker__all[aria-checked="mixed"] {
    border-style: solid;
    border-color: var(--ink);
    background: var(--ink);
    color: var(--paper);
}

.core-edge-picker__all[aria-checked="mixed"] {
    background: var(--ink-soft);
    border-color: var(--ink-soft);
}

.core-edge-picker__edge:focus-visible,
.core-edge-picker__all:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.core-edge-picker__edge:disabled,
.core-edge-picker__all:disabled {
    cursor: not-allowed;
    opacity: 0.55;
}

.core-edge-picker__hint {
    margin: 8px 0 0;
    font-size: var(--fs-12);
    color: var(--ink-faint);
}

.core-edge-picker--locked .core-edge-picker__hint {
    color: var(--ink-soft);
}
