/* ============================================================
   retroTool — Shop-floor instrument theme
   ------------------------------------------------------------
   Design rules:
     1. ONE accent (brand orange). It marks brand, primary action
        and T-positions — nothing else.
     2. Colour means machine state, never decoration.
        green = available · steel = in use · amber/red = attention
     3. Everything else lives on a neutral graphite ramp.
     4. Numbers are readouts: mono, tabular, right-weighted.
   ============================================================ */

:root {
    /* Graphite ramp (dark) */
    --ts-0:  #0b0d10;   /* page */
    --ts-1:  #121519;   /* surface */
    --ts-2:  #171b21;   /* raised surface */
    --ts-3:  #1e242c;   /* hover / inset */
    --ts-line:        #232931;
    --ts-line-strong: #2f3742;

    /* Ink */
    --ts-ink:       #e7ebf0;
    --ts-ink-dim:   #98a3b1;
    --ts-ink-faint: #667180;

    /* Brand accent */
    --ts-accent:       #ff8b3d;
    --ts-accent-hover: #ff9d5c;
    --ts-accent-deep:  #c25c14;
    --ts-accent-soft:  rgba(255, 139, 61, 0.12);
    --ts-accent-line:  rgba(255, 139, 61, 0.32);

    /* State */
    --ts-ok:    #46a06b;
    --ts-cool:  #4d8fb8;
    --ts-warn:  #cf9a2f;
    --ts-alarm: #d1584f;
    --ts-ok-soft:    rgba(70, 160, 107, 0.13);
    --ts-cool-soft:  rgba(77, 143, 184, 0.13);
    --ts-alarm-soft: rgba(209, 88, 79, 0.13);

    /* Type */
    --ts-mono: ui-monospace, "Cascadia Mono", "Segoe UI Mono", "JetBrains Mono",
               "Roboto Mono", Consolas, monospace;

    /* Geometry — tighter than Bootstrap's default, reads as tooling */
    --ts-r:    4px;
    --ts-r-lg: 6px;

    /* ---- Legacy aliases -------------------------------------
       Older markup and JS still reference these names inline.
       Mapped onto the ramp so every page picks up the new
       palette without touching its markup.               ---- */
    --ts-bg-dark:      var(--ts-0);
    --ts-surface-dark: var(--ts-1);
    --ts-border-dark:  var(--ts-line);
    --ts-muted:        var(--ts-ink-faint);
    --ts-success:      var(--ts-ok);
    --ts-info:         var(--ts-cool);
    --ts-warning:      var(--ts-warn);
    --ts-danger:       var(--ts-alarm);
}

/* Light theme — same structure, inverted ramp */
[data-bs-theme="light"] {
    --ts-0:  #eceef1;
    --ts-1:  #ffffff;
    --ts-2:  #f7f8fa;
    --ts-3:  #eef0f3;
    --ts-line:        #dfe3e8;
    --ts-line-strong: #c6ccd4;

    --ts-ink:       #1a1f26;
    --ts-ink-dim:   #5a6572;
    --ts-ink-faint: #7d8794;

    --ts-accent:       #d2690c;
    --ts-accent-hover: #b85a08;
    --ts-accent-deep:  #8f4506;
    --ts-accent-soft:  rgba(210, 105, 12, 0.10);
    --ts-accent-line:  rgba(210, 105, 12, 0.28);

    --ts-ok:    #2f7d4f;
    --ts-cool:  #33708f;
    --ts-warn:  #9a6f10;
    --ts-alarm: #b5443b;
}

[data-bs-theme="dark"] {
    --bs-body-bg: var(--ts-0);
    --bs-body-color: var(--ts-ink);
    --bs-card-bg: var(--ts-1);
    --bs-border-color: var(--ts-line);
    --bs-emphasis-color: var(--ts-ink);
    --bs-secondary-color: var(--ts-ink-dim);
    --bs-tertiary-bg: var(--ts-2);
}

[data-bs-theme="light"] {
    --bs-body-bg: var(--ts-0);
    --bs-body-color: var(--ts-ink);
    --bs-card-bg: var(--ts-1);
    --bs-border-color: var(--ts-line);
}

/* Retune Bootstrap's own palette so nothing renders in stock blue.
   The .text-*/.border-*/.bg-* utilities read the *-rgb triplets, not the
   colour tokens — both have to be remapped or the defaults leak through. */
:root,
[data-bs-theme="dark"],
[data-bs-theme="light"] {
    --bs-primary: var(--ts-accent);
    --bs-link-color: var(--ts-accent);
    --bs-link-hover-color: var(--ts-accent-hover);
    --bs-border-radius: var(--ts-r);
    --bs-border-radius-sm: 3px;
    --bs-border-radius-lg: var(--ts-r-lg);
}

[data-bs-theme="dark"] {
    --bs-primary-rgb:   255, 139, 61;
    --bs-link-color-rgb: 255, 139, 61;
    --bs-link-hover-color-rgb: 255, 157, 92;
    --bs-success-rgb:   70, 160, 107;
    --bs-info-rgb:      77, 143, 184;
    --bs-warning-rgb:   207, 154, 47;
    --bs-danger-rgb:    209, 88, 79;
    --bs-secondary-rgb: 102, 113, 128;
}

[data-bs-theme="light"] {
    --bs-primary-rgb:   210, 105, 12;
    --bs-link-color-rgb: 210, 105, 12;
    --bs-link-hover-color-rgb: 184, 90, 8;
    --bs-success-rgb:   47, 125, 79;
    --bs-info-rgb:      51, 112, 143;
    --bs-warning-rgb:   154, 111, 16;
    --bs-danger-rgb:    181, 68, 59;
    --bs-secondary-rgb: 125, 135, 148;
}

/* ---- Body ---- */
body {
    min-height: 100vh;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    background: var(--ts-0);
    color: var(--ts-ink);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Every figure in the app is a readout: aligned, mono, unambiguous */
.ts-num,
.stat-value,
.t-badge,
.t-badge-sm,
.t-chip,
.util-count {
    font-family: var(--ts-mono);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1, "zero" 1;
}

/* ---- Section heading: uppercase eyebrow + hairline rule ---- */
.ts-section {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0 0 0.6rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ts-ink-faint);
}

.ts-section::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--ts-line);
}

.ts-section .ts-section-note {
    letter-spacing: 0.04em;
    font-weight: 600;
    color: var(--ts-ink-faint);
    text-transform: none;
}

/* ---- Cards: flat, hairline, no chrome ---- */
.card {
    background: var(--ts-1);
    border: 1px solid var(--ts-line);
    border-radius: var(--ts-r-lg);
}

[data-bs-theme="dark"] .card {
    background: var(--ts-1);
    border-color: var(--ts-line);
}

/* ---- Controls ---- */
.form-control,
.form-select {
    background: var(--ts-2);
    border: 1px solid var(--ts-line-strong);
    color: var(--ts-ink);
    border-radius: var(--ts-r);
}

.form-control:focus,
.form-select:focus {
    background: var(--ts-2);
    border-color: var(--ts-accent);
    color: var(--ts-ink);
    box-shadow: 0 0 0 3px var(--ts-accent-soft);
}

.form-control::placeholder { color: var(--ts-ink-faint); }

.form-label {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    color: var(--ts-ink-dim);
    margin-bottom: 0.25rem;
}

.btn {
    border-radius: var(--ts-r);
    font-weight: 600;
    letter-spacing: 0.01em;
}

/* Driven through Bootstrap's own variables rather than plain properties, so
   hover, focus, :active, .show (dropdown open) and disabled all follow. Set
   directly, those states fall back to stock blue. */
.btn-primary {
    --bs-btn-bg: var(--ts-accent);
    --bs-btn-border-color: var(--ts-accent);
    --bs-btn-color: #14100b;
    --bs-btn-hover-bg: var(--ts-accent-hover);
    --bs-btn-hover-border-color: var(--ts-accent-hover);
    --bs-btn-hover-color: #14100b;
    --bs-btn-active-bg: var(--ts-accent-hover);
    --bs-btn-active-border-color: var(--ts-accent-hover);
    --bs-btn-active-color: #14100b;
    --bs-btn-focus-shadow-rgb: 255, 139, 61;
    --bs-btn-disabled-bg: var(--ts-3);
    --bs-btn-disabled-border-color: var(--ts-line-strong);
    --bs-btn-disabled-color: var(--ts-ink-faint);
}

/* Bootstrap compiles literal hex into every .btn-outline-* variant, so the
   colour tokens above never reach them — restate each one on the ramp. */
.btn-outline-primary {
    --bs-btn-color: var(--ts-accent);
    --bs-btn-border-color: var(--ts-accent-line);
    --bs-btn-hover-color: #14100b;
    --bs-btn-hover-bg: var(--ts-accent);
    --bs-btn-hover-border-color: var(--ts-accent);
    --bs-btn-active-color: #14100b;
    --bs-btn-active-bg: var(--ts-accent-hover);
    --bs-btn-active-border-color: var(--ts-accent-hover);
    --bs-btn-disabled-color: var(--ts-ink-faint);
    --bs-btn-disabled-border-color: var(--ts-line);
}

.btn-outline-secondary {
    --bs-btn-color: var(--ts-ink-dim);
    --bs-btn-border-color: var(--ts-line-strong);
    --bs-btn-hover-color: var(--ts-ink);
    --bs-btn-hover-bg: var(--ts-3);
    --bs-btn-hover-border-color: var(--ts-ink-faint);
    --bs-btn-active-color: var(--ts-ink);
    --bs-btn-active-bg: var(--ts-3);
    --bs-btn-active-border-color: var(--ts-ink-faint);
    --bs-btn-disabled-color: var(--ts-ink-faint);
    --bs-btn-disabled-border-color: var(--ts-line);
}

.btn-outline-success {
    --bs-btn-color: var(--ts-ok);
    --bs-btn-border-color: rgba(70, 160, 107, 0.45);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--ts-ok);
    --bs-btn-hover-border-color: var(--ts-ok);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--ts-ok);
    --bs-btn-active-border-color: var(--ts-ok);
}

