/* ================================================================
   MILL SCHEDULER — shop-floor control room aesthetic
   slate-blue panels (matched to the Apollo helmet icon, #2c3e50)
   hot-steel orange / condensed industrial type

   Theming: every color lives in a token below. The default is the
   night-shift (dark) theme; [data-theme="light"] is the day shift.
   ================================================================ */

:root {
    color-scheme: dark;

    /* surfaces */
    --bg: #131a23;
    --bg-deep: #0c1118;
    --panel: #1a2430;
    --panel-raised: #223040;
    --panel-edge: #31435a;
    --row: #1f2b3a;
    --row-hover: #273647;

    /* ink */
    --ink: #d5dbe2;
    --ink-dim: #8c98a7;
    --ink-faint: #5c6979;
    --ink-strong: #f4f6f8;

    /* accents */
    --hot: #ff6a1a;
    --hot-glow: rgba(255, 106, 26, 0.35);
    --hot-soft: rgba(255, 106, 26, 0.07);
    --danger: #ff4545;
    --warning: #ffb020;
    --info: #3ec5e0;
    --ok: #58d68d;
    /* condition-rail bars (backlog #34). --galv is the zinc gray for a galvanized (coated) order,
       chosen to read on the dark row background while staying a subtle status marker, not a chip. */
    --galv: #9aa7b4;
    --pastdue-bg: rgba(255, 200, 70, 0.13); /* faint yellow wash behind a past-due date */

    /* structural bands — bucket (bright/raised) vs nested gauge sub-bucket (recessed) */
    --band-bucket: #243648;
    --band-gauge: #18222e;

    /* a faint inset tint that visually groups the three demand columns on the coil table */
    --coil-demand-tint: rgba(255, 255, 255, 0.022);

    /* tints & lines */
    --hairline: rgba(255, 255, 255, 0.04);
    --col-line: rgba(255, 255, 255, 0.06);
    --row-stripe: rgba(255, 255, 255, 0.015);
    --hover-tint: rgba(255, 255, 255, 0.03);
    --hover-tint-strong: rgba(255, 255, 255, 0.06);
    /* coil breakdown sub-table header band: darker than the rows in either theme, light ink on top */
    --coil-head-bg: #2c3e50;
    --coil-head-ink: #dfe7ee;
    --sheen: rgba(255, 255, 255, 0.025);
    --backdrop: rgba(7, 11, 16, 0.7);

    /* atmosphere */
    --glow: rgba(255, 106, 26, 0.05);
    --scanline: rgba(255, 255, 255, 0.012);

    /* depth */
    --shadow-pane: 0 8px 24px rgba(0, 0, 0, 0.35);
    --shadow-pop: 0 10px 30px rgba(0, 0, 0, 0.5);
    --shadow-modal: 0 20px 60px rgba(0, 0, 0, 0.6);
    --shadow-drag: 0 10px 30px rgba(0, 0, 0, 0.6);
    --shadow-mark: 0 2px 10px rgba(0, 0, 0, 0.4);

    --btn-ok-ink: #1a0d04;

    --font-display: "Barlow Condensed", sans-serif;
    --font-body: "Barlow", sans-serif;
    --font-mono: "IBM Plex Mono", monospace;
}

/* day shift — steel paper, same bones */
[data-theme="light"] {
    color-scheme: light;

    --bg: #d7dee5;
    --bg-deep: #c4cdd6;
    --panel: #eff2f5;
    --panel-raised: #fafcfd;
    --panel-edge: #b7c2cd;
    --row: #f7f9fa;
    --row-hover: #e9eef3;

    --ink: #2a3a4a;
    --ink-dim: #5d6f80;
    --ink-faint: #93a2b0;
    --ink-strong: #18242f;

    --hot: #e05407;
    --hot-glow: rgba(224, 84, 7, 0.25);
    --hot-soft: rgba(224, 84, 7, 0.06);
    --danger: #d32f2f;
    --warning: #a06700;
    --info: #0d7f9b;
    --ok: #1d8a4e;
    /* condition-rail bars (backlog #34): a darker zinc gray so the galvanized bar reads on the
       light row background. */
    --galv: #7c8a99;
    --pastdue-bg: #fdf6cf; /* very light yellow wash behind a past-due date */

    --band-bucket: #ffffff;
    --band-gauge: #e4eaf0;

    --coil-demand-tint: rgba(24, 36, 47, 0.028);

    --hairline: rgba(24, 36, 47, 0.08);
    --col-line: rgba(24, 36, 47, 0.10);
    --row-stripe: rgba(24, 36, 47, 0.02);
    --hover-tint: rgba(24, 36, 47, 0.04);
    --hover-tint-strong: rgba(24, 36, 47, 0.07);
    /* coil breakdown sub-table header band: a slate gray that stands clear of the white rows below */
    --coil-head-bg: #5d6f80;
    --coil-head-ink: #f5f8fa;
    --sheen: rgba(255, 255, 255, 0.55);
    --backdrop: rgba(24, 36, 47, 0.4);

    --glow: rgba(224, 84, 7, 0.045);
    --scanline: rgba(24, 36, 47, 0.018);

    --shadow-pane: 0 6px 20px rgba(24, 36, 47, 0.12);
    --shadow-pop: 0 10px 26px rgba(24, 36, 47, 0.18);
    --shadow-modal: 0 20px 60px rgba(24, 36, 47, 0.28);
    --shadow-drag: 0 10px 30px rgba(24, 36, 47, 0.3);
    --shadow-mark: 0 2px 8px rgba(24, 36, 47, 0.25);

    --btn-ok-ink: #fff;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    width: 100%;
    height: 100%;
    /* clip, not hidden: a hidden box can still be scrolled programmatically
       (edge auto-scroll during drags, focus jumps), which left the whole page
       stuck shifted sideways with no scrollbar to bring it back */
    overflow: clip;
}

body {
    background:
        radial-gradient(1200px 500px at 70% -10%, var(--glow), transparent 60%),
        repeating-linear-gradient(0deg, transparent 0 23px, var(--scanline) 23px 24px),
        var(--bg);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 13px;
    display: flex;
    flex-direction: column;
}

/* smooth theme switches (and hovers) on the big surfaces */
body, .masthead, .pane, .bucket, .bucket-head, .entry, .entry-cols, .op-card, .toast,
.duedate-filter input, .entry-actions button {
    transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}

button:focus-visible, input:focus-visible {
    outline: 2px solid var(--hot);
    outline-offset: 1px;
}

/* ================= masthead ================= */

.masthead {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap; /* tabs/controls wrap to a second row on narrow windows instead of clipping */
    gap: 0 24px;
    background: linear-gradient(180deg, var(--panel-raised), var(--panel));
    border-bottom: 1px solid var(--panel-edge);
    padding: 0 20px;
    min-height: 58px;
    flex: 0 0 auto;
}

.masthead-brand {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* helmet glyph — alpha mask so it follows the theme ink color */
.brand-mark {
    display: block;
    width: 34px;
    height: 34px;
    background: var(--ink-strong);
    -webkit-mask: url(../helmet-mask.png) center / contain no-repeat;
    mask: url(../helmet-mask.png) center / contain no-repeat;
}

.masthead h1 {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 24px;
    letter-spacing: 2px;
    margin: 0;
    color: var(--ink-strong);
}

/* Owner Settings (R12 #30): a configured logo swaps the themed helmet mask for the full-color
   image; the company name rides beside the brand. Absent both, none of this applies. */
.brand-mark-logo {
    -webkit-mask: none;
    mask: none;
    background: none;
}
.brand-mark-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.brand-facility {
    font-family: var(--font-display);
    font-size: 13px;
    letter-spacing: 2px;
    color: var(--ink-dim);
    align-self: center;
    border-left: 1px solid var(--panel-edge);
    padding-left: 12px;
}

/* live-presence facepile — overlapping initials circles of who's online now, beside the brand sub */
.facepile { display: inline-flex; align-items: center; margin-left: 4px; padding-left: 14px; border-left: 1px solid var(--panel-edge); }
.facepile[hidden] { display: none; }
.facepile-avatar {
    width: 26px; height: 26px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-family: var(--font-mono); font-size: 10px; font-weight: 600; color: #fff;
    /* a ring in the masthead's surface colour visually separates the overlapping circles */
    border: 2px solid var(--panel-raised);
    margin-left: -9px; /* overlap the previous circle */
    cursor: default;
    transition: transform .12s;
}
.facepile-avatar:first-child { margin-left: 0; }
.facepile-avatar:hover { transform: translateY(-2px); z-index: 5; } /* lift to read the one you point at */
.facepile-more { background: var(--panel); color: var(--ink-dim); }

.brand-sub {
    font-family: var(--font-display);
    font-size: 13px;
    letter-spacing: 3px;
    color: var(--hot);
    border-left: 1px solid var(--panel-edge);
    padding-left: 12px;
    align-self: center;
}

.machine-tabs {
    display: flex;
    align-items: stretch;
    gap: 2px;
    margin-left: auto;
}

.machine-tab {
    font-family: var(--font-display);
    font-size: 17px;
    font-weight: 600;
    letter-spacing: 1.5px;
    color: var(--ink-dim);
    background: transparent;
    border: none;
    border-bottom: 3px solid transparent;
    padding: 0 18px;
    cursor: pointer;
    transition: color .15s, border-color .15s, background .15s;
}

.machine-tab:hover { color: var(--ink); background: var(--hover-tint); }

.machine-tab.active {
    color: var(--ink-strong);
    border-bottom-color: var(--hot);
    background: linear-gradient(180deg, transparent 60%, var(--hot-soft));
}

.machine-tab .wc {
    display: block;
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 1px;
    color: var(--ink-faint);
}

.masthead-status {
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 1px;
    color: var(--ink-dim);
    /* it's always the last masthead child, so anchor the whole control cluster fully right on
       EVERY screen (board, operator, timeline, coil) regardless of the middle element. */
    margin-left: auto;
}

.theme-toggle {
    background: transparent;
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 1px;
    border-radius: 12px;
    padding: 4px 10px;
    cursor: pointer;
    white-space: nowrap;
    transition: color .15s, border-color .15s;
}

.theme-toggle:hover { color: var(--hot); border-color: var(--hot); }

/* #themeToggle is icon-only (the ☾/☀ label moved to its title tooltip — backlog #16); give the
   lone glyph a touch more size and balanced padding so it reads as a tidy badge. Scoped to the id
   so the BOARD nav-pill (which shares .theme-toggle) is untouched. */
#themeToggle { font-size: 13px; line-height: 1; padding: 3px 9px; }

/* board text size — A− / A+ pill; zooms the two board panes, masthead stays 1× */
.zoom-ctl {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--panel-edge);
    border-radius: 12px;
    overflow: hidden;
}

.zoom-ctl button {
    background: transparent;
    border: none;
    color: var(--ink-dim);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 1px;
    padding: 4px 8px;
    cursor: pointer;
    white-space: nowrap;
    transition: color .15s;
}

.zoom-ctl button:hover:not(:disabled) { color: var(--hot); }
.zoom-ctl button:disabled { color: var(--ink-faint); cursor: default; }

#zoomReset {
    color: var(--ink-faint);
    font-size: 9px;
    min-width: 38px;
    padding: 4px 4px;
    border-left: 1px solid var(--hairline);
    border-right: 1px solid var(--hairline);
}

.pane-unscheduled,
.pane-schedule { zoom: var(--ui-zoom, 1); }

.live-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ink-faint);
}

.live-dot.on {
    background: var(--ok);
    box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 70%, transparent);
    animation: pulse 2.4s infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .45; }
}

/* ================= board layout ================= */

.board {
    display: grid;
    grid-template-columns: minmax(300px, 5fr) 6px minmax(520px, 7fr);
    gap: 8px;
    padding: 14px;
    flex: 1 1 auto;
    min-height: 0;
}

.splitter {
    width: 6px;
    border-radius: 3px;
    background: var(--panel-edge);
    cursor: col-resize;
    align-self: stretch;
    transition: background .15s;
}

.splitter:hover, .splitter.dragging { background: var(--hot); }

body.resizing { cursor: col-resize; user-select: none; }

/* full-screen schedule: hide the unscheduled pane, schedule takes the board */
body.schedule-max .pane-unscheduled,
body.schedule-max .splitter { display: none; }
body.schedule-max .board { grid-template-columns: 1fr; }

.maximize-btn {
    font-size: 14px;
    line-height: 1;
    padding: 3px 8px;
}

.maximize-btn:hover { color: var(--hot); border-color: var(--hot); }

.schedule-totals { margin-left: auto; }

.pane {
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    min-width: 0; /* let the grid shrink panes below their content's natural width */
    box-shadow: var(--shadow-pane);
}

.pane-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap; /* controls drop to a second line instead of hanging off a narrow pane */
    gap: 6px 12px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--panel-edge);
    flex: 0 0 auto;
}

.pane-head h2 {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: 2px;
    margin: 0;
    color: var(--ink-strong);
}

/* hot tick in front of pane titles */
.pane-head h2::before {
    content: '';
    width: 4px;
    height: 15px;
    border-radius: 1px;
    background: var(--hot);
    box-shadow: 0 0 8px var(--hot-glow);
}

.count-badge {
    font-family: var(--font-mono);
    font-size: 11px;
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    color: var(--hot);
    border-radius: 10px;
    padding: 1px 8px;
}

/* unscheduled filter / sort bar (search + sort + size/gauge filters) */
.unsched-filters {
    flex: 0 0 auto;
    padding: 7px 10px;
    border-bottom: 1px solid var(--panel-edge);
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.uf-search input {
    width: 100%;
    box-sizing: border-box;
    background: var(--bg-deep);
    border: 1px solid var(--panel-edge);
    color: var(--ink-strong);
    font-family: var(--font-mono);
    font-size: 12px;
    border-radius: 3px;
    padding: 5px 8px;
}

.uf-selects {
    display: flex;
    gap: 6px;
    align-items: center;
}

.uf-selects select {
    flex: 1 1 0;
    min-width: 0;
    background: var(--bg-deep);
    border: 1px solid var(--panel-edge);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 11px;
    border-radius: 3px;
    padding: 4px;
    cursor: pointer;
}

.uf-clear {
    flex: 0 0 auto;
    background: transparent;
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
    border-radius: 3px;
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .5px;
    padding: 4px 7px;
}

.uf-clear:hover { color: var(--hot); border-color: var(--hot); }

/* shown/total count badge shown beside the filter selects when a filter is active */
.uf-count {
    flex: 0 0 auto;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .5px;
    color: var(--ink-dim);
    white-space: nowrap;
}

.ghost-btn {
    background: transparent;
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
    border-radius: 3px;
    cursor: pointer;
    font-size: 12px;
    line-height: 1;
    padding: 3px 7px;
}

.ghost-btn:hover { color: var(--danger); border-color: var(--danger); }

/* ================= unscheduled list ================= */

.unscheduled-list {
    overflow-y: auto;
    padding: 8px 4px 8px 8px; /* tight right padding so cards fill toward the pane edge */
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.op-card {
    background: var(--row);
    border: 1px solid var(--panel-edge);
    border-left: 3px solid var(--ink-faint);
    border-radius: 4px;
    padding: 8px 10px;
    cursor: grab;
    transition: background .12s, transform .12s, box-shadow .12s;
    /* Off-screen cards skip layout+paint (there are hundreds). Shrinks the rendered tree the
       compositor manages during a drag; contain-intrinsic-size keeps the scrollbar stable and
       is remembered per card once measured. */
    content-visibility: auto;
    contain-intrinsic-size: auto 46px;
}

.op-card:hover { background: var(--row-hover); box-shadow: var(--shadow-pane); }
.op-card:active { cursor: grabbing; }

/* read-only cards in the Scheduled / Completed status views — not draggable */
.op-card.op-static { cursor: default; }
.op-card.op-static:active { cursor: default; }

/* Completed card footer: when-completed stamp + un-complete control */
.op-completed {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid var(--hairline);
}
.op-completed .completed-stamp { font-size: 10.5px; color: var(--ink-dim); }
.uncomplete-btn {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .5px;
    color: var(--ink-dim);
    background: transparent;
    border: 1px solid var(--panel-edge);
    border-radius: 4px;
    padding: 2px 7px;
    cursor: pointer;
    transition: color .12s, border-color .12s;
}
.uncomplete-btn:hover { color: var(--hot); border-color: var(--hot); }

/* age-window note + show-all toggle atop the Completed view (I20) */
.completed-window {
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px;
    margin: 0 0 8px; padding: 6px 8px; border-radius: 6px;
    background: var(--panel-raised); border: 1px solid var(--hairline);
    font-size: 11px; color: var(--ink-dim);
}
.cw-toggle {
    font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .3px;
    color: var(--hot); background: transparent; border: none; padding: 0; cursor: pointer;
    text-decoration: underline; text-underline-offset: 2px;
}
.cw-toggle:hover { opacity: .8; }

/* due-date urgency on the card's leading edge */
.op-card.soon { border-left-color: var(--warning); }
.op-card.late { border-left-color: var(--danger); }

/* ---- galvanized marker (backlog #34, recolumned #42) ----
   A short gray bar marking an order whose coil is galvanized (crosswalk-derived). On the two GRID
   views (board rows + operator rows) it lives in its OWN very narrow dedicated column immediately to
   the LEFT of the customer column (.galv-col / .c-galv), present on every row, so the customer names
   line up whether or not a row is galvanized (backlog #42). On the unscheduled card (a flex line,
   not a grid) it stays INLINE at the start of the customer cell, hugging the company name. Token
   color, both themes; static markup (no per-frame restyle) so it is safe in the perf-sensitive
   unscheduled pool. It carries its own "Galvanized" hover tooltip. */
.galv-mark {
    display: inline-block;
    width: 3.6px; /* 3px + 20% (Chris, 2026-07-02) */
    height: 0.85em;
    margin-right: 6px;
    vertical-align: middle;
    border-radius: 1px;
    background: var(--galv);
}

/* the dedicated narrow galv column (board) — center the bar, no padding, no right margin since the
   bar is no longer sitting before a name */
.galv-col {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 0;
    overflow: hidden;
}
.galv-col .galv-mark { margin-right: 0; }

/* Sales-order marking badges (#68): the bare emoji icon (no chip background, no outline — Chris
   2026-06-26). Lives in the galv column on board rows (which widens to --galv-col-w when marks are
   in use) and inline before the customer name on unscheduled cards. Static markup. */
.so-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 17px;
    height: 17px;
    font-size: 14px;
    line-height: 1;
    vertical-align: middle;
}
/* on the unscheduled card (inline flow) give each chip a touch of right space before the name */
.op-card .cust .so-mark { margin-right: 3px; }
body.has-marks { --galv-col-w: 32px; } /* fits the galv bar + one mark; narrowed to free row width (Chris) */

/* Markings management (#68), in the Admin Console Settings section: a list of defined marks + an
   add/edit form. Reuses the .so-mark chip for the preview and the .adm-btn / .fac-field tokens. */
.mk-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.mk-empty { color: var(--ink-dim); font-size: 13px; padding: 6px 2px; }
.mk-row {
    display: grid;
    grid-template-columns: 22px minmax(150px, 1.3fr) minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border: 1px solid var(--panel-edge);
    border-radius: 8px;
    background: var(--panel-raised);
}
.mk-row .so-mark { width: 20px; height: 20px; font-size: 13px; }
/* name + its pills wrap within their own column (min-width:0) so the pills never overflow into the
   description column when there are two of them */
.mk-name-cell { font-weight: 600; color: var(--ink-strong); display: flex; flex-wrap: wrap; align-items: center; gap: 5px 8px; min-width: 0; }
.mk-desc-cell { color: var(--ink-dim); font-size: 12.5px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mk-pill {
    font-family: var(--font-display); font-size: 9px; font-weight: 700; letter-spacing: .05em;
    padding: 1px 6px; border-radius: 5px; text-transform: uppercase;
    background: color-mix(in srgb, var(--warning) 20%, transparent); color: var(--warning);
}
.mk-row-actions { display: flex; gap: 6px; }
.adm-btn.danger { border-color: var(--danger); color: var(--danger); }
.adm-btn.danger:hover { background: var(--danger); color: #fff; }
.mk-form { display: flex; flex-direction: column; gap: 12px; }
/* icon row: a live preview chip + a click-to-pick palette + a free-text fallback */
.mk-icon-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mk-preview { width: 26px; height: 26px; font-size: 15px; }
/* icon dropdown (collapsed list, not all icons shown at once) + a free-text fallback */
.mk-emoji-select {
    height: 30px; padding: 0 8px; font-size: 16px; line-height: 1;
    border: 1px solid var(--panel-edge); border-radius: 6px; background: var(--panel-raised); color: var(--ink); cursor: pointer;
}
.mk-emoji-select:focus { outline: none; border-color: var(--hot); box-shadow: 0 0 0 2px var(--hot-glow); }
.mk-or { color: var(--ink-dim); font-size: 12px; }
.mk-emoji-input { width: 70px; text-align: center; }
.mk-form-row { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; }
.mk-form-row .fac-field { flex: 1 1 auto; min-width: 0; }
.mk-form-row .fac-field input { flex: 1 1 auto; min-width: 0; }
.mk-form-row .mk-name { flex: 2 1 180px; }
.mk-form-row .mk-desc { flex: 3 1 220px; }
.mk-form-row .mk-owner { flex: 0 0 auto; white-space: nowrap; }
/* the two visibility/use checkboxes stack together as one form item (#68 use+show gates) */
.mk-checks { flex: 0 0 auto; display: flex; flex-direction: column; gap: 4px; }
.mk-checks .fac-check { white-space: nowrap; }

.op-card { position: relative; }

.op-card .line1 {
    display: flex;
    align-items: baseline;
    gap: 10px;
}

.wo-number {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: 13px;
    color: var(--ink-strong);
}

/* description + customer split the middle of line 1 evenly */
.op-desc {
    flex: 1 1 0;
    min-width: 0;
    font-weight: 600;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* fixed columns so every card's line 2 aligns: size | gauge | length | pcs share the
   space evenly, and pounds is pinned to a fixed track on the far right, right-justified */
.op-card .line2 {
    display: grid;
    /* size (incl. wide rect sizes like 2.000 × 6.000) needs the most room, so it gets the
       largest share; gauge is the most compact. pounds is a fixed track pinned right. */
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 0.8fr) minmax(0, 1.05fr) minmax(0, 1.15fr) 86px;
    align-items: center;
    column-gap: 10px;
    margin-top: 4px;
    font-size: 11px;
    color: var(--ink-dim);
}

/* each cell stays on one line and ellipsizes rather than pushing the columns out of line */
.op-card .line2 > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.op-card .line2 .l2-lbs { text-align: right; }

/* customer sits just right of the description, the two splitting line 1's middle space */
.op-card .line1 .cust {
    flex: 1 1 0;
    min-width: 0;
    color: var(--ink-strong);
    font-size: 11px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ⓘ glyph hugging the end of the SO number: hover it for the order + steel detail card.
   No background/border — the glyph is its own circle. */
.op-card .line1 .op-info {
    flex: 0 0 auto;
    margin-left: -5px; /* pull it close to the SO number rather than a full gap away */
    color: var(--ink-dim);
    font-size: 13px;
    line-height: 1;
    cursor: help;
    user-select: none;
    transition: color .12s;
}
.op-card .line1 .op-info:hover { color: var(--hot); }

/* due date is pinned to the right end of line 1 */
.op-card .line1 .due-chip {
    margin-left: auto;
    padding-left: 12px;
    flex: 0 0 auto;
    font-size: 11px;
    white-space: nowrap;
}

/* ===== order info + steel-availability tooltip (hover the line-1 ⓘ) ===== */
.order-tip {
    position: fixed;
    z-index: 1200;
    width: 360px;
    max-width: calc(100vw - 24px);
    background: var(--panel);
    color: var(--ink);
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    box-shadow: 0 14px 40px rgba(0, 0, 0, .38);
    font-size: 12px;
    overflow: hidden;
    opacity: 0;
    transform: translateY(4px);
    transition: opacity .12s ease, transform .12s ease;
    pointer-events: auto;
}
.order-tip.show { opacity: 1; transform: translateY(0); }

.order-tip .ot-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 11px 14px 9px;
    background: var(--band-bucket);
    border-bottom: 1px solid var(--panel-edge);
}
.order-tip .ot-head .ot-so {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 14px;
    color: var(--ink-strong);
}
.order-tip .ot-head .ot-cust {
    margin-left: auto;
    color: var(--ink-dim);
    font-size: 11px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 55%;
}

.order-tip .ot-section {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 14px 5px;
    font-family: var(--font-mono);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--ink-faint);
}
.order-tip .ot-section::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--hairline);
}

