/* ═══════════════════════════════════════════════════════════════════════════
 * NAEPOMS — INTERFACE
 * N.A. Electro Process / MesshPCB India Pvt Ltd
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * WHY THIS WAS REBUILT
 *
 *   The old sheet looked soft and low-resolution, and there were four reasons,
 *   all of them fixable and none of them a matter of taste:
 *
 *   1  -webkit-font-smoothing: antialiased was set on <body>. On a Mac that
 *      thins text slightly. On Windows Chrome it TURNS OFF ClearType, so every
 *      glyph is rendered with grey antialiasing instead of subpixel coverage.
 *      On a 125%-scaled Windows laptop - which is what the factory runs - that
 *      is the whole "blurry" complaint. It is gone.
 *
 *   2  The type was far too small: thirty-two rules at 10px, twenty-six at
 *      11px, eight at 9px, five at 8px and two at 7px. Seven-pixel text is not
 *      small, it is unreadable, and with grey antialiasing it turns to mush.
 *      Nothing here is below 11px.
 *
 *   3  Fractional sizes (12.5px) put glyph stems on half-pixels. The scale
 *      below is whole numbers only.
 *
 *   4  The sidebar logo is a 220x60 PNG drawn 180px wide. At 125% scaling the
 *      browser is upscaling it. index.php now points at the 885x244 original.
 *
 * THE TYPEFACE
 *
 *   IBM Plex Sans, with IBM Plex Mono for anything that is an identifier - a
 *   work order number, a part number, an order number. Chosen for this app in
 *   particular: it was drawn for dense technical interfaces, it holds up at
 *   12px where a geometric face like DM Sans starts to close up, and it has
 *   real tabular figures - which matter more here than anywhere, because half
 *   of every screen is a column of quantities that has to line up.
 *
 * ONE THEME, DONE PROPERLY
 *
 *   Light only. Several thousand inline styles are scattered through the page
 *   scripts with literal colours in them; a dark theme would leave half the
 *   app in one palette and half in the other, which is worse than not having
 *   one. The tokens below are ready for it when those are cleaned up.
 * ═══════════════════════════════════════════════════════════════════════════ */

:root {
    /* ── Brand ─────────────────────────────────────────────────────────
       Their green, unchanged - it is the company's identity. What changed
       is everything around it. */
    /* #00A86B is the identity and stays the identity - it is what is on the
       letterhead. But WHITE TEXT ON IT contrasts only 3.08:1, well under the
       4.5:1 a label needs, which is why the old primary buttons read as soft.
       So the pure brand green is used for accents, bars, rails and icons, and
       anything carrying white text uses --brand-600 (4.55:1) or darker. */
    --brand:        #00A86B;
    --brand-600:    #00875A;
    --brand-700:    #007A50;
    --brand-050:    #E7F7F0;
    --brand-100:    #CFEFE1;
    /* The brand green as a TEXT colour. Order numbers and work order numbers
       are set in it all over the app, and #00A86B at 13px is 3.08:1 - which
       is why they look faint. This is the same hue, dark enough to read. */
    --brand-text:   #00714A;

    /* ── Neutrals ──────────────────────────────────────────────────────
       The old greys were tinted green (#e0ede8 borders, #7a9e90 muted text),
       which made every surface look faintly dirty and every label look faded.
       These carry the barest hint of the brand hue and read as grey. */
    --ink:          #0F1714;   /* 18.2:1 on white */
    --ink-2:        #46554F;   /*  7.9:1 */
    --ink-3:        #5F7068;   /*  5.2:1 white, 4.7:1 on the canvas - and the
                                  canvas is the case that matters, because
                                  muted text sits directly on it between cards.
                                  The first draft was #71827B at 4.05:1. */
    --ink-4:        #84958D;   /*  3.2:1 - placeholders and disabled only */
    --line:         #DFE5E2;
    --line-2:       #C6D1CC;

    /* Surfaces. The page is NOT white: a white card on a white page has no
       edge, which is most of why the old screens looked flat. */
    --canvas:       #F1F4F3;
    --surface:      #FFFFFF;
    --sunk:         #F6F8F7;
    --raised:       #FFFFFF;

    /* ── Sidebar ───────────────────────────────────────────────────────── */
    --nav-bg:       #0B1815;
    --nav-bg-2:     #112420;
    --nav-line:     rgba(255,255,255,.08);
    --nav-ink:      rgba(255,255,255,.76);
    --nav-ink-dim:  rgba(255,255,255,.46);
    --nav-active:   rgba(0,168,107,.20);
    --nav-hover:    rgba(255,255,255,.06);

    /* ── Semantic ──────────────────────────────────────────────────────
       Separate from the brand accent, so "good" never has to fight "ours". */
    /* Every one of these is a text colour somewhere, on white AND on its own
       tint, so both were measured. The first draft had ok at 4.36 and warn at
       4.24 on white, and 3.93 / 3.88 inside their badges - all four failing. */
    --ok:           #07724D;   /* 5.96 on white, 5.38 in its badge */
    --ok-bg:        #E7F7F0;
    --warn:         #8A5200;   /* 6.39 / 5.85 */
    --warn-bg:      #FDF4E3;
    --bad:          #B33125;   /* 6.21 / 5.49 */
    --bad-bg:       #FCEEEC;
    --info:         #1A5AB4;   /* 6.63 / 5.84 */
    --info-bg:      #EAF1FC;

    /* ── Shape ─────────────────────────────────────────────────────────── */
    --r-lg: 14px;
    --r:    10px;
    --r-sm: 7px;
    --r-xs: 5px;

    /* Shadows are for lift, not decoration: one hairline and one soft spread,
       tinted with the ink rather than pure black so they sit on the canvas. */
    --sh-1: 0 1px 2px rgba(15,23,20,.05);
    --sh-2: 0 1px 2px rgba(15,23,20,.05), 0 6px 16px -10px rgba(15,23,20,.28);
    --sh-3: 0 2px 4px rgba(15,23,20,.06), 0 16px 40px -20px rgba(15,23,20,.40);

    /* ── Metrics ───────────────────────────────────────────────────────── */
    --nav-w:    252px;
    --topbar-h: 62px;

    --font: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI',
            Roboto, system-ui, sans-serif;
    --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas,
            monospace;
}

/* ═══ Reset ═══════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
    font-family: var(--font);
    /* 15px, not 14. The old base forced every secondary label down to 10-11px
       to keep a hierarchy, and that is where legibility was lost. */
    font-size: 15px;
    line-height: 1.55;
    color: var(--ink);
    background: var(--canvas);
    min-height: 100vh;
    overflow-x: hidden;
    /* NO -webkit-font-smoothing here. See the note at the top of this file:
       on Windows it disables ClearType and is the single biggest cause of the
       soft, low-resolution look. */
    text-rendering: optimizeLegibility;
    font-feature-settings: 'kern' 1;
}