.btn-outline-info {
    --bs-btn-color: var(--ts-cool);
    --bs-btn-border-color: rgba(77, 143, 184, 0.45);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--ts-cool);
    --bs-btn-hover-border-color: var(--ts-cool);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--ts-cool);
    --bs-btn-active-border-color: var(--ts-cool);
}

.btn-outline-warning {
    --bs-btn-color: var(--ts-warn);
    --bs-btn-border-color: rgba(207, 154, 47, 0.45);
    --bs-btn-hover-color: #14100b;
    --bs-btn-hover-bg: var(--ts-warn);
    --bs-btn-hover-border-color: var(--ts-warn);
    --bs-btn-active-color: #14100b;
    --bs-btn-active-bg: var(--ts-warn);
    --bs-btn-active-border-color: var(--ts-warn);
}

.btn-outline-danger {
    --bs-btn-color: var(--ts-alarm);
    --bs-btn-border-color: rgba(209, 88, 79, 0.45);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--ts-alarm);
    --bs-btn-hover-border-color: var(--ts-alarm);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--ts-alarm);
    --bs-btn-active-border-color: var(--ts-alarm);
}

/* Solid variants used for toasts and status fills */
.btn-success { --bs-btn-bg: var(--ts-ok); --bs-btn-border-color: var(--ts-ok);
               --bs-btn-hover-bg: #3d8f5e; --bs-btn-hover-border-color: #3d8f5e; }
.btn-danger  { --bs-btn-bg: var(--ts-alarm); --bs-btn-border-color: var(--ts-alarm);
               --bs-btn-hover-bg: #bd4c44; --bs-btn-hover-border-color: #bd4c44; }
.btn-secondary { --bs-btn-bg: var(--ts-3); --bs-btn-border-color: var(--ts-line-strong);
                 --bs-btn-color: var(--ts-ink); --bs-btn-hover-bg: var(--ts-line);
                 --bs-btn-hover-border-color: var(--ts-ink-faint); --bs-btn-hover-color: var(--ts-ink); }

/* Destructive, but only announces itself on approach */
.btn-quiet-danger:hover {
    background: var(--ts-alarm-soft) !important;
    border-color: var(--ts-alarm) !important;
    color: var(--ts-alarm) !important;
}

.modal-content {
    background: var(--ts-1);
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r-lg);
}

.modal-header,
.modal-footer {
    border-color: var(--ts-line);
}

.modal-title {
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* ---- Main content spacing for bottom nav ---- */
.main-content {
    padding-bottom: 90px !important;
}

/* ---- Top header bar ---- */
.top-header {
    position: sticky;
    top: 0;
    z-index: 1040;
    background: var(--ts-1);
    border-bottom: 1px solid var(--ts-line);
}

/* Hairline of brand colour along the top edge — the only flourish */
.top-header::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: linear-gradient(90deg,
        var(--ts-accent) 0%,
        var(--ts-accent-line) 22%,
        transparent 55%);
}

/* ---- Brand logo ---- */
.brand-logo {
    display: flex;
    align-items: center;
    gap: 0.2rem;
}
.brand-retro {
    color: var(--ts-accent);
    font-weight: 800;
    font-size: 1.1rem;
    letter-spacing: 2px;
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
}
.brand-tool {
    color: #cfd8e3;
    font-weight: 300;
    font-size: 1.1rem;
    letter-spacing: 2px;
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
}
/* Header logo image (full horizontal logo) */
.brand-header-logo {
    height: 24px;
    width: auto;
    object-fit: contain;
}
.brand-icon {
    color: var(--ts-accent);
}
[data-bs-theme="light"] .brand-tool {
    color: #2c3e50;
}

/* Header separator dot */
.brand-separator {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--ts-muted);
    display: inline-block;
    margin: 0 0.5rem;
    vertical-align: middle;
}

/* Header motto — same two-tone treatment as the login card */
.brand-motto {
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

.brand-motto .motto-old { color: var(--ts-ink-faint); }
.brand-motto .motto-new { color: var(--ts-accent); }

/* Header site link */
.brand-site-link {
    font-size: 0.625rem;
    color: var(--ts-ink-faint) !important;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    transition: color 0.2s;
}
.brand-site-link:hover {
    color: var(--ts-accent) !important;
}

/* ============================================================
   Global search
   ============================================================ */

.header-right {
    min-width: 0;
}

.global-search {
    position: relative;
    width: 260px;
    max-width: 34vw;
}

.global-search .gs-icon {
    position: absolute;
    left: 0.55rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.8rem;
    color: var(--ts-ink-faint);
    pointer-events: none;
}

.global-search input {
    padding-left: 1.9rem;
    height: 32px;
    font-size: 0.8rem;
    background: var(--ts-2);
    border-color: var(--ts-line-strong);
}

.global-search input::-webkit-search-cancel-button {
    filter: grayscale(1) opacity(0.5);
}

.gs-results {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    width: min(420px, 92vw);
    max-height: min(60vh, 460px);
    overflow-y: auto;
    background: var(--ts-1);
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r-lg);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
    z-index: 1060;
    padding: 0.3rem;
}

.gs-group + .gs-group {
    margin-top: 0.2rem;
    border-top: 1px solid var(--ts-line);
    padding-top: 0.3rem;
}

.gs-group-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.25rem 0.5rem;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ts-ink-faint);
}

/* A hit is a row: what it is on the left, where it is on the right. */
.gs-hit {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.55rem;
    border-radius: var(--ts-r);
    text-decoration: none;
    color: var(--ts-ink);
}

.gs-hit-main {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;            /* lets the title ellipsis rather than push */
    flex: 1;
}

.gs-hit-meta {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
    font-size: 0.68rem;
    color: var(--ts-ink-faint);
}

.gs-where {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    max-width: 11rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gs-badge {
    padding: 0.05rem 0.35rem;
    border-radius: 999px;
    background: var(--ts-2, rgba(128, 128, 128, 0.18));
    white-space: nowrap;
}

.gs-badge.is-low { color: var(--ts-danger, #e05252); }

/* Why this row matched, marked in the text itself. */
.gs-hit mark {
    background: var(--ts-accent-soft);
    color: inherit;
    padding: 0 1px;
    border-radius: 2px;
}

.gs-count,
.gs-more {
    padding: 0.2rem 0.55rem;
    font-size: 0.66rem;
    color: var(--ts-ink-faint);
}

.gs-count { border-bottom: 1px solid var(--ts-line); margin-bottom: 0.2rem; }
.gs-more { font-style: italic; }

.gs-group-count {
    margin-left: auto;
    font-weight: 400;
    letter-spacing: 0;
}

.gs-hint {
    margin-top: 0.4rem;
    font-size: 0.7rem;
    opacity: 0.75;
}

.gs-hit:hover,
.gs-hit.is-active {
    background: var(--ts-accent-soft);
    color: var(--ts-ink);
}

.gs-hit-title {
    font-size: 0.82rem;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gs-hit-sub {
    font-size: 0.7rem;
    color: var(--ts-ink-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gs-empty {
    padding: 0.75rem;
    font-size: 0.8rem;
    color: var(--ts-ink-faint);
    text-align: center;
}

/* Below md the box collapses to an icon and expands over the header. */
@media (max-width: 767.98px) {
    .global-search {
        display: none;
        position: absolute;
        left: 0.75rem;
        right: 0.75rem;
        top: 50%;
        transform: translateY(-50%);
        width: auto;
        max-width: none;
        z-index: 1045;
    }
    .global-search.is-open { display: block; }
}

/* ---- Header menu ---- */
.app-menu {
    background: var(--ts-1);
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r-lg);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
    font-size: 0.85rem;
    min-width: 200px;
}

.app-menu .dropdown-item {
    color: var(--ts-ink-dim);
    padding: 0.45rem 0.85rem;
    border-radius: var(--ts-r);
}

.app-menu .dropdown-item:hover,
.app-menu .dropdown-item:focus {
    background: var(--ts-3);
    color: var(--ts-ink);
}

.app-menu .dropdown-item.text-danger:hover {
    background: var(--ts-alarm-soft);
}

.app-menu .dropdown-header {
    color: var(--ts-ink-faint);
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.app-menu .dropdown-divider { border-color: var(--ts-line); }

/* ============================================================
   One Add action, replacing the row of floating buttons
   ============================================================ */

.add-fab {
    position: fixed;
    bottom: 88px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1035;
}

.add-fab > .btn {
    height: 48px;
    border-radius: 24px;
    padding: 0 1.15rem;
    font-size: 0.9rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
}

.add-menu {
    background: var(--ts-1);
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r-lg);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
    padding: 0.3rem;
    min-width: 230px;
    /* The menu opens upward from a fixed button and repositioning is off
       (data-bs-display=static), so on a phone - where the URL bar eats
       real height - a grown list pushed its FIRST items above the screen.
       Cap it to what actually fits and scroll inside instead. dvh tracks
       the browser chrome; vh is the fallback for older WebViews. */
    max-height: calc(100vh - 180px);
    max-height: calc(100dvh - 180px);
    overflow-y: auto;
    overscroll-behavior: contain;
}

.add-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.55rem 0.7rem;
    border-radius: var(--ts-r);
    color: var(--ts-ink-dim);
    font-size: 0.85rem;
    min-height: 44px;
}

.add-menu .dropdown-item:hover {
    background: var(--ts-3);
    color: var(--ts-ink);
}

/* Two-line item: what it does, and what it costs you */
.add-menu .item-2line {
    align-items: flex-start;
    min-height: 52px;
}

.add-menu .item-2line > i { margin-top: 2px; }

.add-menu .item-2line small {
    display: block;
    font-size: 0.68rem;
    color: var(--ts-ink-faint);
    line-height: 1.25;
    margin-top: 1px;
    white-space: normal;
}

.add-menu .dropdown-item i { color: var(--ts-ink-faint); font-size: 1rem; }
.add-menu .dropdown-item:hover i { color: var(--ts-accent); }

.add-menu .dropdown-header {
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ts-ink-faint);
    padding: 0.4rem 0.7rem 0.2rem;
}

/* Vendor marks stay recognisable — that is the point of them. */
.add-menu .vendor-mark {
    width: 18px;
    height: 18px;
    border-radius: 3px;
    object-fit: contain;
    background: #fff;
    flex-shrink: 0;
}

/* The old FAB row sat on top of the last list row. */
.main-content { padding-bottom: 150px !important; }

/* ============================================================
   Build Assembly pickers
   ============================================================ */

.picker {
    border: 1px solid var(--ts-line);
    border-radius: var(--ts-r-lg);
    background: var(--ts-2);
    overflow: hidden;
}

.picker-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    padding: 0.45rem;
    border-bottom: 1px solid var(--ts-line);
}

.picker-search {
    position: relative;
    flex: 1 1 150px;
    min-width: 130px;
}

.picker-search i {
    position: absolute;
    left: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.72rem;
    color: var(--ts-ink-faint);
    pointer-events: none;
}

.picker-search input { padding-left: 1.75rem; }

.picker-filters .form-select { flex: 0 1 auto; max-width: 46%; }

.picker-toggle {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
    color: var(--ts-ink-dim);
    white-space: nowrap;
    cursor: pointer;
}

.picker-list {
    max-height: 230px;
    overflow-y: auto;
}

.picker-row {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.4rem 0.55rem;
    border: none;
    border-top: 1px solid var(--ts-line);
    background: transparent;
    text-align: left;
    color: var(--ts-ink);
}

.picker-row:first-child { border-top: none; }
.picker-row:hover { background: var(--ts-3); }

.picker-row.is-chosen {
    background: var(--ts-accent-soft);
    box-shadow: inset 2px 0 0 var(--ts-accent);
}

.picker-thumb {
    width: 34px;
    height: 34px;
    object-fit: contain;
    border-radius: 3px;
    background: #dcdfe4;
    border: 1px solid var(--ts-line-strong);
}

[data-bs-theme="light"] .picker-thumb { background: #fff; }
.picker-thumb-empty { background: var(--ts-3); }

.picker-main { min-width: 0; }

.picker-name {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.picker-specs {
    display: block;
    font-size: 0.68rem;
    color: var(--ts-ink-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.picker-qty {
    font-family: var(--ts-mono);
    font-size: 0.72rem;
    color: var(--ts-ink-dim);
    padding: 0.05em 0.4em;
    border-radius: 3px;
    background: var(--ts-3);
}

.picker-qty.is-low { color: var(--ts-warn); }

.picker-warn { color: var(--ts-alarm); margin-left: 0.35rem; }
.picker-unknown { color: var(--ts-ink-faint); margin-left: 0.35rem; font-weight: 700; }

.picker-empty {
    padding: 0.9rem;
    text-align: center;
    font-size: 0.78rem;
    color: var(--ts-ink-faint);
}

/* What you are about to build */
#build-preview {
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r-lg);
    background: var(--ts-2);
    padding: 0.6rem 0.7rem;
}

.build-preview-name {
    font-size: 0.85rem;
    font-weight: 600;
    margin-bottom: 0.35rem;
}

.build-preview-specs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    font-family: var(--ts-mono);
    font-size: 0.7rem;
    color: var(--ts-ink-dim);
}

.build-warn {
    margin-top: 0.5rem;
    padding: 0.35rem 0.5rem;
    border-radius: var(--ts-r);
    background: var(--ts-alarm-soft);
    border: 1px solid rgba(209, 88, 79, 0.3);
    color: var(--ts-alarm);
    font-size: 0.75rem;
    font-weight: 600;
}

.build-note {
    margin-top: 0.5rem;
    font-size: 0.72rem;
    color: var(--ts-ink-faint);
}

/* ---- Insert edges ----
   One pip per cutting edge, filled as they are used up. Counting corners is
   how indexable life is actually tracked on the floor. */
.edge-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.1em 0.4em;
    border-radius: 3px;
    border: 1px solid var(--ts-line-strong);
    font-size: 0.65rem;
    color: var(--ts-ink-faint);
    white-space: nowrap;
}

.edge-pip {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    border: 1px solid var(--ts-accent);
    background: var(--ts-accent);
    display: inline-block;
}

.edge-pip.is-used { background: transparent; border-color: var(--ts-ink-faint); }

.edge-text { margin-left: 0.15rem; font-family: var(--ts-mono); }

.edge-chip.is-spent {
    border-color: rgba(209, 88, 79, 0.4);
    background: var(--ts-alarm-soft);
    color: var(--ts-alarm);
    font-weight: 600;
}

/* ---- Collet drawer ---- */
.collet-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 0.4rem;
}

.collet-card {
    position: relative;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.4rem;
    padding: 0.5rem 0.6rem;
    min-height: 52px;
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r);
    background: var(--ts-1);
    color: var(--ts-ink);
    text-align: left;
}