.order-tip .ot-order { padding: 3px 14px 12px; }

/* headline: part number on the left, due chip pinned right */
.order-tip .ot-headline {
    display: flex;
    align-items: baseline;
    gap: 10px;
}
.order-tip .ot-part {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: 13px;
    color: var(--ink-strong);
    word-break: break-word;
}
.order-tip .ot-due {
    margin-left: auto;
    flex: 0 0 auto;
    font-family: var(--font-mono);
    font-size: 12px;
    white-space: nowrap;
}

/* spec line: shape · size · gauge as plain dotted text, no pills */
.order-tip .ot-spec {
    margin-top: 4px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--ink-dim);
}
/* the steel class (ERP Product column) reads slightly stronger than the rest of the spec line —
   it's what a scheduler checks when a GALV mark is missing */
.order-tip .ot-steelclass { color: var(--ink); font-weight: 600; }

/* metric strip: value over label, divided by thin rules — no boxes, no fill */
.order-tip .ot-metrics {
    display: flex;
    margin-top: 12px;
}
.order-tip .ot-metrics .m {
    flex: 1;
    min-width: 0;
    padding: 0 11px;
    border-left: 1px solid var(--hairline);
}
.order-tip .ot-metrics .m:first-child { padding-left: 0; border-left: none; }
.order-tip .ot-metrics .v {
    display: block;
    font-family: var(--font-mono);
    font-size: 15px;
    font-weight: 600;
    line-height: 1.15;
    color: var(--ink-strong);
}
.order-tip .ot-metrics .k {
    display: block;
    margin-top: 1px;
    font-size: 9px;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.order-tip .ot-foot {
    margin-top: 11px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--ink-dim);
}

.order-tip .ot-steel { padding: 0 14px 13px; }
.order-tip .ot-material {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}
.order-tip .ot-material .ot-mat-key {
    font-family: var(--font-mono);
    font-weight: 600;
    color: var(--ink-strong);
}
.order-tip .ot-pill {
    margin-left: auto;
    padding: 1px 8px;
    border-radius: 10px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .5px;
    white-space: nowrap;
}
.order-tip .ot-pill.ok    { background: rgba(46, 160, 90, .16); color: var(--ok); }
.order-tip .ot-pill.short { background: rgba(211, 47, 47, .16); color: var(--danger); }
.order-tip .ot-pill.muted { background: var(--bg-deep); color: var(--ink-dim); }

/* on-hand vs target proportion bar */
.order-tip .ot-bar {
    height: 7px;
    border-radius: 4px;
    background: var(--bg-deep);
    overflow: hidden;
    margin: 2px 0 9px;
}
.order-tip .ot-bar > i {
    display: block;
    height: 100%;
    border-radius: 4px;
    background: var(--ok);
}
.order-tip .ot-bar.short > i { background: var(--danger); }

.order-tip .ot-num {
    display: flex;
    justify-content: space-between;
    padding: 2px 0;
    font-size: 11px;
}
.order-tip .ot-num span:first-child { color: var(--ink-dim); }
.order-tip .ot-num span:last-child { font-family: var(--font-mono); color: var(--ink); }
.order-tip .ot-num.net.short span:last-child { color: var(--danger); font-weight: 600; }
.order-tip .ot-num.net.ok span:last-child { color: var(--ok); font-weight: 600; }

.order-tip .ot-note {
    color: var(--ink-dim);
    font-size: 11px;
    line-height: 1.4;
    padding: 2px 0;
}
.order-tip .ot-note.muted { color: var(--ink-faint); font-style: italic; }

.mono { font-family: var(--font-mono); }

.due-chip { color: var(--ink-dim); }
.due-chip.late { color: var(--danger); font-weight: 600; }
.due-chip.soon { color: var(--warning); }
/* past-due dates on a scheduled order: red text kept, plus a faint yellow highlight */
.entry .due-chip.late { background: var(--pastdue-bg); padding: 0 5px; border-radius: 3px; }

/* Live "on track" overlay (R13 #33): a run is "at risk" when an active overrun on its mill projects
   it to finish past its due date. Surfaced SUBTLY, token-only — the existing colored due edge
   intensifies to the warning ink and a tiny lower-case "behind" marker rides beside the due date. No
   flag chips (the deliberate no-chip rule), no modal, no color floods. The marker only renders inside
   an .at-risk row; rows without it are byte-for-byte today's. */
.behind-mark { display: none; }
.at-risk .behind-mark {
    display: inline;
    font-family: var(--font-mono);
    font-size: 8.5px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--warning);
    margin-left: 5px;
    opacity: .85;
}
/* board: no left edge today, so the due chip carries it — at-risk warms it to the warning ink */
.entry.at-risk .due-chip { color: var(--warning); font-weight: 600; }
.entry.at-risk .due-chip.late { color: var(--danger); } /* already-late stays the stronger red */

.flag-row { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 5px; }

.flag {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 1px;
    border-radius: 2px;
    padding: 1px 6px;
    border: 1px solid;
}

.flag.danger  { color: var(--danger);  border-color: color-mix(in srgb, var(--danger) 50%, transparent);  background: color-mix(in srgb, var(--danger) 9%, transparent); }
.flag.warning { color: var(--warning); border-color: color-mix(in srgb, var(--warning) 50%, transparent); background: color-mix(in srgb, var(--warning) 9%, transparent); }
.flag.info    { color: var(--info);    border-color: color-mix(in srgb, var(--info) 50%, transparent);    background: color-mix(in srgb, var(--info) 9%, transparent); }

/* ================= schedule pane ================= */

.schedule-totals {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink-dim);
    display: flex;
    gap: 16px;
}

.schedule-totals b { color: var(--hot); font-weight: 600; }

.bucket-stack {
    overflow-y: auto;
    overflow-x: auto; /* wide entry grids scroll here instead of blowing out the page */
    padding: 10px 4px 10px 6px; /* tight right padding so mills fill toward the pane edge */
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.bucket {
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-radius: 5px;
    overflow: hidden;
    flex: 0 0 auto;
    min-width: min-content; /* uniform width: numeric columns are fixed and the text columns
        shrink, so every bucket resolves to the same width (the stack only scrolls on a very narrow pane) */
}

/* NO drag-time drop-target coloring. Earlier versions tinted the hovered gauge head / the
   whole board green while dragging; even a flat fill is repainted by the native drag every
   frame as the translucent drag image passes over it, which bogged the drag. The browser's
   own "move" cursor (from the drop handler's preventDefault) is the only drop cue now.
   Gauge sub-buckets are still the ONLY structural drop targets — buckets/mills take no orders. */

.bucket-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px 9px 10px;
    background: var(--band-bucket);
    border-bottom: 1px solid var(--panel-edge);
    border-left: 4px solid var(--hot);
    user-select: none;
}

.bucket-grip {
    cursor: grab;
    color: var(--ink-faint);
    font-size: 14px;
    letter-spacing: -1px;
    padding: 0 2px;
}

.bucket-grip:hover { color: var(--hot); }

.bucket-toggle {
    background: none;
    border: none;
    color: var(--ink-dim);
    cursor: pointer;
    font-size: 12px;
    width: 20px;
    transition: transform .15s;
}

.bucket.expanded .bucket-toggle { transform: rotate(90deg); color: var(--hot); }

.bucket-name {
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: 1px;
    color: var(--ink-strong);
    cursor: text;
    padding: 0 4px;
    border-radius: 3px;
    min-width: 60px;
}

.bucket-name:hover { background: var(--hover-tint-strong); }

.bucket-name input {
    background: var(--bg-deep);
    border: 1px solid var(--hot);
    color: var(--ink-strong);
    font-family: var(--font-display);
    font-size: 16px;
    border-radius: 3px;
    padding: 2px 6px;
    width: 160px;
}

/* fixed columns, right-anchored, so every bucket's numbers line up like a spreadsheet */
.bucket-roll {
    display: grid;
    grid-template-columns: 78px 92px 132px 156px;
    gap: 12px;
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--ink-dim);
    white-space: nowrap;
    text-align: right;
}

.bucket-roll span { overflow: hidden; text-overflow: ellipsis; }
.bucket-roll b { color: var(--ink); font-weight: 500; }
.bucket-roll .est b { color: var(--info); }

.bucket-del {
    background: none;
    border: none;
    color: var(--ink-faint);
    font-size: 14px;
    cursor: pointer;
    padding: 2px 4px;
}

.bucket-del:hover { color: var(--danger); }

/* the small boxed + that adds structure: a bucket (mill header) or gauge sub-bucket (bucket header) */
.icon-add {
    background: none;
    border: 1px solid var(--panel-edge);
    border-radius: 3px;
    color: var(--ink-dim);
    width: 20px;
    height: 20px;
    line-height: 1;
    font-size: 13px;
    cursor: pointer;
    padding: 0;
    flex: 0 0 auto;
}

.icon-add:hover { color: var(--hot); border-color: var(--hot); }

.gauge-del {
    background: none;
    border: none;
    color: var(--ink-faint);
    font-size: 12px;
    cursor: pointer;
    padding: 2px 4px;
    margin-left: 6px;
}

.gauge-del:hover { color: var(--danger); }

/* "WO #" column label + its fill-the-rolling button (#47): a small edit affordance right beside the
   header text, so one click sets the work order number on every line item in this rolling. */
.entry-cols .wo-head {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
}
.wo-fill {
    background: none;
    border: 1px solid var(--panel-edge);
    border-radius: 3px;
    color: var(--ink-dim);
    font-size: 9px;
    line-height: 1;
    cursor: pointer;
    padding: 1px 3px;
}
.wo-fill:hover { color: var(--hot); border-color: var(--hot); }

/* one-field dialog (add bucket / add gauge sub-bucket) */
.dlg-field { margin: 14px 0 4px; }

.dlg-field label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 1px;
    color: var(--ink-dim);
}

.dlg-field input, .dlg-field select {
    background: var(--bg-deep);
    border: 1px solid var(--panel-edge);
    color: var(--ink-strong);
    font-family: var(--font-mono);
    font-size: 13px;
    border-radius: 3px;
    padding: 7px 8px;
}

.entry-list { min-height: 8px; }

.bucket:not(.expanded) .entry-list,
.bucket:not(.expanded) .gauge-group-list,
.bucket:not(.expanded) .entry-cols { display: none; }

/* ================= sales-order import ================= */

.import-cluster {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

/* last sales-order import timestamp, sitting beside the IMPORT button */
.last-import {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .5px;
    color: var(--ink-dim);
    white-space: nowrap;
}

.import-btn { margin-left: 0; }

/* .confirm-box.import-box (two classes) outranks the base .confirm-box width:380px,
   regardless of source order — fill the screen for the wide removal/preview table */
.confirm-box.import-box {
    width: 96vw;
    max-width: none;
    height: 92vh;
    display: flex;
    flex-direction: column;
}

.import-body { flex: 1 1 auto; max-height: none; overflow: auto; padding: 4px 2px; }

.import-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }

.import-chip {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: .5px;
    color: var(--ink-dim);
    border: 1px solid var(--panel-edge);
    border-radius: 12px;
    padding: 3px 10px;
}

.import-chip b { color: var(--ink-strong); }
.import-chip.ok b { color: var(--ok); }
.import-chip.info b { color: var(--info); }
.import-chip.warning b { color: var(--warning); }
.import-chip.danger { border-color: var(--danger); }
.import-chip.danger b { color: var(--danger); }

.import-list { margin-bottom: 10px; }
.import-list summary {
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink);
    padding: 4px 0;
}

/* no inner scroll box — the modal body (flex:1, overflow:auto) is the single scroller,
   so the removal table fills the tall modal instead of a cramped 30vh window */
.import-rows { overflow-x: hidden; border-top: 1px solid var(--hairline); }

.import-row {
    display: grid;
    /* minmax(0,…) lets the flexible columns shrink and wrap instead of overflowing */
    grid-template-columns: 150px minmax(0, 1.4fr) 90px minmax(0, 2fr);
    gap: 14px;
    padding: 4px 6px;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink-dim);
    border-bottom: 1px solid var(--hairline);
}

.import-row span:first-child { color: var(--ink-strong); }
.import-row.skip { grid-template-columns: 150px minmax(0, 1fr); color: var(--warning); }

.import-warn { font-family: var(--font-mono); font-size: 10.5px; color: var(--warning); margin-top: 8px; }
.import-error { color: var(--danger); font-family: var(--font-mono); font-size: 12px; padding: 12px; }

/* the per-mill tab strip is removed; hide its (now empty) container to reclaim masthead space */
#machineTabs:empty { display: none; }

/* ================= All Mills stacked view ================= */

/* each mill carries its own accent color (--mill, set per block in JS) so mills are easy to
   tell apart on the stacked board: a colored left edge + tinted header band + colored name */
.mill-block { margin-bottom: 22px; }

.mill-block-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    background: color-mix(in srgb, var(--mill, var(--hot)) 16%, var(--panel-raised));
    border: 1px solid var(--panel-edge);
    border-left: 4px solid var(--mill, var(--hot));
    border-bottom: none;
    border-radius: 6px 6px 0 0;
}

/* whole-mill collapse: just the head shows; rounded all corners when collapsed */
.mill-collapse {
    background: transparent;
    border: none;
    color: var(--ink-dim);
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    padding: 2px 4px;
    transition: transform .12s, color .12s;
}
.mill-collapse:hover { color: var(--mill, var(--hot)); }
.mill-block:not(.collapsed) .mill-collapse { transform: rotate(90deg); } /* ▶ points down when expanded */
.mill-block.collapsed .mill-block-head { border-bottom: 1px solid var(--panel-edge); border-radius: 6px; }
.mill-block.collapsed .mill-buckets,
.mill-block.collapsed .mill-autoroute { display: none; }
.mill-block.collapsed { margin-bottom: 10px; }

.mill-pdf { font-size: 14px; }

/* faint colored band down the mill's buckets so the whole mill reads as one group */
.mill-block .mill-buckets {
    border-left: 4px solid color-mix(in srgb, var(--mill, var(--hot)) 32%, transparent);
    padding-left: 8px;
}

.mill-block-roll { margin-left: auto; }

.mill-block-name {
    font-family: var(--font-display);
    font-size: 21px;
    font-weight: 700;
    letter-spacing: 1.5px;
    color: var(--mill, var(--hot));
    text-transform: uppercase;
}

/* the colored dot the name reads against, for an extra cue */
.mill-block-name::before {
    content: "";
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--mill, var(--hot));
    margin-right: 9px;
    vertical-align: middle;
}

.mill-block-roll {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink-dim);
    white-space: nowrap;
}