img, svg, video, canvas { display: block; max-width: 100%; }
img { image-rendering: auto; }
input, select, textarea, button { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; }
a { color: inherit; text-decoration: none; }
table { border-collapse: collapse; width: 100%; }
h1, h2, h3, h4, h5 { font-weight: 650; line-height: 1.25; text-wrap: balance; }
code, kbd, .mono, .code { font-family: var(--mono); font-size: .92em; }

/* Anything that reads as an identifier - order numbers, work orders, part
   numbers - is set in the mono face so it can be compared character by
   character without being read as a word. */
.wo-num, .ct-wo-num, .num-id { font-family: var(--mono); letter-spacing: .01em; }

/* Every column of figures lines up. This app is mostly columns of figures. */
.num, .val, td.num, th.num, .text-right, .stat-value, .ct-kpi-value,
.tbl td.num, .ct-tbl td.num {
    font-variant-numeric: tabular-nums;
}

::selection { background: var(--brand-100); color: var(--ink); }

:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: var(--r-xs);
}

/* ═══ Scrollbars ══════════════════════════════════════════════════════════ */

* { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
    background: var(--line-2); border-radius: 6px;
    border: 2px solid transparent; background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--ink-4); background-clip: content-box; }
.scroll-y { overflow-y: auto; }

/* ═══ Shell ═══════════════════════════════════════════════════════════════ */

#app { display: flex; min-height: 100vh; }

#main {
    flex: 1;
    min-width: 0;                 /* lets wide tables scroll instead of pushing */
    display: flex;
    flex-direction: column;
    background: var(--canvas);
}

.content, #content {
    flex: 1;
    padding: 22px 26px 64px;
    min-width: 0;
}

/* ═══ Sidebar ═════════════════════════════════════════════════════════════ */

.sidebar {
    width: var(--nav-w);
    flex: 0 0 var(--nav-w);
    background: linear-gradient(180deg, var(--nav-bg-2) 0%, var(--nav-bg) 240px);
    color: var(--nav-ink);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    border-right: 1px solid rgba(0,0,0,.4);
    z-index: 60;
}

.sidebar-brand {
    padding: 18px 18px 14px;
    border-bottom: 1px solid var(--nav-line);
}
.sidebar-brand img { width: 172px; height: auto; }

.brand-icon {
    width: 38px; height: 38px; border-radius: var(--r-sm);
    background: var(--brand); color: #fff;
    display: grid; place-items: center;
    font-weight: 750; font-size: 14px; letter-spacing: .02em;
}
.brand-title { font-size: 13px; font-weight: 700; color: #fff; letter-spacing: .03em; }
.brand-sub   { font-size: 11px; color: var(--nav-ink-dim); }

.sidebar-user {
    display: flex; align-items: center; gap: 11px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--nav-line);
}
.user-avatar {
    width: 38px; height: 38px; flex: 0 0 38px; border-radius: 50%;
    display: grid; place-items: center;
    color: #fff; font-weight: 700; font-size: 13px; letter-spacing: .02em;
}
.user-name { font-size: 13px; font-weight: 650; color: #fff; }
.user-role { font-size: 11px; color: var(--nav-ink-dim); letter-spacing: .04em;
             text-transform: uppercase; }

#sidebar-nav {
    flex: 1; overflow-y: auto; padding: 10px 10px 20px;
    overscroll-behavior: contain;
}

.nav-btn {
    width: 100%;
    display: flex; align-items: center; gap: 11px;
    /* 42px tall. The old rows were 32 and impossible to hit on a tablet with
       gloves on, which is how half the shop uses this. */
    min-height: 42px;
    padding: 9px 12px;
    border-radius: var(--r-sm);
    color: var(--nav-ink);
    font-size: 14px; font-weight: 500;
    text-align: left;
    transition: background .12s, color .12s;
}
.nav-btn:hover { background: var(--nav-hover); color: #fff; }
.nav-btn.active {
    background: var(--nav-active); color: #fff; font-weight: 650;
    box-shadow: inset 2px 0 0 var(--brand);
}
.nav-icon  { font-size: 16px; line-height: 1; flex: 0 0 auto; }
.nav-label { flex: 1; min-width: 0; }
.nav-arrow { font-size: 11px; color: var(--nav-ink-dim); transition: transform .18s; }
.nav-arrow.open { transform: rotate(90deg); }
.nav-count {
    font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 99px;
    background: var(--brand-600); color: #fff; font-variant-numeric: tabular-nums;
}

.nav-sub { padding: 3px 0 8px 12px; margin-left: 11px;
           border-left: 1px solid var(--nav-line); }
.nav-group {
    font-size: 11px; font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; color: var(--nav-ink-dim);
    padding: 12px 12px 5px;
}
.nav-sub-btn {
    width: 100%; display: block; min-height: 36px;
    padding: 8px 12px; border-radius: var(--r-sm);
    color: var(--nav-ink); font-size: 13px; text-align: left;
    transition: background .12s, color .12s;
}
.nav-sub-btn:hover  { background: var(--nav-hover); color: #fff; }
.nav-sub-btn.active { background: var(--nav-active); color: #fff; font-weight: 650; }

.sidebar-footer {
    padding: 12px 18px; border-top: 1px solid var(--nav-line);
}
.version-badge {
    font-size: 11px; color: var(--nav-ink-dim); font-family: var(--mono);
    letter-spacing: .04em;
}

/* ═══ Topbar ══════════════════════════════════════════════════════════════ */

#topbar {
    position: sticky; top: 0; z-index: 50;
    min-height: var(--topbar-h);
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; padding: 10px 26px;
    background: rgba(255,255,255,.86);
    backdrop-filter: saturate(1.6) blur(10px);
    -webkit-backdrop-filter: saturate(1.6) blur(10px);
    border-bottom: 1px solid var(--line);
}
.topbar-left  { display: flex; align-items: center; gap: 12px; min-width: 0; }
.topbar-right { display: flex; align-items: center; gap: 9px; flex-shrink: 0; }

#page-title { font-size: 19px; font-weight: 680; letter-spacing: -.01em; }
.breadcrumb {
    font-size: 12px; color: var(--ink-3); margin-top: 1px;
    letter-spacing: .01em;
}

.btn-icon {
    width: 40px; height: 40px; border-radius: var(--r-sm);
    display: grid; place-items: center;
    font-size: 18px; color: var(--ink-2);
    transition: background .12s, color .12s;
}
.btn-icon:hover { background: var(--sunk); color: var(--ink); }

#toggle-sidebar { display: none; }

#mobile-backdrop {
    display: none; position: fixed; inset: 0;
    background: rgba(11,24,21,.45); z-index: 55;
    backdrop-filter: blur(2px);
}

/* ═══ Buttons ═════════════════════════════════════════════════════════════ */

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    /* 40px is the smallest a finger reliably hits. The old 28px buttons are
       why the tablet on the floor needs three taps. */
    min-height: 40px;
    padding: 9px 17px;
    border: 1px solid var(--line-2);
    border-radius: var(--r-sm);
    background: var(--surface);
    color: var(--ink);
    font-size: 14px; font-weight: 600;
    white-space: nowrap;
    box-shadow: var(--sh-1);
    transition: background .12s, border-color .12s, color .12s, box-shadow .12s;
}
.btn:hover { border-color: var(--ink-4); box-shadow: var(--sh-2); }
.btn:active { transform: translateY(.5px); }
.btn:disabled, .btn[disabled] {
    opacity: .5; cursor: not-allowed; box-shadow: none; transform: none;
}
.btn-icon-left { font-size: 15px; line-height: 1; }