.collet-card:hover {
    background: var(--ts-2);
    border-color: var(--ts-ink-faint);
}

/* An empty pocket in the drawer should read as empty at a glance. */
.collet-card.is-empty {
    opacity: 0.45;
    border-style: dashed;
}

.collet-card.is-low { border-color: rgba(207, 154, 47, 0.5); }

.collet-size {
    font-family: var(--ts-mono);
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.collet-qty {
    font-family: var(--ts-mono);
    font-size: 0.72rem;
    color: var(--ts-ink-faint);
}

.collet-card.is-low .collet-qty { color: var(--ts-warn); }

.collet-sealed {
    position: absolute;
    right: 0.35rem;
    bottom: 0.3rem;
    font-size: 0.55rem;
    color: var(--ts-cool);
}

/* Adapter chips in the build modal */
.adapter-row { display: flex; flex-wrap: wrap; gap: 0.35rem; }

.adapter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r);
    background: var(--ts-2);
    color: var(--ts-ink-dim);
    font-family: var(--ts-mono);
    font-size: 0.75rem;
    min-height: 36px;
}

.adapter-chip:hover { background: var(--ts-3); color: var(--ts-ink); }

.adapter-chip.is-chosen {
    background: var(--ts-accent-soft);
    border-color: var(--ts-accent);
    color: var(--ts-accent);
}

.adapter-qty { font-size: 0.68rem; opacity: 0.7; }

/* ---- Import flows ---- */
.batch-list {
    max-height: 260px;
    overflow-y: auto;
    border: 1px solid var(--ts-line);
    border-radius: var(--ts-r);
}

.batch-row {
    display: grid;
    grid-template-columns: 18px 110px minmax(0, 1fr);
    gap: 0.5rem;
    align-items: center;
    padding: 0.3rem 0.5rem;
    font-size: 0.78rem;
    border-top: 1px solid var(--ts-line);
}

.batch-row:first-child { border-top: none; }
.batch-row.ok i { color: var(--ts-ok); }
.batch-row.bad i { color: var(--ts-alarm); }
.batch-row.bad .batch-name { color: var(--ts-alarm); }

.batch-art {
    font-family: var(--ts-mono);
    font-size: 0.72rem;
    color: var(--ts-ink-dim);
}

.batch-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--ts-ink-dim);
}

/* One card per spreadsheet column: heading, what it maps to, sample values */
.sheet-cols {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 0.5rem;
}

.sheet-col {
    border: 1px solid var(--ts-line);
    border-radius: var(--ts-r);
    padding: 0.5rem;
    background: var(--ts-2);
}

.sheet-col-head {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--ts-ink);
    margin-bottom: 0.3rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sheet-samples {
    margin-top: 0.3rem;
    font-family: var(--ts-mono);
    font-size: 0.66rem;
    color: var(--ts-ink-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sheet-preview {
    font-size: 0.72rem;
    white-space: nowrap;
}

.sheet-preview th {
    font-size: 0.6rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ts-ink-faint);
    border-color: var(--ts-line);
}

.sheet-preview td {
    color: var(--ts-ink-dim);
    border-color: var(--ts-line);
}

/* ---- Login page branding ---- */
/* ---- Login / Register animated background ---- */
.login-bg {
    position: fixed;
    inset: 0;
    overflow: hidden;
    z-index: 0;
    background: var(--ts-bg-dark);
}

/* G-code scrolling panel — left side */
.login-bg .gcode-panel {
    position: absolute;
    left: 0;
    top: 0;
    width: 220px;
    height: 100%;
    overflow: hidden;
    /* Texture, not decoration — it should register only once you look for it */
    opacity: 0.16;
    mask-image: linear-gradient(to bottom, transparent 0%, white 12%, white 88%, transparent 100%);
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, white 12%, white 88%, transparent 100%);
}
.login-bg .gcode-scroll {
    font-family: var(--ts-mono);
    font-size: 11px;
    line-height: 2;
    color: var(--ts-accent);
    white-space: pre;
    pointer-events: none;
    animation: gcodeScroll 60s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
    .login-bg .gcode-scroll { animation: none; }
}
@keyframes gcodeScroll {
    0% { transform: translateY(-50%); }
    100% { transform: translateY(0); }
}
@media (max-width: 992px) {
    .login-bg .gcode-panel { width: 120px; font-size: 9px; }
}
@media (max-width: 576px) {
    .login-bg .gcode-panel { width: 80px; opacity: 0.08; }
}

.login-card {
    border: 1px solid var(--ts-line-strong);
    overflow: hidden;
    position: relative;
    z-index: 1;
    background: var(--ts-1);
}

/* A single struck rule, not a gradient wash */
.login-card::before {
    content: '';
    display: block;
    height: 2px;
    background: var(--ts-accent);
}

.login-lang {
    position: absolute;
    top: 0.85rem;
    right: 0.85rem;
    z-index: 2;
}

.login-brand-wrap {
    text-align: center;
    padding: 0.75rem 0 0;
    margin-bottom: 1.75rem;
}

.login-logo-img {
    max-width: 220px;
    width: 74%;
    height: auto;
    margin-bottom: 0.85rem;
}

/* The line is a contrast — let the two halves carry it, rather than
   setting the whole thing in accent italic. Old = steel, new = live. */
.login-motto {
    display: flex;
    justify-content: center;
    gap: 0.5em;
    margin: 0;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.2em;
    text-transform: uppercase;
}

.login-motto .motto-old { color: var(--ts-ink-faint); }
.login-motto .motto-new { color: var(--ts-accent); }

/* Separates the brand lockup from the product itself */
.login-title {
    position: relative;
    margin: 1.1rem 0 0;
    padding-top: 1.1rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    color: var(--ts-ink-dim);
}

.login-title::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: var(--ts-line);
}