.mill-block-roll b { color: var(--ink); }

/* drop-to-auto-file strip (per mill). STATIC styling only — no :hover or drag-time restyle,
   so the native drag never repaints it (perf rule 4). The "move" cursor is the drop cue. */
.mill-autoroute {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin: 8px 0 10px;
    /* twice the original drop-target height so it's an easier target (GLT, 2026-06-14) */
    min-height: 68px;
    padding: 9px 12px;
    /* subtle pale-yellow fill + amber dashed outline so the drop target reads clearly without
       shouting (theme-aware: the yellow is mixed into the panel, so it stays soft in dark mode).
       Static only — no drag-time restyle (perf rule 4). */
    border: 1.5px dashed color-mix(in srgb, #e3b021 55%, var(--panel-edge));
    border-radius: 8px;
    background: color-mix(in srgb, #f4d23c 13%, var(--panel-raised));
    color: var(--ink-dim);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 1.5px;
    text-align: center;
    user-select: none;
}

.mill-autoroute .ar-icon { color: var(--hot); font-size: 14px; line-height: 1; }

/* home-mill tag on unscheduled cards in All Mills mode */
.mill-tag {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: .5px;
    color: var(--ink-dim);
    border: 1px solid var(--panel-edge);
    border-radius: 8px;
    padding: 1px 6px;
    white-space: nowrap;
}

/* ================= gauge (wall) sub-groups ================= */

/* a wall campaign band within the OD campaign — sized between the bucket head and rows */
.gauge-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 12px 4px 18px; /* tighter vertical spacing (about half) so the gauge band reads distinct from the bucket */
    margin-left: 14px; /* nest the wall band inside the OD bucket */
    background: var(--band-gauge);
    border-top: 1px solid var(--panel-edge);
    border-bottom: 1px solid var(--hairline);
    border-left: 4px solid var(--info);
    user-select: none;
}

/* data rows sit recessed below the bands, so the structure reads at a glance */
.gauge-group .entry-list,
.gauge-group .entry-cols { margin-left: 14px; background: var(--bg); }
.gauge-group .entry-list { border-left: 1px solid var(--hairline); }

.gauge-grip {
    cursor: grab;
    color: var(--ink-faint);
    font-size: 13px;
    letter-spacing: -1px;
}

.gauge-grip:hover { color: var(--hot); }

.gauge-toggle {
    background: none;
    border: none;
    color: var(--ink-dim);
    cursor: pointer;
    font-size: 10px;
    width: 16px;
    padding: 0;
    transition: transform .15s;
}

.gauge-group.expanded .gauge-toggle { transform: rotate(90deg); color: var(--hot); }

.gauge-label {
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 600;
    letter-spacing: .8px;
    color: var(--ink-strong);
}

.gauge-roll {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--ink-dim);
    white-space: nowrap;
}

.gauge-roll b { color: var(--ink); font-weight: 500; }

/* collapsed gauge group: hide its column labels and rows, keep the band */
.gauge-group:not(.expanded) .entry-cols,
.gauge-group:not(.expanded) .entry-list { display: none; }

/* per-gauge trailing totals band (#67): bookends a rolling's order list with its TOTAL bundles
   remaining (under the BDL column) and TOTAL pounds remaining (under LBS RMN), column-aligned via the
   shared entry grid. Very dim by default; brightens while the cursor is over this group's orders (the
   adjacent .entry-list), so the totals you read belong to the rolling you're hovering. */
/* `.gauge-group .gauge-totals` (0,2,0) so this padding/line-height beat the shared `.entry,…,.gauge-totals`
   grid rule (0,1,0, declared later) — otherwise its `padding: 5px 10px` + normal line-height made the
   bottom band much taller than the per-length overlays. Kept tight to match `.len-total` (Chris 2026-06-26). */
.gauge-group .gauge-totals {
    margin-left: 14px;            /* nest like .entry-list / .entry-cols so columns line up */
    padding: 0 10px;
    /* a soft tint just above the row color — much lighter than the gauge-header band, so the length
       separator reads as a fine divider, not a heavy band (Chris 2026-06-26). Theme-aware. */
    background: color-mix(in srgb, var(--ink-dim) 7%, var(--row));
    border-top: 1px solid var(--hairline);   /* faint top edge (was the darker --panel-edge) */
    border-left: 1px solid var(--hairline);
    font-family: var(--font-mono);
    font-size: 10px;
    line-height: 1.2;
    letter-spacing: .4px;
    color: var(--ink-faint);     /* very dim until hovered */
    transition: color .12s ease;
    cursor: default;
}
.gauge-totals .gt-label, .len-total .gt-label { grid-column: 1 / 13; text-align: right; text-transform: uppercase; white-space: nowrap; overflow: hidden; }
.gauge-totals .gt-bdl,   .len-total .gt-bdl   { grid-column: 13; text-align: center; font-weight: 600; white-space: nowrap; }
/* LBS RMN total spans the OPEN+LBS RMN tracks so a large number (millions) never wraps in the
   narrow rmn column; still right-aligned to the LBS RMN edge. */
.gauge-totals .gt-lbs,   .len-total .gt-lbs   { grid-column: 15 / 17; text-align: right; font-weight: 600; white-space: nowrap; }
.entry-list:hover + .gauge-totals,
.gauge-totals:hover { color: var(--ink-strong); }
.gauge-group:not(.expanded) .gauge-totals { display: none; }

/* Per-length-group total on the length-change line (#67, corrected to PER LENGTH 2026-06-25): an
   overlay sitting in the gap above the row that starts a new cut length, showing the JUST-ENDED
   length's bundles + lbs remaining, column-aligned via the shared entry grid. It is a child of the
   .entry (never of .entry-list) and absolutely positioned with pointer-events:none, so the SortableJS
   drop-index math, clicks, and drag are all untouched. The .entry--len-break row reserves the gap. */
/* `.entry > .len-total` (0,2,0) so this padding beats the shared `.entry,…,.len-total` grid rule's
   `padding: 5px 10px` (0,1,0, declared later in the file) — that override was inflating the band and
   pushing the text to the bottom (the "extra room on top"). */
.entry > .len-total {
    position: absolute;
    left: 0; right: 0; top: -14px;
    /* zero vertical padding so the band hugs the text height (Chris 2026-06-26); short band, even gaps */
    padding: 0 10px;
    /* a soft tint just above the row color — much lighter than the gauge-header band, so the length
       separator reads as a fine divider, not a heavy band (Chris 2026-06-26). Theme-aware. */
    background: color-mix(in srgb, var(--ink-dim) 7%, var(--row));
    border-top: 1px solid var(--hairline);   /* faint top edge (was the darker --panel-edge) */
    font-family: var(--font-mono);
    font-size: 10px;
    line-height: 1.2;
    letter-spacing: .4px;
    color: var(--ink-faint);     /* dim until the sub-bucket's orders are hovered */
    transition: color .12s ease;
    pointer-events: none;
}
.entry-list:hover .len-total { color: var(--ink-strong); }

/* ================= entry rows ================= */

/* fixed widths on all data columns so rows align:
   seq (#) | WO# (hand-typed) | galv | customer | desc | SO | len | strip w | wpf | pcs | ft/hr | bdl | wt/bdl | lbs ord | open | lbs rmn | due | est
   (galv is the very narrow dedicated column for the galvanized indicator bar — backlog #42 — so the
   bar no longer shifts the customer name right on galvanized rows; customer names align on every row)
   (seq is the far-left line-number column with the "#" header, backlog #22; WO# is the manual-entry
   column, backlog #20; OD and GA removed per backlog #18 — the part-number description carries
   size + gauge; STRIP W and WPF added per backlog #19; actions live on their own sub-line below
   the data row) */
.entry, .entry-cols, .gauge-totals, .len-total {
    display: grid;
    /* The numeric/short columns are FIXED widths sized to their content, so every bucket's grid
       resolves to the same width regardless of how big its numbers are (the "2x6 wider than the
       others" bug came from content-driven fr columns under a max-content bucket). Customer and
       Description are the only flexible columns: they take the surplus on a wide pane and shrink
       (clipping with an ellipsis) on a narrow one, so the data fits without a horizontal scrollbar
       at normal widths. Header (.entry-cols) shares this template so columns stay aligned. */
    grid-template-columns:
        /* LBS ORD sits just left of SO (backlog #51); OPEN + LBS RMN stay on the right.
           The galv column (3rd) widens via --galv-col-w only when markings are in use (#68). */
        16px minmax(60px, 78px) var(--galv-col-w, 12px) minmax(54px, 1.3fr) minmax(54px, 0.7fr) minmax(60px, 0.2fr) 64px
        minmax(54px, 0.2fr) minmax(52px, 0.2fr) minmax(48px, 0.18fr)
        minmax(42px, 0.16fr) minmax(46px, 0.18fr) minmax(52px, 0.2fr) minmax(48px, 0.2fr)
        minmax(52px, 0.2fr) minmax(52px, 0.2fr)
        minmax(48px, 0.18fr) minmax(62px, 0.22fr);
    align-items: center;
    gap: 6px;
    padding: 5px 8px;
}

/* column labels atop each open bucket */
.entry-cols {
    padding: 4px 10px 3px;
    font-family: var(--font-mono);
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--ink);
    background: var(--bg-deep);
    border-bottom: 1px solid var(--panel-edge);
    user-select: none;
}

.entry-cols .r { text-align: right; }
.entry-cols .c { text-align: center; }

.entry {
    border-bottom: 1px solid var(--hairline);
    background: var(--row);
    cursor: grab;
    font-size: 12px;
    position: relative; /* positioning context for the condition rail (#34) */
}

.entry:hover { background: var(--row-hover); }
.entry:active { cursor: grabbing; }

/* Length-group separator (backlog #35): the first row of a new cut-length run within a gauge
   sub-bucket gets a heavier top rule + a little breathing room, so operators see length-group
   boundaries at a glance (John builds loads grouped by length). This is a CSS treatment on the
   existing first row — NOT a new .entry-list child — so the SortableJS drop-index math is intact.
   Theme-correct via the --panel-edge token; never a hard-coded color. */
.entry.entry--len-break {
    /* reserve room above the row for the per-length total overlay (#67); the overlay's gray band is
       the length separator now, so no border is needed here. Kept tight so the band has even gaps. */
    margin-top: 15px;
}

.entry .seq {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--ink-faint);
    text-align: right;
}

/* hand-typed ERP work order number (backlog #20): the second column, just right of the
   line-number "#" (backlog #22). double-click to edit, dotted underline cues that it's
   editable; the ＋ placeholder shows faint until one is entered */
.entry .wo-num {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: center; /* values centered under the centered "WO #" header */
    cursor: text;
    text-decoration: underline dotted var(--ink-faint);
    text-underline-offset: 2px;
}
.entry .wo-num.wo-empty { color: var(--ink-faint); text-decoration: none; }
.entry .wo-input {
    width: 100%;
    box-sizing: border-box;
    background: var(--bg-deep);
    border: 1px solid var(--panel-edge);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 11px;
    border-radius: 3px;
    padding: 2px 4px;
}

/* split-run ordinal — small yellow number right of the WO number */
.entry .split-no {
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 600;
    color: var(--warning);
    margin-left: 4px;
    line-height: 0; /* don't let the superscript stretch the row */
}

.entry .desc {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: center;
    color: var(--ink);
}

.entry .cust {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--ink-dim);
    font-size: 11px;
    /* SO/customer fonts swapped on scheduled rows: customer takes the mono face */
    font-family: var(--font-mono);
}

/* ...and the SO number takes the body (sans) face that the customer used to have.
   Sized a touch smaller than the base 13px so it sits closer to the rest of the row
   (mostly 11px) while staying bold + ink-strong so it's still the row's anchor. */
.entry .wo-number { font-family: var(--font-body); white-space: nowrap; font-size: 12px; }

/* Coil-shortage marker (#57, partial fill #63): a subtle red behind the SO number sized by
   --coil-short-pct — the share of the order's pounds that won't have steel in time. The red is
   anchored to the RIGHT (the short tail end of the order): the first (100 − pct)% stays clear for
   the part that IS covered, the last pct% is red (Chris, 2026-06-24). The darker-red left edge line
   (the box-shadow) always stays as the marker anchor. 100% = the whole cell red (fully short).
   Static (set at render, never during a drag) so it doesn't regress drag perf; quiet, not an alarm. */
.entry .wo-number.coil-short {
    background: linear-gradient(to right,
        transparent calc(100% - var(--coil-short-pct, 100%)),
        color-mix(in srgb, var(--danger) 20%, transparent) calc(100% - var(--coil-short-pct, 100%)));
    box-shadow: inset 2px 0 0 var(--danger);
    border-radius: 3px;
    padding: 1px 5px 1px 4px;
}


/* Finished goods cover the pounds remaining (R16): a soft green wash on the LBS RMN cell that
   fades in from the left edge and out at the right, kept light so the number stays readable.
   Static at render (never restyled during a drag) and paired with the large hover card. */
.entry .feet.fg-cover {
    background: linear-gradient(to right,
        transparent 0,
        color-mix(in srgb, var(--ok) 24%, transparent) 26%,
        color-mix(in srgb, var(--ok) 24%, transparent) 74%,
        transparent 100%);
    border-radius: 3px;
    cursor: help;
}

.entry .lbs, .entry .feet, .entry .feet-ord, .entry .pcs, .entry .due-chip, .entry .est-start, .entry .item,
.entry .len, .entry .strip, .entry .wpf, .entry .rate, .entry .bdl, .entry .bwt {
    font-family: var(--font-mono);
    font-size: 11px;
    text-align: right;
    white-space: nowrap;
}

.entry .item { color: var(--ink-dim); text-align: left; }
/* the pounds columns read right-aligned as a numeric group (LBS ORD now sits left of SO, #51) */
.entry .feet-ord, .entry .lbs, .entry .feet { text-align: right; }
/* keep LBS ORD's number off the left-aligned SO that now follows it (#51) */
.entry .feet-ord, .entry-cols .feet-ord { padding-right: 10px; }
/* LEN / STRIP W / BDL / WT-BDL read centered under their (centered) headers; WPF stays right (numeric) */
.entry .len, .entry .strip, .entry .bdl, .entry .bwt { text-align: center; }
/* WPF is a muted reference number like FT/HR */
.entry .wpf { color: var(--ink-dim); }
.entry .est-start { color: var(--info); }
/* LBS ORD is the static reference; mute it so the live LBS RMN reads as the active number */
.entry .feet-ord { color: var(--ink-dim); }
.entry .rate { color: var(--ink-dim); }
.entry .bdl { cursor: pointer; }
/* editable LBS cell on a split half (backlog #11): same affordance as the bundle cell */
.entry .lbs.wt-editable { cursor: pointer; text-decoration: underline dotted var(--ink-faint); text-underline-offset: 2px; }
.entry .bdl-input, .entry .wt-input {
    width: 100%;
    font-family: var(--font-mono);
    font-size: 11px;
    text-align: right;
    background: var(--bg-deep);
    border: 1px solid var(--hot);
    border-radius: 3px;
    color: var(--ink);
    padding: 1px 3px;
}
.entry .wt-input { text-align: center; }

/* sub-line under the data row: flags left, actions right, columns stay aligned.
   Starts under the customer column (track 4 since the galv column was inserted at track 3). */
.entry-sub {
    grid-column: 4 / -1;
    display: flex;
    align-items: center;
    gap: 8px;
    padding-top: 3px;
}

.entry-flags {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}

.entry-flags:empty { display: none; }

/* actions: right-justified on the sub-line, revealed on hover/focus */
.entry-actions {
    margin-left: auto;
    display: flex;
    gap: 2px;
    opacity: 0;
    transition: opacity .12s;
}

.entry:hover .entry-actions,
.entry:focus-within .entry-actions { opacity: 1; }

.entry-actions button {
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
    border-radius: 3px;
    font-size: 10px;
    font-family: var(--font-mono);
    cursor: pointer;
    padding: 2px 6px;
    line-height: 1.4;
}

.entry-actions button:hover { color: var(--ink-strong); border-color: var(--hot); }
.entry-actions button.tog-on { color: var(--hot); border-color: var(--hot); }
.entry-actions button.x:hover { color: var(--danger); border-color: var(--danger); }

/* inline CMT button (reserved slot after the SO): fades in on hover, or stays lit if a comment exists */
.entry .act-comment {
    justify-self: start;
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 9px;
    line-height: 1.3;
    padding: 1px 4px;
    cursor: pointer;
    opacity: 0;
    transition: opacity .12s;
}
.entry:hover .act-comment, .entry:focus-within .act-comment { opacity: 1; }
.entry .act-comment.has-cmt { opacity: 1; color: var(--hot); border-color: var(--hot); }
.entry .act-comment:hover { color: var(--ink-strong); border-color: var(--hot); }

/* unschedule X pinned at the right end of every row, always visible */
.entry .act-unsched {
    justify-self: end;
    background: transparent;
    border: 1px solid transparent;
    color: var(--ink-faint);
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1;
    padding: 0 4px;
    cursor: pointer;
}
.entry .act-unsched:hover { color: var(--danger); border-color: var(--danger); }

.entry .comment-row {
    grid-column: 4 / -1;
    font-size: 11px;
    color: var(--warning);
    font-style: italic;
    padding-top: 2px;
}

.entry .comment-row input {
    width: 100%;
    background: var(--bg-deep);
    border: 1px solid var(--panel-edge);
    color: var(--ink);
    font-size: 11px;
    border-radius: 3px;
    padding: 3px 6px;
}

/* drag ghosts — PAINT-CHEAP: opacity ONLY, no color. The ghost (insertion placeholder) sits
   DIRECTLY under the native drag image while the user positions a drop, so any background/
   outline on it re-rasters every frame and bogs the drag. Opacity is a compositor-only op. */
.sortable-ghost { opacity: .4; }
/* one-time cost: dragClass styles only the snapshot taken at dragstart, not per-frame */
.sortable-drag { box-shadow: var(--shadow-drag); }

/* the small opaque drag image (setDragImage). Lives off-screen but MUST stay rendered for the
   browser to snapshot it. Tiny + opaque on purpose: the per-frame repaint under the native drag
   image is a small rect, not the full-width translucent card snapshot the browser uses by default. */
.drag-chip {
    position: fixed;
    top: -1000px;
    left: -1000px;
    padding: 5px 11px;
    background: var(--hot);
    color: #fff;
    font: 600 12px var(--font-mono);
    letter-spacing: .5px;
    border-radius: 4px;
    white-space: nowrap;
    pointer-events: none;
    z-index: -1;
}

/* ================= empty states ================= */

.empty-note {
    color: var(--ink-faint);
    font-size: 12px;
    text-align: center;
    padding: 26px 10px;
    font-style: italic;
}

/* ================= toasts ================= */

.toast-rail {
    position: fixed;
    bottom: 16px;
    right: 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    z-index: 50;
}

.toast {
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-left: 3px solid var(--info);
    color: var(--ink);
    border-radius: 4px;
    padding: 10px 14px;
    font-size: 12px;
    min-width: 240px;
    box-shadow: var(--shadow-pop);
    animation: slide-in .2s ease-out;
}

.toast.error { border-left-color: var(--danger); }
.toast.success { border-left-color: var(--ok); }

@keyframes slide-in {
    from { transform: translateX(30px); opacity: 0; }
    to { transform: none; opacity: 1; }
}

/* ================= confirm dialog ================= */