.btn-primary, .btn-p {
    background: var(--brand-600); border-color: var(--brand-600); color: #fff;
}
.btn-primary:hover, .btn-p:hover { background: var(--brand-700); border-color: var(--brand-700); }

.btn-success, .btn-green { background: var(--ok);   border-color: var(--ok);   color: #fff; }
.btn-danger,  .btn-d     { background: var(--bad);  border-color: var(--bad);  color: #fff; }
.btn-warning             { background: var(--warn); border-color: var(--warn); color: #fff; }
.btn-info,    .btn-b     { background: var(--info); border-color: var(--info); color: #fff; }
.btn-teal                { background: var(--brand-700); border-color: var(--brand-700); color: #fff; }
.btn-dark                { background: var(--ink); border-color: var(--ink); color: #fff; }
.btn-success:hover, .btn-green:hover, .btn-danger:hover, .btn-d:hover,
.btn-warning:hover, .btn-info:hover, .btn-b:hover, .btn-teal:hover,
.btn-dark:hover { filter: brightness(1.08); }

.btn-ghost, .btn-o, .btn-secondary {
    background: transparent; border-color: var(--line-2); color: var(--ink-2);
    box-shadow: none;
}
.btn-ghost:hover, .btn-o:hover, .btn-secondary:hover {
    background: var(--sunk); color: var(--ink); border-color: var(--ink-4);
}

.btn-lg { min-height: 46px; padding: 12px 24px; font-size: 15px; }
.btn-sm, .btn-s { min-height: 34px; padding: 6px 13px; font-size: 13px; }
.btn-xs { min-height: 30px; padding: 4px 10px; font-size: 12px; border-radius: var(--r-xs); }

.btn-icon-sm {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 30px; padding: 4px 9px;
    border: 1px solid var(--line); border-radius: var(--r-xs);
    background: var(--surface); color: var(--ink-2);
    font-size: 12px; font-weight: 600;
}
.btn-icon-sm:hover { border-color: var(--ink-4); color: var(--ink); }
.btn-icon-sm.danger { color: var(--bad); border-color: var(--bad-bg); }
.btn-icon-sm.danger:hover { background: var(--bad-bg); border-color: var(--bad); }

.btn-group { display: inline-flex; gap: 0; }
.btn-group .btn { border-radius: 0; margin-left: -1px; box-shadow: none; }
.btn-group .btn:first-child { border-radius: var(--r-sm) 0 0 var(--r-sm); margin-left: 0; }
.btn-group .btn:last-child  { border-radius: 0 var(--r-sm) var(--r-sm) 0; }

.row-btn { display: inline-flex; gap: 5px; flex-wrap: wrap; }
.page-actions, .export-btns, .ct-actions, .ct-form-actions, .ct-period-btns,
.filter-row, .toggle-group, .tog-grp, .route-tabs, .sched-filter {
    display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
}

.opt-btn, .ct-pbtn, .rtab {
    min-height: 34px; padding: 6px 14px;
    border: 1px solid var(--line-2); border-radius: 99px;
    background: var(--surface); color: var(--ink-2);
    font-size: 13px; font-weight: 600;
}
.opt-btn:hover, .ct-pbtn:hover, .rtab:hover { border-color: var(--brand); color: var(--brand); }
.opt-btn.active, .ct-pbtn.active, .rtab.active {
    background: var(--brand-600); border-color: var(--brand-600); color: #fff;
}

/* ═══ Page heading ════════════════════════════════════════════════════════ */

.page-heading, .ct-page-title {
    font-size: 21px; font-weight: 680; letter-spacing: -.012em;
    margin: 0 0 16px;
    display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
}
.section-title, .ct-section-title, .card-title, .ct-form-title,
.pcb-section-title, .ct-alerts-title {
    font-size: 14px; font-weight: 680; color: var(--ink);
    letter-spacing: -.005em;
}
.ct-section-title, .section-title { margin: 0 0 11px; }
.ct-section { margin-bottom: 24px; }

/* ═══ Cards ═══════════════════════════════════════════════════════════════ */

.card, .ct-form-card, .ct-alerts-panel, .sched-card, .pcb-section,
.loading-box, .cfg-item, .ct-info-box {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-1);
}
.card { padding: 18px 20px; }
.ct-form-card, .ct-alerts-panel, .sched-card, .cfg-item { padding: 16px 18px; }

.card-header {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    padding: 15px 20px; border-bottom: 1px solid var(--line);
}
.card-body   { padding: 18px 20px; }
.card-footer {
    padding: 13px 20px; border-top: 1px solid var(--line);
    background: var(--sunk);
    border-radius: 0 0 var(--r-lg) var(--r-lg);
}
/* A card built from header/body/footer has already paid for its padding. */
.card:has(> .card-header), .card:has(> .card-body) { padding: 0; }

/* ═══ Stat tiles ══════════════════════════════════════════════════════════ */

.stat-grid, .ct-kpi-grid {
    display: grid; gap: 13px;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    margin-bottom: 20px;
}
.ct-kpi-grid-4 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

.stat-card, .ct-kpi-card {
    position: relative; overflow: hidden;
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 3px solid var(--ink-4);
    border-radius: var(--r);
    padding: 15px 17px;
    box-shadow: var(--sh-1);
}
.stat-icon, .ct-kpi-icon { font-size: 18px; line-height: 1; margin-bottom: 8px; }
.stat-label, .ct-kpi-label {
    /* 11px is the floor. Below that, uppercase letter-spaced text stops being
       readable and starts being texture. */
    font-size: 11px; font-weight: 700; letter-spacing: .07em;
    text-transform: uppercase; color: var(--ink-3);
}
.stat-value, .ct-kpi-value {
    font-size: 27px; font-weight: 720; line-height: 1.08;
    letter-spacing: -.02em; margin-top: 5px;
}
.ct-kpi-sub, .cfg-hint, .ct-small, .hint, .list-meta, .sched-sub, .hist-sub,
.ct-refresh-note, .pcb-inp-hint, .ss-item-sub {
    font-size: 12px; color: var(--ink-3); line-height: 1.5;
}

.ct-kpi-green  { border-left-color: var(--ok); }
.ct-kpi-green  .ct-kpi-value { color: var(--ok); }
.ct-kpi-red, .ct-kpi-alert { border-left-color: var(--bad); }
.ct-kpi-red    .ct-kpi-value, .ct-kpi-alert .ct-kpi-value { color: var(--bad); }
.ct-kpi-yellow { border-left-color: var(--warn); }
.ct-kpi-yellow .ct-kpi-value { color: var(--warn); }
.ct-kpi-blue   { border-left-color: var(--info); }
.ct-kpi-blue   .ct-kpi-value { color: var(--info); }

.ct-val-ok     { color: var(--ok);   font-weight: 650; }
.ct-val-warn   { color: var(--warn); font-weight: 650; }
.ct-val-danger { color: var(--bad);  font-weight: 650; }

/* ═══ Tables ══════════════════════════════════════════════════════════════ */

.table-wrap, .ct-table-wrap, .tbl-wrap {
    overflow-x: auto;
    border-radius: var(--r-lg);
    /* The fade tells you there is more to the right before you find out by
       scrolling. On a laptop with a trackpad that is not obvious otherwise. */
    background:
        linear-gradient(90deg, var(--surface) 30%, rgba(255,255,255,0)) left / 32px 100% no-repeat,
        linear-gradient(90deg, rgba(255,255,255,0), var(--surface) 70%) right / 32px 100% no-repeat,
        linear-gradient(90deg, rgba(15,23,20,.09), rgba(255,255,255,0)) left / 10px 100% no-repeat,
        linear-gradient(90deg, rgba(255,255,255,0), rgba(15,23,20,.09)) right / 10px 100% no-repeat,
        var(--surface);
    background-attachment: local, local, scroll, scroll, local;
}

.tbl, .ct-tbl, .sched-tbl, .process-rpt-table, .print-table {
    width: 100%;
    font-size: 13px;
    border-collapse: separate;
    border-spacing: 0;
}

.tbl thead th, .ct-tbl thead th, .sched-tbl thead th, .process-rpt-table thead th {
    position: sticky; top: 0; z-index: 2;
    background: var(--sunk);
    text-align: left;
    padding: 11px 14px;
    font-size: 11px; font-weight: 700; letter-spacing: .07em;
    text-transform: uppercase; color: var(--ink-3);
    border-bottom: 1px solid var(--line-2);
    white-space: nowrap;
}
.tbl tbody td, .ct-tbl tbody td, .sched-tbl tbody td, .process-rpt-table tbody td {
    padding: 11px 14px;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}
.tbl tbody tr:last-child td, .ct-tbl tbody tr:last-child td { border-bottom: 0; }
.tbl tbody tr, .ct-tbl tbody tr { transition: background .1s; }
.tbl tbody tr:hover, .ct-tbl tbody tr:hover { background: var(--sunk); }

.tbl td.num, .ct-tbl td.num, .tbl th.num, .ct-tbl th.num,
.text-right { text-align: right; }
.nowrap { white-space: nowrap; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 0; }

.th-sort { cursor: pointer; user-select: none; }
.th-sort:hover { color: var(--brand); }

.ct-row-warn      { background: var(--warn-bg); }
.ct-row-danger    { background: var(--bad-bg); }
.ct-row-highlight { background: var(--brand-050); }
.row-late, .row-adjusted { box-shadow: inset 3px 0 0 var(--bad); }
.row-done      { box-shadow: inset 3px 0 0 var(--ok); }
.row-progress  { box-shadow: inset 3px 0 0 var(--info); }
.row-coupled, .row-cnc, .row-hal, .row-outsrc { box-shadow: inset 3px 0 0 var(--ink-4); }

.table-toolbar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap; margin-bottom: 13px;
}

/* ═══ Forms ═══════════════════════════════════════════════════════════════ */

/* .pcb-field-row is NOT here: those stack a label above its field, and this
   one puts a 130px label BESIDE it. Inheriting flex-direction:column from
   this rule is what collapsed every input on the two PCB forms to its
   natural width. */
.form-group, .ct-field, .field, .fld, .cfg-item {
    display: flex; flex-direction: column; gap: 5px;
}
.form-label, .ct-field label, .lbl, .pcb-label, .form-group > label,
.cap-input + label {
    font-size: 12px; font-weight: 650; color: var(--ink-2);
    letter-spacing: .01em;
}

.form-input, .cap-input, .cap-select, .pcb-inp, .search-select-input,
input[type=text], input[type=number], input[type=date], input[type=email],
input[type=password], input[type=tel], input[type=search], select, textarea {
    width: 100%;
    min-height: 40px;
    padding: 9px 12px;
    background: var(--surface);
    border: 1px solid var(--line-2);
    border-radius: var(--r-sm);
    font-size: 14px;
    color: var(--ink);
    transition: border-color .12s, box-shadow .12s;
}
textarea { min-height: 84px; padding: 10px 12px; resize: vertical; }

.form-input:hover, .cap-input:hover, .pcb-inp:hover, select:hover { border-color: var(--ink-4); }
.form-input:focus, .cap-input:focus, .cap-select:focus, .pcb-inp:focus,
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-050);
}
input:disabled, select:disabled, textarea:disabled {
    background: var(--sunk); color: var(--ink-3); cursor: not-allowed;
}
input::placeholder, textarea::placeholder { color: var(--ink-4); }

select, .cap-select {
    appearance: none; -webkit-appearance: none;
    padding-right: 34px;
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'%3E%3Cpath d='M1 1l4.5 4.5L10 1' fill='none' stroke='%2371827B' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
}

input[type=checkbox], input[type=radio] {
    width: 17px; height: 17px; min-height: 0;
    accent-color: var(--brand); cursor: pointer;
}
/* .pcb-tog is deliberately NOT here: it is a segmented-control button, not a
   row of checkboxes, and giving it display:flex with an 8px gap is what broke
   the joined toggle strip into loose separate buttons. It is styled in full
   in the PCB form section below. */
.checkbox-row, .pcb-toggles {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.checkbox-row label {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 13px; cursor: pointer; min-height: 34px;
}

.form-row, .form-grid, .form-grid-2, .grid-2, .grid2,
.detail-grid, .cfg-grid, .process-grid, .ct-form-grid {
    display: grid; gap: 14px;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.form-grid-3, .grid-3 { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.form-full, .full, .ct-field-full, .w-full { grid-column: 1 / -1; }
.form-section { margin-bottom: 22px; }
.ct-form-sub { font-size: 12px; color: var(--ink-3); margin: -4px 0 12px; }

.search-box, .search-select-wrap { position: relative; }
.search-select-list {
    position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 4px);
    max-height: 260px; overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--line-2); border-radius: var(--r);
    box-shadow: var(--sh-3);
}
.search-select-item, .ss-item-name {
    padding: 9px 12px; font-size: 13px; cursor: pointer;
    border-bottom: 1px solid var(--line);
}
.search-select-item:last-child { border-bottom: 0; }
.search-select-item:hover { background: var(--brand-050); }

/* ═══ Badges, pills, chips ════════════════════════════════════════════════ */

.badge, .pill, .chip, .ct-badge, .badge-sched, .ct-status-badge,
.ct-pri-badge, .ct-bottleneck-badge, .badge-pill, .process-chip, .ct-proc-chip {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 10px;
    border-radius: 99px;
    font-size: 12px; font-weight: 700; letter-spacing: .02em;
    white-space: nowrap;
    background: var(--sunk); color: var(--ink-2);
    border: 1px solid var(--line);
}
.badge-ok, .badge-completed, .badge-approved, .badge-dispatched,
.ct-status-ok, .badge-on {
    background: var(--ok-bg); color: var(--ok); border-color: transparent;
}
.badge-pending, .badge-sched, .ct-status-risk, .ct-pri-medium {
    background: var(--warn-bg); color: var(--warn); border-color: transparent;
}
.badge-late, .badge-cancelled, .badge-urgent, .ct-status-delayed,
.ct-pri-urgent, .ct-bottleneck-badge {
    background: var(--bad-bg); color: var(--bad); border-color: transparent;
}
.badge-in, .ct-pri-high { background: var(--info-bg); color: var(--info); border-color: transparent; }
.ct-pri-low { background: var(--sunk); color: var(--ink-3); }

.priority-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }

.ct-rank {
    display: inline-grid; place-items: center;
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--sunk); color: var(--ink-2);
    font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}

/* ═══ Alerts ══════════════════════════════════════════════════════════════ */

.alert, .alert-error, .ct-alert, .gen-warning, .ct-info-box {
    padding: 12px 15px;
    border: 1px solid var(--line);
    border-left: 3px solid var(--ink-4);
    border-radius: var(--r);
    font-size: 13px; line-height: 1.55;
    background: var(--sunk);
}
.alert-error, .ct-alert-danger {
    background: var(--bad-bg); border-color: transparent;
    border-left-color: var(--bad); color: var(--bad);
}
.ct-alert-warning, .gen-warning {
    background: var(--warn-bg); border-color: transparent;
    border-left-color: var(--warn); color: var(--warn);
}
.ct-alert-info, .ct-info-box {
    background: var(--info-bg); border-color: transparent;
    border-left-color: var(--info); color: var(--info);
}
.alert-row { display: flex; align-items: flex-start; gap: 10px; }

/* ═══ Progress ════════════════════════════════════════════════════════════ */

.progress-bar, .ct-prog-bar, .ct-bar-track, .prog-bar-wrap, .prog-bar-slim,
.ct-prog-wrap {
    height: 8px; border-radius: 99px;
    background: var(--line); overflow: hidden;
}
.prog-bar-slim { height: 5px; }
.progress-fill, .ct-prog-fill, .ct-bar-fill, .prog-bar-slim-fill {
    height: 100%; border-radius: 99px;
    background: var(--brand);
    transition: width .35s cubic-bezier(.4,0,.2,1);
}
.ct-prog-txt, .ct-bar-val {
    font-size: 12px; font-weight: 650; color: var(--ink-2);
    font-variant-numeric: tabular-nums;
}
.ct-bar-row { display: flex; align-items: center; gap: 11px; margin-bottom: 9px; }
.ct-bar-label { flex: 0 0 auto; font-size: 13px; min-width: 128px; }
.ct-bar-track { flex: 1; }

/* ═══ Lists ═══════════════════════════════════════════════════════════════ */

.list-row, .detail-item, .tmrw-item, .cfg-item, .timeline-item {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 0; border-bottom: 1px solid var(--line);
}
.list-row:last-child, .detail-item:last-child { border-bottom: 0; }
.list-title, .tmrw-name, .step-name, .ct-staff-name, .timeline-name {
    font-size: 13px; font-weight: 650;
}
.list-sub, .list-info { font-size: 12px; color: var(--ink-3); }

.timeline { position: relative; padding-left: 22px; }
.timeline::before {
    content: ''; position: absolute; left: 5px; top: 6px; bottom: 6px;
    width: 1px; background: var(--line-2);
}
.timeline-item { position: relative; border-bottom: 0; padding: 9px 0; }
.timeline-dot {
    position: absolute; left: -21px; top: 15px;
    width: 11px; height: 11px; border-radius: 50%;
    background: var(--brand); border: 2px solid var(--surface);
    box-shadow: 0 0 0 1px var(--line-2);
}
.timeline-meta { font-size: 12px; color: var(--ink-3); }

/* ═══ Modal ═══════════════════════════════════════════════════════════════ */

.modal-overlay {
    position: fixed; inset: 0; z-index: 200;
    background: rgba(11,24,21,.5);
    backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
    display: flex; align-items: flex-start; justify-content: center;
    padding: 5vh 18px 18px;
    overflow-y: auto;
}
.modal-card {
    width: 100%; max-width: 620px;
    background: var(--surface);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-3);
    overflow: hidden;
    animation: modal-in .18s cubic-bezier(.2,.7,.3,1);
}
.modal-wide { max-width: 1040px; }
@keyframes modal-in { from { opacity: 0; transform: translateY(-8px) scale(.99); } }
@media (prefers-reduced-motion: reduce) {
    .modal-card { animation: none; }
    * { transition-duration: .01ms !important; }
}
.modal-header {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; padding: 16px 20px;
    border-bottom: 1px solid var(--line);
    font-size: 16px; font-weight: 680;
}
.modal-body   { padding: 20px; max-height: 74vh; overflow-y: auto; }
.modal-footer {
    display: flex; justify-content: flex-end; gap: 9px;
    padding: 14px 20px; border-top: 1px solid var(--line);
    background: var(--sunk);
}
.modal-close {
    width: 34px; height: 34px; border-radius: var(--r-sm);
    display: grid; place-items: center;
    font-size: 20px; line-height: 1; color: var(--ink-3);
}
.modal-close:hover { background: var(--bad-bg); color: var(--bad); }