.login-brand-name {
    font-size: 1.8rem;
    letter-spacing: 4px;
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
}
.login-brand-name .brand-retro {
    font-size: 1.8rem;
    font-weight: 800;
}
.login-brand-name .brand-tool {
    font-size: 1.8rem;
    font-weight: 300;
}
.login-footer-link {
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    transition: color 0.2s;
}
.login-footer-link:hover {
    color: var(--ts-accent) !important;
}

/* ---- Dashboard welcome banner ---- */
.dash-welcome {
    background: linear-gradient(135deg, var(--ts-surface-dark) 0%, rgba(230, 126, 34, 0.08) 100%);
    border: 1px solid var(--ts-border-dark);
    border-left: 3px solid var(--ts-accent);
    border-radius: 0.375rem;
    padding: 0.5rem 0.75rem;
}
.dash-welcome-logo {
    width: 28px;
    height: 28px;
    object-fit: contain;
    flex-shrink: 0;
}
.dash-motto {
    font-size: 0.65rem;
    color: var(--ts-muted);
    font-weight: 600;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    font-style: italic;
}
[data-bs-theme="light"] .dash-welcome {
    background: linear-gradient(135deg, #fff 0%, rgba(230, 126, 34, 0.06) 100%);
}

/* ---- Bottom nav (all screen sizes) ---- */
.bottom-nav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    justify-content: space-around;
    align-items: center;
    height: 72px;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    z-index: 1050;
    background: var(--ts-1);
    border-top: 1px solid var(--ts-line);
}

.bottom-nav-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 6px 10px;
    color: var(--ts-ink-faint);
    text-decoration: none;
    font-size: 0.7rem;
    letter-spacing: 0.03em;
    min-width: 56px;
    position: relative;
    transition: color 0.15s;
}

/* Active tab marked by a bar on the top edge, not just colour */
.bottom-nav-item.active::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 26px;
    height: 2px;
    background: var(--ts-accent);
}

.bottom-nav-item i {
    font-size: 1.3rem;
    margin-bottom: 2px;
}

/* Bigger nav items for main pages */
.bottom-nav-main {
    min-width: 64px;
}

.bottom-nav-main i {
    font-size: 1.6rem;
    margin-bottom: 3px;
}

.bottom-nav-main span {
    font-size: 0.75rem;
    font-weight: 600;
}

.bottom-nav-item.active,
.bottom-nav-item:hover {
    color: var(--ts-accent);
}

.bottom-nav-main.active {
    color: var(--ts-accent);
}

/* Desktop: larger bottom nav */
@media (min-width: 768px) {
    .bottom-nav {
        height: 76px;
    }
    .bottom-nav-main i {
        font-size: 2rem;
    }
    .bottom-nav-main span {
        font-size: 0.9rem;
    }
    .bottom-nav-item i {
        font-size: 1.6rem;
    }
    .bottom-nav-item span {
        font-size: 0.8rem;
    }
    .bottom-nav-item {
        min-width: 80px;
    }
    .bottom-nav-main {
        min-width: 90px;
    }
}

/* ---- Readout strip: one panel, hairline-divided cells ---- */
.stat-strip {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    background: var(--ts-1);
    border: 1px solid var(--ts-line);
    border-radius: var(--ts-r-lg);
    overflow: hidden;
}

.stat-strip .stat-card {
    border: 0;
    border-left: 1px solid var(--ts-line);
    border-radius: 0;
    background: transparent;
}

.stat-strip .stat-card:first-child {
    border-left: 0;
}

.stat-card {
    text-align: left;
    padding: 0.7rem 0.9rem;
}

.stat-card .stat-value {
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.02em;
    color: var(--ts-ink);
}

.stat-card .stat-label {
    font-size: 0.625rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-weight: 700;
    color: var(--ts-ink-faint);
    margin-top: 0.15rem;
}

/* The one figure that means "something is out on the floor" */
.stat-card.is-live .stat-value { color: var(--ts-accent); }

.stat-card.is-zero .stat-value { color: var(--ts-ink-faint); }

@media (max-width: 575.98px) {
    .stat-card { padding: 0.55rem 0.6rem; }
    .stat-card .stat-value { font-size: 1.35rem; }
    .stat-card .stat-label { font-size: 0.5625rem; letter-spacing: 0.08em; }
}

/* ---- Status badges — tinted, with a state dot ---- */
.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    padding: 0.25em 0.6em;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.7rem;
    letter-spacing: 0.03em;
    white-space: nowrap;
    border: 1px solid transparent;
}

.status-badge::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

.status-available {
    background: var(--ts-ok-soft);
    border-color: rgba(70, 160, 107, 0.3);
    color: var(--ts-ok);
}

.status-in-use {
    background: var(--ts-cool-soft);
    border-color: rgba(77, 143, 184, 0.3);
    color: var(--ts-cool);
}

/* Icons inside status badges are redundant next to the dot */
.status-badge i { display: none; }

/* ---- Tool type badges — neutral; the label already says the type ---- */
.badge-milling,
.badge-drilling,
.badge-turning {
    background: transparent !important;
    color: var(--ts-ink-faint) !important;
    border: 1px solid var(--ts-line-strong);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* In dense chip lists the type repeats on every row — keep it a footnote */
.dash-tool-chip .badge {
    font-size: 0.5625rem !important;
    padding: 0.15em 0.35em;
    line-height: 1.3;
}

/* ---- Machine utilization bar ---- */
.utilization-bar {
    height: 4px;
    border-radius: 2px;
    overflow: hidden;
    background: var(--ts-3);
}

.utilization-bar .fill {
    height: 100%;
    border-radius: 2px;
    transition: width 0.3s;
}

.util-count {
    font-size: 0.8rem;
    color: var(--ts-ink-dim);
}

.util-count .util-used { color: var(--ts-ink); font-weight: 600; }

/* ---- Card hover ---- */
.card-clickable {
    cursor: pointer;
    transition: transform 0.15s, box-shadow 0.15s;
}

.card-clickable:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

/* ---- Touch-friendly buttons ---- */
@media (max-width: 767.98px) {
    .btn {
        min-height: 44px;
    }

    .btn-lg {
        min-height: 52px;
        font-size: 1.1rem;
    }
}

/* ---- FAB (floating action button) — horizontal centered ---- */
.fab {
    position: fixed;
    bottom: 88px;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.3rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    z-index: 1030;
    border: none;
    /* Center: positioned via left + transform */
    left: 50%;
    transform: translateX(calc(-50% + 8px));
}

.fab-secondary {
    transform: translateX(calc(-50% + -52px));
}

.fab-third {
    transform: translateX(calc(-50% + -112px));
}

.fab-fourth {
    transform: translateX(calc(-50% + -172px));
}

.fab-fifth {
    transform: translateX(calc(-50% + -232px));
}

.fab-bar {
    position: fixed;
    bottom: 88px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 10px;
    z-index: 1030;
}

.fab-pill {
    height: 48px;
    border-radius: 24px !important;
    padding: 0 18px !important;
    font-size: 1rem;
    display: flex;
    align-items: center;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    border: none;
}

.fab-wizard {
    transform: translateX(calc(-50% + -230px));
    width: auto;
    height: 48px;
    border-radius: 24px !important;
    padding: 0 16px !important;
    font-size: 1rem;
    display: flex;
    align-items: center;
    gap: 5px;
    box-shadow: 0 4px 16px rgba(230, 126, 34, 0.4);
}

.fab-build {
    transform: translateX(calc(-50% + 100px));
    width: auto;
    height: 48px;
    border-radius: 24px !important;
    padding: 0 16px !important;
    font-size: 1rem;
    display: flex;
    align-items: center;
    gap: 5px;
    box-shadow: 0 4px 16px rgba(25, 135, 84, 0.4);
}

.widia-fab {
    background: #000 !important;
    border: none !important;
    padding: 0 !important;
    overflow: hidden;
}
.widia-fab:hover { opacity: 0.85; }
.widia-fab-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.hoffmann-fab {
    background: #FF7000 !important;
    border: none !important;
    padding: 0 !important;
    overflow: hidden;
}

.hoffmann-fab:hover {
    background: #e66300 !important;
}

.hoffmann-fab-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

/* ---- Machine select tiles ---- */
.machine-select-btn {
    --bs-btn-color: var(--ts-ink);
    --bs-btn-border-color: var(--ts-line-strong);
    --bs-btn-hover-color: var(--ts-ink);
    --bs-btn-hover-bg: var(--ts-2);
    --bs-btn-hover-border-color: var(--ts-ink-faint);
    background: var(--ts-1);
    border-radius: var(--ts-r-lg);
    padding: 0.7rem 0.85rem !important;
    line-height: 1.45;
}

.machine-select-btn strong {
    display: block;
    font-size: 0.95rem;
    letter-spacing: 0.01em;
    margin-bottom: 0.15rem;
}

.machine-select-btn small {
    font-size: 0.72rem;
}

/* Holder type is the compatibility key — keep it readable, not muted away */
.machine-select-btn small:nth-of-type(2) {
    font-family: var(--ts-mono);
    color: var(--ts-ink-dim) !important;
    letter-spacing: 0.02em;
}

.machine-select-btn small:last-of-type {
    color: var(--ts-ink-faint);
    font-variant-numeric: tabular-nums;
}

.machine-select-btn.active {
    background: var(--ts-accent-soft) !important;
    border-color: var(--ts-accent) !important;
    color: var(--ts-ink) !important;
}

.machine-select-btn.active strong { color: var(--ts-accent); }

/* ---- Assignment step indicator ---- */
.step-indicator {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.step-dot {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8rem;
    font-weight: 700;
    background: var(--ts-border-dark);
    color: var(--ts-muted);
}

.step-dot.active {
    background: var(--ts-accent);
    color: white;
}

.step-dot.done {
    background: var(--ts-success);
    color: white;
}

/* ---- T-number badge — a slot label stamped on the magazine ---- */
.t-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 52px;
    padding: 0.28em 0.6em;
    border-radius: 3px;
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.04em;
    background: var(--ts-accent-soft);
    border: 1px solid var(--ts-accent-line);
    color: var(--ts-accent);
}

/* ---- Tool loadout table ---- */
.loadout-table .tool-row {
    border-bottom: 1px solid var(--ts-border-dark);
    padding: 0.75rem 0;
}

.loadout-table .tool-row:last-child {
    border-bottom: none;
}

/* ---- Used T-numbers reference ---- */
.used-t-numbers {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.used-t-numbers .t-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.2em 0.45em;
    border-radius: 3px;
    font-size: 0.75rem;
    font-weight: 600;
    background: var(--ts-cool-soft);
    border: 1px solid rgba(77, 143, 184, 0.3);
    color: var(--ts-cool);
}

/* ---- Search input ---- */
.search-input {
    max-width: 300px;
}

@media (max-width: 767.98px) {
    .search-input {
        max-width: 100%;
    }
}

/* ---- Compact table on mobile ---- */
@media (max-width: 767.98px) {
    .table-responsive-cards .table {
        font-size: 0.85rem;
    }
}

/* ---- Loading spinner ---- */
.loading-spinner {
    text-align: center;
    padding: 3rem;
    color: var(--ts-muted);
}

/* ---- Empty state ---- */
.empty-state {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--ts-muted);
}