.confirm-backdrop {
    position: fixed;
    inset: 0;
    background: var(--backdrop);
    backdrop-filter: blur(3px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
    animation: fade-in .15s ease-out;
}

.confirm-box {
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-top: 3px solid var(--hot);
    border-radius: 6px;
    padding: 20px 24px;
    width: 380px;
    box-shadow: var(--shadow-modal);
    animation: pop-in .18s ease-out;
}

@keyframes fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes pop-in {
    from { transform: translateY(8px) scale(.97); opacity: 0; }
    to { transform: none; opacity: 1; }
}

.confirm-title {
    font-family: var(--font-display);
    font-size: 20px;
    letter-spacing: 1.5px;
    margin: 0 0 8px;
    color: var(--ink-strong);
}

.confirm-message { color: var(--ink-dim); margin: 0 0 18px; white-space: pre-line; }

.confirm-actions { display: flex; justify-content: flex-end; gap: 8px; }

.confirm-actions button {
    font-family: var(--font-display);
    font-size: 14px;
    letter-spacing: 1.5px;
    border-radius: 4px;
    padding: 7px 18px;
    cursor: pointer;
}

.btn-cancel {
    background: transparent;
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
}

.btn-ok {
    background: var(--hot);
    border: 1px solid var(--hot);
    color: var(--btn-ok-ink);
    font-weight: 600;
}

.btn-ok:hover { filter: brightness(1.1); }

/* ===== record-footage-ran modal (reuses .confirm-backdrop / .confirm-box) ===== */
.footage-order { font-family: var(--font-mono); font-size: 12px; color: var(--ink-dim); margin-bottom: 12px; }
.footage-stats {
    display: flex;
    gap: 8px;
    margin-bottom: 14px;
}
.footage-stats span {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 7px 10px;
    border: 1px solid var(--hairline);
    border-radius: 8px;
    background: var(--bg-deep);
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: .6px;
    color: var(--ink-faint);
}
.footage-stats b { font-size: 15px; font-weight: 600; color: var(--ink-strong); }
.footage-input-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-size: 12px;
    color: var(--ink-dim);
    margin-bottom: 10px;
}
.footage-input {
    width: 130px;
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 6px;
    color: var(--ink-strong);
    font-family: var(--font-mono);
    font-size: 15px;
    text-align: right;
    padding: 7px 10px;
}
.footage-input:focus { outline: none; border-color: var(--hot); box-shadow: 0 0 0 2px var(--hot-glow); }
.footage-preview { font-size: 12px; color: var(--ink-dim); margin-bottom: 16px; }
.footage-preview b { font-family: var(--font-mono); font-size: 14px; color: var(--ok); }
.footage-note { font-size: 11px; color: var(--ink-faint); margin: -6px 0 16px; line-height: 1.4; }

/* ================= right-click context menu ================= */

.ctx-menu {
    position: fixed;
    z-index: 300;
    min-width: 160px;
    padding: 4px;
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-radius: 6px;
    box-shadow: var(--shadow-pop);
    display: flex;
    flex-direction: column;
    animation: pop-in .12s ease-out;
}

.ctx-item {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    border-radius: 4px;
    padding: 8px 12px;
    font-family: var(--font-display);
    font-size: 13px;
    letter-spacing: 1px;
    color: var(--ink);
    cursor: pointer;
}

.ctx-item:hover { background: var(--row-hover); }

/* thin rule separating the edit actions from the remove/complete actions */
.ctx-sep { height: 1px; margin: 4px 6px; background: var(--panel-edge); }

.ctx-item.danger { color: var(--danger); }
.ctx-item.danger:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); }

/* Mark complete reads as a positive/done action — dark green in light mode (var(--ok) = #1d8a4e) */
.ctx-item.complete { color: var(--ok); }
.ctx-item.complete:hover { background: color-mix(in srgb, var(--ok) 14%, transparent); }

/* ================= mill maintenance ================= */

.maint-box {
    width: 720px;
    max-width: 92vw;
    max-height: 82vh;
    display: flex;
    flex-direction: column;
}

.maint-body {
    overflow-y: auto;
    margin-bottom: 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.maint-mill {
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 5px;
    padding: 10px 12px;
}

.maint-mill.new { border-style: dashed; }

.maint-row, .maint-rate {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    flex-wrap: wrap;
}

.maint-row label, .maint-rate label {
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 1px;
    color: var(--ink-dim);
}

/* checkbox toggle (METRIC LEN) reads inline, not stacked like the text inputs */
.maint-row label.m-check {
    flex-direction: row;
    align-items: center;
    gap: 6px;
    padding-bottom: 5px;
}
.maint-row label.m-check input { width: auto; padding: 0; }

/* global bundle-size reference rows reuse the run-rate row styling */
.maint-rate .b-size { min-width: 200px; }
.bundle-sizes-section .maint-rates-title { color: var(--hot); }

.maint-row input, .maint-rate input {
    background: var(--bg-deep);
    border: 1px solid var(--panel-edge);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 12px;
    border-radius: 3px;
    padding: 4px 6px;
    width: 110px;
}

/* selects styled to match the inputs (flat slate + a custom caret), not the native OS look */
.maint-row select, .maint-rate select {
    background-color: var(--bg-deep);
    border: 1px solid var(--panel-edge);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 12px;
    border-radius: 3px;
    padding: 4px 24px 4px 6px;
    width: 110px;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5l4 4 4-4' fill='none' stroke='%238a96a4' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 7px center;
}
.maint-row select:focus, .maint-rate select:focus { outline: none; border-color: var(--hot); }
.maint-rate select:disabled { opacity: .45; cursor: default; }
.maint-rate .r-size { width: 190px; }
.maint-rate .r-gauge { width: 118px; }
.maint-rate .r-fpm, .maint-rate .r-fph { width: 76px; }
/* FT/HR is calculated, not entered — read as a derived value, not an input */
.maint-rate .r-fph {
    background: transparent;
    border-color: transparent;
    color: var(--ink-dim);
    cursor: default;
}

.maint-row .m-name { width: 170px; }
.maint-row .m-order { width: 60px; }
.maint-row .m-co { width: 90px; }
.maint-row .m-rmd { width: 90px; }
.maint-row input[type=color] {
    width: 46px;
    height: 28px;
    padding: 2px;
    cursor: pointer;
}

.maint-mill button {
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 1px;
    padding: 6px 10px;
    cursor: pointer;
}

.maint-mill button:hover { color: var(--ink-strong); border-color: var(--hot); }
.maint-mill button.x:hover { color: var(--danger); border-color: var(--danger); }

.maint-rates {
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px dashed var(--panel-edge);
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.maint-rates-title {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 1px;
    color: var(--ink-faint);
    text-transform: uppercase;
}

/* observed (learned) rate — advisory only (Living Schedule, R13 #32). A subtle suggestion that sits
   after the configured rate inputs; the ACCEPT pill is the single Owner path to use it. */
.rate-observed {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--ink-dim);
    margin-left: 4px;
    white-space: nowrap;
    align-self: center;
}
.rate-observed.empty { display: none; }

.maint-mill button.rate-accept {
    align-self: center;
    color: var(--hot);
    border-color: var(--panel-edge);
}
.maint-mill button.rate-accept:hover { border-color: var(--hot); }

/* an observation with no configured rate yet: a read-only suggestion row in the rate grid */
.maint-rate.observed-only { opacity: .9; }
.rate-observed-key {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink);
    align-self: center;
    min-width: 240px;
}
.rate-observed-note {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 1px;
    color: var(--ink-faint);
    text-transform: uppercase;
    align-self: center;
}

/* ================= gantt timeline page ================= */

.nav-pill { text-decoration: none; display: inline-flex; align-items: center; }

.gantt-main {
    display: flex;
    padding: 14px;
    flex: 1 1 auto;
    min-height: 0;
}

.gantt-pane { flex: 1 1 auto; min-width: 0; }

/* timeline zoom slider — sits between the title and the totals in the pane head */
.gantt-zoom {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    cursor: pointer;
}

/* "hide non-working days" toggle: a compact checkbox + mono label, styled to sit with the
   zoom control. margin-left:auto right-aligns the whole control group (toggle + zoom + totals);
   the toggle is hidden when no operating calendar is configured (no defined working days). */
.gantt-skipoff {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 1px;
    color: var(--ink-dim);
}

.gantt-skipoff input {
    accent-color: var(--hot);
    cursor: pointer;
}

.gantt-skipoff:hover { color: var(--ink); }

.gzoom-end {
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 1px;
    color: var(--ink-dim);
}

.gzoom-slider {
    width: 150px;
    accent-color: var(--hot);
    cursor: pointer;
}

.gantt-scroll {
    overflow: auto;
    flex: 1 1 auto;
    position: relative;
    cursor: grab;
    user-select: none;
}

.gantt-scroll.panning { cursor: grabbing; }
.gantt-scroll.panning .gbar, .gantt-scroll.panning .gbucket, .gantt-scroll.panning .gbar-wo-out { pointer-events: none; }

.grow {
    display: flex;
    align-items: stretch;
    min-width: max-content;
    border-bottom: 1px solid var(--hairline);
}

.glane-label {
    position: sticky;
    left: 0;
    z-index: 3;
    flex: 0 0 190px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    padding: 8px 12px;
    background: var(--panel);
    border-right: 1px solid var(--panel-edge);
}

.glane-name {
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 600;
    letter-spacing: 1px;
    color: var(--ink-strong);
}

.glane-roll {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: .5px;
    color: var(--ink-dim);
}

.glane-track {
    position: relative;
    flex: 0 0 auto;
    /* roomier lanes so the order bars can stretch out and read at a glance */
    min-height: 116px;
}

/* bucket capsule: labeled span over the bucket's full time range — solid fill */
.gbucket {
    position: absolute;
    top: 9px;
    height: 21px;
    border: 1px solid color-mix(in srgb, var(--bc) 70%, #000);
    background: var(--bc);
    border-radius: 10px;
    display: flex;
    align-items: center;
    padding: 0 9px;
    overflow: hidden;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: 8.5px;
    font-weight: 600;
    letter-spacing: 1px;
    color: #10151c;
    cursor: pointer;
}

.gbucket:hover { filter: brightness(1.12); }

/* gauge-change boundary inside a bucket capsule */
.gbucket-tick {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: color-mix(in srgb, var(--bc) 40%, #000);
    pointer-events: none;
}

/* tick boundary line — same x as the axis tick above it. Sub-day (hour) ticks draw a
   faint hairline; midnight ticks (.gday-major) keep the stronger day rule. */
.gday {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--hairline);
}

.gday-major { background: var(--panel-edge); }

/* alternating day shading so the day rhythm reads at a glance */
.gband {
    position: absolute;
    top: 0;
    bottom: 0;
    background: var(--hover-tint);
    pointer-events: none;
}

.gaxis {
    position: sticky;
    top: 0;
    z-index: 4;
    background: var(--bg-deep);
    border-bottom: 1px solid var(--panel-edge);
}

.gaxis .glane-track { min-height: 30px; background: none; }

.gaxis-label {
    justify-content: center;
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 1px;
    color: var(--ink-dim);
    background: var(--bg-deep);
}

.gaxis-tick {
    position: absolute;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    padding-left: 6px;
    border-left: 1px solid var(--panel-edge);
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 1px;
    color: var(--ink);
    white-space: nowrap;
}

.gnow {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--hot);
    box-shadow: 0 0 6px var(--hot-glow);
    z-index: 3;
    pointer-events: none;
}

/* a small downward-pointing cap at the top so the current-time line still reads as a marker */
.gnow::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 7px solid var(--hot);
}

/* facility open/close markers (#43): a dashed rule at the open time and the close time on each
   working day, drawn behind the order bars. The element carries the dashed stroke as a left border;
   pointer-events:none keeps it from eating bar hovers. Sized for prominence (Chris, 2026-06-19). */
.gophours {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    border-left: 2px dashed var(--ink-dim);
    pointer-events: none;
    z-index: 1;
}

.gbar {
    position: absolute;
    top: 42px;
    height: 62px;
    border-radius: 6px;
    /* a muted tint of the bucket hue — lighter than the solid capsule, but kept reasonably
       saturated (not washed to pastel) so it reads as an industrial color. --barmix (set per
       order, alternating ~64%/84%) gives consecutive orders in a bucket a subtle shade difference
       so they read as separate runs; falls back to 72% when unset. */
    background: color-mix(in srgb, color-mix(in srgb, var(--bc) var(--barmix, 72%), #fff) 74%, transparent);
    /* a hairline edge in the bucket color gives each order its own outline so a row of
       them reads as separate blocks instead of one merged strip — replaces the heavy
       drop shadow that made dense lanes look like a pile of floating chips */
    border: 1px solid color-mix(in srgb, var(--bc) 55%, transparent);
    color: #10151c;
    font-family: var(--font-mono);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    padding: 0 9px;
    overflow: hidden;
    white-space: nowrap;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
    transition: filter .12s, box-shadow .12s;
}

.gbar-wo { font-size: 11px; font-weight: 600; }
.gbar-sub { font-size: 9px; opacity: .75; }

/* order # floated just past a short run's sliver so it stays identifiable without inflating
   the bar (which would distort the time axis). Sits in the same vertical band as the bars. */
.gbar-wo-out {
    position: absolute;
    top: 42px;
    height: 62px;
    display: flex;
    align-items: center;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    color: var(--ink-strong);
    white-space: nowrap;
    cursor: pointer;
    z-index: 1;
}
.gbar-wo-out:hover { text-decoration: underline; }

.gbar:hover {
    filter: brightness(1.12);
    box-shadow: 0 0 0 2px var(--ink-strong), 0 4px 12px rgba(0, 0, 0, 0.35);
    z-index: 2;
}

.gbar.late { outline: 2px solid var(--danger); outline-offset: 1px; }

/* ---- fancy hover card ---- */

.gtip {
    position: fixed;
    z-index: 200;
    width: 340px;
    pointer-events: none;
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-top: 3px solid var(--hot);
    border-radius: 6px;
    padding: 12px 14px;
    box-shadow: var(--shadow-modal);
    backdrop-filter: blur(4px);
    animation: pop-in .14s ease-out;
    font-size: 12px;
    color: var(--ink);
}

.gtip-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.gtip-wo {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: 14px;
    color: var(--ink-strong);
}

.gtip-wo .split-no {
    font-size: 9px;
    color: var(--warning);
    margin-left: 3px;
}

.gtip-where {
    font-family: var(--font-display);
    font-size: 11px;
    letter-spacing: 1.5px;
    color: var(--hot);
    text-align: right;
}

.gtip-desc {
    font-weight: 600;
    color: var(--ink-strong);
    margin-top: 6px;
}

.gtip-cust {
    color: var(--ink-dim);
    font-size: 11px;
    margin-bottom: 8px;
}

.gtip-grid {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 3px 14px;
    padding: 8px 0;
    border-top: 1px dashed var(--panel-edge);
    border-bottom: 1px dashed var(--panel-edge);
}

.gtip-grid span {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 1px;
    color: var(--ink-faint);
    align-self: center;
}

.gtip-grid b {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    color: var(--ink);
}

.gtip-times {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 0 2px;
}

.gtip-times > div { display: flex; flex-direction: column; gap: 1px; }

.gtip-times span {
    font-family: var(--font-mono);
    font-size: 8.5px;
    letter-spacing: 1px;
    color: var(--ink-faint);
}

.gtip-times b {
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--info);
}

.gtip-arrow { color: var(--ink-faint); }

.gtip-due {
    font-family: var(--font-mono);
    font-size: 11px;
    margin-top: 4px;
}

.gtip-comment {
    margin-top: 6px;
    font-style: italic;
    font-size: 11px;
    color: var(--warning);
}

.gtip-flags { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 8px; }

/* ================= operator view ================= */

/* the operator page scrolls vertically as one column, unlike the clipped board */
.op-main {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: auto;
    /* roomier page gutter so the mill cards float on the deeper background, matching the coil and
       planning pages (backlog #41) */
    padding: 20px 22px 32px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* TV/kiosk mode: operator.js zooms .op-main to exactly fill the screen width —
   as large as possible but never clipped (nobody can scroll a wall TV);
   zoom (not transform) so the fixed grid columns scale with the type */
body.tv .op-picker { display: none; }

.op-picker {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

/* operator screen runs every font 2px larger than the board/timeline */
body:has(.op-picker) .masthead-status,
body:has(.op-picker) .theme-toggle { font-size: 12px; }

.op-pill {
    background: transparent;
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: 1px;
    border-radius: 12px;
    padding: 4px 10px;
    cursor: pointer;
    white-space: nowrap;
    transition: color .15s, border-color .15s;
}

.op-pill:hover { color: var(--hot); border-color: var(--hot); }

.op-pill.active {
    color: var(--hot);
    border-color: var(--hot);
    background: var(--hot-soft);
}

/* a bounded, centered content column so the stacked mills don't sprawl across a wide monitor,
   matching the coil page's .coil-page wrapper (backlog #41). min-width: max-content still forces the
   shared grid to its true width so columns line up page-wide and the ?tv=1 fit math measures right. */
.op-stack {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 1600px;
    width: 100%;
    margin: 0 auto;
    min-width: max-content; /* sections share the widest grid so columns align page-wide */
}

@media (max-width: 800px) {
    .op-stack { min-width: 0; }
}

.op-stale {
    background: color-mix(in srgb, var(--warning) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--warning) 50%, transparent);
    border-radius: 5px;
    color: var(--warning);
    font-family: var(--font-mono);
    font-size: 13px;
    letter-spacing: 1px;
    padding: 8px 12px;
}

/* each mill lifts off the page on its own raised panel card, matching the coil and planning views
   (backlog #41): panel surface, edge border, ~10px radius, and the shared pane shadow. overflow:hidden
   keeps the data rows clipped to the rounded corners. */
.op-section {
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    box-shadow: var(--shadow-pane);
    overflow: hidden;
    flex: 0 0 auto;
    min-width: max-content; /* keep the fixed data columns intact; the page scrolls */
}

.op-mill-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 18px;
    padding: 13px 18px;
    border-radius: 10px 10px 0 0; /* hug the card's rounded top corners */
    background: linear-gradient(180deg, var(--sheen), transparent);
    border-bottom: 2px solid var(--hot);
}

.op-mill-name {
    font-family: var(--font-display);
    font-size: 27px;
    font-weight: 700;
    letter-spacing: 2px;
    color: var(--ink-strong);
}

.op-mill-roll {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--ink-dim);
    white-space: nowrap;
}

/* document icon that opens the mill's schedule PDF (operator + board) */
.pdf-btn {
    background: none;
    border: 1px solid transparent;
    border-radius: 3px;
    color: var(--ink-dim);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    padding: 2px 5px;
}

.pdf-btn:hover { color: var(--hot); border-color: var(--hot); }

body.tv .pdf-btn { display: none; }
/* kiosk auto-fits the wall, so the viewer text-size control is not needed there */
body.tv #opZoomCtl { display: none; }

/* display-only kiosk: the Living Schedule run controls never show (also gated in JS) */
body.tv .op-run, body.tv .op-run-timer { display: none; }
/* kiosk: the colored due edge alone carries at-risk; drop the small "behind" text marker (R13 #33) */
body.tv .op-entry .behind-mark { display: none; }

/* kiosk: the redesigned panel-card layout (backlog #41) fills the wall edge-to-edge — drop the
   centered max-width cap and the page gutter so fitTv()'s width measurement sees the full screen and
   the zoom never leaves dead margin; flatten the card lift (no scroller on a TV to motivate depth). */
body.tv .op-main { padding: 6px; }
body.tv .op-stack { max-width: none; margin: 0; gap: 10px; }
body.tv .op-section { border-radius: 6px; box-shadow: none; }

/* the FPM-column toggle that rides beside the schedule PDF buttons (backlog #21) */
.pdf-rate-opt {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.06em;
    color: var(--ink-dim);
    cursor: pointer;
    user-select: none;
}