/* ═══ Toast ═══════════════════════════════════════════════════════════════ */

#toast-container {
    position: fixed; right: 18px; bottom: 18px; z-index: 300;
    display: flex; flex-direction: column; gap: 9px;
    max-width: min(400px, calc(100vw - 36px));
}
.toast {
    padding: 12px 16px;
    background: var(--ink); color: #fff;
    border-radius: var(--r);
    box-shadow: var(--sh-3);
    font-size: 13px; line-height: 1.5;
    animation: toast-in .2s cubic-bezier(.2,.7,.3,1);
    white-space: pre-line;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(10px); } }
.toast-success { background: var(--ok); }
.toast-error   { background: var(--bad); }
.toast-info    { background: var(--info); }

/* ═══ Empty & loading ═════════════════════════════════════════════════════ */

.empty, .empty-state, .ct-empty {
    padding: 44px 22px; text-align: center;
    color: var(--ink-3); font-size: 13px;
}
.empty-state .icon, .ct-empty .icon { font-size: 30px; display: block; margin-bottom: 9px; opacity: .5; }

.loading, .loading-box {
    padding: 40px 22px; text-align: center;
    color: var(--ink-3); font-size: 13px;
}
.spinner {
    width: 26px; height: 26px; margin: 0 auto 11px;
    border: 2.5px solid var(--line-2); border-top-color: var(--brand);
    border-radius: 50%;
    animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ═══ Kanban / Gantt ══════════════════════════════════════════════════════ */

.kanban-board {
    display: grid; gap: 13px;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.kanban-col {
    background: var(--sunk); border: 1px solid var(--line);
    border-radius: var(--r); padding: 12px;
    min-height: 130px;
}

.gantt-container { overflow-x: auto; padding-bottom: 8px; }
.gantt-row  { display: flex; align-items: center; gap: 10px; min-height: 32px; }
.gantt-label { flex: 0 0 150px; font-size: 12px; color: var(--ink-2);
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gantt-bars { flex: 1; position: relative; height: 22px;
              background: var(--sunk); border-radius: var(--r-xs); }
.gantt-bar  { position: absolute; height: 100%; border-radius: var(--r-xs);
              background: var(--brand); display: flex; align-items: center; }
.gantt-bar-txt { font-size: 11px; color: #fff; font-weight: 650; padding: 0 7px;
                 overflow: hidden; white-space: nowrap; }
.gantt-axis { display: flex; border-top: 1px solid var(--line); margin-top: 6px; }
.gantt-tick { flex: 1; font-size: 11px; color: var(--ink-3); text-align: center; padding-top: 4px; }
.gantt-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 11px; }
.gantt-leg-item { display: inline-flex; align-items: center; gap: 6px;
                  font-size: 12px; color: var(--ink-2); }
.gantt-leg-dot { width: 10px; height: 10px; border-radius: 3px; }

/* ═══ Scheduler / tomorrow board ══════════════════════════════════════════ */

.sched-card { margin-bottom: 13px; }
.tmrw-group  { margin-bottom: 18px; }
.tmrw-header, .tmrw-proc-header {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    padding: 10px 14px; background: var(--sunk);
    border: 1px solid var(--line); border-radius: var(--r) var(--r) 0 0;
    font-size: 13px; font-weight: 680;
}
.tmrw-items { border: 1px solid var(--line); border-top: 0;
              border-radius: 0 0 var(--r) var(--r); }
.tmrw-item  { padding: 10px 14px; }
.tmrw-count { font-variant-numeric: tabular-nums; color: var(--ink-3); font-size: 12px; }
.tmrw-hrs, .tmrw-time { font-family: var(--mono); font-size: 12px; color: var(--ink-2); }
.tmrw-wo   { font-family: var(--mono); font-weight: 650; font-size: 13px; }
.tmrw-proc, .tmrw-staff { font-size: 12px; color: var(--ink-2); }

/* ═══ Route flow ══════════════════════════════════════════════════════════ */

.route-flow { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.route-step {
    padding: 8px 13px; border: 1px solid var(--line-2);
    border-radius: var(--r-sm); background: var(--surface);
    font-size: 13px; font-weight: 600;
}
.route-coupled { border-color: var(--info); color: var(--info); background: var(--info-bg); }
.route-outsrc  { border-color: var(--warn); color: var(--warn); background: var(--warn-bg); }
.route-add-bar { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 13px; }
.step-num {
    display: inline-grid; place-items: center;
    width: 20px; height: 20px; border-radius: 50%;
    background: var(--sunk); color: var(--ink-3);
    font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}

/* ═══ PCB product form ════════════════════════════════════════════════════
 *
 * The Create Work Order and Add Product forms. Restored from the build these
 * were designed in - the geometry is the original: 130px labels, 38px inputs,
 * 80px short fields, 200px medium, a JOINED toggle strip with a visible
 * selected state, and a 320px summary that stays with you as you scroll.
 *
 * Deliberately NOT scoped under .pcb-layout: the Edit Work Order panel uses
 * the same .pcb-inp and .pcb-tog components without that wrapper, and scoping
 * would have left its priority toggle with no visible selected state.
 *
 * .pcb-inp.med is two classes and so beats the bare .med helper further down
 * on its own; the base rule names the element (input.pcb-inp) so it can beat
 * input[type=number], which otherwise wins the tie and forces width:100%.
 * ══════════════════════════════════════════════════════════════════════════ */

.pcb-layout { display: flex; gap: 24px; align-items: flex-start; }
.pcb-left  { flex: 1; min-width: 0; }
.pcb-right { width: 320px; flex-shrink: 0;
                         position: sticky; top: calc(var(--topbar-h) + 14px); }

/* ── Sections ─────────────────────────────────────────────────────────── */
.pcb-section {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r); margin-bottom: 18px; overflow: hidden;
}
.pcb-section-title {
    font-size: 14px; font-weight: 700; color: var(--ink);
    padding: 14px 20px 10px; background: transparent;
    border-bottom: 2px solid var(--brand-600); border-radius: 0;
    display: flex; align-items: center; gap: 8px;
}
.pcb-section-title span { font-size: 15px; }
.pcb-section-body { padding: 16px 20px 20px; }

/* ── Field rows ───────────────────────────────────────────────────────── */
.pcb-field-row {
    display: flex; flex-direction: row; align-items: center;
    margin-bottom: 14px; gap: 10px;
}
.pcb-field-row:last-child { margin-bottom: 0; }
.pcb-label {
    width: 130px; flex-shrink: 0; margin: 0;
    font-size: 12.5px; font-weight: 600; color: var(--ink-2);
}
.pcb-field-body {
    flex: 1; min-width: 0; display: flex; align-items: center;
    gap: 6px; flex-wrap: wrap;
}

/* ── Inputs ───────────────────────────────────────────────────────────────
 * The three width classes are the whole reason this form reads as a form
 * rather than a stack of identical boxes: a quantity is 80px, a name is the
 * full row. Written with the .pcb-inp prefix so the bare .med / .sm helpers
 * elsewhere in this stylesheet cannot win. */
input.pcb-inp, select.pcb-inp, textarea.pcb-inp, .pcb-inp {
    height: 38px; min-height: 38px; padding: 0 12px;
    border: 1.5px solid var(--line-2); border-radius: var(--r-sm);
    font-size: 13px; font-weight: 600; color: var(--ink);
    background: var(--surface); outline: none;
    transition: border-color .15s, box-shadow .15s;
}
.pcb-inp:focus {
    border-color: var(--brand-600);
    box-shadow: 0 0 0 3px var(--brand-050);
}
input.pcb-inp.sm, select.pcb-inp.sm, .pcb-inp.sm { width: 80px;  max-width: 80px; text-align: center; }
input.pcb-inp.med, select.pcb-inp.med, .pcb-inp.med { width: 200px; max-width: 200px; font-weight: 600; }
input.pcb-inp.full, select.pcb-inp.full, .pcb-inp.full { width: 100%;  max-width: none; }
textarea.pcb-inp { height: auto; min-height: 56px; padding: 8px 12px; }
select.pcb-inp   { padding-right: 28px; cursor: pointer; }
.pcb-inp-x {
    color: var(--ink-4); font-size: 14px; font-weight: 700;
    margin: 0 2px; max-width: none; width: auto;
}
.pcb-inp-hint {
    font-size: 11px; color: var(--ink-3); margin-left: 8px; white-space: nowrap;
}

/* ── The toggle strip ─────────────────────────────────────────────────────
 * One joined control, not a row of buttons — and .on is what tells the
 * operator what the order actually is. Losing it was the real breakage. */
.pcb-toggles { display: flex; gap: 0; flex-wrap: wrap; align-items: center; }
.pcb-tog {
    display: inline-flex; align-items: center; justify-content: center;
    height: 34px; min-height: 34px; padding: 0 14px; gap: 0;
    border: 1.5px solid var(--line-2); background: var(--surface);
    color: var(--ink-2); font-family: inherit; font-size: 12px; font-weight: 600;
    cursor: pointer; transition: all .15s; white-space: nowrap; border-radius: 0;
}
.pcb-tog:first-child        { border-radius: var(--r-sm) 0 0 var(--r-sm); }
.pcb-tog:last-child         { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.pcb-tog:not(:first-child)  { margin-left: -1.5px; }
.pcb-tog.on {
    background: var(--brand-600); color: #fff; border-color: var(--brand-600);
    position: relative; z-index: 1;
}
.pcb-tog:hover:not(.on) { background: var(--sunk); border-color: var(--ink-4); }
.pcb-tog:focus-visible  { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ── Summary card ─────────────────────────────────────────────────────── */
.pcb-summary {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r); overflow: hidden; padding: 0; position: static;
}
.pcb-summary-hd {
    background: linear-gradient(135deg, var(--brand-700), var(--brand));
    color: #fff; padding: 14px 18px; margin: 0;
    font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 8px;
}
.pcb-summary-panel {
    margin: 16px; padding: 14px; text-align: center;
    border: 2px solid var(--brand-600); border-radius: var(--r-sm);
    background: var(--surface); position: static;
}
.pcb-summary-panel-label {
    font-size: 10px; font-weight: 600; color: var(--brand-text);
    text-transform: uppercase; letter-spacing: 1px; margin-bottom: 4px;
}
.pcb-summary-panel-val { font-size: 20px; font-weight: 800; color: var(--ok); }

.pcb-sum-rows { padding: 0 18px 12px; display: block; }
.pcb-sum-r {
    display: flex; justify-content: space-between; gap: 12px;
    padding: 5px 0; border-bottom: 1px solid var(--sunk); font-size: 12px;
}
.pcb-sum-r:last-child { border-bottom: none; }
.pcb-sum-r .lbl { color: var(--ink-3); }
.pcb-sum-r .val { font-weight: 700; color: var(--ink); }

/* ── Summary totals ───────────────────────────────────────────────────────
 * The JS writes these colour names. Every one of them needs a rule or the
 * card renders as plain text on white. */
.pcb-sum-totals { padding: 0 14px 14px; border: 0; margin: 0; }
.pcb-sum-tot {
    display: flex; justify-content: space-between; align-items: center;
    padding: 8px 12px; border-radius: var(--r-sm); margin-bottom: 6px;
    font-size: 12.5px; font-weight: 700;
}
.pcb-sum-tot:last-child { margin-bottom: 0; }
.pcb-sum-tot.orange { background: var(--warn-bg); color: var(--warn); border: 1px solid #F0DCB4; }
.pcb-sum-tot.blue   { background: var(--info-bg); color: var(--info); border: 1px solid #C9DCF7; }
.pcb-sum-tot.green  { background: var(--ok-bg);   color: var(--ok);   border: 1px solid var(--brand-100); }
.pcb-sum-tot.teal   {
    background: linear-gradient(135deg, var(--brand-700), var(--brand));
    color: #fff; font-size: 13px; padding: 10px 12px; border: 0;
}

/* ── Save button ──────────────────────────────────────────────────────── */
.pcb-save-btn {
    width: 100%; margin-top: 14px; padding: 14px;
    font-family: inherit; font-size: 14px; font-weight: 700;
    border: none; border-radius: var(--r);
    background: linear-gradient(135deg, var(--brand-700), var(--brand));
    color: #fff; cursor: pointer; transition: transform .15s, box-shadow .15s;
    box-shadow: 0 4px 12px rgba(0, 135, 90, .3);
}
.pcb-save-btn:hover {
    transform: translateY(-1px); box-shadow: 0 6px 20px rgba(0, 135, 90, .4);
}

/* ── On a phone ───────────────────────────────────────────────────────────
 * The label column and the sticky summary both stop making sense below the
 * width they were drawn for. */
@media (max-width: 1024px) {
    .pcb-layout { flex-direction: column; gap: 16px; }
    .pcb-right { width: 100%; position: static; }
    .pcb-field-row { flex-direction: column; align-items: stretch; gap: 6px; }
    .pcb-label { width: auto; }
    /* Qualified with the element the same way the desktop rules are. A media
       query does not raise specificity: bare .pcb-inp (0,1,0) loses to
       input.pcb-inp (0,1,1) above however far down the file it sits, and the
       16px is what stops iOS zooming the page when a field takes focus. */
    input.pcb-inp, select.pcb-inp, textarea.pcb-inp, .pcb-inp { font-size: 16px; }
    input.pcb-inp.med, select.pcb-inp.med, .pcb-inp.med { width: 100%; max-width: none; }
    input.pcb-inp.sm, .pcb-inp.sm { width: 96px; max-width: 96px; }
    .pcb-tog { height: 40px; min-height: 40px; }
}

/* ═══ Helpers ═════════════════════════════════════════════════════════════ */

.flex         { display: flex; }
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.gap-2 { gap: 8px; } .gap-3 { gap: 12px; }
.center, .text-center { text-align: center; }
.hidden { display: none !important; }
.mt-4 { margin-top: 16px; } .mt-6 { margin-top: 24px; }
.mb-4 { margin-bottom: 16px; } .mb-6 { margin-bottom: 24px; }
.fw-600 { font-weight: 600; } .fw-700 { font-weight: 700; } .fw-800 { font-weight: 780; }
.text-sm { font-size: 13px; } .text-xs { font-size: 12px; }
.text-muted   { color: var(--ink-3); }
.text-primary { color: var(--brand-text); }
.text-danger  { color: var(--bad); }
.med { font-weight: 600; } .sm { font-size: 13px; } .big { font-size: 17px; }
.orange { color: var(--warn); }
.danger { color: var(--bad); }
.sec { color: var(--ink-3); }
.mobile-only { display: none; }

/* ═══ Mobile & tablet ═════════════════════════════════════════════════════
 *
 * The floor uses tablets and phones, so this is not a courtesy. Below 1024px
 * the sidebar becomes a drawer, every control clears 44px, and every table
 * scrolls inside itself rather than pushing the page sideways.
 * ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 1024px) {
    .sidebar {
        position: fixed; top: 0; left: 0; bottom: 0;
        transform: translateX(-100%);
        transition: transform .22s cubic-bezier(.4,0,.2,1);
        box-shadow: var(--sh-3);
        height: 100dvh;
    }
    .sidebar.mobile-open { transform: translateX(0); }
    #mobile-backdrop.mobile-open,
    .sidebar.mobile-open ~ #main #mobile-backdrop { display: block; }
    #toggle-sidebar { display: grid; }
    #topbar  { padding: 9px 14px; }
    /* The title block takes what is left after the buttons, and the crumb
       ellipses rather than wrapping the header to three lines. */
    .topbar-left > div { min-width: 0; }
    #page-title, .breadcrumb {
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .content, #content { padding: 16px 14px 72px; }
    .pcb-layout { grid-template-columns: minmax(0,1fr); }
    .pcb-summary, .pcb-summary-panel { position: static; }
}

@media (max-width: 640px) {
    body { font-size: 15px; }
    #page-title { font-size: 17px; }
    .page-heading, .ct-page-title { font-size: 18px; }
    .card { padding: 15px 15px; }
    .card-header, .card-body { padding: 14px 15px; }

    /* iOS zooms the whole page when a field under 16px takes focus, and never
       zooms back out. Every input is 16px on a phone for that reason alone.

       The attribute selectors have to be repeated here. The base rule targets
       input[type=text] at specificity (0,1,1); a bare .cap-input in a media
       query is only (0,1,0) and loses to it however late it comes - which is
       why the first draft of this block silently did nothing. */
    input, select, textarea,
    input[type=text], input[type=number], input[type=date], input[type=email],
    input[type=password], input[type=tel], input[type=search],
    .form-input, .cap-input, .cap-select, .pcb-inp, .search-select-input {
        font-size: 16px; min-height: 44px;
    }
    input[type=checkbox], input[type=radio] { min-height: 0; width: 20px; height: 20px; }

    /* Everything tappable clears 38px. The row actions - Edit, Owner, Delete -
       were 30px, which is the whole "needs three taps" complaint. */
    .btn { min-height: 44px; padding: 11px 18px; }
    .btn-sm, .btn-s { min-height: 40px; }
    .btn-xs, .btn-icon-sm { min-height: 38px; padding: 8px 13px; font-size: 13px; }
    .opt-btn, .ct-pbtn, .rtab { min-height: 40px; padding: 9px 16px; }
    .nav-sub-btn { min-height: 42px; }
    .nav-btn { min-height: 46px; }
    .modal-close, .btn-icon { width: 44px; height: 44px; }

    .stat-grid, .ct-kpi-grid { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 10px; }
    .stat-value, .ct-kpi-value { font-size: 23px; }

    .form-row, .form-grid, .form-grid-2, .form-grid-3,
    .grid-2, .grid2, .grid-3, .ct-form-grid { grid-template-columns: minmax(0,1fr); }
    .pcb-field-row { grid-template-columns: minmax(0,1fr); gap: 5px; }

    .tbl, .ct-tbl { font-size: 13px; }
    .tbl thead th, .ct-tbl thead th { padding: 9px 11px; }
    .tbl tbody td, .ct-tbl tbody td { padding: 11px; }

    /* A ten-column table on a 375px screen has to scroll sideways, and the
       moment it does you lose sight of WHICH ROW you are reading. The first
       column stays put, so the order number is always on screen. */
    .tbl  tbody td:first-child, .tbl  thead th:first-child,
    .ct-tbl tbody td:first-child, .ct-tbl thead th:first-child {
        position: sticky; left: 0; z-index: 1;
        background: var(--surface);
        box-shadow: 1px 0 0 var(--line);
    }
    .ct-tbl thead th:first-child, .tbl thead th:first-child {
        z-index: 3; background: var(--sunk);
    }
    .tbl tbody tr:hover td:first-child, .ct-tbl tbody tr:hover td:first-child {
        background: var(--sunk);
    }

    .modal-overlay { padding: 0; align-items: flex-end; }
    .modal-card { max-width: 100%; border-radius: var(--r-lg) var(--r-lg) 0 0;
                  max-height: 92dvh; display: flex; flex-direction: column; }
    .modal-body { max-height: none; flex: 1; }
    .modal-footer { position: sticky; bottom: 0; }

    #toast-container { left: 12px; right: 12px; bottom: 12px; max-width: none; }
    .mobile-only { display: block; }
    .topbar-right .btn span:not(.btn-icon-left) { display: none; }
}

/* ═══ Print ═══════════════════════════════════════════════════════════════ */

@media print {
    .sidebar, #topbar, #toast-container, .modal-overlay, .btn,
    .page-actions, .export-btns, #mobile-backdrop { display: none !important; }
    body, #main, .content, #content { background: #fff; padding: 0; }
    .card, .ct-form-card { box-shadow: none; border: 1px solid #ccc; break-inside: avoid; }
    .tbl thead th, .ct-tbl thead th { position: static; background: #f2f2f2; color: #000; }
    tr, .stat-card, .ct-kpi-card { break-inside: avoid; }
    a[href]::after { content: ''; }
}

.print-header { text-align: center; margin-bottom: 16px; }
.print-company { font-size: 17px; font-weight: 720; }
.print-company-sub, .print-footer { font-size: 12px; color: var(--ink-3); }
.print-wo-title { font-size: 15px; font-weight: 700; margin: 9px 0; }
.print-qr { width: 128px; height: 128px; }
.print-process-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px,1fr)); gap: 8px; }
.print-process-box { border: 1px solid var(--line-2); border-radius: var(--r-xs); padding: 8px; font-size: 12px; }
.wo-print-page { padding: 14mm; }
.sign { border-top: 1px solid var(--ink-3); padding-top: 6px; font-size: 12px; text-align: center; }

/* ═══ Remaining classes carried over ══════════════════════════════════════
 * Everything the page scripts emit that has not been picked up by a family
 * rule above. Checked against the old sheet selector by selector, so nothing
 * silently loses the styling it had.
 * ═══════════════════════════════════════════════════════════════════════ */

.ct-btn-submit { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }
.ct-btn-submit:hover { background: var(--brand-700); }
.ct-btn-cancel { background: transparent; border-color: var(--line-2); color: var(--ink-2); }
.ct-btn-cancel:hover { background: var(--sunk); }

.btn-sched-save    { background: var(--ok);  border-color: var(--ok);  color: #fff; }
.btn-sched-danger  { background: var(--bad); border-color: var(--bad); color: #fff; }
.btn-sched-outline { background: transparent; border-color: var(--line-2); color: var(--ink-2); }
.btn-sched-outline:hover { background: var(--sunk); border-color: var(--ink-4); }
.btn-coupled-on    { background: var(--info); border-color: var(--info); color: #fff; }

.ct-toolbar, .ct-bonus-actions {
    display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
    margin-bottom: 13px;
}
.ct-date { font-family: var(--mono); font-size: 12px; color: var(--ink-2); }

.cfg-highlight { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-050); }
.gen-stats {
    display: grid; gap: 11px;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    margin-bottom: 15px;
}
.proc-cell { display: flex; align-items: center; gap: 7px; }
.timeline-content { flex: 1; min-width: 0; }
.name { font-weight: 650; }
.tw-print-head { font-size: 15px; font-weight: 700; margin-bottom: 9px; }

/* The drawer's open state is toggled by class on the sidebar; the backdrop is
   a sibling inside <main>, so it cannot be reached by a CSS combinator from
   there. app.js sets this class on both. */
#mobile-backdrop.mobile-open { display: block; }