.empty-state i {
    font-size: 3rem;
    margin-bottom: 1rem;
    display: block;
}

/* ---- Scrollbar styling for dark theme ---- */
[data-bs-theme="dark"] ::-webkit-scrollbar {
    width: 8px;
}

[data-bs-theme="dark"] ::-webkit-scrollbar-track {
    background: var(--ts-bg-dark);
}

[data-bs-theme="dark"] ::-webkit-scrollbar-thumb {
    background: var(--ts-border-dark);
    border-radius: 4px;
}

/* ---- Confirm button (for assign page) ---- */
.btn-assign-confirm {
    background: var(--ts-success);
    color: white;
    font-size: 1.2rem;
    font-weight: 700;
    padding: 1rem;
    border: none;
}

.btn-assign-confirm:hover {
    background: #219a52;
    color: white;
}

/* ---- Batch Assignment: two-panel layout ---- */
#machine-loadout-panel {
    border: 1px solid var(--ts-border-dark, #333);
    border-radius: 8px;
    padding: 0.75rem;
    background: rgba(0,0,0,0.15);
}

@media (min-width: 768px) {
    #machine-loadout-col {
        position: sticky;
        top: 60px;
        max-height: calc(100vh - 120px);
        overflow-y: auto;
    }
}

@media (max-width: 767.98px) {
    #machine-loadout-panel {
        max-height: 200px;
        overflow-y: auto;
        margin-bottom: 1rem;
    }
}

.loadout-tool-row {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    /* Tall enough to hit with a finger at the machine, where this is used. */
    min-height: 40px;
    padding: 0.3rem 0.15rem;
    border-bottom: 1px solid rgba(255,255,255,0.05);
    border-radius: 6px;
}

.loadout-tool-row:hover { background: rgba(255, 255, 255, 0.04); }

.loadout-tool-row:last-child { border-bottom: none; }

.tool-assign-card {
    transition: all 0.15s;
    cursor: pointer;
    border-width: 2px;
}

.tool-assign-card.selected {
    border-color: var(--ts-success) !important;
    background: rgba(39, 174, 96, 0.1) !important;
    color: inherit;
}

.tool-assign-card:hover:not(:disabled) {
    border-color: var(--ts-success);
}

/* Storage locations list */
.loc-row {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.55rem 0.6rem;
    border-bottom: 1px solid var(--ts-border);
    cursor: pointer;
}

.loc-row:last-child { border-bottom: none; }
.loc-row:hover { background: var(--ts-surface-2, rgba(128, 128, 128, 0.08)); }

/* Expand control. Leaf rows keep the same width so names stay in one column
   whether or not the row has children. */
.loc-twisty {
    width: 1.6rem;
    min-width: 1.6rem;
    height: 1.6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: none;
    color: var(--ts-ink-faint);
    border-radius: var(--ts-r, 4px);
}

.loc-twisty:hover:not(.is-leaf) {
    background: var(--ts-surface-2, rgba(128, 128, 128, 0.15));
    color: var(--ts-ink);
}

.loc-twisty.is-leaf { pointer-events: none; }

.loc-contents {
    max-height: 16rem;
    overflow-y: auto;
    border-top: 1px solid var(--ts-border);
    padding-top: 0.4rem;
}

.loc-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.1rem;
}

.loc-item + .loc-item { border-top: 1px solid var(--ts-line, rgba(128, 128, 128, 0.12)); }

.loc-item-icon {
    color: var(--ts-ink-faint);
    font-size: 0.85rem;
    width: 1rem;
    text-align: center;
    flex-shrink: 0;
}

.loc-item-main {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

.loc-item-title {
    font-size: 0.8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.loc-item-sub {
    font-size: 0.68rem;
    color: var(--ts-ink-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A tool that cannot go in right now. Shown rather than hidden, but visibly
   set apart so it never competes with what the operator can actually pick. */
.tool-assign-card.tool-blocked {
    border: 1px dashed var(--ts-border);
    border-radius: var(--ts-radius, 6px);
    background: transparent;
    cursor: default;
    opacity: 0.75;
}

.blocked-reason {
    display: inline-block;
    font-size: 0.72rem;
    line-height: 1.4;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: var(--ts-surface-2, rgba(128, 128, 128, 0.15));
    color: var(--ts-text-muted, #8b8b8b);
    white-space: nowrap;
}

/* Magazine occupancy. Length is capacity, not addresses — see
   renderCapacityMeter() for why there is no pocket grid here. */
.capacity-bar {
    display: flex;
    height: 6px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--ts-surface-2, rgba(128, 128, 128, 0.2));
}

.capacity-fill {
    height: 100%;
    transition: width 0.2s ease;
}

.capacity-fill.used { background: var(--ts-accent); }
.capacity-fill.pending { background: var(--ts-success); }

/* The machine picker in the page header. Drawn as a pill so it reads as a
   control standing next to the title, not as a second title in a different
   font — two text sizes running into each other looked like a mistake. */
.machine-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.8rem;
    border: 1px solid var(--ts-border-dark, #3a3f54);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.03);
    color: inherit;
    font-size: 0.92rem;
    font-weight: 600;
}

[data-bs-theme="light"] .machine-switch {
    border-color: #dee2e6;
    background: #f8f9fa;
}

.machine-switch:hover {
    color: inherit;
    border-color: var(--ts-accent);
}

.machine-switch .bi-gear-wide-connected { color: var(--ts-accent); }
.machine-switch small { font-weight: 400; }

.loadout-tool-row.return-selected {
    background: rgba(220, 53, 69, 0.1);
    border-radius: 4px;
}

.pending-tool-row {
    border: 1px dashed var(--ts-success);
    border-radius: 6px;
    padding: 0.4rem 0.5rem;
    margin-bottom: 0.4rem;
    background: rgba(39, 174, 96, 0.05);
}

.assign-sticky-bar {
    position: fixed;
    bottom: 70px;
    left: 0; right: 0;
    background: var(--ts-surface-dark, #1a1d28);
    border-top: 2px solid var(--ts-success);
    padding: 0.75rem 1rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    z-index: 1030;
}

[data-bs-theme="light"] .assign-sticky-bar {
    background: #f8f9fa;
}

[data-bs-theme="light"] #machine-loadout-panel {
    background: rgba(0,0,0,0.03);
    border-color: #ddd;
}

/* ---- Category toggle (pill tabs) ---- */
.category-toggle {
    display: flex;
    gap: 2px;
    background: var(--ts-2);
    border: 1px solid var(--ts-line);
    border-radius: var(--ts-r-lg);
    padding: 3px;
}

.category-toggle .btn {
    border: none;
    border-radius: var(--ts-r);
    min-width: 70px;
    padding: 0.35rem 1rem;
    font-weight: 600;
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ts-ink-faint);
    background: transparent;
    transition: color 0.15s, background 0.15s;
}

.category-toggle .btn:hover {
    color: var(--ts-ink);
    background: var(--ts-3);
}

/* One selected state, not one colour per category */
.category-toggle .btn.active,
.category-toggle .btn.active[data-cat="all"],
.category-toggle .btn.active[data-cat="milling"],
.category-toggle .btn.active[data-cat="turning"] {
    background: var(--ts-accent) !important;
    color: #14100b !important;
    box-shadow: none;
}

/* ---- Holder mismatch warning ---- */
.holder-mismatch {
    color: var(--ts-danger);
    font-weight: 600;
}

.holder-match {
    color: var(--ts-success);
}

/* ---- App Dialog overlay (custom confirm/prompt) ---- */
.app-dialog-overlay {
    position: fixed;
    inset: 0;
    z-index: 9990;
    background: rgba(0, 0, 0, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    animation: dialogFadeIn 0.15s ease;
}

@keyframes dialogFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.app-dialog {
    background: var(--bs-modal-bg, var(--bs-body-bg));
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
    min-width: 280px;
    max-width: 360px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
    animation: dialogSlideIn 0.15s ease;
}

@keyframes dialogSlideIn {
    from { transform: scale(0.95) translateY(-10px); opacity: 0; }
    to { transform: scale(1) translateY(0); opacity: 1; }
}

/* ---- Quick actions — one primary, the rest quiet ---- */
.quick-action-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 56px;
    padding: 0.6rem 0.75rem;
    font-weight: 600;
    font-size: 0.85rem;
    letter-spacing: 0.02em;
    border-radius: var(--ts-r-lg);
    border: 1px solid var(--ts-line-strong);
    background: var(--ts-1);
    color: var(--ts-ink-dim);
    text-decoration: none;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
}

.quick-action-btn i {
    font-size: 1.15rem;
    color: var(--ts-ink-faint);
    transition: color 0.15s;
}

.quick-action-btn:hover {
    background: var(--ts-2);
    border-color: var(--ts-ink-faint);
    color: var(--ts-ink);
}

.quick-action-btn:hover i { color: var(--ts-ink-dim); }

/* The action the shop actually opens this app to do */
.quick-action-btn.is-primary {
    background: var(--ts-accent-soft);
    border-color: var(--ts-accent-line);
    color: var(--ts-accent);
}

.quick-action-btn.is-primary i { color: var(--ts-accent); }

.quick-action-btn.is-primary:hover {
    background: var(--ts-accent);
    border-color: var(--ts-accent);
    color: #14100b;
}

.quick-action-btn.is-primary:hover i { color: #14100b; }

@media (max-width: 575.98px) {
    .quick-action-btn {
        flex-direction: column;
        gap: 0.2rem;
        font-size: 0.7rem;
        padding: 0.5rem 0.3rem;
        min-height: 58px;
        text-align: center;
        line-height: 1.15;
    }
    .quick-action-btn i { font-size: 1.15rem; }
}

/* ---- Dashboard: machine rows ---- */
.machine-link {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--ts-ink);
    text-decoration: none;
}

.machine-link i {
    color: var(--ts-ink-faint);
    font-size: 0.9rem;
}

.machine-link:hover { color: var(--ts-accent); }
.machine-link:hover i { color: var(--ts-accent); }

.machine-line {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    min-width: 0;
}

.machine-name {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--ts-ink);
}

.machine-type {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ts-ink-faint);
}

.count-tag {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ts-ink-faint);
}