.pdf-rate-opt input { cursor: pointer; margin: 0; }

.op-mill-head .op-mill-title { display: flex; align-items: center; gap: 8px; }

.op-mill-roll b { color: var(--hot); font-weight: 600; }

.op-bucket-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 6px 12px;
    border-top: 1px solid var(--panel-edge);
    background: linear-gradient(180deg, var(--sheen), transparent);
}

.op-bucket-name {
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: 1.5px;
    color: var(--ink-strong);
    text-transform: uppercase;
}

.op-bucket-roll {
    font-family: var(--font-mono);
    font-size: 12.5px;
    color: var(--ink-dim);
    white-space: nowrap;
}

/* wall-campaign band under the bucket head — no actions, operator-only */
.op-gauge-head {
    padding: 5px 12px 5px 22px;
    background: var(--hover-tint);
    border-top: 1px solid var(--hairline);
}

.op-gauge-label {
    font-family: var(--font-mono);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .8px;
    color: var(--ink-strong);
}

/* one shared grid template for the column labels and every data row, so every
   column lines up spreadsheet-perfect down the whole page:
   seq | WO | item | due | customer | description | scarf | pieces | bundles | feet | weight | ft/hr | est
   Most data columns flex a little (minmax + small fr) so surplus width spreads
   evenly across the table instead of pooling in two columns; cells carry their
   own horizontal padding so the hairline column separators sit centered. */
.op-cols, .op-row {
    display: grid;
    grid-template-columns:
        /* Lbs Ord sits just left of SO (backlog #51); Open LB + Lbs Rmn stay on the right */
        40px 14px minmax(150px, 1.4fr) 76px minmax(86px, 0.4fr) 128px minmax(140px, 0.9fr)
        minmax(74px, 0.4fr) minmax(100px, 0.5fr)
        minmax(72px, 0.35fr) minmax(70px, 0.35fr) minmax(106px, 0.55fr) minmax(96px, 0.45fr) minmax(94px, 0.45fr)
        minmax(96px, 0.45fr);
    padding: 0 8px;
}

.op-cols > span, .op-row > span { padding: 5px 9px 4.5px; }

/* light vertical rules between columns — ledger-style scanning aid */
.op-cols > span + span, .op-row > span + span {
    border-left: 1px solid var(--col-line);
}

/* dedicated narrow galv column (backlog #42): center the bar, kill horizontal padding, and suppress
   the ledger vertical rules around it so the tiny column reads clean — no rule to its left (it is the
   2nd child) and none to the customer column's left, so the bar floats in its own quiet gutter. The
   empty galv HEADER cell is the 2nd child of .op-cols, so the same suppression applies there. */
.op-row .c-galv, .op-cols > span:nth-child(2) { border-left: none; }
.op-row .c-galv + span, .op-cols > span:nth-child(2) + span { border-left: none; }
.op-row .c-galv {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    overflow: hidden;
}
.op-row .c-galv .galv-mark { margin-right: 0; }

.op-cols {
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--ink);
    background: var(--bg-deep);
    border-bottom: 1px solid var(--panel-edge);
    user-select: none;
}

.op-cols > span { padding-top: 4px; padding-bottom: 3px; }

.op-cols .r, .op-row .c-feet, .op-row .c-feet-ord, .op-row .c-pcs, .op-row .c-rate,
.op-row .c-wt, .op-row .c-wtb, .op-row .c-strip, .op-row .c-len { text-align: right; }
/* LBS ORD is the static reference; mute it so LBS RMN reads as the live number */
.op-row .c-feet-ord { font-family: var(--font-mono); color: var(--ink-dim); }
.op-cols .ctr, .op-row .c-desc, .op-row .c-due, .op-row .c-bdl { text-align: center; }

.op-entry {
    border-bottom: 1px solid var(--hairline);
    border-left: 4px solid transparent;
    background: var(--row);
    font-size: 14px;
    position: relative; /* positioning context for the condition rail (#34) */
}

.op-entry:nth-child(even of .op-entry) { background: var(--row-stripe); }
.op-entry.current { border-left-color: var(--hot); background: var(--hot-soft); }
.op-entry.late { border-left-color: var(--danger); }
.op-entry.soon { border-left-color: var(--warning); }
/* Live "on track" overlay (R13 #33): at-risk warms the left edge + due ink (unless the row is already
   the running "current" highlight or already late, which read stronger). Subtle, token-only. */
.op-entry.at-risk:not(.current):not(.late) { border-left-color: var(--warning); }
.op-entry.at-risk:not(.late) .c-due { color: var(--warning); }

/* Length-group separator (backlog #35): the first row of a new cut-length run within a gauge
   sub-bucket gets a clean horizontal rule + a little space, mirroring the board so operators see
   the length-group boundaries John builds loads around. Token-only, so it reads in both themes and
   in the ?tv=1 kiosk zoom.
   Unlike the board, the operator row carries a 4px colored due-urgency border-left, which used to
   "cap" a plain border-top at the corner, and it sits inside a panel card whose background shows
   through the gap above the row, so a thin line left a lighter "section" above it. The fix is a
   full-width ::before that fills the WHOLE separation (the gap plus the line) as one SOLID gray
   band, uninterrupted edge to edge, so there is no lighter section. The z-index keeps it over the
   colored urgency edge so it never notches, even on a late/current row. */
.op-entry.len-break {
    margin-top: 5px;
}
.op-entry.len-break::before {
    content: "";
    position: absolute;
    left: -4px; /* extend over the 4px colored urgency border so the band reaches the card's left edge */
    right: 0;
    top: -5px; /* start at the top of the 5px gap so the whole band is solid gray */
    height: 7px; /* 5px gap + 2px */
    background: var(--bg); /* match the page background (#d7dee5 light) so it matches the board divider, not the lighter card */
    z-index: 2;
}

.op-row { padding-left: 4px; } /* 4px accent edge + 4px = the 8px shared gutter */

/* 13px cells sit on the same baseline as their 14px neighbors */
.op-row .c-strip { padding-top: 6px; }

.op-row .c-seq {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--ink-faint);
    text-align: right;
    white-space: nowrap;
}

.op-row .cur-mark { color: var(--hot); font-size: 11px; }

/* Living Schedule (R13 #31): a subtle in-grid Start/Stop affordance on the active/next run only.
   Low contrast — a quiet glyph that brightens to the hot accent on hover, no buttons or color floods.
   Lives inside the existing seq cell, so it adds no column for everyone. */
.op-row .op-run {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--ink-faint);
    font-size: 12px;
    line-height: 1;
    padding: 0 2px;
    margin-left: 4px;
    vertical-align: baseline;
    transition: color .12s;
}
.op-row .op-run:hover { color: var(--hot); }
.op-row .op-run.stop { color: var(--ink-dim); }

.op-row .op-run-timer {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--ink-faint);
    margin-left: 3px;
    letter-spacing: .5px;
}

.op-row .c-wo {
    font-family: var(--font-mono);
    font-weight: 600;
    color: var(--ink-strong);
    white-space: nowrap;
}

.op-row .c-item, .op-row .c-feet, .op-row .c-due, .op-row .c-pcs, .op-row .c-rate,
.op-row .c-bdl, .op-row .c-wt, .op-row .c-wtb {
    font-family: var(--font-mono);
    white-space: nowrap;
}

/* the WO number anchors the row; the item number steps back */
.op-row .c-item { color: var(--ink-dim); }

/* dates always read at the same weight, colored or not */
.op-row .c-due { font-weight: 600; }

.op-row .c-strip {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--ink-dim);
    white-space: nowrap;
}

.op-row .c-desc, .op-row .c-cust {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.op-row .c-cust { color: var(--ink-dim); }

/* cut-length column; on metric mills it shows millimeters, accented so the operator can
   spot the value they key into the (metric) mill panel */
.op-row .c-len { font-family: var(--font-mono); white-space: nowrap; }
.op-row .c-len.metric { font-weight: 600; color: var(--hot); }

/* flags / comments / split note live under the row, never inline with data */
.op-sub {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 0 12px 5px 54px; /* indent under the WO column */
}

.op-sub .op-comment {
    font-style: italic;
    font-size: 13px;
    color: var(--warning);
}

.op-sub .op-split {
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--ink-dim);
}

.op-idle {
    padding: 16px 14px;
    color: var(--ink-faint);
    font-style: italic;
    font-size: 15px;
}

/* phones/tablets: the wide grid collapses to a stacked card per run */
@media (max-width: 800px) {
    /* scoped to the operator page (the only masthead with a picker) */
    body:has(.op-picker) .masthead { flex-wrap: wrap; row-gap: 6px; }

    .op-mill-head { flex-wrap: wrap; row-gap: 2px; }
    .op-mill-roll { white-space: normal; }

    .op-section { min-width: 0; }
    .op-cols { display: none; }

    .op-cols, .op-row {
        /* minmax(0,…): a long nowrap customer name must shrink, not push the
           right column out of the clipped section */
        grid-template-columns: 34px minmax(0, 1fr) auto;
        grid-template-areas:
            "seq wo    due"
            "seq cust  feet"
            "seq desc  desc"
            "seq len   strip"
            "seq pcs   bdl"
            "seq wtb   wt";
        gap: 2px 8px;
        padding: 6px 12px 6px 8px;
    }

    /* the card layout has no columns to separate */
    .op-row > span, .op-cols > span,
    .op-row > span + span, .op-cols > span + span { padding: 0; border-left: none; }
    .op-row .c-strip { padding-top: 0; }

    .op-row .c-seq  { grid-area: seq; }
    .op-row .c-wo   { grid-area: wo; }
    .op-row .c-item { display: none; }
    .op-row .c-desc { grid-area: desc; white-space: normal; text-align: left; }
    .op-row .c-len  { grid-area: len; }
    .op-row .c-cust { grid-area: cust; }
    .op-row .c-feet { grid-area: feet; }
    .op-row .c-due  { grid-area: due; text-align: right; }
    .op-row .c-strip { grid-area: strip; }
    .op-row .c-pcs  { grid-area: pcs; }
    .op-row .c-bdl  { grid-area: bdl; text-align: left; }
    .op-row .c-wtb  { grid-area: wtb; }
    .op-row .c-wt   { grid-area: wt; }
    .op-row .c-rate { display: none; }
    .op-row .c-feet-ord { display: none; } /* kiosk view stays compact: remaining only */
    /* the stacked card places cells by named grid-area; the galv cell has no area, so drop it (the
       inline galv-mark would otherwise occupy a phantom auto-placed slot) — backlog #42 */
    .op-row .c-galv { display: none; }
}

/* ================= coil inventory page ================= */

.coil-main {
    flex: 1 1 auto;
    min-height: 0; /* let this flex child shrink so its overflow:auto scrolls (body is overflow:clip) */
    overflow: auto;
    padding: 20px 22px 32px;
}