.count-tag .ts-num {
    color: var(--ts-ink-dim);
    font-weight: 600;
}

/* ---- Dashboard: recent activity ---- */
.activity-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 0.65rem;
    border-color: var(--ts-line) !important;
    padding: 0.55rem 0.75rem;
}

.activity-dir {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 3px;
    font-size: 0.75rem;
}

.activity-dir.is-out {
    background: var(--ts-cool-soft);
    color: var(--ts-cool);
}

.activity-dir.is-back {
    background: var(--ts-ok-soft);
    color: var(--ts-ok);
}

.activity-tool {
    font-weight: 600;
    font-size: 0.9rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.activity-target {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.8rem;
    color: var(--ts-ink-dim);
    white-space: nowrap;
}

.activity-time {
    font-size: 0.72rem;
    color: var(--ts-ink-faint);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

@media (max-width: 575.98px) {
    .activity-row {
        grid-template-columns: auto minmax(0, 1fr);
        row-gap: 0.3rem;
    }
    .activity-target { grid-column: 2; }
    .activity-time { grid-column: 2; }
}

/* ---- Dashboard: Tools in Machines chips ---- */
.dash-tool-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.dash-tool-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.25rem 0.55rem 0.25rem 0.3rem;
    border-radius: var(--ts-r);
    background: var(--ts-2);
    border: 1px solid var(--ts-line);
    font-size: 0.8rem;
    white-space: nowrap;
    transition: border-color 0.15s, background 0.15s;
}

.dash-tool-chip:hover {
    background: var(--ts-3);
    border-color: var(--ts-line-strong);
}

.dash-tool-name {
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-tool-chip-link {
    text-decoration: none;
    color: inherit;
    transition: transform 0.1s;
}

.dash-tool-chip-link:hover {
    color: inherit;
    border-color: var(--ts-accent-line);
}

@media (max-width: 575.98px) {
    .dash-tool-chip {
        font-size: 0.75rem;
    }
    .dash-tool-name {
        max-width: 120px;
    }
}

/* ---- Tool list layout ---- */
.tool-list-items {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.tool-list-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.6rem 0.75rem;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
    background: var(--ts-1);
    border: 1px solid var(--ts-line);
    border-left: 2px solid transparent;
    border-radius: var(--ts-r);
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s;
}

.tool-list-row:hover {
    background: var(--ts-2);
    border-left-color: var(--ts-accent);
}

/* Build tags (assembled / indexable) — construction facts, not state */
.badge.tag-build {
    background: transparent;
    border: 1px solid var(--ts-line-strong);
    color: var(--ts-ink-dim);
    font-weight: 600;
    font-size: 0.65rem;
    letter-spacing: 0.03em;
}

.badge.tag-build i { opacity: 0.6; }

/* Product photos need a light backdrop, but a grid of pure-white tiles
   on a dark page reads as strobing — soften and contain them. */
.tool-list-thumb {
    width: 38px;
    height: 38px;
    object-fit: contain;
    border-radius: var(--ts-r);
    background: #dcdfe4;
    border: 1px solid var(--ts-line-strong);
    padding: 2px;
    flex-shrink: 0;
}

[data-bs-theme="light"] .tool-list-thumb {
    background: #fff;
}

.tool-list-main {
    flex: 1;
    min-width: 0;
}

.tool-list-name {
    font-weight: 600;
    font-size: 0.95rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tool-list-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: center;
    margin-top: 2px;
    font-size: 0.8rem;
}

.tool-list-meta .badge {
    font-size: 0.7rem;
}

.tool-list-status {
    flex-shrink: 0;
    text-align: right;
    font-size: 0.85rem;
}

.tool-assignment-link {
    color: var(--ts-info);
    text-decoration: none;
    font-weight: 600;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.tool-assignment-link:hover {
    color: var(--ts-accent);
}

.t-badge-sm {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 26px;
    padding: 0.1em 0.35em;
    border-radius: 3px;
    font-weight: 700;
    font-size: 0.75rem;
    letter-spacing: 0.03em;
    background: var(--ts-accent-soft);
    border: 1px solid var(--ts-accent-line);
    color: var(--ts-accent);
}

.tool-available-tag {
    color: var(--ts-success);
    font-weight: 600;
    white-space: nowrap;
}

@media (max-width: 575.98px) {
    .tool-list-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.3rem;
        overflow: hidden;
    }
    .tool-list-main {
        width: 100%;
        min-width: 0;
    }
    .tool-list-status {
        text-align: left;
        font-size: 0.8rem;
    }
}

/* ============================================================
   Tool instances — the physical copies
   ============================================================ */

/* Each list entry is a row plus a collapsible panel of its instances. */
.tool-list-item + .tool-list-item {
    margin-top: 2px;
}

.inst-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex-shrink: 0;
    min-height: 34px;
    padding: 0.2rem 0.5rem;
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r);
    background: var(--ts-2);
    color: var(--ts-ink-dim);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.inst-toggle:hover {
    color: var(--ts-ink);
    border-color: var(--ts-ink-faint);
    background: var(--ts-3);
}

.inst-toggle .bi {
    font-size: 0.7rem;
    transition: transform 0.15s;
}

.inst-toggle.open .bi-chevron-down {
    transform: rotate(180deg);
}

/* Flag a tool that has no loadable copy left. */
.inst-toggle.none-free {
    border-color: rgba(207, 154, 47, 0.4);
    color: var(--ts-warn);
}

.inst-panel {
    border: 1px solid var(--ts-line);
    border-top: none;
    border-radius: 0 0 var(--ts-r) var(--ts-r);
    background: var(--ts-0);
    padding: 0.5rem 0.6rem 0.6rem;
}

.inst-panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.4rem;
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ts-ink-faint);
}

/* ident · state · life · where-it-is · actions.
   Life and location get the flexible space; the rest size to content. */
.inst-row {
    display: grid;
    grid-template-columns: auto auto minmax(120px, 1fr) minmax(150px, 1.4fr) auto;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.5rem;
    border-radius: var(--ts-r);
    border: 1px solid transparent;
}

.inst-row + .inst-row {
    margin-top: 2px;
}

.inst-row:hover {
    background: var(--ts-2);
    border-color: var(--ts-line);
}

.inst-row.is-scrapped {
    opacity: 0.5;
}

.inst-ident {
    font-family: var(--ts-mono);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--ts-ink-dim);
    letter-spacing: 0.02em;
}

.inst-meta {
    min-width: 0;
    font-size: 0.75rem;
    color: var(--ts-ink-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.inst-meta .inst-measure {
    font-family: var(--ts-mono);
    font-variant-numeric: tabular-nums;
    color: var(--ts-ink);
}

.inst-actions {
    display: flex;
    gap: 0.25rem;
    justify-content: flex-end;
}

.inst-actions .btn {
    --bs-btn-padding-y: 0.15rem;
    --bs-btn-padding-x: 0.4rem;
    font-size: 0.7rem;
    min-height: 30px;
}

/* ---- State chip ---- */
.state-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    padding: 0.15em 0.5em;
    border-radius: 999px;
    border: 1px solid transparent;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    white-space: nowrap;
}

.state-chip::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

.state-in_crib    { background: var(--ts-3); border-color: var(--ts-line-strong); color: var(--ts-ink-dim); }
.state-preset     { background: var(--ts-accent-soft); border-color: var(--ts-accent-line); color: var(--ts-accent); }
.state-in_machine { background: var(--ts-cool-soft); border-color: rgba(77,143,184,0.3); color: var(--ts-cool); }
.state-regrind    { background: rgba(207,154,47,0.13); border-color: rgba(207,154,47,0.3); color: var(--ts-warn); }
.state-scrapped   { background: var(--ts-alarm-soft); border-color: rgba(209,88,79,0.3); color: var(--ts-alarm); }

/* ---- Tool life ---- */
.life-wrap {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    min-width: 0;
}

.life-bar {
    flex: 1;
    min-width: 46px;
    height: 4px;
    border-radius: 2px;
    background: var(--ts-3);
    overflow: hidden;
}

.life-fill {
    height: 100%;
    border-radius: 2px;
    background: var(--ts-accent);
    transition: width 0.3s;
}

.life-fill.warn  { background: var(--ts-warn); }
.life-fill.spent { background: var(--ts-alarm); }

.life-text {
    font-family: var(--ts-mono);
    font-variant-numeric: tabular-nums;
    font-size: 0.7rem;
    color: var(--ts-ink-faint);
    white-space: nowrap;
}

.life-text.spent { color: var(--ts-alarm); font-weight: 600; }

.life-none {
    font-size: 0.7rem;
    color: var(--ts-ink-faint);
    opacity: 0.6;
}

@media (max-width: 767.98px) {
    .inst-row {
        grid-template-columns: auto 1fr;
        row-gap: 0.35rem;
    }
    .inst-row > .life-wrap,
    .inst-row > .inst-meta { grid-column: 1 / -1; }
    .inst-actions { grid-column: 1 / -1; justify-content: flex-start; }
}

/* Instance picker inside a pending assignment row */
.pending-inst {
    margin-top: 0.35rem;
    font-family: var(--ts-mono);
    font-size: 0.72rem;
    padding: 0.2rem 1.6rem 0.2rem 0.4rem;
    min-height: 30px;
}

/* ============================================================
   Stock movements
   ============================================================ */

.mv-table {
    border: 1px solid var(--ts-line);
    border-radius: var(--ts-r-lg);
    overflow: hidden;
    background: var(--ts-1);
}

.mv-row {
    display: grid;
    grid-template-columns: 132px minmax(0, 2fr) 130px 70px 70px minmax(0, 1.2fr);
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.7rem;
    border-top: 1px solid var(--ts-line);
    font-size: 0.8rem;
}

.mv-row-consume {
    grid-template-columns: minmax(0, 2fr) 70px minmax(80px, 1.4fr) 90px 90px;
}

.mv-row:first-child { border-top: none; }
.mv-row:not(.mv-head):hover { background: var(--ts-2); }

.mv-head {
    background: var(--ts-2);
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ts-ink-faint);
}