/* a bounded, centered content column so the page doesn't sprawl across a wide monitor */
.coil-page {
    max-width: 1500px;
    width: 100%;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* each region lifts off the page on its own raised panel card, matching the planning view */
.coil-card {
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    box-shadow: var(--shadow-pane);
    animation: fade-in .18s ease-out;
}
.coil-header-card { padding: 16px 20px 18px; }
.coil-table-card { padding: 6px; }
/* readiness dashboard gets the same inset as the header card so the title, summary and
   show/hide button don't run to the card edge (collapsed or expanded) */
.coil-dash-card { padding: 16px 20px 18px; }

.coil-summary {
    display: flex;
    gap: 16px;
    align-items: center;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: .5px;
    color: var(--ink-dim);
    white-space: nowrap;
    flex-wrap: wrap;
}

.coil-summary b { color: var(--ink-strong); font-weight: 600; }
.coil-summary .sum-short b, .coil-summary .sum-short { color: var(--danger); }

/* ----- header card: title + import stamp + import actions + intro + filters ----- */
.coil-toolbar {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}
.coil-toolbar-lead { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.coil-card-title {
    margin: 0;
    font-family: var(--font-display);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: 2px;
    color: var(--ink-strong);
}
.coil-stamp {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .6px;
    color: var(--ink-dim);
    white-space: nowrap;
}
.coil-toolbar-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* intro is reference material: a quiet, secondary info strip, not a heavy band */
.coil-hint {
    margin: 12px 0 0;
    font-family: var(--font-body);
    font-size: 12px;
    line-height: 1.55;
    color: var(--ink-dim);
    max-width: 110ch;
}
.coil-hint b { color: var(--ink); font-weight: 600; }
.coil-short-key { color: var(--danger); font-weight: 600; }

/* galvanized marker in the TYPE column */
.coil-galv {
    font-family: var(--font-mono);
    color: var(--hot);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 0.06em;
}
.coil-bare { color: var(--ink-faint); font-size: 12px; }

/* ----- filter bar (search + cascading width/gauge/type selects) ----- */
.coil-filters {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--hairline);
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
/* BY SHORTAGE / BY MILL segmented view switch (#56) */
.coil-viewtabs {
    display: inline-flex;
    flex: 0 0 auto;
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-radius: 7px;
    padding: 2px;
    gap: 2px;
}
.cv-tab {
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .6px;
    color: var(--ink-dim);
    padding: 6px 12px;
    border-radius: 5px;
    transition: background .12s ease, color .12s ease;
}
.cv-tab:hover { color: var(--ink-strong); }
.cv-tab.active {
    background: var(--hot);
    color: #fff;
}

.cf-search { flex: 1 1 220px; min-width: 180px; }
.cf-search input {
    width: 100%;
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 12px;
    border-radius: 6px;
    padding: 7px 10px;
}
.cf-search input::placeholder { color: var(--ink-faint); }
.cf-selects { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cf-selects select {
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 11.5px;
    border-radius: 6px;
    padding: 6px 8px;
    cursor: pointer;
    min-width: 116px;
}
.cf-clear {
    background: transparent;
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
    border-radius: 6px;
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .6px;
    padding: 6px 10px;
}
.cf-clear:hover { color: var(--hot); border-color: var(--hot); }
.cf-count {
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: .5px;
    color: var(--ink-dim);
    white-space: nowrap;
}
.cf-count b { color: var(--ink-strong); }

/* ----- the availability data table ----- */
.coil-table {
    border-radius: 6px;
    overflow: hidden;
    background: var(--panel-raised);
    min-width: max-content;
    /* don't let the flex column shrink the table to fit (which clips rows under
       overflow:hidden); keep full height so .coil-main's overflow:auto scrolls the list */
    flex: 0 0 auto;
}

/* clickable sort headers in the availability table */
.coil-sort { cursor: pointer; user-select: none; display: inline-flex; align-items: center; gap: 3px; }
.coil-sort.r { justify-content: flex-end; }
.coil-sort:hover { color: var(--ink-strong); }
.coil-sort .sort-arrow { color: var(--hot); }

/* shared grid so labels and rows line up: width | gauge | class | sched | all-open | on-hand | target | orders | over-short */
.coil-cols, .coil-row {
    display: grid;
    grid-template-columns:
        104px minmax(150px, 1.2fr) 72px
        minmax(112px, 1fr) minmax(112px, 1fr) minmax(112px, 1fr)
        minmax(116px, 1fr) 56px minmax(150px, 1.1fr);
    align-items: center;
    gap: 10px;
    padding: 0 16px;
}

.coil-cols {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .8px;
    color: var(--ink-dim);
    background: var(--panel);
    border-bottom: 2px solid var(--panel-edge);
    user-select: none;
    position: sticky;
    top: 0;
    z-index: 1;
    min-height: 38px;
}

.coil-cols .r { text-align: right; }
.coil-cols .coil-sort.sorted { color: var(--hot); }

.coil-row {
    font-size: 13px;
    min-height: 46px;
    border-bottom: 1px solid var(--hairline);
    border-left: 4px solid transparent;
    color: var(--ink);
}
.coil-row:last-child { border-bottom: none; }
.coil-row:nth-child(even) { background: var(--row-stripe); }
.coil-row:hover { background: var(--hover-tint); }
.coil-row .r { text-align: right; }
.coil-row .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.coil-row .dim { color: var(--ink-dim); }
.coil-row .coil-width { color: var(--ink-strong); font-weight: 500; }
.coil-row .coil-gauge { font-family: var(--font-body); }

/* quietly group the three demand columns (ON SCHEDULE / ALL OPEN / ON HAND) with a faint inset
   band, separating them from the target/over-short figures */
.coil-cols > span:nth-child(4),
.coil-cols > span:nth-child(5),
.coil-cols > span:nth-child(6),
.coil-row > span:nth-child(4),
.coil-row > span:nth-child(5),
.coil-row > span:nth-child(6) {
    background: var(--coil-demand-tint);
    /* extend the band to the row edges between the 10px grid gaps */
    box-shadow: -5px 0 0 var(--coil-demand-tint), 5px 0 0 var(--coil-demand-tint);
}

/* a short group: just a thin red left status edge + a legible danger figure, no row fill
   (per Chris, only orders short on steel get a red background, not the aggregate group rows) */
.coil-row.short { border-left-color: var(--danger); }

.coil-over { color: var(--ink-dim); font-weight: 500; }
.coil-short-amt {
    color: var(--danger);
    font-weight: 600;
    letter-spacing: .3px;
}

/* ----- per-rolling demand breakdown (#54): a caret expands the runs behind a group's scheduled demand ----- */
.coil-row .coil-width { display: flex; align-items: center; gap: 6px; }
.coil-exp {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    margin-right: 4px;
    width: 22px;
    flex: 0 0 22px;
    color: var(--ink-dim);
    font-size: 22px; /* a big, easy-to-hit expand triangle for the strip-width rows (Chris, 2026-06-24) */
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform .12s ease, color .12s ease;
}
.coil-exp:hover { color: var(--hot); }
.coil-exp.open { transform: rotate(90deg); color: var(--hot); }
.coil-exp-spacer { flex: 0 0 22px; width: 22px; margin-right: 4px; }

.coil-rollings {
    background: var(--panel);
    border-bottom: 1px solid var(--hairline);
    border-left: 4px solid var(--panel-edge);
    padding: 6px 16px 9px 40px;
}
.coil-rolling-head, .coil-rolling-row {
    display: grid;
    grid-template-columns: minmax(90px, .8fr) minmax(100px, 1fr) minmax(120px, 1.1fr) 116px 120px 64px;
    align-items: center;
    gap: 10px;
}
.coil-rolling-head {
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 600;
    letter-spacing: .7px;
    color: var(--ink-dim);
    padding-bottom: 3px;
}
.coil-rolling-head .r, .coil-rolling-row .r { text-align: right; }
.coil-rolling-row {
    font-size: 12px;
    min-height: 27px;
    color: var(--ink);
    border-top: 1px solid var(--hairline);
}
.coil-rolling-row .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.coil-rolling-row .dim { color: var(--ink-dim); }
.coil-rolling-row .cr-mill { color: var(--ink-strong); font-weight: 500; }
.coil-rolling-row .cr-bucket { font-family: var(--font-body); }
.coil-rolling-row .cr-gauge { font-family: var(--font-body); color: var(--ink-dim); }
.coil-rolling-row .cr-mill, .coil-rolling-row .cr-bucket, .coil-rolling-row .cr-gauge {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ----- BY MILL view (#56): each mill's rollings in schedule order, with the coil each needs ----- */
.coil-mill-group { border-bottom: 1px solid var(--panel-edge); }
.coil-mill-group:last-child { border-bottom: none; }
.coil-mill-band {
    display: flex;
    align-items: baseline;
    gap: 12px;
    background: var(--panel);
    border-bottom: 2px solid var(--panel-edge);
    padding: 9px 16px;
}
.coil-mill-band .cm-mill-name {
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 700;
    letter-spacing: .4px;
    color: var(--ink-strong);
}
.coil-mill-band .cm-mill-meta {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .5px;
    color: var(--ink-dim);
}
.coil-mill-band .cm-short { color: var(--danger); font-weight: 600; }

.cm-cols, .cm-row {
    display: grid;
    grid-template-columns:
        minmax(150px, 1.4fr) 104px minmax(140px, 1fr) 72px
        124px minmax(120px, 1fr) minmax(140px, 1.1fr);
    align-items: center;
    gap: 10px;
    padding: 0 16px;
}
.cm-cols {
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 600;
    letter-spacing: .7px;
    color: var(--ink-dim);
    min-height: 30px;
    border-bottom: 1px solid var(--hairline);
}
.cm-cols .r { text-align: right; }
.cm-row {
    font-size: 13px;
    min-height: 40px;
    color: var(--ink);
    border-bottom: 1px solid var(--hairline);
    border-left: 4px solid transparent;
}
.cm-row:last-child { border-bottom: none; }
.cm-row:nth-child(even) { background: var(--row-stripe); }
.cm-row:hover { background: var(--hover-tint); }
.cm-row .r { text-align: right; }
.cm-row .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.cm-row .cm-bucket { color: var(--ink-strong); font-weight: 500; line-height: 1.25; overflow: hidden;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; word-break: break-word; }
.cm-row .cm-gauge { font-family: var(--font-body); color: var(--ink-dim); }
/* short rolling: thin red left edge only, no fill (red fill is reserved for short order rows) */
.cm-row.short { border-left-color: var(--danger); }
/* By Mill OVER/SHORT cell: stack the pounds short over the day+time the mill runs dry (#67) */
.cm-status-short { display: inline-flex; flex-direction: column; align-items: flex-end; line-height: 1.15; }
.cm-runout { font-size: 10px; color: var(--ink-dim); white-space: nowrap; margin-top: 1px; }

/* ----- runout timing (#55): the "needed by" cell = est run start + how far off ----- */
.cr-needed, .cm-needed { font-size: 12px; white-space: nowrap; }
.cr-needed .mono, .cm-needed .mono { font-family: var(--font-mono); }
.cr-rel {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--ink-dim);
    margin-left: 2px;
}
.cr-rel.soon { color: var(--warning); font-weight: 600; }

/* ----- per-order steel coverage (#58): the orders under each rolling, tinted by whether the coil
   on hand will cover them in time (covered = light, short = subtle pink) ----- */
.coil-orders {
    padding: 2px 0 6px 56px; /* indent under the rolling row */
}
.coil-order-head, .coil-order-row {
    display: grid;
    grid-template-columns: minmax(100px, .85fr) minmax(110px, 1.2fr) minmax(80px, .75fr) 90px 80px minmax(150px, 1fr);
    align-items: center;
    gap: 10px;
    padding: 0 12px;
}
.coil-order-head {
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 600;
    letter-spacing: .6px;
    /* darker gray band + light font so the column labels read clearly over the white rows below */
    background: var(--coil-head-bg);
    color: var(--coil-head-ink);
    min-height: 22px;
    border-radius: 4px;
    margin-bottom: 2px;
}
.coil-order-head .r, .coil-order-row .r { text-align: right; }
.coil-order-row {
    font-size: 11.5px;
    min-height: 24px;
    color: var(--ink);
    border-left: 3px solid transparent;
    border-bottom: 1px solid var(--panel-edge); /* a gray separator between every row, covered or short */
    border-radius: 3px;
}
.coil-order-row .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.coil-order-row .dim { color: var(--ink-dim); }
.coil-order-row .co-cust, .coil-order-row .co-size {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* covered = "will have steel in time": a clean WHITE row (raised surface) to break up the panel
   monotony and set the not-short orders apart from the short ones (Chris, 2026-06-24) */
.coil-order-row.covered {
    background: var(--panel-raised);
}
/* short = "won't have steel in time": red fills the RIGHT share of the row equal to the order's
   short fraction (--coil-short-pct from JS) — the part that runs out before the coil reaches it —
   leaving the covered front of the order clear, with the darker-red left edge line kept as the
   marker anchor. Mirrors the board's coil-short fill (#63 parity, Chris 2026-06-24). */
.coil-order-row.short {
    background: linear-gradient(to right,
        transparent calc(100% - var(--coil-short-pct, 100%)),
        color-mix(in srgb, var(--danger) 14%, transparent) calc(100% - var(--coil-short-pct, 100%)));
    border-left-color: var(--danger);
}
/* per-order run window column (start -> end on the shop calendar): kept compact and on one line,
   centered in its column, the little arrow muted so the two timestamps read as a single span */
.co-run { text-align: center; }
.coil-order-row .co-run { font-size: 10.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.co-run-sep { margin: 0 3px; color: var(--ink-faint); }

/* ============================================================================
   Coil Readiness dashboard (#65) — a card-based control-room readout matched to
   Chris's mockup: white cards on the light page, red as the accent, green/amber/red
   only on the timeline run bars. Green = covered, amber = short within buffer, red
   = no steel in time (the red begins where the steel runs out, by proportion).
   ============================================================================ */
.coil-dash-card { background: transparent; border: none; box-shadow: none; padding: 0; margin-bottom: 18px; }
.cr-topbar { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.cr-brand { display: flex; align-items: center; gap: 12px; min-width: 0; flex-wrap: wrap; }
.cr-logo { width: 30px; height: 30px; color: var(--danger); display: inline-flex; align-items: center; justify-content: center; }
.cr-logo svg { width: 28px; height: 28px; }
.cr-title { font-family: var(--font-display); font-size: 22px; font-weight: 700; letter-spacing: .04em; color: var(--ink-strong); margin: 0; }
.cr-headline { font-family: var(--font-body); font-size: 14px; color: var(--ink-dim); }
.cr-headline b { color: var(--ink); font-weight: 600; }
.cr-headline .red { color: var(--danger); }
.cr-topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.cr-asof { display: inline-flex; align-items: center; gap: 7px; background: var(--panel-raised); border: 1px solid var(--panel-edge); border-radius: 9px; padding: 7px 12px; font-family: var(--font-body); font-size: 13px; color: var(--ink-dim); }
.cr-asof svg { width: 16px; height: 16px; }
.cr-hide { display: inline-flex; align-items: center; gap: 7px; background: var(--danger); border: 1px solid var(--danger); color: #fff; font-family: var(--font-display); font-size: 13px; font-weight: 600; letter-spacing: .03em; padding: 8px 14px; border-radius: 9px; cursor: pointer; }
.cr-hide:hover { filter: brightness(1.06); }
.cr-caret { font-size: 10px; opacity: .85; }
.dash-body { margin-top: 0; }

/* tone palette (green/amber/red), consumed via var(--tone) by donuts + bars */
.kpi-donut.ok, .cv2-donut.ok, .cv2-fill.ok, .cv2-pct.ok { --tone: var(--ok); }
.kpi-donut.warn, .cv2-donut.warn, .cv2-fill.warn, .cv2-pct.warn { --tone: var(--warning); }
.kpi-donut.bad, .cv2-donut.bad, .cv2-fill.bad, .cv2-pct.bad { --tone: var(--danger); }
.kpi-donut.na, .cv2-donut.na { --tone: var(--panel-edge); }

/* ----- KPI status strip: icon + number cards ----- */
.kpi-row { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; margin-bottom: 16px; }
@media (max-width: 1200px) { .kpi-row { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 680px) { .kpi-row { grid-template-columns: repeat(2, 1fr); } }
.kpi {
    display: flex; align-items: center; gap: 12px; text-align: left; min-width: 0;
    background: var(--panel-raised); border: 1px solid var(--panel-edge); border-radius: 14px;
    padding: 14px 16px; box-shadow: var(--shadow-pane); cursor: pointer;
    transition: transform .1s ease, box-shadow .1s ease;
}
.kpi.static { cursor: default; }
.kpi:not(.static):hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0,0,0,.10); }
.kpi-icon { flex: 0 0 46px; width: 46px; height: 46px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
.kpi-icon svg { width: 22px; height: 22px; }
.kpi-icon.alarm { background: color-mix(in srgb, var(--danger) 12%, transparent); color: var(--danger); }
.kpi-icon.muted { background: color-mix(in srgb, var(--ink-dim) 12%, transparent); color: var(--ink-dim); }
.kpi-donut {
    position: relative; flex: 0 0 46px; width: 46px; height: 46px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: conic-gradient(var(--tone) calc(var(--pct) * 1%), color-mix(in srgb, var(--panel-edge) 40%, var(--panel-raised)) 0);
}
.kpi-donut::before { content: ""; position: absolute; inset: 6px; border-radius: 50%; background: var(--panel-raised); }
.kpi-donut b { position: relative; font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--ink-strong); }
.kpi-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.kpi-big { font-family: var(--font-mono); font-size: 22px; font-weight: 600; color: var(--ink-strong); line-height: 1.1; white-space: nowrap; }
.kpi-big small { font-size: 13px; color: var(--ink-dim); font-weight: 500; }
.kpi-big.red { color: var(--danger); }
.kpi-label { font-family: var(--font-display); font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink); }
.kpi-sub { font-size: 11px; color: var(--ink-dim); line-height: 1.25; overflow: hidden;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; word-break: break-word; }

/* ----- middle band: order priority + coverage ----- */
.dash-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 16px; margin-bottom: 16px; }
@media (max-width: 1000px) { .dash-grid { grid-template-columns: 1fr; } }
.dash-panel { background: var(--panel-raised); border: 1px solid var(--panel-edge); border-radius: 14px; padding: 18px 20px; box-shadow: var(--shadow-pane); }
.panel-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; }
.panel-title { font-family: var(--font-display); font-size: 15px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-strong); }
.panel-sub { font-size: 12px; color: var(--ink-dim); }

/* order priority (coil dashboard). SCOPED under .op-panel: the operator schedule view already owns
   the global .op-row and .op-pill class names, so these rules must NOT leak onto that page (they did
   after #65 reused the names — the operator grid collapsed to 4 columns and its mill picker restyled). */
.op-panel .op-row { display: grid; grid-template-columns: 152px minmax(150px, 1.3fr) 128px minmax(120px, 1.2fr); gap: 10px; align-items: center; }
.op-panel .op-row .r { text-align: right; }
.op-head { font-family: var(--font-display); font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); padding: 0 4px 8px; border-bottom: 1px solid var(--panel-edge); }
.op-item { width: 100%; text-align: left; background: none; border: none; border-bottom: 1px solid color-mix(in srgb, var(--panel-edge) 45%, transparent); padding: 9px 4px; cursor: pointer; border-radius: 6px; }
.op-item:hover { background: color-mix(in srgb, var(--danger) 5%, transparent); }
.op-need { display: flex; align-items: center; gap: 8px; }
.op-panel .op-pill { font-family: var(--font-display); font-size: 10px; font-weight: 700; letter-spacing: .04em; padding: 2px 8px; border-radius: 6px; min-width: 40px; text-align: center; }
.op-panel .op-pill.now { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.op-panel .op-pill.soon { background: color-mix(in srgb, var(--warning) 20%, transparent); color: var(--warning); }
.op-panel .op-pill.later { background: color-mix(in srgb, var(--info) 14%, transparent); color: var(--info); }
.op-date { font-family: var(--font-mono); font-size: 12px; color: var(--ink-dim); }
.op-mat { font-family: var(--font-mono); font-size: 13px; color: var(--ink); line-height: 1.25; overflow: hidden;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; word-break: break-word; }
.op-short { font-family: var(--font-mono); font-size: 13px; font-weight: 600; color: var(--danger); }
.op-short small { font-weight: 400; color: color-mix(in srgb, var(--danger) 65%, var(--ink-dim)); }
.op-drv { font-size: 12.5px; color: var(--ink-dim); line-height: 1.25; overflow: hidden;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; word-break: break-word; }
.op-more { display: block; width: 100%; text-align: center; background: none; border: none; margin-top: 10px; padding: 8px; color: var(--ink-dim); font-family: var(--font-display); font-size: 12px; font-weight: 600; letter-spacing: .04em; cursor: pointer; }
.op-more:hover { color: var(--danger); }
.op-more-ar { font-size: 11px; }
.op-empty { color: var(--ink-dim); padding: 18px 4px; font-size: 13px; }

/* coverage: donut + bare/galv bars + buy-plan callout */
.cv2-grid { display: grid; grid-template-columns: 150px 1fr; gap: 20px; align-items: center; margin-bottom: 14px; }
@media (max-width: 1200px) { .cv2-grid { grid-template-columns: 120px 1fr; gap: 14px; } }
.cv2-donut {
    position: relative; width: 150px; height: 150px; border-radius: 50%;
    display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
    background: conic-gradient(var(--tone) calc(var(--pct) * 1%), color-mix(in srgb, var(--panel-edge) 40%, var(--panel-raised)) 0);
}
@media (max-width: 1200px) { .cv2-donut { width: 120px; height: 120px; } }
.cv2-donut::before { content: ""; position: absolute; inset: 16px; border-radius: 50%; background: var(--panel-raised); }
.cv2-donut b { position: relative; font-family: var(--font-mono); font-size: 34px; font-weight: 600; color: var(--ink-strong); line-height: 1; }
.cv2-donut small { position: relative; margin-top: 5px; font-family: var(--font-display); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-dim); }
.cv2-bars { display: flex; flex-direction: column; min-width: 0; }
.cv2-row { display: grid; grid-template-columns: 34px 1fr; gap: 10px; align-items: center; padding: 10px 0; }
.cv2-row + .cv2-row { border-top: 1px solid color-mix(in srgb, var(--panel-edge) 50%, transparent); }
.cv2-ico { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--ink-dim) 10%, transparent); color: var(--ink-dim); }
.cv2-ico svg { width: 18px; height: 18px; }
.cv2-main { min-width: 0; }
.cv2-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 5px; }
.cv2-lab { font-family: var(--font-display); font-size: 12px; font-weight: 700; letter-spacing: .05em; color: var(--ink); }
.cv2-pct { font-family: var(--font-mono); font-size: 14px; font-weight: 600; color: var(--tone); }
.cv2-track { height: 9px; border-radius: 5px; background: color-mix(in srgb, var(--panel-edge) 45%, var(--panel-raised)); overflow: hidden; }
.cv2-fill { display: block; height: 100%; border-radius: 5px; background: var(--tone); }
.cv2-sub { display: flex; justify-content: space-between; margin-top: 5px; font-size: 11px; color: var(--ink-dim); font-family: var(--font-mono); }
.cv2-callout { display: flex; align-items: center; gap: 12px; background: color-mix(in srgb, var(--danger) 6%, transparent); border: 1px solid color-mix(in srgb, var(--danger) 20%, transparent); border-radius: 10px; padding: 12px 14px; }
.cv2-callout-ico { color: var(--danger); display: flex; }
.cv2-callout-ico svg { width: 20px; height: 20px; }
.cv2-callout-txt { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.cv2-callout-txt b { font-size: 13px; color: var(--ink-strong); }
.cv2-callout-txt small { font-size: 11.5px; color: var(--ink-dim); }
.cv2-btn { background: var(--panel-raised); border: 1px solid var(--danger); color: var(--danger); font-family: var(--font-display); font-size: 12px; font-weight: 600; letter-spacing: .03em; padding: 7px 14px; border-radius: 8px; cursor: pointer; white-space: nowrap; }
.cv2-btn:hover { background: var(--danger); color: #fff; }

/* ----- mill timeline: duration bars on a selectable day/week/month/quarter scale (#65) ----- */
/* "Hide non-working time" toggle: sits at the right of the panel head, just before the zoom group */
.tl-pack { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-display); font-size: 11px; font-weight: 600; letter-spacing: .03em; color: var(--ink-dim); cursor: pointer; user-select: none; white-space: nowrap; }
.tl-pack:hover { color: var(--ink); }
.tl-pack input { accent-color: var(--hot); cursor: pointer; margin: 0; }
.tl-scale { margin-left: 12px; display: inline-flex; gap: 2px; background: color-mix(in srgb, var(--panel-edge) 30%, var(--panel-raised)); border: 1px solid var(--panel-edge); border-radius: 8px; padding: 2px; }
.tl-scale-btn { background: none; border: none; font-family: var(--font-display); font-size: 11px; font-weight: 600; letter-spacing: .03em; color: var(--ink-dim); padding: 4px 10px; border-radius: 6px; cursor: pointer; }
.tl-scale-btn:hover { color: var(--ink); }
.tl-scale-btn.active { background: var(--panel-raised); color: var(--ink-strong); box-shadow: 0 1px 3px rgba(0,0,0,.12); }
.tl-scroll {
    overflow-x: auto; overflow-y: hidden; cursor: grab; user-select: none;
    border: 1px solid var(--panel-edge); border-radius: 10px; background: var(--panel-raised);
    padding: 8px 0 10px; scrollbar-width: thin;
}
.tl-scroll.grabbing { cursor: grabbing; }
.tl-inner { position: relative; }
.tl-grid { position: absolute; inset: 0; pointer-events: none; }
.tl-grid i { position: absolute; top: 0; bottom: 0; width: 1px; background: color-mix(in srgb, var(--panel-edge) 40%, transparent); }
.tl-axis { position: relative; height: 20px; margin-left: var(--tl-label, 130px); }
.tl-tick { position: absolute; top: 0; transform: translateX(-50%); text-align: center; }
.tl-tick i { display: block; width: 1px; height: 5px; margin: 0 auto 2px; background: var(--panel-edge); }
.tl-tick b { font-family: var(--font-mono); font-size: 10px; font-weight: 500; color: var(--ink-faint); white-space: nowrap; }
.tl-tick.now i { background: var(--danger); height: 7px; }
.tl-tick.now b { color: var(--danger); font-weight: 600; }
.tl-lanes { position: relative; display: flex; flex-direction: column; margin-top: 4px; }
.tl-lane { display: grid; grid-template-columns: var(--tl-label, 130px) 1fr; align-items: center; border-top: 1px solid color-mix(in srgb, var(--panel-edge) 45%, transparent); }
.tl-lane:first-child { border-top: none; }
.tl-mill {
    position: sticky; left: 0; z-index: 6; align-self: stretch; display: flex; align-items: center;
    background: var(--panel-raised); border-right: 1px solid var(--panel-edge); padding: 0 10px 0 8px;
    font-family: var(--font-display); font-size: 12px; font-weight: 600; letter-spacing: .03em; text-transform: uppercase;
    color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tl-track { position: relative; height: 34px; }
.tl-cap {
    position: absolute; top: 6px; height: 22px; display: flex; align-items: center; box-sizing: border-box;
    padding: 0 6px; border-radius: 5px; cursor: pointer; overflow: hidden; white-space: nowrap;
    border: 1px solid var(--panel-edge); border-left-width: 3px;
    font-family: var(--font-mono); font-size: 10px; font-weight: 600; color: var(--ink-strong);
}
.tl-cap b { overflow: hidden; text-overflow: ellipsis; }
.tl-cap:hover { z-index: 5; box-shadow: 0 2px 8px rgba(0,0,0,.18); }
/* a run split across working days (gaps over non-working days): the first segment keeps the rounded
   left + colored edge tab and squares its cut right edge; continuation segments square the cut left
   edge and drop the heavy tab so the pieces read as one paused-and-resumed run. */
.tl-cap.tl-seg-first { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.tl-cap.tl-seg-mid { border-radius: 0; border-left-width: 1px; border-left-color: var(--panel-edge); }
.tl-cap.tl-seg-last { border-top-left-radius: 0; border-bottom-left-radius: 0; border-left-width: 1px; border-left-color: var(--panel-edge); }
.tl-legend { margin-top: 12px; font-size: 11.5px; color: var(--ink-dim); display: flex; align-items: center; flex-wrap: wrap; gap: 16px; }
.tl-key { display: inline-block; width: 11px; height: 11px; border-radius: 3px; margin: 0 5px 0 0; }
/* hoverable legend entries with a styled tooltip describing each state */
.tl-leg-item { position: relative; display: inline-flex; align-items: center; cursor: help; outline: none; }
.tl-leg-item::after {
    content: attr(data-tip);
    position: absolute; bottom: calc(100% + 9px); left: -8px; width: 250px;
    background: var(--panel-raised); color: var(--ink); border: 1px solid var(--panel-edge);
    border-radius: 8px; padding: 9px 11px; box-shadow: 0 8px 22px rgba(0,0,0,.20); z-index: 30;
    font-family: var(--font-body); font-size: 12px; font-weight: 400; line-height: 1.45;
    text-transform: none; letter-spacing: 0; white-space: normal;
    opacity: 0; visibility: hidden; transform: translateY(4px); transition: opacity .12s ease, transform .12s ease; pointer-events: none;
}
/* little arrow */
.tl-leg-item::before {
    content: ""; position: absolute; bottom: calc(100% + 3px); left: 6px; width: 10px; height: 10px;
    background: var(--panel-raised); border-left: 1px solid var(--panel-edge); border-top: 1px solid var(--panel-edge);
    transform: rotate(45deg); z-index: 31;
    opacity: 0; visibility: hidden; transition: opacity .12s ease;
}
.tl-leg-item:hover::after, .tl-leg-item:focus-visible::after { opacity: 1; visibility: visible; transform: translateY(0); }
.tl-leg-item:hover::before, .tl-leg-item:focus-visible::before { opacity: 1; visibility: visible; }
.tl-leg-item:focus-visible { box-shadow: 0 0 0 2px color-mix(in srgb, var(--info) 45%, transparent); border-radius: 4px; }
.tl-key.ok { background: color-mix(in srgb, var(--ok) 45%, var(--panel-raised)); border: 1px solid var(--ok); }
.tl-key.warn { background: color-mix(in srgb, var(--warning) 45%, var(--panel-raised)); border: 1px solid var(--warning); }
.tl-key.bad { background: color-mix(in srgb, var(--danger) 45%, var(--panel-raised)); border: 1px solid var(--danger); }

/* ----- notes: calm informational cards, not alarm blocks ----- */
.coil-notes { display: flex; flex-direction: column; gap: 14px; }
.coil-note {
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    box-shadow: var(--shadow-pane);
    padding: 14px 18px;
    animation: fade-in .18s ease-out;
}
.coil-note-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}
.coil-note-title {
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 1px;
    color: var(--ink-strong);
}
.coil-note-total {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink-dim);
}
.coil-note-total b { color: var(--ink); }
.coil-note-desc {
    font-size: 12px;
    line-height: 1.5;
    color: var(--ink-dim);
    margin: 0;
}
.coil-note-desc b { color: var(--ink); }
.coil-note.warn .coil-note-title { color: var(--ink-strong); }
.coil-note .coil-breakdown { margin: 10px 0 0; display: flex; flex-direction: column; gap: 1px; }
.coil-breakdown-row {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: baseline;
    gap: 14px;
    padding: 6px 0;
    border-top: 1px solid var(--hairline);
    font-size: 12px;
}
.coil-breakdown-row:first-child { border-top: none; }
.coil-breakdown-label { color: var(--ink); }
.coil-breakdown-count {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink-dim);
    white-space: nowrap;
}
.coil-breakdown-lbs {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--ink-strong);
    white-space: nowrap;
    min-width: 88px;
    text-align: right;
}

/* ----- demand drill-down: the 📊 ORDERS column + hover popover ----- */

.coil-graph {
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    cursor: pointer;
    font-size: 15px;
    line-height: 1;
    padding: 2px 5px;
}
.coil-graph:hover { background: var(--row-hover); border-color: var(--panel-edge); }

.coil-pop {
    position: fixed;
    z-index: 2000;
    width: 800px;
    max-height: 72vh;
    overflow-y: auto;
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-radius: 8px;
    box-shadow: var(--shadow-pane);
    padding: 10px 12px;
    font-size: 11px;
    color: var(--ink);
}
.coil-pop[hidden] { display: none; }

.cp-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    border-bottom: 1px solid var(--panel-edge);
    padding-bottom: 6px;
    margin-bottom: 8px;
}
.cp-title { font-family: var(--font-mono); font-weight: 600; font-size: 12px; color: var(--ink-strong); }
.cp-cov {
    font-family: var(--font-display);
    font-size: 24px;
    font-weight: 700;
    line-height: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    white-space: nowrap;
}
.cp-cov small { font-family: var(--font-mono); font-size: 8px; letter-spacing: .5px; color: var(--ink-dim); font-weight: 400; }
.cp-cov.ok { color: var(--ok); }
.cp-cov.bad { color: var(--danger); }

.cp-bars { display: flex; flex-direction: column; gap: 4px; margin-bottom: 9px; }
.cp-bar { display: grid; grid-template-columns: 116px 1fr 78px; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 10px; }
.cp-bar-l { color: var(--ink-dim); letter-spacing: .5px; display: flex; align-items: center; }

/* little circled-i explainer next to each bar label (native title tooltip on hover) */
.cp-i {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 12px;
    height: 12px;
    margin-left: 5px;
    border: 1px solid var(--ink-faint);
    border-radius: 50%;
    font-family: var(--font-body, sans-serif);
    font-style: normal;
    font-size: 8px;
    font-weight: 700;
    line-height: 1;
    color: var(--ink-dim);
    cursor: help;
}
.cp-i:hover { border-color: var(--hot); color: var(--hot); }
.cp-bar-track { background: var(--bg-deep); border-radius: 3px; height: 10px; overflow: hidden; }
.cp-bar-track i { display: block; height: 100%; background: var(--ink-faint); }
.cp-bar-track i.dim { opacity: .5; }
.cp-bar-track i.ok { background: var(--ok); }
.cp-bar-track i.bad { background: var(--danger); }
.cp-bar-track i.tgt { background: var(--hot); }
.cp-bar-v { text-align: right; color: var(--ink); }

.cp-orders-head { font-family: var(--font-mono); font-size: 10px; color: var(--ink-dim); margin-bottom: 4px; }
.cp-orders-head b { color: var(--ink-strong); }

.cp-orders { display: flex; flex-direction: column; }
.cp-ord {
    display: grid;
    grid-template-columns: 1.1fr 64px 94px 56px 44px 40px 92px 96px 36px;
    gap: 6px;
    align-items: center;
    padding: 2px 4px;
    font-size: 10px;
    border-bottom: 1px solid var(--hairline);
}
/* keep every cell on one line (SIZE like "2.000 × 4.000" must not wrap) */
.cp-ord > span { white-space: nowrap; }
.cp-mill { overflow: hidden; text-overflow: ellipsis; }
.cp-ord.cp-ord-h {
    font-family: var(--font-mono);
    color: var(--ink-dim);
    letter-spacing: .5px;
    border-bottom: 1px solid var(--panel-edge);
    position: sticky;
    top: 0;
    background: var(--panel-raised);
}
.cp-ord .r { text-align: right; }
.cp-ord .mono { font-family: var(--font-mono); }
.cp-ord .dim { color: var(--ink-dim); }
.cp-ord.open { opacity: .7; }
.cp-cust { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cp-sch .ok { color: var(--ok); }
.cp-empty { color: var(--ink-dim); padding: 8px 4px; }

.import-note {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--warning);
    margin-bottom: 10px;
}

/* ================= scrollbars ================= */

::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: var(--bg-deep); }
::-webkit-scrollbar-thumb { background: var(--panel-edge); border-radius: 5px; }
::-webkit-scrollbar-thumb:hover { background: var(--ink-faint); }

/* ================= auth pages (login / register / pending) ================= */

.auth-body {
    min-height: 100vh;
    display: flex;
    background: linear-gradient(160deg, var(--bg), var(--bg-deep));
}

.auth-wrap {
    margin: auto;
    width: 100%;
    max-width: 380px;
    padding: 24px;
}

.auth-card {
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    box-shadow: var(--shadow-pane);
    padding: 26px 24px;
}

.auth-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 20px;
}

.auth-brand .brand-mark { width: 38px; height: 38px; }

.auth-brand h1 {
    margin: 0;
    font-family: var(--font-display);
    font-size: 20px;
    font-weight: 700;
    letter-spacing: 2px;
    color: var(--ink-strong);
}

.auth-sub {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 2px;
    color: var(--hot);
}

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

.auth-field { display: flex; flex-direction: column; gap: 5px; }

.auth-field > span {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 1.5px;
    color: var(--ink-dim);
}

.auth-field input {
    background: var(--row);
    border: 1px solid var(--panel-edge);
    border-radius: 5px;
    padding: 9px 11px;
    color: var(--ink-strong);
    font-family: var(--font-body, inherit);
    font-size: 14px;
}

.auth-field input:focus { outline: none; border-color: var(--hot); }

.auth-hint { font-size: 11px; color: var(--ink-faint); }

.auth-btn {
    margin-top: 4px;
    background: var(--hot);
    border: none;
    border-radius: 5px;
    padding: 11px;
    color: #fff;
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 1.5px;
    cursor: pointer;
}

.auth-btn:hover { filter: brightness(1.06); }
.auth-btn:disabled { opacity: .6; cursor: default; }

.auth-or {
    display: flex;
    align-items: center;
    text-align: center;
    margin: 16px 0;
    color: var(--ink-faint);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 2px;
}
.auth-or::before, .auth-or::after { content: ''; flex: 1; border-top: 1px solid var(--panel-edge); }
.auth-or span { padding: 0 10px; }

.auth-google {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-radius: 5px;
    padding: 10px;
    color: var(--ink-strong);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
}
.auth-google:hover { background: var(--row-hover); }
.auth-google .g-mark {
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--hot);
    font-size: 16px;
}

.auth-foot { margin: 18px 0 0; text-align: center; font-size: 13px; color: var(--ink-dim); }
.auth-foot a { color: var(--hot); text-decoration: none; }
.auth-foot a:hover { text-decoration: underline; }

.auth-error {
    background: rgba(255, 69, 69, 0.12);
    border: 1px solid var(--danger);
    border-radius: 5px;
    padding: 9px 11px;
    margin-bottom: 14px;
    color: var(--danger);
    font-size: 13px;
}

.auth-note {
    background: var(--hot-soft);
    border: 1px solid var(--panel-edge);
    border-radius: 5px;
    padding: 12px;
    margin-bottom: 14px;
    color: var(--ink);
    font-size: 13px;
    line-height: 1.5;
}
.auth-note a { color: var(--hot); }

/* ================= user menu (initials avatar + dropdown) in the masthead ================= */

.user-menu { position: relative; display: inline-flex; align-items: center; }

.user-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: var(--hot);
    color: #fff;
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .5px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: filter .12s, box-shadow .12s;
}
.user-avatar:hover { filter: brightness(1.08); }
.user-menu.open .user-avatar { box-shadow: 0 0 0 3px var(--hot-glow); }

.user-dropdown {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 210px;
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-radius: 8px;
    box-shadow: var(--shadow-pane);
    padding: 6px;
    z-index: 1000;
    display: flex;
    flex-direction: column;
}
.user-dropdown[hidden] { display: none; }