.mv-when,
.mv-after,
.mv-delta,
.mv-rate {
    font-family: var(--ts-mono);
    font-variant-numeric: tabular-nums;
}

.mv-when { color: var(--ts-ink-faint); font-size: 0.72rem; }
.mv-after { color: var(--ts-ink-dim); }
.mv-rate { color: var(--ts-ink); font-weight: 600; }

.mv-item {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--ts-ink);
}

/* Which kind of thing moved, kept quiet next to the name */
.mv-kind {
    display: inline-block;
    margin-right: 0.4rem;
    padding: 0.05em 0.35em;
    border-radius: 3px;
    border: 1px solid var(--ts-line-strong);
    font-size: 0.6rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ts-ink-faint);
}

.mv-reason {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    padding: 0.1em 0.4em;
    border-radius: 3px;
    white-space: nowrap;
}

.mv-ref {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.72rem;
    color: var(--ts-ink-faint);
}

.mv-actor {
    margin-left: 0.4rem;
    opacity: 0.65;
    font-style: normal;
}

/* Direction, not decoration: in is good, out is spend, scrap is loss. */
.tone-in      { color: var(--ts-ok); }
.tone-out     { color: var(--ts-accent); }
.tone-bad     { color: var(--ts-alarm); }
.tone-warn    { color: var(--ts-warn); }
.tone-neutral { color: var(--ts-ink-dim); }

.mv-reason.tone-in      { background: var(--ts-ok-soft); }
.mv-reason.tone-out     { background: var(--ts-accent-soft); }
.mv-reason.tone-bad     { background: var(--ts-alarm-soft); }
.mv-reason.tone-warn    { background: rgba(207, 154, 47, 0.13); }
.mv-reason.tone-neutral { background: var(--ts-3); }

.mv-spark {
    display: block;
    height: 4px;
    border-radius: 2px;
    background: var(--ts-3);
    overflow: hidden;
}

.mv-spark-fill {
    display: block;
    height: 100%;
    border-radius: 2px;
    background: var(--ts-accent);
}

@media (max-width: 767.98px) {
    .mv-row,
    .mv-row-consume {
        grid-template-columns: 1fr auto;
        row-gap: 0.25rem;
    }
    .mv-head { display: none; }
    .mv-when, .mv-ref, .mv-spark { grid-column: 1 / -1; }
}

/* ---- Offset register pills (H/D) ---- */
.reg-pill {
    display: inline-flex;
    align-items: center;
    font-family: var(--ts-mono);
    font-size: 0.7rem;
    font-weight: 600;
    padding: 0.1em 0.35em;
    border-radius: 3px;
    background: var(--ts-3);
    border: 1px solid var(--ts-line-strong);
    color: var(--ts-ink-dim);
    letter-spacing: 0.02em;
}

/* ---- Activity collapse ---- */
.activity-collapsed {
    display: none;
}

.activity-expanded {
    display: block;
}

.activity-toggle-btn {
    cursor: pointer;
    border: none !important;
    opacity: 0.7;
    transition: opacity 0.15s;
}

.activity-toggle-btn:hover {
    opacity: 1;
}

/* ---- Modal: keep footer visible above bottom nav ---- */
.modal-dialog-scrollable {
    max-height: calc(100vh - 90px) !important;
}

.modal-dialog-scrollable .modal-content {
    max-height: calc(100vh - 90px) !important;
}

/* Fullscreen modals: ensure body scrolls and footer stays above bottom nav */
@media (max-width: 767.98px) {
    .modal-fullscreen-md-down .modal-content {
        max-height: 100vh !important;
        height: 100vh !important;
    }
    .modal-fullscreen-md-down .modal-body {
        overflow-y: auto !important;
        flex: 1 1 auto;
        padding-bottom: 80px;
    }
    .modal-fullscreen-md-down .modal-footer {
        position: sticky;
        bottom: 0;
        background: var(--bs-modal-bg, var(--bs-body-bg));
        z-index: 10;
        padding-bottom: calc(0.75rem + 76px);
        box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.3);
    }
}

/* Desktop modals also need to scroll properly with Hoffmann content */
@media (min-width: 768px) {
    .modal-dialog-scrollable .modal-body {
        overflow-y: auto !important;
    }
}

/* ---- Tool hover preview card ---- */
.tool-preview {
    position: fixed;
    z-index: 1060;
    width: 300px;
    background: var(--bs-modal-bg, var(--bs-body-bg));
    border: 1px solid var(--ts-border-dark);
    border-radius: 0.5rem;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
    padding: 0.75rem;
    pointer-events: none;
    opacity: 0;
    transform: scale(0.95);
    transition: opacity 0.15s, transform 0.15s;
}

.tool-preview.visible {
    opacity: 1;
}

.tool-preview:not(.touch-mode).visible {
    transform: scale(1);
}

/* Allow interaction on touch (long-press) */
.tool-preview.touch-mode {
    pointer-events: auto;
}

.tool-preview-img {
    width: 100%;
    max-height: 160px;
    object-fit: contain;
    background: #dcdfe4;
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r);
    padding: 6px;
    margin-bottom: 0.5rem;
}

[data-bs-theme="light"] .tool-preview-img { background: #fff; }

.tool-preview-name {
    font-weight: 700;
    font-size: 0.95rem;
    margin-bottom: 0.4rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tool-preview-specs {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.15rem 0.5rem;
    font-size: 0.8rem;
}

.tool-preview-specs dt {
    color: var(--ts-muted);
    font-weight: 400;
}

.tool-preview-specs dd {
    margin: 0;
    font-weight: 600;
}

/* ---- Tool modal image ---- */
.tf-image-preview {
    max-height: 140px;
    max-width: 100%;
    object-fit: contain;
    background: #dcdfe4;
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r);
    padding: 4px;
}

[data-bs-theme="light"] .tf-image-preview { background: #fff; }

/* ---- Language toggle ---- */
#lang-toggle,
#lang-toggle-mobile {
    font-weight: 700;
    font-size: 0.75rem;
    min-width: 32px;
    min-height: 32px;
    padding: 2px 6px;
}

/* ---- Tour (Driver.js) custom theme ---- */
.retrotool-tour-popover.driver-popover {
    background: var(--ts-surface-dark, #1a1d28);
    color: #e0e0e0;
    border: 1px solid var(--ts-accent);
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
    max-width: 340px;
}

.retrotool-tour-popover .driver-popover-title {
    color: var(--ts-accent);
    font-size: 1rem;
    font-weight: 700;
}

.retrotool-tour-popover .driver-popover-description {
    color: #c0c0c0;
    font-size: 0.875rem;
    line-height: 1.5;
}

.retrotool-tour-popover .driver-popover-progress-text {
    color: #888;
    font-size: 0.75rem;
}

.retrotool-tour-popover .driver-popover-navigation-btns button,
.retrotool-tour-popover .driver-popover-next-btn,
.retrotool-tour-popover .driver-popover-prev-btn,
.retrotool-tour-popover button.driver-popover-done-btn {
    border-radius: 6px;
    font-size: 0.8rem;
    padding: 6px 16px;
    font-weight: 300 !important;
    text-shadow: none !important;
    -webkit-font-smoothing: antialiased !important;
    -moz-osx-font-smoothing: grayscale !important;
    letter-spacing: 0.02em;
}

.retrotool-tour-popover .driver-popover-next-btn {
    background: var(--ts-accent) !important;
    color: #fff !important;
    border: none;
}

.retrotool-tour-popover .driver-popover-next-btn:hover {
    background: var(--ts-accent-hover) !important;
}

.retrotool-tour-popover .driver-popover-prev-btn {
    background: transparent !important;
    color: #aaa !important;
    border: 1px solid #555 !important;
}

.retrotool-tour-popover .driver-popover-close-btn {
    color: #888 !important;
}

.retrotool-tour-popover .driver-popover-arrow-side-left .driver-popover-arrow,
.retrotool-tour-popover .driver-popover-arrow-side-right .driver-popover-arrow,
.retrotool-tour-popover .driver-popover-arrow-side-top .driver-popover-arrow,
.retrotool-tour-popover .driver-popover-arrow-side-bottom .driver-popover-arrow {
    border-color: var(--ts-accent);
}

/* Light theme overrides for tour */
[data-bs-theme="light"] .retrotool-tour-popover.driver-popover {
    background: #fff;
    color: #333;
    border: 1px solid var(--ts-accent);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
}

[data-bs-theme="light"] .retrotool-tour-popover .driver-popover-description {
    color: #555;
}

[data-bs-theme="light"] .retrotool-tour-popover .driver-popover-prev-btn {
    color: #555 !important;
    border-color: #ccc !important;
}

/* ---- Help Page ---- */
.help-page {
    max-width: 700px;
    margin: 0 auto;
}

.help-section .card-title {
    font-size: 1.1rem;
    font-weight: 700;
    margin-bottom: 0.75rem;
}

.help-steps {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.help-step {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.help-step-num {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--ts-accent);
    color: #fff;
    font-weight: 700;
    font-size: 0.9rem;
    flex-shrink: 0;
}

.help-step p {
    margin: 0.25rem 0 0 0;
    font-size: 0.875rem;
    opacity: 0.8;
}

.help-list {
    padding-left: 1.25rem;
    font-size: 0.875rem;
    opacity: 0.85;
}

.help-list li {
    margin-bottom: 0.4rem;
}

.help-tip {
    background: rgba(230, 126, 34, 0.1);
    border-left: 3px solid var(--ts-accent);
    padding: 0.5rem 0.75rem;
    border-radius: 0 6px 6px 0;
    font-size: 0.85rem;
    margin-top: 0.75rem;
}

/* A page's filter row stays reachable while its list scrolls.
   Only from md up: on a phone these filters stack four rows deep and would
   eat a fifth of the screen permanently, which costs more than it saves.
   The tab bar on Stock is different — it stays pinned everywhere, because
   it is navigation and it collapses to icons. */
@media (min-width: 768px) {
    .page-toolbar {
        position: sticky;
        top: var(--header-h, 49px);
        z-index: 1035;
        background: var(--ts-0);
        margin-inline: -1rem;
        padding: 0.5rem 1rem;
        border-bottom: 1px solid var(--ts-line);
    }
}

/* ---- Stock page: type selector + list tools ---- */

/* Two rows: what you're looking at, then how you filter it.
   Sticks under the header so you can still switch tabs and filter part-way
   down a long list. Bleeds to the page edges, otherwise rows show through
   beside it as they scroll past. */
.stock-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;

    position: sticky;
    top: var(--header-h, 49px);
    z-index: 1035;
    background: var(--ts-0);
    margin-inline: -1rem;
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--ts-line);
}

/* One segmented control, same pattern as the category toggle on Tools —
   picking one of N should look the same everywhere in the app. */
.stock-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    background: var(--ts-2);
    border: 1px solid var(--ts-line);
    border-radius: var(--ts-r-lg);
    padding: 3px;
    margin: 0;
    list-style: none;
}