.user-card {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 10px 10px;
    border-bottom: 1px solid var(--panel-edge);
    margin-bottom: 4px;
}
.user-card-name { color: var(--ink-strong); font-weight: 600; font-size: 13px; }
.user-card-email {
    color: var(--ink-dim);
    font-family: var(--font-mono);
    font-size: 10px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.user-item {
    display: block;
    width: 100%;
    padding: 8px 10px;
    border: none;
    background: transparent;
    color: var(--ink);
    font-family: inherit;
    font-size: 13px;
    text-align: left;
    text-decoration: none;
    border-radius: 5px;
    cursor: pointer;
}
.user-item:hover { background: var(--row-hover); color: var(--ink-strong); }
.user-logout { color: var(--danger); }
.user-logout:hover { background: rgba(255, 69, 69, 0.1); color: var(--danger); }
/* quiet footer link at the very bottom of the menu — opens the About page in a new tab */
.user-about {
    margin-top: 4px;
    border-top: 1px solid var(--panel-edge);
    border-radius: 0 0 5px 5px;
    color: var(--ink-dim);
    font-size: 12px;
    letter-spacing: .3px;
}

body.tv .user-menu { display: none; }

/* ================= admin console ================= */

/* content pages (account, planning, share) live here. The page itself is clipped
   (html/body overflow:clip), so this main must be the scroll container — fill the space
   under the masthead and scroll its own content, or a tall page is cut off below the fold
   with no way to reach it. Sections may still scroll inside themselves (e.g. the planning
   tables' own max-height), which nests cleanly under this page scroll. */
.admin-main {
    padding: 18px 22px 30px;
    display: flex;
    flex-direction: column;
    gap: 26px;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

/* console shell: a sticky section nav on the left, a panel pane on the right. The page itself
   doesn't scroll (html/body are clipped), so the console fills the space under the masthead and
   scrolls its own content — otherwise a tall panel (e.g. Settings) is cut off below the fold. */
.console {
    display: grid;
    grid-template-columns: 212px minmax(0, 1fr);
    gap: 22px;
    align-items: start;
    padding: 18px 22px 30px;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.console-nav {
    position: sticky;
    /* top:0, not the container's 18px pad: a positive sticky offset holds the rail that many px
       below the scrollport even at rest, leaving it sitting lower than the panel beside it. 0 keeps
       the rail's top flush with the panel's top, and it still pins under the masthead on overflow. */
    top: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* a distinct floating rail, not loose items on the page */
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 12px;
    box-shadow: var(--shadow-pane);
    padding: 10px;
}

.console-id {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 12px;
    border: 1px solid var(--panel-edge);
    border-radius: 6px;
    background: var(--panel-raised);
}
.console-id-label { font-family: var(--font-mono); font-size: 9px; letter-spacing: 1px; color: var(--ink-dim); }
.console-id-name { font-family: var(--font-display); font-size: 15px; letter-spacing: .5px; color: var(--ink-strong); }
.console-id .adm-pill { align-self: flex-start; margin-top: 3px; }

.console-nav-items { display: flex; flex-direction: column; gap: 2px; }
.console-nav-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    border-left: 2px solid transparent;
    border-radius: 6px;
    padding: 9px 12px;
    font-family: var(--font-display);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 1px;
    color: var(--ink-dim);
    cursor: pointer;
}
.console-nav-item:hover { color: var(--ink); background: var(--hover-tint); }
.console-nav-item.active {
    color: var(--ink-strong);
    background: var(--panel-raised);
    border-left-color: var(--hot);
}
.console-nav-item .nav-label { flex: 1; }
.console-nav-item .nav-badge {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--ink-dim);
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    padding: 0 7px;
    min-width: 20px;
    text-align: center;
}
.console-nav-item.active .nav-badge { color: var(--ink); border-color: var(--ink-faint); }
.console-nav-note { font-size: 11px; line-height: 1.4; color: var(--ink-dim); margin: 0; padding: 0 12px; }

.console-content { min-width: 0; }
.console-panel { display: none; }
.console-panel.active {
    display: block;
    animation: fade-in .15s ease-out;
    /* the content pane is a distinct floating panel, matching the nav rail */
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 12px;
    box-shadow: var(--shadow-pane);
    padding: 18px 20px 20px;
}

.console-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.console-head h2 {
    font-family: var(--font-display);
    font-size: 20px;
    font-weight: 600;
    letter-spacing: 2px;
    color: var(--ink-strong);
    margin: 0;
    display: flex;
    align-items: center;
    gap: 8px;
}
.console-head-actions { margin-left: auto; display: flex; gap: 8px; }
.console-head-actions .adm-btn { font-size: 11px; letter-spacing: 1px; padding: 5px 10px; }

/* the wide users table scrolls horizontally inside its panel rather than the whole page */
/* each table scrolls inside its own control (both axes) instead of growing the whole page —
   long lists like sign-in history / activity stay contained. The column header sticks on top. */
.table-scroll { overflow: auto; max-height: 62vh; border-radius: 6px; }
.table-scroll .admin-cols { position: sticky; top: 0; z-index: 1; }

@media (max-width: 760px) {
    .console { grid-template-columns: 1fr; gap: 14px; }
    .console-nav { position: static; }
    .console-nav-items { flex-direction: row; flex-wrap: wrap; }
    .console-nav-item { border-left: 0; border-bottom: 2px solid transparent; border-radius: 4px 4px 0 0; }
    .console-nav-item.active { border-left: 0; border-bottom-color: var(--hot); }
}

.admin-section h2 {
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: 2px;
    color: var(--ink-strong);
    margin: 0 0 6px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.admin-hint { font-size: 12px; color: var(--ink-dim); margin-bottom: 10px; }
.admin-hint b { color: var(--ink); }

.admin-table {
    border: 1px solid var(--panel-edge);
    border-radius: 6px;
    overflow: hidden;
    background: var(--panel-raised);
    min-width: max-content;
}

.admin-cols-users {
    /* ACTIONS is a FIXED width, not auto — each header/row is its own grid, so a content-sized
       (auto) actions column resolves wider in rows (buttons) than in the header ("ACTIONS"),
       which shifts the flexible USER column and misaligns every column. Fixed keeps them in lockstep. */
    grid-template-columns: minmax(180px, 1.6fr) 90px 80px 60px 110px 110px 60px 110px 360px;
}
.admin-cols-logins {
    grid-template-columns: 130px minmax(200px, 1.6fr) 80px 90px 130px;
}
.admin-cols-backups {
    grid-template-columns: 160px minmax(150px, 1fr) minmax(200px, 1.4fr) 130px;
}
.admin-cols-activity {
    grid-template-columns: 130px minmax(160px, 1.3fr) 120px minmax(200px, 1.6fr) 120px;
}
.admin-cols-online {
    grid-template-columns: minmax(200px, 1.6fr) 140px minmax(160px, 1fr);
}
.admin-cols-opt-mill {
    grid-template-columns: minmax(160px, 1.4fr) 120px 120px 130px;
}
.admin-cols-opt-order {
    grid-template-columns: 110px minmax(120px, 1fr) minmax(160px, 1.4fr) 110px 130px;
}
.admin-cols-xwalk {
    grid-template-columns: minmax(150px, 1.2fr) minmax(150px, 1.2fr) 75px 110px 70px 100px 110px;
}
/* read-only sales-order file view (#71/#72, salesorders.html) */
.admin-cols-sofile {
    grid-template-columns: 88px minmax(120px, 1fr) 85px minmax(150px, 1.2fr) 88px 100px 55px 65px
        70px 55px 60px 70px 70px 50px 82px 90px 90px 105px;
}
.admin-cols-sofile > span { min-width: 0; }
.so-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.so-sort:hover { color: var(--ink); }
.so-cust { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.so-closed > span > * { opacity: .55; }
/* column-source tints (#72): FILE is the untinted baseline; parsed / derived / system get a
   soft wash so a reader can tell literal file content from computed or bookkeeping values.
   Applied to header + every cell (full column stripes). Kept translucent so both themes work. */
.so-src-parsed { background: color-mix(in srgb, #4a90d9 8%, transparent); }
.so-src-derived { background: color-mix(in srgb, #9b59b6 8%, transparent); }
.so-src-system { background: color-mix(in srgb, var(--ink-dim) 10%, transparent); }
.admin-cols-sofile > span[class*="so-src"] { padding: 6px 6px; margin: -6px -5px; }
/* the legend chips reuse the same tint classes over a small bordered key */
.so-legend { display: inline-flex; gap: 6px; margin-left: 4px; vertical-align: baseline; }
.so-key {
    font-family: var(--font-mono); font-style: normal; font-size: 9.5px; letter-spacing: 1px;
    color: var(--ink-dim); border: 1px solid var(--panel-edge); border-radius: 3px; padding: 1px 6px;
}

/* ===== Inventory dump screen (R16, inventory.html, Owner+) ===== */
/* TAG | TYPE | PART | WIDTH | LEN | CLASS | GAGE | STORAGE | PCS | LBS | HEAT | YS | TS | E | CE | REC'D | LOC */
.admin-cols-inv {
    grid-template-columns: 62px 48px minmax(130px, 1.4fr) 60px 58px 55px 62px 92px 48px 70px
        minmax(80px, 1fr) 46px 46px 52px 56px 72px 64px;
}
.admin-cols-inv > span { min-width: 0; }
/* finished goods older than the fresh window: on hand, but the in-stock check disregards it */
.inv-stale > span > * { opacity: .55; }
.inv-stale-date { color: var(--warning); }
.inv-stale-key { color: var(--ink-dim); }

/* ===== Coil & Tube crosswalk manager (#69, coils.html, Owner+) ===== */
/* .coil-card carries no inset of its own — every variant adds one (.coil-header-card etc.),
   so the manager card gets the same padding or its title/hint run flush to the card edge */
.xw-card { padding: 16px 20px 18px; }
.xw-card .xw-body { margin-top: 12px; }
.xw-bar { display: flex; align-items: center; gap: 12px; margin: 0 0 10px; flex-wrap: wrap; }
.xw-pager { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.xw-pager .adm-btn:disabled { opacity: .35; cursor: default; }
.xw-page { font-family: var(--font-mono); font-size: 11px; color: var(--ink-dim); min-width: 110px; text-align: center; }
.xw-scroll { overflow-x: auto; }
.xw-actions { display: flex; gap: 6px; justify-self: end; }
/* add/edit modal form. .confirm-box.xw-box outranks the base 380px width the same way
   .import-box does — a comfortable form width, NOT the import modal's near-fullscreen. */
.confirm-box.xw-box { width: min(480px, 94vw); }
.xw-form { display: flex; flex-direction: column; gap: 12px; margin: 6px 0 16px; }
.xw-field { display: flex; flex-direction: column; gap: 4px; }
.xw-fl {
    font-family: var(--font-mono); font-size: 10px; letter-spacing: 1px;
    text-transform: uppercase; color: var(--ink-dim);
}
.xw-fl small { text-transform: none; letter-spacing: 0; color: var(--ink-faint); margin-left: 4px; }
.xw-field input {
    background: var(--bg-deep); border: 1px solid var(--panel-edge); border-radius: 4px;
    color: var(--ink-strong); font-family: var(--font-mono); font-size: 13px; padding: 7px 9px;
}
.xw-field input:focus { outline: none; border-color: var(--hot); }
/* the parent field's live parse feedback — color only, no layout shift */
.xw-preview { font-family: var(--font-mono); font-size: 11px; min-height: 15px; color: var(--ink-dim); margin-top: -6px; }
.xw-preview.ok { color: var(--ok); }
.xw-preview.warn { color: var(--warning); }
.xw-err { color: var(--danger); font-size: 12px; }

/* ---- Schedule optimizer (R15) ---- */
.opt-goal-label {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: var(--font-mono); font-size: 10px; letter-spacing: 1px; color: var(--ink-dim);
}
.opt-goal-label select {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    background-color: var(--bg-deep); border: 1px solid var(--panel-edge); border-radius: 4px;
    color: var(--ink-strong); font-family: var(--font-mono); font-size: 11px; padding: 5px 24px 5px 8px; cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5l4 4 4-4' fill='none' stroke='%238a96a4' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 7px center;
}
.opt-goal-label select:focus { outline: none; border-color: var(--hot); }
.opt-head {
    border: 1px solid var(--panel-edge); border-left: 3px solid var(--ink-faint);
    border-radius: 8px; background: var(--panel-raised); padding: 16px 18px; margin-bottom: 18px;
}
.opt-head.good { border-left-color: var(--hot); }
.opt-headline { font-family: var(--font-display); font-size: 20px; font-weight: 600; color: var(--ink-strong); letter-spacing: .3px; }
.opt-headline .opt-pct { color: var(--hot); }
.opt-head.good .opt-headline b { color: var(--hot); }
.opt-sub { color: var(--ink-dim); font-size: 13px; margin-top: 6px; }
.opt-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--ink-dim); margin: 18px 0 8px; }
.opt-table { margin-bottom: 4px; }
.opt-better { color: var(--ok); }
.admin-cols-share {
    grid-template-columns: minmax(160px, 1.4fr) 110px minmax(140px, 1fr) 130px 130px minmax(200px, auto);
}
.admin-section h2 #backupNow,
.admin-section h2 #createLink { margin-left: auto; font-size: 11px; letter-spacing: 1px; }

/* freshly created share link: highlighted row with a read-only URL field + copy */
.share-new {
    margin: 10px 0 14px;
    padding: 10px 12px;
    border: 1px solid var(--hot);
    border-radius: 6px;
    background: color-mix(in srgb, var(--hot) 10%, transparent);
}
.share-new-label { font-size: 11px; font-weight: 600; letter-spacing: .5px; color: var(--ink); margin-bottom: 6px; text-transform: uppercase; }
.share-new-row { display: flex; gap: 8px; align-items: center; }
.share-new-row input {
    flex: 1 1 auto;
    font-family: var(--font-mono);
    font-size: 12px;
    padding: 6px 8px;
    border: 1px solid var(--panel-edge);
    border-radius: 4px;
    background: var(--panel-raised);
    color: var(--ink);
}

.admin-cols, .admin-row { display: grid; align-items: center; gap: 10px; padding: 6px 12px; }
.admin-cols {
    background: var(--panel);
    border-bottom: 1px solid var(--panel-edge);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 1px;
    color: var(--ink-dim);
}
.admin-row { border-bottom: 1px solid var(--panel-edge); font-size: 12px; color: var(--ink); }
.admin-row:last-child { border-bottom: none; }
.admin-row .r, .admin-cols .r { text-align: right; justify-self: end; }
.admin-row .mono { font-family: var(--font-mono); font-size: 11px; }
.admin-row .dim { color: var(--ink-dim); }

.adm-user { display: flex; flex-direction: column; line-height: 1.25; }
.adm-user b { color: var(--ink-strong); }

/* activity ACTION cell: the action on top, the redacted request summary as a muted mono sub-line */
.adm-act { display: flex; flex-direction: column; gap: 1px; line-height: 1.3; min-width: 0; }
.adm-act > b { color: var(--ink); font-weight: 500; }
.adm-act > small { color: var(--ink-dim); font-size: 11px; word-break: break-word; }

/* facility operating-days checkboxes (#14) */
/* ===== Operating Calendar: each setting is its own control-panel card (#14/#15) ===== */
/* Owner Settings (R12) — a single calm column of configuration cards at a comfortable reading
   width. One concept per card; mono is reserved for the data values, labels read in the display
   face. Replaces the earlier ragged two-column masonry. */
#settingsPanel {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 660px;
}

.fac-card {
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: var(--shadow-pane);
}

/* header: a small steel-orange tick beside the display-face title over a quiet description
   (the old full-height rail repeated five times read as loud and ragged) */
.fac-card-head {
    padding: 14px 18px 13px;
    border-bottom: 1px solid var(--hairline);
}
.fac-card-title {
    display: flex;
    align-items: center;
    gap: 9px;
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--ink-strong);
}
.fac-card-title::before {
    content: "";
    width: 3px;
    height: 14px;
    border-radius: 2px;
    background: var(--hot);
    flex: none;
}
.fac-card-sub {
    display: block;
    margin-top: 5px;
    padding-left: 12px;
    font-family: var(--font-body);
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--ink-dim);
}

.fac-card-body { padding: 18px; }
.fac-fine { margin: 14px 0 0; font-family: var(--font-body); font-size: 12px; line-height: 1.45; color: var(--ink-dim); }
.fac-fine b { color: var(--ink); font-weight: 600; }

/* footer: a quiet divider — status note left, save action right; no heavy fill */
.fac-card-foot {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 18px;
    border-top: 1px solid var(--hairline);
}
.fac-foot-note { font-family: var(--font-body); font-size: 12px; color: var(--ink-dim); }
.fac-foot-actions { margin-left: auto; display: flex; gap: 8px; }
.fac-card-foot .adm-btn {
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 1px;
    padding: 7px 16px;
    border-radius: 6px;
}
.fac-card-foot .adm-btn.ok { background: color-mix(in srgb, var(--ok) 12%, transparent); }
.fac-card-foot .adm-btn.ok:hover { background: color-mix(in srgb, var(--ok) 20%, transparent); }

/* Business Days picker: filled toggle chips (selected = hot), checkbox kept for accessibility */
.fac-days { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }
.fac-day {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 54px;
    padding: 9px 14px;
    border: 1px solid var(--panel-edge);
    border-radius: 7px;
    background: var(--panel);
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--ink-faint);
    cursor: pointer;
    user-select: none;
    transition: color .12s, border-color .12s, background .12s;
}
.fac-day input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.fac-day:hover { border-color: var(--hot); color: var(--ink); }
.fac-day:has(input:checked) {
    border-color: var(--hot);
    background: var(--hot-soft);
    color: var(--ink-strong);
}
.fac-day:has(input:focus-visible) { box-shadow: 0 0 0 2px var(--hot-glow); }

/* form field: label reads in the display face, the value stays mono */
.fac-hours { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0; }
.fac-field { display: flex; align-items: center; gap: 12px; }
.fac-field .fl {
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--ink-dim);
}
.fac-field .fl small {
    margin-left: 5px;
    font-weight: 500;
    letter-spacing: .5px;
    text-transform: none;
    color: var(--ink-faint);
}
.fac-field input[type="time"],
.fac-field input[type="number"],
.fac-field input[type="text"] {
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 6px;
    color: var(--ink-strong);
    font-family: var(--font-mono);
    font-size: 14px;
    padding: 7px 10px;
}
.fac-field input:focus { outline: none; border-color: var(--hot); box-shadow: 0 0 0 2px var(--hot-glow); }
.fac-field input[readonly] {
    color: var(--ink-faint);
    background: color-mix(in srgb, var(--ink) 4%, transparent);
    border-style: dashed;
}
.facility-arrow { color: var(--ink-faint); font-size: 16px; }

/* Scheduling Thresholds: a tidy column of aligned label -> value rows */
.fac-fields { display: flex; flex-direction: column; gap: 11px; margin: 0; max-width: 380px; }
.fac-fields .fac-field { justify-content: space-between; }
.fac-fields .fac-field input { width: 108px; text-align: right; }
/* the computed mirror sits apart, read as a derived read-out */
.fac-field.derived { margin-top: 4px; padding-top: 12px; border-top: 1px dashed var(--hairline); }

/* Branding: facility name input can run wide */
.fac-name input[type="text"] { width: 280px; max-width: 100%; }

/* Print Options checkbox row */
.fac-check {
    display: flex; align-items: center; gap: 10px;
    font-family: var(--font-body); font-size: 13px; color: var(--ink);
}
.fac-check b { font-family: var(--font-mono); font-size: 12px; color: var(--ink-strong); }

/* branding logo control (R12 #30) */
.fac-logo { display: flex; align-items: center; gap: 16px; margin-top: 16px; flex-wrap: wrap; }
.fac-logo-preview {
    width: 132px; height: 56px;
    display: flex; align-items: center; justify-content: center;
    border: 1px dashed var(--panel-edge); border-radius: 8px;
    background: color-mix(in srgb, var(--ink) 3%, transparent);
    overflow: hidden;
    flex: none;
}
.fac-logo-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
.fac-logo-empty {
    font-family: var(--font-display); font-size: 11px;
    font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--ink-faint);
}
.fac-logo-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fac-logo-actions input[type="file"] { font-family: var(--font-body); font-size: 12px; color: var(--ink-dim); max-width: 220px; }
/* dress the native file button to match the rest of the controls */
.fac-logo-actions input[type="file"]::file-selector-button {
    font-family: var(--font-display);
    font-size: 11px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase;
    color: var(--ink-dim);
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 6px;
    padding: 6px 12px;
    margin-right: 10px;
    cursor: pointer;
    transition: color .12s, border-color .12s;
}
.fac-logo-actions input[type="file"]::file-selector-button:hover { color: var(--ink-strong); border-color: var(--hot); }
.fac-logo-actions .adm-btn {
    font-family: var(--font-display);
    font-size: 11px; font-weight: 600; letter-spacing: 1px;
    padding: 7px 14px; border-radius: 6px;
}

.adm-user small { color: var(--ink-dim); font-size: 11px; }

.adm-pill {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 1px;
    padding: 2px 6px;
    border-radius: 3px;
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
}
.adm-pill.ok { color: var(--ok); border-color: var(--ok); }
.adm-pill.warn { color: var(--warning); border-color: var(--warning); }
.adm-pill.bad { color: var(--danger); border-color: var(--danger); }
.adm-pill.admin { color: var(--hot); border-color: var(--hot); }

/* role badge — quiet by design: borderless mono text that blends into the row, with only a
   subtle darkness gradient (Read-only lightest → Admin darkest) instead of loud colored boxes. */
.adm-role { font-family: var(--font-mono); font-size: 10px; letter-spacing: 1px; color: var(--ink-dim); }
.adm-role-readonly { color: var(--ink-faint); }
.adm-role-standard { color: var(--ink-dim); }
.adm-role-owner { color: var(--ink); }
.adm-role-admin { color: var(--ink-strong); font-weight: 600; }

.adm-actions { display: flex; flex-wrap: wrap; gap: 5px; justify-content: flex-end; }
.adm-btn {
    background: transparent;
    border: 1px solid var(--panel-edge);
    border-radius: 3px;
    color: var(--ink-dim);
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: .5px;
    padding: 3px 7px;
    cursor: pointer;
}
.adm-btn:hover { color: var(--ink-strong); border-color: var(--ink-faint); }
.adm-btn.ok { color: var(--ok); border-color: var(--ok); }
.adm-btn.ok:hover { background: rgba(88, 214, 141, 0.1); }
.adm-btn.danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 55%, transparent); }
.adm-btn.danger:hover { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); }

/* The per-row role <select> sits inline with the .adm-btn action buttons, so it wears the same flat
   look: transparent fill, themed border, mono caps, and a custom caret (no native OS chrome). */
.adm-role-sel {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background: transparent;
    border: 1px solid var(--panel-edge);
    border-radius: 3px;
    color: var(--ink-dim);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .5px;
    padding: 3px 22px 3px 8px;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5l4 4 4-4' fill='none' stroke='%238a96a4' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 6px center;
}
.adm-role-sel:hover { color: var(--ink-strong); border-color: var(--ink-faint); }
.adm-role-sel:focus { outline: none; border-color: var(--hot); }

/* Create-user form: align the inputs and the role select into one tidy row, all themed to match the
   rest of the console (flat slate fields, themed border, custom caret on the select). */
.adm-create-user { margin: 4px 0 14px; }
.adm-create-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.adm-create-row input,
.adm-create-row select {
    background: var(--bg-deep);
    border: 1px solid var(--panel-edge);
    border-radius: 3px;
    color: var(--ink-strong);
    font-family: var(--font-mono);
    font-size: 12px;
    padding: 6px 8px;
}
.adm-create-row input::placeholder { color: var(--ink-faint); }
.adm-create-row input:focus,
.adm-create-row select:focus { outline: none; border-color: var(--hot); }
.adm-create-row select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 24px;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5l4 4 4-4' fill='none' stroke='%238a96a4' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 7px center;
}

/* ============ Roadmap & Open Issues view (planning.html, R11) ============ */
.planning-main { max-width: 1400px; width: 100%; margin: 0 auto; }
.planning-intro { font-size: 13px; line-height: 1.5; color: var(--ink-dim); margin: 0 0 22px; max-width: 80ch; }

/* each list sits on its own light panel card so the three groups lift off the grey page
   background with real contrast, matching the board's panel treatment. The near-white
   table then reads as a nested raised surface inside the panel (R11 polish, 2026-06-18). */
.planning-main .admin-section {
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    padding: 16px 20px 20px;
    box-shadow: var(--shadow-pane);
}
.planning-main .admin-section + .admin-section { margin-top: 4px; }

.planning-head {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 12px;
}
.planning-head h2 { margin: 0; }
.planning-search {
    margin-left: auto;
    width: min(320px, 42vw);
    background: var(--panel-raised);
    border: 1px solid var(--panel-edge);
    border-radius: 4px;
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 12px;
    padding: 5px 9px;
}
.planning-search:focus { outline: none; border-color: var(--hot); }
.planning-search::placeholder { color: var(--ink-faint); }

.planning-table {
    border: 1px solid var(--panel-edge);
    border-radius: 8px;
    overflow: auto;
    /* each table scrolls inside its own control (sticky header below) so a long list never
       pushes the page; both sections stay reachable on one screen */
    max-height: 52vh;
    background: var(--panel-raised);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.planning-tbl { border-collapse: collapse; width: 100%; font-size: 13px; }
.planning-tbl thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--panel);
    text-align: left;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 1px;
    color: var(--ink-dim);
    font-weight: 600;
    padding: 10px 14px;
    border-bottom: 2px solid var(--panel-edge);
    cursor: pointer;
    white-space: nowrap;
    user-select: none;
}
.planning-tbl thead th:hover { color: var(--ink); }
.planning-tbl thead th.sorted { color: var(--hot); }
.planning-tbl tbody td {
    padding: 9px 14px;
    border-bottom: 1px solid var(--panel-edge);
    color: var(--ink);
    vertical-align: top;
    line-height: 1.5;
}
/* subtle zebra striping aids scanning; placed before :hover so hover still wins */
.planning-tbl tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--ink) 3.5%, transparent); }
.planning-tbl tbody tr:last-child td { border-bottom: none; }
.planning-tbl tbody tr:hover td { background: var(--hot-soft); }
.planning-tbl td.c-id { font-family: var(--font-mono); font-weight: 600; color: var(--ink-strong); white-space: nowrap; }
.planning-tbl td.c-date { font-family: var(--font-mono); color: var(--ink-dim); white-space: nowrap; }
.planning-tbl .c-source { white-space: nowrap; }
.planning-tbl .c-id { width: 46px; }
.planning-tbl .c-date { width: 96px; }
.planning-tbl .c-status { width: 104px; }
.planning-tbl .c-source, .planning-tbl .c-feature { width: 160px; }
.planning-tbl .c-wide { min-width: 320px; }
.planning-tbl td code {
    font-family: var(--font-mono);
    font-size: 11px;
    background: var(--panel);
    border: 1px solid var(--panel-edge);
    border-radius: 3px;
    padding: 0 4px;
}
.planning-tbl td a { color: var(--info); }

/* muted status pills — colored text + thin border on a transparent ground (no shouting) */
.st-pill {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .5px;
    line-height: 1.5;
    padding: 2px 9px;
    border-radius: 10px;
    border: 1px solid var(--panel-edge);
    color: var(--ink-dim);
    white-space: nowrap;
}
.st-pill.st-open   { color: var(--warning); border-color: color-mix(in srgb, var(--warning) 45%, transparent); }
.st-pill.st-active { color: var(--info);    border-color: color-mix(in srgb, var(--info) 45%, transparent); }
.st-pill.st-done   { color: var(--ok);      border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.st-pill.st-muted  { color: var(--ink-faint); border-color: var(--panel-edge); }