/* Movements is a log across every type, not another type. */
.stock-tabs .stock-tab-sep {
    margin-left: 0.35rem;
    padding-left: 0.4rem;
    border-left: 1px solid var(--ts-line-strong);
}

.stock-tab-btn {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.7rem;
    border: none;
    border-radius: var(--ts-r);
    background: transparent;
    color: var(--ts-ink-faint);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    white-space: nowrap;
    transition: color 0.15s, background 0.15s;
}

.stock-tab-btn:hover {
    background: var(--ts-3);
    color: var(--ts-ink);
}

/* Bootstrap bakes #0d6efd into --bs-nav-pills-link-active-bg, so remapping
   --bs-primary never reaches it. Restate the active state outright. */
.stock-tabs .nav-link.active,
.stock-tabs .nav-link.show {
    background: var(--ts-accent) !important;
    color: #14100b !important;
}

.stock-tab-icon {
    width: 26px;
    height: 16px;
    flex-shrink: 0;
    opacity: 0.7;
}

.stock-tab-btn:hover .stock-tab-icon { opacity: 0.9; }
.nav-link.active .stock-tab-icon { opacity: 1; }

.stock-bar-tools {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.stock-search {
    position: relative;
    width: 200px;
}

.stock-search i {
    position: absolute;
    left: 0.55rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.75rem;
    color: var(--ts-ink-faint);
    pointer-events: none;
}

.stock-search input {
    padding-left: 1.85rem;
}

@media (max-width: 767.98px) {
    .stock-bar-tools {
        width: 100%;
        margin-left: 0;
    }
    .stock-search { flex: 1; width: auto; }
    .stock-tab-btn span { display: none; }   /* icons only when space is tight */
    .stock-tab-btn { padding: 0.4rem 0.55rem; }
    .stock-tab-icon { width: 30px; height: 18px; }
}

/* ---- Wizard ---- */
.wiz-thumb {
    width: 40px;
    height: 40px;
    object-fit: contain;
    background: #dcdfe4;
    border: 1px solid var(--ts-line-strong);
    border-radius: var(--ts-r);
    flex-shrink: 0;
}

[data-bs-theme="light"] .wiz-thumb { background: #fff; }

.wiz-thumb-empty {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
}

#wizardModal .list-group-item {
    border-color: rgba(255,255,255,0.1);
}

#wizardModal .list-group-item:hover {
    background: rgba(230, 126, 34, 0.1);
}

/* ---- Assign page: the magazine panel ----
   Sticky so the machine state stays in view while scrolling a long shelf;
   drawn as one bordered panel so the page reads "shelf left, machine right"
   rather than two loose lists. */
@media (min-width: 992px) {
    .assign-loadout-col {
        position: sticky;
        top: 60px;
        align-self: flex-start;
        max-height: calc(100vh - 80px);
        overflow-y: auto;
    }
}

.assign-magazine {
    background: var(--ts-card, rgba(255, 255, 255, 0.03));
    border: 1px solid var(--ts-border-dark, #3a3f54);
    border-radius: 12px;
    padding: 0.9rem;
}

[data-bs-theme="light"] .assign-magazine {
    border-color: #dee2e6;
    background: #fff;
}

/* ---- Assign page: tool rows ----
   Full-width rows, 52px targets, diameter in a fixed right column: the
   figures the operator hunts by sit in the same place on every row. */
.tool-assign-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    min-height: 52px;
    padding: 0.45rem 0.7rem;
    background: transparent;
    border: 1px solid var(--ts-border-dark, #3a3f54);
    border-radius: 10px;
    color: inherit;
    text-align: left;
    transition: border-color 0.15s, background 0.15s;
    cursor: pointer;
}

[data-bs-theme="light"] .tool-assign-row { border-color: #dee2e6; }

.tool-assign-row:hover:not(:disabled):not(.tool-blocked) {
    border-color: var(--ts-success);
}

.tool-assign-row.selected {
    border-color: var(--ts-success);
    background: rgba(39, 174, 96, 0.12);
}

.tool-assign-row.job-selected {
    border-color: var(--ts-warning, #f39c12);
    background: rgba(243, 156, 18, 0.12);
}

.tool-assign-row:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.tool-assign-row .tar-check { font-size: 1.05rem; flex-shrink: 0; }

.tool-assign-row .tar-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.tool-assign-row .tar-name {
    font-size: 0.86rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tool-assign-row .tar-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
    color: var(--ts-muted, #8a90a5);
}

.tool-assign-row .tar-dia {
    flex-shrink: 0;
    min-width: 3.4rem;
    text-align: right;
    font-weight: 700;
    font-size: 0.95rem;
    font-variant-numeric: tabular-nums;
    color: var(--ts-accent, #e67e22);
}

.tool-assign-row.tool-blocked {
    cursor: default;
    opacity: 0.75;
    border-style: dashed;
}

/* ---- Drag & Drop ---- */
.dragging {
    opacity: 0.5;
    transform: scale(0.95);
}

.drop-highlight {
    outline: 2px dashed var(--ts-accent) !important;
    outline-offset: -2px;
    background: rgba(230, 126, 34, 0.05) !important;
    border-radius: 8px;
    transition: outline 0.2s, background 0.2s;
}

/* Job Build Mode */
.job-build-highlight {
    border: 2px solid rgba(230, 126, 34, 0.2);
    border-radius: 10px;
    padding: 8px;
    animation: jobBreathe 3s ease-in-out infinite;
}

@keyframes jobBreathe {
    0%, 100% { border-color: rgba(230, 126, 34, 0.15); }
    50% { border-color: rgba(230, 126, 34, 0.7); }
}

.tool-assign-card.job-selected {
    border-color: var(--ts-accent) !important;
    background: rgba(230, 126, 34, 0.1) !important;
}

.loadout-tool-row.job-selected-row {
    background: rgba(230, 126, 34, 0.1);
    border-left: 3px solid var(--ts-accent);
}

.tool-assign-card[draggable="true"],
.loadout-tool-row[draggable="true"] {
    cursor: grab;
}

.tool-assign-card[draggable="true"]:active,
.loadout-tool-row[draggable="true"]:active {
    cursor: grabbing;
}

/* Belongs to this place but is not in it right now — in a machine, at the
   sharpening service, or scrapped. Dimmed so the two lists never read as one. */
.loc-item.is-away { opacity: 0.6; }
.loc-item.is-away .loc-item-title { text-decoration: line-through; }

/* Disassemble: one row per part, name on the left, destination on the right. */
.disasm-part {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--ts-line, rgba(128, 128, 128, 0.12));
}

.disasm-part:last-child { border-bottom: none; }
.disasm-part-name { flex: 1; min-width: 0; font-size: 0.85rem; }
.disasm-part-name > span { display: block; overflow: hidden; text-overflow: ellipsis; }
.disasm-part .disasm-loc { max-width: 13rem; }
.disasm-part.is-scrapped { opacity: 0.5; }
.disasm-part.is-scrapped .disasm-part-name > span { text-decoration: line-through; }

/* Holder shape editor: the drawing sits on the page's own surface, not on a
   white card, because it is an SVG that follows the theme. */
.hp-preview {
    border: 1px solid var(--ts-border);
    border-radius: var(--ts-r-lg, 8px);
    background: var(--ts-1, #14171b);
    padding: 0.4rem;
    min-height: 6rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.hp-preview svg { max-width: 100%; height: auto; }

/* Item picture inside an edit modal. Sized like the inline-styled previews
   in the other stock forms; without a cap a phone photo filled the whole
   modal and buried the form under itself. */
.modal-item-image {
    max-height: 120px;
    max-width: 100%;
    object-fit: contain;
    border-radius: 6px;
    background: #fff;
    padding: 4px;
}


/* Extra photos on a stock item. Thumbs are finger-sized; tapping one makes
   it the display picture, the corner button removes it. */
.photo-gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: center;
    margin-bottom: 0.75rem;
}

.photo-gallery:empty { display: none; }

.pg-thumb {
    position: relative;
}

.pg-thumb img {
    width: 64px;
    height: 64px;
    object-fit: cover;
    border-radius: 8px;
    background: #fff;
    border: 1px solid var(--ts-line-strong, #3a3f54);
    cursor: pointer;
}

.pg-del {
    position: absolute;
    top: -7px;
    right: -7px;
    width: 22px;
    height: 22px;
    padding: 0;
    border-radius: 50%;
    border: none;
    background: var(--ts-danger, #dc3545);
    color: #fff;
    font-size: 0.75rem;
    line-height: 1;
}
