:root {
  --bg: #f7f4f5;           /* soft warm white */
  --surface: #ffffff;      /* card / paper */
  --surface-2: #f5eef1;
  --ink: #3a3537;          /* charcoal-grey text */
  --ink-soft: #6c6469;
  --muted: #a59ba1;        /* soft grey */
  --line: #efe8ec;
  --line-strong: #e3d9df;
  --accent: #f6b5d3;       /* brand pink */
  --accent-deep: #d4669e;  /* readable pink — links, hover, active text */
  --accent-soft: #fcecf3;  /* pale pink — badges, chips, active pill */
  --mark: #ef96c4;         /* wordmark "st" */
  --brand-grey: #7f7f7f;   /* brand grey — wordmark body, logo bg */
  --sidebar: #ffffff;      /* light sidebar */
  --sidebar-ink: #6c6469;
  --danger: #c0564b;
  --ok: #4a8f6b;
  --warn: #c98a2c;
  --focus-ring: 0 0 0 3px rgba(246,181,211,.40);
  --shadow: 0 1px 2px rgba(60,50,55,.05), 0 10px 30px rgba(60,50,55,.07);
  --shadow-lg: 0 24px 60px rgba(60,50,55,.16);
  --r: 14px;
  --r-sm: 9px;
  --serif: "Fraunces", Georgia, serif;
  --round: "Fredoka", "Inter", sans-serif;
  --sans: "Inter", "Noto Sans Thai", -apple-system, BlinkMacSystemFont, sans-serif;

  /* Spacing scale — calibrated to values already used in this file (18/22/26/40/48…)
     so adopting these in new CSS shifts nothing visually. */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px;
  --s-5: 22px; --s-6: 26px; --s-7: 36px; --s-8: 48px;
  /* Type scale — six steps covering the sizes already hardcoded across the file. */
  --fs-xs: 11px; --fs-sm: 12.5px; --fs-base: 14px;
  --fs-md: 17px; --fs-lg: 22px; --fs-xl: 34px;
  /* Z-index scale — fixes real ordering bugs (toast at 9999 rendering over a modal
     at 100; a tooltip with no declared layer at all). */
  --z-sticky: 5; --z-nav: 40; --z-drawer: 60;
  --z-modal: 100; --z-tooltip: 300; --z-toast: 400;

  /* Content width — ONE value for every route. This used to be 1200px with wide-table
     routes opting into min(1720px,100%) via .content.is-wide, but on a wide monitor the
     1200px cap plus `margin:0 auto` left ~200px of dead space either side of the content
     (Home, Collection, etc.) while the opted-in routes (Create PO, PO History, Receiving)
     filled the screen properly — which is exactly the mismatch the user reported. The
     100% term means the content simply fills the space beside the sidebar until the
     screen gets genuinely huge, and the 1720px term stops line lengths running away on
     ultra-wide displays. */
  --content-max: min(1720px, 100%);
}
/* Inert hook for a future platform-wide dark theme — deliberately empty. Dark mode
   was removed from the Sale Analysis/Projects modules (see .sx-root below) rather
   than extended everywhere; if it's wanted later, values go here. */
html[data-theme="dark"] { color-scheme: dark; }
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body { font-family: var(--sans); background: var(--bg); color: var(--ink); font-size: 14px; -webkit-font-smoothing: antialiased; }
.hidden { display: none !important; }
.muted { color: var(--muted); }
.error { color: var(--danger); min-height: 1.2em; margin: 10px 0 0; font-size: 13px; }
.link { color: var(--accent-deep); text-decoration: none; font-weight: 600; }
.link:hover { color: var(--ink); }
.brand-mark { color: var(--accent-deep); }
/* brand wordmark (rounded, lowercase) */
.brand-text { font-family: var(--round); text-transform: lowercase; font-weight: 600; color: var(--brand-grey); letter-spacing: -.01em; }
.brand-text .wm-mark { color: var(--mark); }

h1, h2, h3 { font-family: var(--serif); font-weight: 600; letter-spacing: -0.01em; }

.demo-badge {
  position: fixed; bottom: 16px; right: 16px; z-index: 200; background: var(--ink); color: #fff;
  font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  padding: 8px 14px; border-radius: 999px; box-shadow: var(--shadow-lg); opacity: .92;
}

/* ---------- buttons ---------- */
.btn {
  font-family: var(--sans); font-weight: 600; font-size: 13.5px; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink);
  padding: 11px 18px; border-radius: var(--r-sm); transition: all .16s ease;
}
.btn:hover { border-color: var(--accent); color: var(--accent-deep); }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--ink); color: #fff; border-color: var(--ink); }
.btn-primary:hover { background: var(--accent-deep); border-color: var(--accent-deep); color: #fff; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn-ghost:hover { background: var(--surface-2); color: var(--ink); border-color: transparent; }
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-danger:hover { background: #a8483e; border-color: #a8483e; color: #fff; }
.btn-block { width: 100%; margin-top: 10px; }
.btn-sm { padding: 8px 13px; font-size: 12.5px; }
.btn-icon { padding: 9px; width: 36px; height: 36px; }
.skip-link { position: absolute; top: -50px; left: 12px; z-index: var(--z-toast); background: var(--ink); color: #fff; padding: 10px 18px; border-radius: var(--r-sm); font-weight: 600; text-decoration: none; transition: top .15s; }
.skip-link:focus { top: 12px; }
/* Sprite icons (index.html's <symbol> defs) — presentation attributes on the <symbol>
   itself don't apply through <use>'s shadow DOM, but CSS properties do, so fill/stroke
   live here rather than on the sprite markup. */
.ic { width: 18px; height: 18px; display: inline-block; vertical-align: -4px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.btn .ic, .btn-icon .ic { width: 16px; height: 16px; vertical-align: -3px; }

/* ---------- login ---------- */
.login-screen { min-height: 100vh; display: grid; grid-template-columns: 1.05fr .95fr; }
.login-aside {
  background:
    radial-gradient(680px 460px at 20% 16%, #fbdcea 0%, transparent 62%),
    radial-gradient(620px 520px at 90% 94%, #f0e6eb 0%, transparent 58%), #f8eef3;
  color: var(--ink); display: flex; flex-direction: column; justify-content: flex-end; padding: 56px 60px;
}
.login-wordmark { font-size: 76px; line-height: 1; }
.login-wordmark .brand-text { font-weight: 600; }
.login-tag { color: var(--ink-soft); font-size: 14px; letter-spacing: .04em; margin: 18px 0 0; }
.login-card { align-self: center; width: 100%; max-width: 380px; margin: 0 auto; padding: 44px 44px; background: var(--surface); }
.login-screen > .login-card { box-shadow: none; border: none; background: transparent; }
.login-card h1 { margin: 0 0 4px; font-size: 30px; }
.login-card .muted { margin: 0 0 26px; font-size: 13px; }
.login-hint { margin-top: 20px; font-size: 12px; text-align: center; }

/* ---------- inputs ----------
   Layout (width/margin) lives in a zero-specificity :where() so every existing
   per-module override (.ws-table input, .pj-editable-table input, .tlv-toolbar
   select, …) keeps winning automatically — no call site needs to change. Only
   the shared "skin" (padding/border/font/colour) stays at normal specificity. */
:where(input, select) { width: 100%; margin-top: 7px; min-width: 0; }
:where(label) { display: block; font-weight: 600; font-size: 12px; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; }
.label-plain { text-transform: none; letter-spacing: normal; font-weight: 500; color: var(--ink); }
input, select {
  padding: 11px 13px; font-family: var(--sans); font-size: 14px; font-weight: 500;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: var(--surface); color: var(--ink); text-transform: none; letter-spacing: normal;
}
/* Hide the browser's native number spinners (the up/down arrows that appear on hover in
   Create PO's Total to order / Actual ordered, and in every other numeric cell — they all
   have the identical behaviour). Purely visual: the fields stay type="number", so typing,
   min/max and every existing calculation and validation are unchanged. Removing them also
   takes away a real hazard in a PO worksheet — a stray click on an arrow silently changes
   an order quantity by one. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
input::placeholder { color: #c3b8bf; }
input:focus, select:focus { outline: none; border-color: var(--accent-deep); box-shadow: var(--focus-ring); }
.search { max-width: 380px; margin: 0 0 22px; }
:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 2px; }

/* New-form opt-in wrapper (Phase 5 inline validation) — not backfilled onto
   existing markup, :where() above already fixed those. */
.form-field { margin-bottom: 14px; }
/* fieldError()'s fallback (no .form-field wrapper) marks the input's own parent, which
   varies across this app's existing markup (bare <label>, .picker-block, a plain row div
   around a <select> + button) — kept generic rather than enumerating every wrapper shape. */
.field-msg { color: var(--danger); font-size: var(--fs-sm); margin-top: 5px; display: block; text-transform: none; letter-spacing: normal; font-weight: 500; }
.is-invalid > input, .is-invalid > select, .is-invalid > .chip-pick { border-color: var(--danger); }
.is-invalid > .chip-pick { border-width: 1px; border-style: solid; border-radius: var(--r-sm); padding: 6px; }

/* ---------- app shell ---------- */
/* minmax(0, 1fr), NOT 1fr. A `1fr` track has an automatic minimum, so it refuses to shrink
   below its content's min-content width — any wide child (the Timeline's
   `.tlv-grid{min-width:max-content}`, or a `.dt` table's `--dt-min`) then inflates this
   track, widens .content past the viewport and scrolls the WHOLE PAGE sideways, dragging
   the header and toolbar off-screen with it. minmax(0,…) lets the track shrink so those
   children scroll inside their own `overflow:auto` box, which is what they were built to do.
   Measured on Timeline before/after: page scrollWidth 1572 -> 1397 at a 1397px viewport. */
.app { display: grid; grid-template-columns: 256px minmax(0, 1fr); min-height: 100vh; }
.sidebar { background: var(--sidebar); color: var(--sidebar-ink); padding: 26px 18px; display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; border-right: 1px solid var(--line); }
.sidebar-top { display: flex; align-items: center; justify-content: space-between; }
.logo { font-size: 27px; padding: 2px 10px 26px; }
.logo .brand-text { font-weight: 600; }
.nav-drawer-close { display: none; }
/* ---- swap-in logo support: drop a logo.png in the project root ---- */
.brand-logo { display: none; }
.has-logo .brand-text { display: none; }
.has-logo .brand-logo { display: block; }
.logo .brand-logo { height: 30px; width: auto; }
.login-wordmark .brand-logo { height: 76px; width: auto; max-width: 100%; }
.po-doc-brand .brand-logo { height: 36px; width: auto; }
.nav { display: flex; flex-direction: column; gap: 3px; overflow-y: auto; }
.nav-item { display: flex; align-items: center; gap: 13px; padding: 12px 14px; border-radius: var(--r-sm); color: var(--sidebar-ink); text-decoration: none; font-weight: 600; font-size: 14px; transition: all .15s; }
.nav-item .ic { width: 18px; text-align: center; opacity: .75; }
.nav-item:hover { background: var(--surface-2); color: var(--ink); }
.nav-item.active { background: var(--accent-soft); color: var(--accent-deep); }
.nav-item.active .ic { opacity: 1; color: var(--accent-deep); }
/* Groups (Products/Orders/Insights/Projects/Finance/Admin) mirror the permission matrix —
   a group with zero visible items gets .hidden (JS, refreshNavGroups()) rather than
   rendering an empty labelled section. */
.nav-group { margin-top: 14px; }
.nav-group-title { padding: 0 14px 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.nav-group .nav-item { gap: 13px; }
/* Once so few tabs are visible that grouping adds no scanning value (≤5 total), the nav
   flattens back into a plain list — group titles disappear, spacing equalizes. */
.nav--flat .nav-group { margin-top: 0; }
.nav--flat .nav-group-title { display: none; }
.sidebar-foot { margin-top: auto; border-top: 1px solid var(--line); padding-top: 16px; }
.user-chip { font-size: 12px; color: var(--muted); margin-bottom: 10px; word-break: break-all; }
.mobile-topbar { display: none; }
.nav-scrim { display: none; }

.content { width: 100%; padding: 40px 48px 70px; max-width: var(--content-max); margin: 0 auto; }
.view { animation: fade .25s ease; }
@keyframes fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 30px; padding-bottom: 22px; border-bottom: 1px solid var(--line); }
.page-head h1 { margin: 0 0 6px; font-size: 34px; }
.page-head p { margin: 0; font-size: 14px; }
.section-title { font-size: 19px; margin: 36px 0 16px; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; margin: 40px 0 16px; }
.section-head .section-title { margin: 0; }
.back-link { color: var(--muted); text-decoration: none; font-weight: 600; font-size: 13px; display: inline-block; margin-bottom: 18px; }
.back-link:hover { color: var(--accent-deep); }

/* ---------- home dashboard (Platform UX Phase 2) ---------- */
.home-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-5); align-items: start; }
.home-card { grid-column: span 2; }
.home-card.span-half { grid-column: span 1; }
@media (max-width: 900px) { .home-grid { grid-template-columns: minmax(0, 1fr); } .home-card.span-half { grid-column: span 1; } }
.home-card .card-title { font-family: var(--serif); font-size: var(--fs-md); font-weight: 600; margin: 0 0 var(--s-3); display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.home-card .card-title .link { font-size: var(--fs-sm); font-weight: 600; }

.home-queue { display: flex; flex-direction: column; gap: 2px; }
.home-queue-row { display: flex; align-items: center; gap: 10px; padding: 10px 8px; border-radius: var(--r-sm); text-decoration: none; color: var(--ink); font-weight: 600; font-size: 13.5px; transition: background .12s; }
.home-queue-row:hover { background: var(--surface-2); }
.home-queue-dot { width: 8px; height: 8px; border-radius: 999px; flex-shrink: 0; background: var(--muted); }
.home-queue-dot.warn { background: var(--warn); }
.home-queue-dot.danger { background: var(--danger); }
.home-queue-row .home-queue-count { font-family: var(--serif); font-size: 15px; min-width: 22px; }
.home-queue-row .home-queue-label { flex: 1; color: var(--ink-soft); font-weight: 500; }
.home-queue-empty { color: var(--muted); font-size: 13.5px; padding: 6px 8px; }

.tile-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s-3); }
.tile { background: var(--surface-2); border-radius: var(--r-sm); padding: var(--s-4); text-decoration: none; color: var(--ink); display: block; transition: transform .12s, box-shadow .12s; }
.tile:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.tile-num { display: block; font-family: var(--serif); font-size: 26px; line-height: 1.1; }
.tile-label { color: var(--muted); font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; margin-top: 6px; display: block; }
.tile-delta { font-size: 11.5px; font-weight: 600; margin-top: 4px; }
.tile-delta.up { color: var(--ok); } .tile-delta.down { color: var(--danger); } .tile-delta.flat { color: var(--muted); }

.home-list { display: flex; flex-direction: column; gap: 10px; }
.home-list-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; text-decoration: none; color: var(--ink); font-size: 13px; }
.home-list-row .hl-main { font-weight: 600; }
.home-list-row .hl-sub { color: var(--muted); font-size: 12px; }
.home-progress { width: 100%; height: 5px; background: var(--surface-2); border-radius: 999px; overflow: hidden; margin-top: 4px; }
.home-progress > span { display: block; height: 100%; background: var(--accent-deep); border-radius: 999px; }

.home-empty { text-align: center; padding: var(--s-6) var(--s-4); color: var(--muted); }
.home-empty .ic { width: 30px; height: 30px; opacity: .45; margin-bottom: 8px; }
.home-empty p { margin: 4px 0 0; font-size: 13px; }

/* ---------- stats (legacy — still used by non-Home stat rows if any) ---------- */
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 24px 26px; }
.stat-num { display: block; font-family: var(--serif); font-size: 38px; line-height: 1; }
.stat-label { color: var(--muted); font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; margin-top: 10px; display: block; }

/* ---------- workflow ---------- */
.workflow { display: flex; align-items: stretch; gap: 8px; }
.step-card { flex: 1; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 26px; cursor: pointer; transition: all .18s; }
.step-card:hover { border-color: var(--accent); transform: translateY(-3px); box-shadow: var(--shadow); }
.step-no { font-family: var(--serif); font-size: 13px; font-weight: 700; color: var(--accent-deep); letter-spacing: .14em; margin-bottom: 14px; }
.step-card h3 { margin: 0 0 8px; font-size: 18px; }
.step-card p { margin: 0 0 16px; color: var(--muted); font-size: 13px; line-height: 1.6; }
.step-link { color: var(--accent-deep); font-weight: 700; font-size: 13px; }
.step-arrow { display: grid; place-items: center; color: var(--line-strong); font-size: 20px; }

/* ---------- cards / grids ---------- */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 22px; }
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 22px; }
.col-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; cursor: pointer; transition: all .18s; }
.col-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); border-color: var(--line-strong); }
.col-card .thumb { aspect-ratio: 1/1; background: linear-gradient(135deg, var(--accent-soft), var(--surface-2)); display: grid; place-items: center; color: var(--line-strong); font-size: 34px; overflow: hidden; }
.col-card .thumb img { width: 100%; height: 100%; object-fit: cover; }
.col-card .meta { padding: 16px 18px; }
.col-card .meta strong { display: block; font-family: var(--serif); font-size: 17px; font-weight: 600; }
.col-card .meta .sub { color: var(--muted); font-size: 12px; margin-top: 4px; }
.badge { display: inline-block; background: var(--accent-soft); color: var(--accent-deep); font-weight: 700; font-size: 11px; letter-spacing: .05em; text-transform: uppercase; padding: 5px 12px; border-radius: 999px; margin-top: 10px; }

/* collection detail */
.collection-head { align-items: center; }
.collection-hero { display: flex; gap: 22px; align-items: center; }
.collection-hero-img { width: 96px; height: 96px; border-radius: var(--r-sm); object-fit: cover; background: var(--accent-soft); }
.item-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 18px; }
.item-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 16px; transition: all .15s; }
.item-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow); }
.item-card .item-top { display: flex; gap: 13px; align-items: center; margin-bottom: 12px; }
.item-card .item-thumb { width: 56px; height: 56px; border-radius: 8px; object-fit: cover; background: var(--accent-soft); flex: none; }
.item-card .item-title { font-family: var(--serif); font-weight: 600; font-size: 15px; margin-bottom: 4px; }
.item-card svg { width: 100%; }

/* ---------- form grid ---------- */
.form-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 0 18px; }
.form-grid .full { grid-column: 1 / -1; }

.pm-image-row { display: flex; align-items: center; gap: 12px; }
.pm-image-row input[type=file] { flex: 1; min-width: 0; }
.pm-image-preview { width: 54px; height: 54px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); background: var(--bg); flex: 0 0 auto; }

/* ---------- modal ---------- */
.modal-backdrop { position: fixed; inset: 0; background: rgba(27,24,21,.5); backdrop-filter: blur(3px); display: grid; place-items: center; z-index: var(--z-modal); padding: 20px; }
.modal { background: var(--surface); border-radius: 18px; padding: 30px; width: 100%; max-width: 440px; max-height: calc(100vh - 40px); overflow-y: auto; box-shadow: var(--shadow-lg); animation: pop .16s ease; border: 1px solid var(--line); }
.modal-wide { max-width: 760px; }
@keyframes pop { from { transform: scale(.97); opacity: 0; } to { transform: none; opacity: 1; } }
.modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; }
.modal-head h2 { margin: 0; font-size: 22px; }
.modal-close { border: none; background: var(--surface-2); width: 32px; height: 32px; border-radius: 8px; cursor: pointer; font-size: 14px; color: var(--muted); }
.modal-close:hover { background: var(--accent-soft); color: var(--accent-deep); }
/* ---------- command palette (Phase 6 speed layer) ---------- */
.cmdk-trigger { display: flex; align-items: center; gap: 10px; width: 100%; margin: 4px 0 14px; padding: 10px 12px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm); color: var(--muted); font: inherit; font-weight: 600; font-size: 13px; cursor: pointer; text-align: left; }
.cmdk-trigger:hover { border-color: var(--line-strong); color: var(--ink); }
.cmdk-trigger .cmdk-kbd { margin-left: auto; font-size: 11px; font-weight: 700; color: var(--muted); background: var(--surface); border: 1px solid var(--line-strong); border-radius: 5px; padding: 2px 6px; }
.cmdk-modal.modal-backdrop { align-items: flex-start; padding-top: 12vh; }
.modal.cmdk-modal { max-width: 600px; padding: 0; overflow: visible; }
.cmdk-input-row { display: flex; align-items: center; gap: 10px; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.cmdk-input-row .ic { flex: none; color: var(--muted); }
.cmdk-input { border: none; padding: 0; margin: 0; font-size: 16px; box-shadow: none; }
.cmdk-input:focus { outline: none; box-shadow: none; }
.cmdk-input-row .modal-close { flex: none; width: 26px; height: 26px; font-size: 11px; }
.cmdk-results { max-height: 60vh; overflow-y: auto; padding: 8px; }
.cmdk-group-label { padding: 10px 12px 4px; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.cmdk-item { display: flex; align-items: center; gap: 12px; padding: 11px 12px; border-radius: var(--r-sm); cursor: pointer; color: var(--ink); }
.cmdk-item .ic { flex: none; color: var(--muted); opacity: .8; }
.cmdk-item-main { flex: 1; min-width: 0; }
.cmdk-item-title { font-weight: 600; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk-item-sub { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk-item.active, .cmdk-item:hover { background: var(--accent-soft); }
.cmdk-item.active .cmdk-item-title, .cmdk-item:hover .cmdk-item-title { color: var(--accent-deep); }
.cmdk-empty { padding: 30px 20px; text-align: center; color: var(--muted); font-size: 13px; }
.photo-lightbox-backdrop { background: rgba(10, 9, 8, .82); cursor: zoom-out; }
.photo-lightbox-img { max-width: min(90vw, 1100px); max-height: 90vh; object-fit: contain; border-radius: var(--r-sm); box-shadow: var(--shadow-lg); cursor: default; }
.photo-lightbox-close { position: fixed; top: 20px; right: 20px; background: rgba(255,255,255,.12); color: #fff; }
.photo-lightbox-close:hover { background: rgba(255,255,255,.22); color: #fff; }
/* Every real content photo (collection/product/PO thumbnails, hero images, previews) gets a
   zoom-in cursor as a hint that clicking enlarges it — see the document-level click delegate
   in app.js. The brand logo is excluded there, not here, since exclusion needs JS anyway. */
.thumb img, .collection-hero-img, .pick-thumb img, .pst-id img, .sv-coll img, .imp-thumb img, .pm-image-preview {
  cursor: zoom-in;
}
.cr-hint { margin: -8px 0 14px; font-size: 12.5px; }
.cr-reasons { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
.cr-reasons label, .cr-other-label { display: flex; align-items: center; gap: 9px; font-size: 13.5px; cursor: pointer; }
.cr-reasons input[type="checkbox"], .cr-other-label input[type="checkbox"] { width: auto; margin: 0; accent-color: var(--accent-deep); transform: scale(1.15); }
.cr-other-label { margin-bottom: 8px; }
#cr-other-text { width: 100%; box-sizing: border-box; margin: 0 0 10px; padding: 9px 11px; font-size: 13.5px; font-family: inherit; resize: vertical; }
#cr-other-text.hidden { display: none; }
.cr-error { color: var(--danger, #b3352c); font-size: 13px; margin: 0 0 10px; }
.cr-error.hidden { display: none; }
.cr-actions { display: flex; gap: 10px; justify-content: flex-end; }
.barcode-box { display: flex; align-items: center; justify-content: space-between; gap: 18px; background: var(--surface-2); border: 1px dashed var(--line-strong); border-radius: var(--r-sm); padding: 16px 18px; margin: 8px 0 16px; }
.barcode-box svg { max-width: 250px; height: 58px; }
code { background: var(--accent-soft); color: var(--accent-deep); padding: 3px 9px; border-radius: 6px; font-size: 13.5px; font-weight: 700; letter-spacing: .03em; font-family: "SF Mono", ui-monospace, monospace; }

/* ---------- PO builder ---------- */
.po-layout { display: grid; grid-template-columns: 360px 1fr; gap: 24px; align-items: start; }
.po-picker { padding: 18px; position: sticky; top: 24px; }
.po-picker-list { max-height: 70vh; overflow: auto; display: flex; flex-direction: column; gap: 9px; }
.pick-row { display: flex; align-items: center; gap: 11px; padding: 11px; border: 1px solid var(--line); border-radius: var(--r-sm); cursor: pointer; transition: all .14s; }
.pick-row:hover { border-color: var(--line-strong); }
.pick-row.on { border-color: var(--accent); background: var(--accent-soft); }
.pick-row .pr-main { flex: 1; min-width: 0; }
.pick-row .pr-main strong { font-size: 13px; display: block; }
.pick-row .pr-main span { font-size: 11px; color: var(--muted); }
.pick-row input[type="number"] { width: 58px; margin: 0; padding: 7px; }
.pick-row input[type="checkbox"] { width: auto; margin: 0; accent-color: var(--accent); }
.po-fields { margin-bottom: 22px; }
.po-actions { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 8px; }

/* PO printable document */
.po-document { background: #fff; border: 1px solid var(--line); border-radius: var(--r); padding: 36px; box-shadow: var(--shadow); }
.po-doc-head { display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 2px solid var(--ink); padding-bottom: 18px; margin-bottom: 22px; }
.po-doc-brand { font-size: 27px; }
.po-doc-head .muted { font-size: 12px; letter-spacing: .14em; text-transform: uppercase; margin-top: 4px; }
.po-doc-meta { text-align: right; font-size: 13px; line-height: 1.8; }
.po-doc-meta strong { color: var(--muted); font-weight: 600; margin-right: 8px; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
.doc-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.doc-table th { text-align: left; color: var(--muted); font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; padding: 10px; border-bottom: 1px solid var(--line); }
.doc-table td { padding: 12px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.doc-table td.empty { text-align: center; color: var(--muted); padding: 36px; font-style: italic; }
.doc-table .di { width: 42px; height: 42px; border-radius: 6px; object-fit: cover; background: var(--accent-soft); }
.doc-table svg { height: 32px; }
.po-doc-foot { display: flex; justify-content: flex-end; gap: 34px; font-family: var(--serif); font-weight: 700; padding-top: 18px; font-size: 16px; }

/* At 960px a 256px static sidebar plus a wide .dt table is already broken — raised from
   920 to 1080 so the drawer takes over before that crush happens. Below this width the
   sidebar becomes a slide-in drawer (closed by default) instead of a squeezed static column,
   opened via the hamburger in .mobile-topbar. */
@media (max-width: 1080px) {
  /* minmax(0,…) here for the same reason as the desktop rule above — on a phone a wide
     table or the Gantt would otherwise stretch this single track past the viewport and
     scroll the whole page sideways, which is the harder failure to notice on mobile. */
  .app { grid-template-columns: minmax(0, 1fr); }
  .mobile-topbar { display: flex; align-items: center; gap: 12px; position: sticky; top: 0; z-index: var(--z-nav); background: var(--sidebar); border-bottom: 1px solid var(--line); padding: 12px 16px; }
  .mobile-topbar .mobile-brand { font-size: 19px; }
  .sidebar { position: fixed; inset: 0 auto 0 0; z-index: var(--z-drawer); width: 280px; height: 100vh; transform: translateX(-100%); transition: transform .2s ease; box-shadow: var(--shadow-lg); }
  .sidebar.open { transform: translateX(0); }
  .sidebar-top .logo { padding: 2px 0 0; }
  .nav-drawer-close { display: block; }
  .nav-scrim { display: block; position: fixed; inset: 0; background: rgba(27,24,21,.45); z-index: calc(var(--z-drawer) - 1); opacity: 0; pointer-events: none; transition: opacity .2s ease; }
  .nav-scrim.show { opacity: 1; pointer-events: auto; }
  .content { padding: 22px 16px 60px; }
  .page-head { flex-direction: column; align-items: flex-start; gap: 12px; }
  .page-head h1 { font-size: 24px; }
  .head-actions { flex-wrap: wrap; }
  .workflow { flex-direction: column; }
  .step-arrow { transform: rotate(90deg); }
  .po-layout { grid-template-columns: 1fr; }
  .po-picker { position: static; }
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  .modal { padding: 22px 18px; }
  .recv-editor-head, .recv-receipt-meta, .bcm-drill-controls { gap: 10px; }
}

/* ---------- wordmark in PO doc ---------- */
.po-doc-brand .brand-text { font-weight: 600; }

/* ---------- hints & pills ---------- */
.hint { text-transform: none; letter-spacing: normal; font-weight: 500; color: var(--muted); font-size: 11px; margin-left: 6px; }
.codepill { display: inline-flex; align-items: center; gap: 6px; background: var(--surface-2); border: 1px solid var(--line); color: var(--ink-soft); font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; padding: 5px 11px; border-radius: 999px; }
.codepill strong { font-family: "SF Mono", ui-monospace, monospace; color: var(--accent-deep); letter-spacing: .02em; }
.card-pills { display: flex; gap: 8px; align-items: center; margin-top: 11px; flex-wrap: wrap; }
.card-pills .badge { margin-top: 0; }
.product-card .thumb { font-size: 30px; }
.cw-colour { color: var(--accent-deep); font-weight: 700; }
.mnfpill { font-weight: 700; }
.mnfpill.mnf-empty { color: var(--line-strong); border-style: dashed; }

/* MNF editor on the colourway detail page */
.mnf-edit { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-soft); }
.mnf-edit select { text-transform: none; letter-spacing: normal; font-weight: 600; padding: 6px 10px; border-radius: 999px; min-width: 140px; }

/* role-based UI */
.role-hidden { display: none !important; }

/* Users & roles */
.users-list { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; }
.user-row { display: flex; flex-direction: column; gap: 14px; padding: 18px 20px; }
.user-main { display: flex; flex-direction: column; gap: 3px; }
/* Account actions (reset password / delete) sit above the per-tab permission grid.
   Wraps so the pair never squeezes the email off the row on a narrow screen. */
.user-acct-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.user-acct-actions .btn[disabled] { opacity: .45; cursor: not-allowed; }
.user-main strong { font-size: 15px; }
.user-main .badge { margin-top: 0; }
.user-id { font-size: 11px; font-family: "SF Mono", ui-monospace, monospace; word-break: break-all; }
.role-chip { position: relative; cursor: pointer; user-select: none; margin: 0; display: inline-block; text-transform: none; width: fit-content; }
.role-chip input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.role-chip span { display: inline-block; padding: 8px 15px; border-radius: 999px; font-size: 13px; font-weight: 600; text-transform: none; letter-spacing: normal; border: 1.5px solid var(--line-strong); background: var(--bg); color: var(--ink-soft); transition: background .14s, border-color .14s, color .14s; }
.role-chip:hover span { border-color: var(--accent); color: var(--ink); }
.role-chip input:checked + span { background: var(--accent-deep); border-color: var(--accent-deep); color: #fff; }
.role-chip.is-self { cursor: not-allowed; }
.role-chip.is-self span { opacity: .55; }
.role-chip.is-self:hover span { border-color: var(--line-strong); color: var(--ink-soft); }

/* Per-user permission matrix (Users page) — one row per tab, a None/View/Full
   button group, plus any independent extra sub-permission checkboxes. */
.perm-tab-grid { display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--line); padding-top: 10px; }
.perm-tab-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; padding: 7px 0; border-bottom: 1px solid var(--line); }
.perm-tab-row:last-child { border-bottom: none; }
.perm-tab-label { font-size: 13px; font-weight: 600; min-width: 150px; flex: 1 0 150px; }
.perm-lvl-group { display: inline-flex; border: 1.5px solid var(--line-strong); border-radius: 999px; overflow: hidden; }
.perm-lvl-btn { border: none; background: var(--bg); color: var(--ink-soft); font-size: 12px; font-weight: 600; padding: 6px 13px; cursor: pointer; transition: background .14s, color .14s; }
.perm-lvl-btn + .perm-lvl-btn { border-left: 1.5px solid var(--line-strong); }
.perm-lvl-btn:hover { color: var(--ink); }
.perm-lvl-btn.on { background: var(--accent-deep); color: #fff; }
.perm-extra-group { display: flex; flex-wrap: wrap; gap: 6px 12px; }
.perm-extra-chip { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-soft); cursor: pointer; user-select: none; }
.perm-extra-chip input { margin: 0; cursor: pointer; }

/* PO history */
.pos-list { display: flex; flex-direction: column; gap: 12px; margin-top: 18px; }
.po-hist { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 20px; }
.po-hist-main { display: flex; flex-direction: column; gap: 4px; }
.po-hist-main strong { font-family: var(--serif); font-size: 16px; }
.po-hist-sub { font-size: 12px; }
.po-hist-pills { display: flex; gap: 8px; align-items: center; margin-top: 6px; }
.po-hist-pills .badge { margin-top: 0; }
.po-hist-act { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
.btn-danger { color: #a23232; border-color: #f0bcbc; }
.btn-danger:hover { background: #fdecec; border-color: #e79a9a; color: #8c2424; }

/* PO detail modal */
.pod-meta { font-size: 13px; margin: -6px 0 14px; }
.pod-lines { max-height: 56vh; overflow: auto; }
.pod-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.pod-table th, .pod-table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.pod-table th { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }
.pod-table .num { text-align: right; }
.pod-table code { font-size: 11px; }
.pod-table tfoot td { font-weight: 700; border-top: 2px solid var(--line-strong); border-bottom: none; }
.pod-actions { display: flex; justify-content: space-between; gap: 10px; margin-top: 18px; }

/* PO single-MNF banner */
.po-mnf-banner { margin: 14px 0 4px; padding: 12px 16px; border-radius: var(--r-sm); font-size: 13px; border: 1px solid var(--line); }
.po-mnf-banner.hidden { display: none; }
.po-mnf-banner.ok { background: var(--accent-soft); border-color: var(--line-strong); color: var(--ink); }
.po-mnf-banner.warn { background: #fdecec; border-color: #f0bcbc; color: #a23232; }

/* ---------- product detail ---------- */
.pd-codes { display: flex; gap: 10px; align-items: center; margin-top: 12px; flex-wrap: wrap; }
.pd-codes .badge { margin-top: 0; }
.variant-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 16px; }
.variant-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 16px; transition: all .15s; }
.variant-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow); }
.vc-head { margin-bottom: 12px; }
.vc-title { font-family: var(--serif); font-weight: 600; font-size: 14px; }
.vc-lai { font-size: 11px; margin-top: 1px; }
.variant-card svg { width: 100%; }
.vc-sku { font-size: 10.5px; color: var(--muted); margin-top: 8px; line-height: 1.4; word-break: break-word; }

/* ---------- chip pickers (add product) ---------- */
.picker-block { margin-bottom: 16px; }
.picker-label { font-weight: 600; font-size: 12px; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }
.chip-pick { display: flex; flex-wrap: wrap; gap: 7px; max-height: 132px; overflow: auto; padding: 2px; }
.chip { font-family: var(--sans); font-size: 12.5px; font-weight: 600; cursor: pointer; border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-soft); padding: 7px 12px; border-radius: 999px; transition: all .13s; }
.chip:hover { border-color: var(--accent); color: var(--accent-deep); }
.chip.on { background: var(--ink); color: #fff; border-color: var(--ink); }

/* ---------- generation preview ---------- */
.gen-preview { display: flex; align-items: center; justify-content: space-between; gap: 20px; background: var(--surface-2); border: 1px dashed var(--line-strong); border-radius: var(--r-sm); padding: 18px 20px; margin: 6px 0 16px; }
.gp-left { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.gp-row { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.gp-row .muted { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; min-width: 132px; }
.gp-row .sku { font-size: 11.5px; color: var(--ink-soft); word-break: break-word; }
.gen-preview svg { max-width: 240px; height: 56px; flex: none; }

/* ---------- wide PO doc ---------- */
.doc-scroll { overflow-x: auto; }
.doc-table .td-name { font-weight: 600; }
.doc-table td code { font-size: 11px; letter-spacing: .02em; }

@media (max-width: 920px) {
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  .login-screen { grid-template-columns: 1fr; }
  .login-aside { padding: 40px 32px; min-height: 200px; }
  .login-wordmark { font-size: 40px; }
  .gen-preview { flex-direction: column; align-items: stretch; }
}

/* ---------- PO worksheet (size-split) ---------- */
.po-head-card { margin-bottom: 18px; }
.po-head-card .po-actions { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 6px; }
.po-addstyle { margin-bottom: 22px; }
.po-pick-head { margin-bottom: 14px; }
.po-pick-title { font-size: 18px; margin: 0 0 2px; }
.po-pick-sub { font-size: 13px; }
.po-pick-bar { display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.po-pick-bar .search { margin: 0; flex: 1; min-width: 220px; }
.po-collection-filter { width: auto; min-width: 200px; margin: 0; }
.po-pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; max-height: 460px; overflow: auto; padding: 2px; }
.po-pick-empty { padding: 28px 4px; grid-column: 1 / -1; }
.pick-card { text-align: left; border: 1px solid var(--line); background: var(--surface); border-radius: var(--r); padding: 0; cursor: pointer; font-family: var(--sans); overflow: hidden; transition: all .15s; display: flex; flex-direction: column; }
.pick-card:hover { border-color: var(--accent); box-shadow: var(--shadow); transform: translateY(-2px); }
.pick-thumb { position: relative; aspect-ratio: 1/1; background: linear-gradient(135deg, var(--accent-soft), var(--surface-2)); display: grid; place-items: center; color: var(--line-strong); font-size: 30px; overflow: hidden; }
.pick-thumb img { width: 100%; height: 100%; object-fit: cover; }
.pick-add, .pick-added { position: absolute; bottom: 8px; right: 8px; font-size: 11px; font-weight: 700; padding: 5px 10px; border-radius: 999px; letter-spacing: .02em; }
.pick-add { background: var(--ink); color: #fff; opacity: 0; transform: translateY(4px); transition: all .15s; }
.pick-card:hover .pick-add { opacity: 1; transform: none; }
.pick-added { background: #e9f3ec; color: #3f7d52; }
.pick-info { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 4px; }
.pick-info strong { font-family: var(--serif); font-weight: 600; font-size: 15px; color: var(--ink); }
.pick-line { font-size: 12px; color: var(--ink-soft); }
.pick-line2 { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 4px; }
.pick-line2 .badge { margin-top: 0; }
.pick-card.added { opacity: .6; cursor: default; }
.pick-card.added:hover { transform: none; box-shadow: none; border-color: var(--line); }
.po-empty { padding: 32px 0; }

.po-style { margin-bottom: 20px; padding: 0; overflow: hidden; }
.po-style-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 15px 20px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.pst-id { display: flex; align-items: center; gap: 13px; }
.pst-id img, .pst-noimg { width: 46px; height: 46px; border-radius: 9px; object-fit: cover; background: var(--accent-soft); display: grid; place-items: center; color: var(--line-strong); flex: none; }
.pst-id strong { font-family: var(--serif); font-weight: 600; font-size: 16px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tag { font-size: 10px; font-weight: 700; letter-spacing: .06em; padding: 3px 9px; border-radius: 999px; text-transform: uppercase; }
.tag-new { background: #e9f3ec; color: #3f7d52; }
.tag-restock { background: var(--accent-soft); color: var(--accent-deep); }
.restock-select { width: auto; margin: 0 0 0 8px; padding: 3px 22px 3px 9px; font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; border: none; border-radius: 999px; cursor: pointer; vertical-align: middle; }
.pst-total { display: flex; align-items: center; gap: 14px; }
.pst-total .inline { display: flex; flex-direction: column; margin: 0; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.pst-total .inline input { width: 120px; margin-top: 5px; font-weight: 700; }
.iconbtn { border: 1px solid var(--line-strong); background: var(--surface); width: 34px; height: 34px; border-radius: 8px; cursor: pointer; color: var(--muted); font-size: 13px; flex: none; }
.iconbtn:hover { border-color: var(--danger); color: var(--danger); }

/* ===== Data table system (.dt) — shared layout mechanics for Order Status, Receiving,
   Reorder Alerts, Create PO worksheet, Sales Projection (see PM's own .pj-fixed-table for
   the same mechanism applied earlier). table-layout:fixed + <colgroup> is the only way to
   stop input[type=date]'s non-overridable ~110-140px intrinsic minimum from crushing text
   columns down to nothing under table-layout:auto — under fixed, the browser doesn't
   consult cell content at all, so column width is exactly what the <col> says. */
.dt-wrap, .po-style-scroll, .sx-table-wrap { overflow-x: auto; }
.dt { table-layout: fixed; min-width: var(--dt-min, 900px); }
.dt th, .dt td { overflow-wrap: break-word; }
.dt thead th { position: sticky; top: 0; background: var(--surface); z-index: var(--z-sticky); }
.dt th:first-child, .dt td:first-child { position: sticky; left: 0; background: var(--surface); z-index: 1; }
.dt thead th:first-child { z-index: calc(var(--z-sticky) + 1); }
.dt tfoot td:first-child { background: var(--surface); }
.dt col.c-date { width: 112px; }
.dt col.c-sel { width: 118px; }
.dt col.c-num { width: 76px; }
.dt col.c-qty { width: 88px; }
.dt col.c-code { width: 150px; }
.dt col.c-act { width: 64px; }
.dt col.c-thumb { width: 60px; }
.dt col.c-flex { width: auto; }
.dt-edit input, .dt-edit select, .dt-edit textarea { width: 100%; border: 1px solid transparent; background: transparent; padding: 4px 6px; border-radius: 6px; font: inherit; }
.dt-edit input:hover, .dt-edit select:hover, .dt-edit input:focus, .dt-edit select:focus { border-color: var(--line-strong); background: var(--surface-2); }
/* Card-per-row below 700px — the three views actually used on the warehouse floor
   (Order Status, Reorder Alerts, Receiving). Cells opt in via data-label; a cell with
   neither data-label nor .dt-card-title (row numbers, thumbnails) is dropped in card view
   rather than rendered as a bare unlabeled row. */
@media (max-width: 700px) {
  .dt-cards { min-width: 0; }
  .dt-cards thead, .dt-cards tfoot { display: none; }
  .dt-cards, .dt-cards tbody, .dt-cards tr { display: block; width: 100%; }
  .dt-cards tbody tr { border: 1px solid var(--line); border-radius: var(--r-sm); margin-bottom: 10px; padding: 4px 12px; background: var(--surface); position: static; }
  .dt-cards td { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 3px 8px; text-align: right; padding: 6px 0; border-bottom: 1px solid var(--line); position: static; }
  .dt-cards tr td:last-child { border-bottom: none; }
  .dt-cards td[data-label]::before { content: attr(data-label); flex: 0 0 100%; color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: .05em; text-align: left; }
  .dt-cards td.dt-card-title { display: block; text-align: left; font-weight: 600; padding: 8px 0; border-bottom: 1px solid var(--line-strong); }
  .dt-cards td:not([data-label]):not(.dt-card-title) { display: none; }
}
/* Overrides .ws-table/.sx-table's white-space:nowrap on th (needs higher specificity than
   those single-class rules since .dt wrapping is the whole point of the fixed layout —
   headers should wrap onto 2 lines in a narrow column, not force it wide). */
.ws-table.dt th, .sx-table.dt th { white-space: normal; }

.po-style-scroll { overflow-x: auto; }
.ws-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.ws-table th { text-align: left; color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: .05em; padding: 10px 12px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.ws-table td { padding: 7px 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.ws-table .ws-size { font-weight: 600; }
.ws-table code { font-size: 11px; background: none; color: var(--ink-soft); padding: 0; }
.ws-table input { width: 80px; margin: 0; padding: 7px 8px; }
.ws-pct { white-space: nowrap; }
.ws-pct input { width: 58px; }
.ws-pct span { color: var(--muted); margin-left: 3px; }
.ws-rm { white-space: nowrap; }
.ws-rm input.rm-reused { background: var(--accent-soft, #fde9f3); border-color: var(--accent, #f6b5d3); }
.ws-rm .rm-tag { margin-left: 5px; color: var(--accent-deep, #c2557f); font-size: 12px; cursor: help; }
.ws-table .oq { font-family: var(--serif); font-weight: 700; font-size: 15px; color: var(--ink-soft); }
.ws-table .ws-sales { font-weight: 600; color: var(--ink-soft); text-align: center; }
.ws-table .ws-salespct { font-weight: 600; color: var(--accent-deep); text-align: center; white-space: nowrap; }
.ws-table .ws-notrecv { font-weight: 600; color: var(--muted); text-align: center; }
.ws-table tfoot td { font-weight: 700; border-top: 2px solid var(--line-strong); border-bottom: none; }
.ws-table .ws-proj { font-family: var(--serif); font-weight: 700; font-size: 15px; color: var(--ink-soft); text-align: center; white-space: nowrap; }
.ws-table .ws-projpct { font-weight: 600; color: var(--accent-deep); text-align: center; white-space: nowrap; }
.po-sync-status { margin-top: 8px; font-size: 12px; }
.po-edit-banner { margin: 12px 0 2px; padding: 10px 14px; border-radius: var(--r-sm); font-size: 13px; background: var(--accent-soft, #fde9f3); border: 1px solid var(--accent, #f6b5d3); color: var(--ink); }
.po-edit-banner.hidden { display: none; }
.linkbtn { background: none; border: none; padding: 0; margin-left: 6px; color: var(--accent-deep, #c2557f); font: inherit; font-weight: 600; text-decoration: underline; cursor: pointer; }

/* ===== Goods Receiving ===== */
.recv-status-card { margin-bottom: 20px; }
.recv-rm-missing { border-color: var(--danger) !important; background: #fdecec; }
.recv-status-bar { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin: 12px 0; }
.recv-status-bar .search { flex: 1; min-width: 220px; }
.recv-pending-only { margin: 0; white-space: nowrap; }
.po-hist.recv-sel { border-color: var(--accent, #f6b5d3); box-shadow: 0 0 0 2px var(--accent-soft, #fde9f3); }
.recv-badge { display: inline-block; font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 20px; vertical-align: middle; letter-spacing: .02em; }
.recv-badge.done { background: #e3f4ea; color: #1f7a45; }
.recv-badge.pending { background: #fdeede; color: #9a5a13; }
.recv-badge.open { background: var(--surface-2, #f1eee9); color: var(--muted); }
.recv-badge.cancelled { background: #fbe4e4; color: #a12f2f; }
.oos-summary { margin: 2px 0 12px; }
#oos-table .num { text-align: right; font-variant-numeric: tabular-nums; }
#oos-table tr.oos-overdue td { background: #fbeaea; }
#oos-table .codepill { margin: 2px 4px 2px 0; }
.oos-thumb-cell { width: 44px; padding-right: 4px !important; }
.oos-thumb { width: 36px; height: 36px; border-radius: 8px; object-fit: cover; display: block; cursor: zoom-in; }
.oos-thumb-empty { display: grid; place-items: center; background: var(--surface-2); color: var(--line-strong); font-size: 15px; cursor: default; }

/* ---- Sales Analysis (Hero Product dashboard) ---- */
.sa-status { margin: -6px 0 14px; }
.stat-link { cursor: pointer; }
.stat-link:hover .stat-num { color: var(--accent-deep); }
.sa-alerts-card { border-color: #f3c1c1; }
.sa-manual-tag { display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; background: var(--surface-2); color: var(--muted); padding: 2px 8px; border-radius: 20px; vertical-align: middle; margin-left: 6px; }
/* ---- Auto Reorder Alert System ---- */
.sa-reorder-card { border-color: #e8b4b4; }
.sa-reorder-card .po-pick-title { color: #a12f2f; }
.sa-ro-settings { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; margin: 12px 0 14px; padding: 10px 14px; background: var(--surface-2, #faf7f4); border-radius: var(--r-sm); }
.sa-ro-settings label { display: inline-flex; align-items: center; gap: 8px; margin: 0; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.sa-ro-settings select, .sa-ro-settings input { margin: 0; padding: 7px 10px; width: auto; font-size: 13px; text-transform: none; letter-spacing: normal; font-weight: 500; }
.sa-ro-settings input { width: 76px; }
.sa-ro-total { font-size: 12.5px; color: var(--ink-soft); font-weight: 600; margin-left: auto; white-space: nowrap; }
#sa-reorder-table tr.sa-ro-critical td { background: #fdf3f3; }
#sa-reorder-table tr.sa-ro-warning td { background: #fdf8ec; }
.sa-badge.warn { background: #fdeede; color: #9a5a13; }
.sa-ro-ok { padding: 4px 0 2px; }
.sa-lead-lbl { display: inline-flex; align-items: center; gap: 8px; margin: 0; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.sa-lead-lbl select { margin: 0; padding: 6px 9px; width: auto; font-size: 12.5px; text-transform: none; letter-spacing: normal; font-weight: 500; }
.sa-alerts-card .po-pick-title { color: #a12f2f; }
#sa-alerts-table tr.sa-alert-row td { background: #fdf3f3; }
.sa-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.sa-chips .chip.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-deep); }
.sa-badge { display: inline-block; font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 20px; vertical-align: middle; letter-spacing: .02em; white-space: nowrap; }
.sa-badge.hero   { background: #e3f4ea; color: #1f7a45; }
.sa-badge.fast   { background: #e3edfb; color: #1f4f9a; }
.sa-badge.normal { background: #fdf3d7; color: #8a6d1a; }
.sa-badge.slow   { background: #fbe4e4; color: #a12f2f; }
.sa-badge.disc   { background: var(--surface-2, #f1eee9); color: var(--muted); }
.sa-badge.new    { background: var(--accent-soft); color: var(--accent-deep); }
.sa-score { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.sa-score-num { font-family: var(--serif); font-weight: 700; font-size: 15px; min-width: 26px; text-align: right; }
.sa-score-bar { width: 54px; height: 6px; border-radius: 4px; background: var(--surface-2, #f1eee9); overflow: hidden; }
.sa-score-fill { height: 100%; border-radius: 4px; }
.sa-score-fill.hero   { background: #2f9e5f; }
.sa-score-fill.fast   { background: #3d74d6; }
.sa-score-fill.normal { background: #d9a821; }
.sa-score-fill.slow   { background: #d65454; }
#sa-table tr.sa-prod { cursor: pointer; }
#sa-table tr.sa-prod:hover td { background: var(--accent-soft, #fde9f3); }
#sa-table tr.sa-prod.disc td { color: var(--muted); }
#sa-table tr.sa-detail > td { background: var(--surface-2, #faf7f4); padding: 14px 16px 16px; }
.sa-detail-head { display: flex; justify-content: flex-start; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; }
.sa-detail-action { font-size: 13px; }
.sa-sku-table { width: auto; max-width: 100%; border-collapse: collapse; font-size: 12.5px; }
.sa-sku-table th { text-align: left; color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: .05em; padding: 6px 10px; border-bottom: 1px solid var(--line); }
.sa-sku-table td { padding: 5px 10px; border-bottom: 1px solid var(--line); }
.sa-sku-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.sa-sku-table input.sa-min { width: 70px; margin: 0; padding: 5px 8px; }
.sa-sku-table tr.sa-low td { background: #fdf3f3; }
.sa-foot { margin: 12px 4px 0; font-size: 12px; line-height: 2; }
.sa-days { white-space: nowrap; }
.recv-editor-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 14px; }
.recv-editor-head h2 { margin: 0 0 4px; font-family: var(--serif); font-size: 18px; }
.recv-editor-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.recv-locked-note { margin: 0 0 12px; padding: 10px 14px; border-radius: var(--r-sm); font-size: 13px; font-weight: 600; background: #e3f4ea; border: 1px solid #b6e0c6; color: #1f7a45; }
.recv-locked-note.hidden { display: none; }
.recv-locked-note.danger { background: #fbe4e4; border-color: #f0c2c2; color: #a12f2f; }
.recv-table th, .recv-table td { white-space: nowrap; }
.recv-table .recv-sub { font-size: 11px; font-weight: 400; }
.recv-table input[type=number] { width: 74px; }
.recv-table input[type=date] { width: 138px; }
.recv-table input[type=text] { width: 96px; }
.recv-var { font-family: var(--serif); font-weight: 700; font-size: 15px; text-align: center; }
.recv-var.over { color: #1f7a45; }
.recv-var.short { color: #b5462f; }
.recv-var.exact { color: var(--muted); }
.recv-stat { text-align: center; }
.ws-total td { font-weight: 700; border-top: 2px solid var(--line-strong); border-bottom: none; background: var(--surface-2); }
.ws-note { padding: 8px 20px 14px; font-size: 12px; color: var(--muted); min-height: 4px; }
.ws-note.warn { color: var(--danger); font-weight: 600; }

/* ---------- Excel import + collection export ---------- */
/* flex-shrink:0 + nowrap so a long intro paragraph beside these can't squeeze the
   buttons into a narrow column of wrapped words (the Users page did exactly that). */
.head-actions { display: flex; gap: 10px; flex-wrap: wrap; flex-shrink: 0; }
.head-actions .btn { white-space: nowrap; }
.chk { display: flex; align-items: center; gap: 8px; text-transform: none; letter-spacing: normal; font-weight: 500; font-size: 13px; color: var(--ink-soft); margin: 4px 0 14px; }
.chk input { width: auto; margin: 0; accent-color: var(--accent-deep); }
.imp-status { font-size: 13px; margin-bottom: 10px; min-height: 1em; }
.imp-status .warn { color: var(--danger); font-weight: 600; }
.imp-preview { max-height: 340px; overflow: auto; display: flex; flex-direction: column; gap: 8px; }
.imp-row { display: flex; gap: 12px; align-items: center; border: 1px solid var(--line); border-radius: var(--r-sm); padding: 10px 12px; }
.imp-thumb { width: 46px; height: 46px; border-radius: 8px; overflow: hidden; background: var(--accent-soft); display: grid; place-items: center; color: var(--line-strong); flex: none; }
.imp-thumb img { width: 100%; height: 100%; object-fit: cover; }
.imp-meta { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.imp-meta strong { font-family: var(--serif); font-weight: 600; font-size: 14px; display: flex; gap: 8px; align-items: center; }
.imp-meta > span { font-size: 11px; }
.imp-meta code { font-size: 11px; align-self: flex-start; }
.imp-warn { margin-top: 10px; font-size: 12px; color: var(--muted); }
.imp-warn summary { cursor: pointer; color: var(--danger); font-weight: 600; }
.imp-warn div { padding: 2px 0; }

/* ---------- Product Details panel ---------- */
.pd-details { margin-top: 24px; padding: 0; overflow: hidden; }
.pd-details-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.pd-details-head h3 { margin: 0; font-family: var(--serif); font-size: 16px; font-weight: 600; }
.pd-section { padding: 16px 20px; border-bottom: 1px solid var(--line); }
.pd-section:last-child { border-bottom: none; }
.pd-section-title { margin: 0 0 12px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }
.pd-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px 16px; }
.pd-fields label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; font-weight: 600; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .04em; }
.pd-fields label input, .pd-fields label textarea, .pd-fields label select { font-size: 13px; font-weight: 400; text-transform: none; letter-spacing: normal; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); resize: vertical; }
.pd-fields label input:focus, .pd-fields label textarea:focus, .pd-fields label select:focus { border-color: var(--accent); outline: none; background: var(--surface); }
.pd-fields label input:disabled, .pd-fields label textarea:disabled, .pd-fields label select:disabled { opacity: .55; cursor: not-allowed; }
.pd-full { grid-column: 1 / -1; }
.pd-check { flex-direction: row !important; align-items: center; gap: 8px; cursor: pointer; text-transform: none !important; letter-spacing: normal !important; font-size: 13px !important; font-weight: 500 !important; color: var(--ink) !important; }
.pd-check input[type=checkbox] { width: auto; margin: 0; accent-color: var(--accent-deep); transform: scale(1.2); }
.pd-hidden { display: none !important; }
.pd-field-label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); display: block; margin-bottom: 8px; }

/* Fabric type — select + optional free-text below */
.pd-fabric-wrap { display: flex; flex-direction: column; gap: 6px; }
.pd-fabric-other { font-size: 13px; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); }

/* Size measurement table */
.pd-size-wrap { display: flex; flex-direction: column; }
.size-msr-table { width: 100%; border-collapse: collapse; font-size: 12px; margin-top: 4px; }
.size-msr-table th { background: var(--surface-2); padding: 6px 8px; text-align: center; font-size: 11px; font-weight: 700; border: 1px solid var(--line); white-space: nowrap; }
.msr-unit { font-weight: 400; color: var(--muted); font-size: 10px; }
.size-msr-table td { border: 1px solid var(--line); padding: 2px 4px; }
.msr-size { font-weight: 700; text-align: center; background: var(--surface-2); color: var(--ink); min-width: 36px; }
.msr-input { width: 58px; text-align: center; border: none; background: transparent; padding: 4px 2px; font-size: 12px; color: var(--ink); }
.msr-input:focus { outline: 2px solid var(--accent); border-radius: 3px; background: var(--surface); }
.msr-input:disabled { opacity: .5; cursor: not-allowed; }

/* Exclusive platform compound group */
.pd-excl-group { display: flex; flex-direction: column; }
.pd-excl-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.pd-excl-row label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }
.pd-excl-row label input, .pd-excl-row label select { font-size: 13px; font-weight: 400; text-transform: none; letter-spacing: normal; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); }
#pd-exclusive-other { font-size: 13px; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); align-self: flex-end; }

/* Care instruction — grouped chip panel */
.pd-care-wrap { display: flex; flex-direction: column; gap: 8px; }
.pd-care-count { font-size: 11px; font-weight: 400; color: var(--accent-deep); text-transform: none; letter-spacing: normal; }
.pd-care-groups { display: flex; flex-direction: column; gap: 10px; }
.care-group { display: flex; flex-direction: column; gap: 6px; }
.care-group-title { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.care-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.care-chip { position: relative; cursor: pointer; user-select: none; }
.care-chip input[type=checkbox] { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.care-chip span { display: inline-block; padding: 4px 11px; border-radius: 20px; font-size: 12px; font-weight: 500; text-transform: none; letter-spacing: normal; border: 1.5px solid var(--line); background: var(--bg); color: var(--ink-soft); transition: background .1s, border-color .1s, color .1s; line-height: 1.5; }
.care-chip:hover span { border-color: var(--accent); color: var(--ink); }
.care-chip input:checked + span { background: var(--accent-deep); border-color: var(--accent-deep); color: #fff; font-weight: 600; }
.care-chip:has(input:disabled) { cursor: not-allowed; }
.care-chip:has(input:disabled) span { opacity: .45; }
.pd-care-other-input { font-size: 13px; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); width: 100%; margin-top: 4px; }
.pd-care-other-input:focus { border-color: var(--accent); outline: none; }

/* Print barcode label modal */
#print-modal .modal { max-width: 480px; }
.print-modal-form { display: flex; flex-direction: column; gap: 16px; margin-top: 16px; }
.print-modal-row { display: flex; flex-wrap: wrap; gap: 12px; }
.print-modal-row label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }
.print-modal-row label input, .print-modal-row label select { font-size: 13px; font-weight: 400; text-transform: none; letter-spacing: normal; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); }
.print-modal-row label input:focus, .print-modal-row label select:focus { border-color: var(--accent); outline: none; }
.print-modal-section-title { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin-bottom: 6px; }
#print-sizes-wrap { display: flex; flex-direction: column; }

/* ===== Barcode Master ===== */
.bcm-note { margin-bottom: 16px; padding: 14px 18px; font-size: 13px; line-height: 1.6; }
.bcm-structure { margin-bottom: 16px; padding: 16px 18px; }
.bcm-structure h3 { margin: 0 0 12px; font-family: var(--serif); font-size: 15px; }
.bcm-struct-row { display: flex; gap: 4px; align-items: stretch; }
.bcm-seg { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; padding: 8px 4px; background: var(--surface-2, #f1eee9); border: 1px solid var(--line); border-radius: var(--r-sm); text-align: center; }
.bcm-seg-name { font-size: 12px; font-weight: 700; color: var(--ink); }
.bcm-seg-w { font-size: 10px; color: var(--muted); }
.bcm-struct-eg { margin-top: 10px; font-size: 12px; }
.bcm-tables { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.bcm-card { padding: 16px 18px; }
.bcm-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.bcm-card-head h3 { margin: 0; font-family: var(--serif); font-size: 16px; }
.bcm-cat-row { font-size: 12px; color: var(--ink-soft); margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
.bcm-cat-select { flex: 1; padding: 6px 9px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); font-size: 13px; }
.bcm-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.bcm-table th { text-align: left; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding: 4px 8px; border-bottom: 1px solid var(--line); }
.bcm-table td { padding: 5px 8px; border-bottom: 1px solid var(--line-soft, #f0ece6); }
.bcm-table tbody tr:last-child td { border-bottom: none; }
.bcm-code { font-family: var(--mono, monospace); font-weight: 700; color: var(--accent-deep, #c2557f); white-space: nowrap; }
.bcm-add { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.bcm-add input { flex: 1; min-width: 90px; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); font-size: 13px; }
.bcm-add .bcm-code-in { flex: 0 0 80px; min-width: 70px; }
.bcm-next { font-size: 12px; color: var(--muted); white-space: nowrap; }
.bcm-rules { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; margin-top: 16px; }
.bcm-rule h3 { margin: 0 0 8px; font-family: var(--serif); font-size: 15px; }
.bcm-rule p { margin: 0; font-size: 13px; line-height: 1.6; color: var(--ink-soft); }

/* Activity Log */
.log-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 16px; }
.log-filters select { padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); font-size: 13px; }
.log-filters .search { margin: 0; max-width: 260px; }
.log-count { margin-left: auto; font-size: 12px; }
.log-card { overflow-x: auto; }
.log-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.log-table th { text-align: left; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding: 6px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.log-table td { padding: 7px 10px; border-bottom: 1px solid var(--line-soft, #f0ece6); vertical-align: top; }
.log-table tbody tr:last-child td { border-bottom: none; }
.log-badge { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.log-badge.log-create { background: #e5f3ea; color: #2f7a4d; }
.log-badge.log-update { background: #fdf1dc; color: #b3721c; }
.log-badge.log-delete { background: #fbe7e7; color: #b33a3a; }

/* Barcode Master — drill-down viewers */
.bcm-drill { grid-column: 1 / -1; }
.bcm-drill-hint { margin: 0 0 12px; font-size: 12px; }
.bcm-drill-controls { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 14px; }
.bcm-drill-controls label { display: flex; flex-direction: column; gap: 5px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 0; flex: 1; min-width: 180px; }
.bcm-drill-controls select { margin-top: 0; padding: 8px 10px; font-size: 13px; background: var(--bg); }
.bcm-next-line { margin-top: 10px; font-size: 12px; }
/* A code/sub-code collision is a data fault the user has to see, not a styling accident —
   tint the row and name the problem rather than quietly rendering one of the two records. */
.bcm-table tr.bcm-clash td { background: #fdf3f1; }
.bcm-warn { display: inline-block; margin-left: 6px; font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: var(--danger); white-space: nowrap; }
.bcm-warn-line { margin: 0 0 10px; padding: 8px 12px; border-radius: 8px; font-size: 12.5px;
  background: #fdf3f1; color: var(--danger); border: 1px solid rgba(190,74,60,.25); }
.bcm-scope-display { display: flex; flex-direction: column; gap: 5px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); flex: 1; min-width: 180px; }
.bcm-scope-display strong { font-size: 14px; font-weight: 600; text-transform: none; letter-spacing: normal; color: var(--ink); padding: 8px 10px; background: var(--surface-2); border-radius: var(--r-sm); }
.bcm-dup-group { margin-bottom: 18px; padding-bottom: 16px; border-bottom: 1px solid var(--line); }
.bcm-dup-group:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }
.bcm-dup-name { font-weight: 700; font-size: 13px; margin-bottom: 8px; color: var(--accent-deep, #c2557f); }
.bcm-dup-lead { font-size: 13px; margin: 0 0 12px; }
.bcm-dup-actions { margin-top: 10px; }
.bcm-dup-bulk { margin: 0 0 18px; }
.bcm-table tr.bcm-dup-keep td { background: #f2faf5; }
.bcm-table tr.bcm-dup-drop td { background: #fdf3f1; }
.bcm-dup-tag { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; white-space: nowrap; }
.bcm-dup-keep .bcm-dup-tag { color: #2c7a58; }
.bcm-dup-drop .bcm-dup-tag { color: #c0392b; }

/* Receiving — receipt history + new-receipt form */
#recv-history { margin: 4px 0 18px; }
.recv-hist-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-bottom: 8px; }
.recv-hist-empty { font-size: 13px; margin: 4px 0 16px; }
.recv-receipt { border: 1px solid var(--line); border-radius: var(--r-sm); margin-bottom: 8px; background: var(--surface); }
.recv-receipt summary { cursor: pointer; padding: 10px 14px; font-size: 13px; list-style: none; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.recv-receipt summary::-webkit-details-marker { display: none; }
.recv-receipt summary::before { content: "▸"; color: var(--muted); }
.recv-receipt[open] summary::before { content: "▾"; }
.recv-receipt-table { margin: 0 14px 12px; width: calc(100% - 28px); }
.recv-form-title { font-family: var(--serif); font-size: 16px; margin: 6px 0 12px; }
.recv-receipt-meta { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; margin-bottom: 12px; }
.recv-receipt-meta label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); margin: 0; min-width: 180px; }
.recv-receipt-meta label input { margin-top: 0; padding: 8px 10px; font-size: 13px; }
.recv-form-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-left: auto; align-items: flex-end; }
#recv-form-wrap.hidden { display: none; }

/* Product detail — add size control */
.pd-size-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.pd-size-add { display: flex; gap: 8px; align-items: center; }
.pd-size-add select { width: auto; min-width: 150px; margin: 0; padding: 7px 10px; font-size: 13px; }

/* Collection tab — product-level search results */
.card-grid.as-results { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.prod-result .meta strong { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 16px; }
.prod-result .meta .sub { margin-top: 5px; }
.prod-result-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

/* Collection launch date (detail header) */
.cd-launch-row { display: flex; align-items: center; gap: 8px; margin: 8px 0; flex-wrap: wrap; }
.cd-launch-label { margin: 0; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.cd-launch-input { width: auto; margin: 0; padding: 6px 10px; font-size: 13px; }
.cd-launch-input:disabled { opacity: .6; }
.cd-launch-status { font-size: 12px; }

/* Product search result — detail lines (Colours / Sizes) */
.prod-result-detail { margin-top: 4px; }
.prod-result .pr-lbl { display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-right: 6px; }

/* Product Details — Fabric & Hardware detail box */
.pd-fabric-detail-lbl { margin-top: 10px; }
.pd-fabric-detail-lbl textarea { width: 100%; margin-top: 5px; padding: 8px 10px; font-size: 13px; font-weight: 400; text-transform: none; letter-spacing: normal; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); color: var(--ink); resize: vertical; line-height: 1.5; }

/* Add Product — colour chip search */
.chip-search { width: 100%; max-width: 320px; margin: 0 0 10px; padding: 8px 11px; font-size: 13px; }

/* ===== Stock Value ===== */
.sv-coll-list { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.sv-coll { display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px 7px 8px; border-radius: 999px; border: 1.5px solid var(--line-strong); background: var(--surface); color: var(--ink-soft); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; transition: all .14s; }
.sv-coll img, .sv-coll-ph { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; display: inline-flex; align-items: center; justify-content: center; background: var(--accent-soft); color: var(--line-strong); }
.sv-coll:hover { border-color: var(--accent); color: var(--ink); }
.sv-coll.on { background: var(--accent-deep); border-color: var(--accent-deep); color: #fff; }
.sv-card { padding: 20px 22px; }
.sv-card h2 { margin: 0 0 16px; font-family: var(--serif); font-size: 20px; display: flex; align-items: center; gap: 10px; }
.sv-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; margin-bottom: 18px; }
.sv-stat { display: flex; flex-direction: column; gap: 4px; padding: 16px 18px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-2); }
.sv-stat-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.sv-stat-num { font-family: var(--serif); font-size: 26px; font-weight: 700; color: var(--ink); }
.sv-stat.sv-even .sv-stat-num { color: #1f7a45; }
.sv-stat.sv-gap { background: #fdeede; border-color: #f2d3ae; }
.sv-stat.sv-gap .sv-stat-num { color: #9a5a13; }
.sv-table { width: 100%; }
.sv-table tfoot td { font-weight: 700; border-top: 2px solid var(--line-strong); background: var(--surface-2); }
.sv-note { font-size: 12px; margin: 12px 0 0; }

/* Collection header — grouped date fields styled like the Product Details card */
.cd-dates { display: flex; flex-direction: row; flex-wrap: wrap; gap: 16px 44px; margin: 14px 0 4px; align-items: flex-start; }
.cd-launch-status { flex-basis: 100%; }
.cd-hero-main { min-width: 0; }
.cd-name-row { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.cd-name-row h1 { margin: 0; }
.cd-name-row .badge { margin-top: 0; transform: translateY(-3px); }
.cd-name-input { font-family: var(--serif); font-weight: 600; letter-spacing: -0.01em; font-size: 34px; margin: 0; padding: 0 4px; width: auto; min-width: 200px; }
#cd-name-edit-btn { align-self: center; }
#cd-name-edit-btn:hover { border-color: var(--accent); color: var(--accent-deep); }
.cd-release { font-size: 13px; }
.collection-hero { align-items: flex-start; }
.collection-head .head-actions { max-width: 420px; justify-content: flex-end; }
.cd-dates-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); margin-bottom: 7px; }
.cd-dates-fields { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-end; }
.cd-dates-fields label { display: flex; flex-direction: column; gap: 5px; margin: 0; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }
.cd-dates-fields label input, .cd-dates-fields label select { margin: 0; width: auto; min-width: 175px; padding: 8px 11px; font-size: 13px; font-weight: 400; background: var(--surface-2); border-color: transparent; border-radius: var(--r-sm); }
.cd-dates-fields label input:focus, .cd-dates-fields label select:focus { background: var(--surface); border-color: var(--accent-deep); }
.cd-platform-other { width: auto; min-width: 175px; margin: 0; padding: 8px 11px; font-size: 13px; align-self: flex-end; }
.cd-dates-fields input:disabled, .cd-dates-fields select:disabled { opacity: .6; }

/* Size measurement — admin delete-size button */
.msr-del-cell { text-align: center; width: 34px; }
.msr-del { border: none; background: none; color: var(--muted); font-size: 13px; cursor: pointer; padding: 4px 8px; border-radius: 6px; }
.msr-del:hover { background: #fdecec; color: #a23232; }

/* Stock Value — clickable PO number */
.sv-po-link { border: none; background: none; padding: 0; font: inherit; font-weight: 700; color: var(--accent-deep); cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.sv-po-link:hover { color: var(--ink); }

/* ===== Sales Projections (admin) ===== */
.pj-editor { padding: 22px 24px; margin-top: 18px; }
.pj-top { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; margin-bottom: 14px; }
.pj-top label, .pj-fields label { display: flex; flex-direction: column; gap: 5px; margin: 0; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.pj-top label input, .pj-top label select, .pj-fields label input { margin: 0; padding: 8px 11px; font-size: 13px; font-weight: 400; background: var(--surface-2); border-color: transparent; }
.pj-top label input:focus, .pj-top label select:focus, .pj-fields label input:focus { background: var(--surface); border-color: var(--accent-deep); }
.pj-top .pj-wide, .pj-fields .pj-wide { grid-column: span 2; }
.pj-top .pj-wide input { min-width: 260px; }
.pj-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px 16px; margin-bottom: 6px; }
.pj-section-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); margin: 18px 0 10px; padding-top: 14px; border-top: 1px solid var(--line); }
.pj-table th, .pj-table td { white-space: nowrap; }
.pj-table input, .pj-table select { margin: 0; padding: 6px 8px; font-size: 12.5px; }
.pj-table .pj-name-in { min-width: 160px; }
.pj-table select { max-width: 190px; }
.pj-table .pj-num { width: 84px; text-align: right; }
.pj-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.pj-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.pj-status { margin-top: 10px; font-size: 12.5px; min-height: 1.2em; }

/* Payment Voucher — reuses the projection editor's field styling */
.vc-editor { padding: 22px 24px; margin-top: 18px; }
.vc-section-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); margin: 18px 0 10px; padding-top: 14px; border-top: 1px solid var(--line); }
.vc-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px 16px; margin-bottom: 6px; }
.vc-fields label { display: flex; flex-direction: column; gap: 5px; margin: 0; min-width: 0; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
/* width:100%+min-width:0 stop a <select>'s long option text from forcing its grid
   track (and the whole row) wider than the viewport — that's what caused fields to
   look cut off / overlapping at the edge. margin-top:auto on the control (and on
   .vc-po-chips below) pins every field's input/select/chip-box to the BOTTOM of its
   label — since a grid row stretches every label to the row's tallest item, a field
   with a one-line hint (e.g. Voucher date) would otherwise pack its input higher up
   than a field with a two-line hint (e.g. Supplier), leaving inputs misaligned. */
.vc-fields label input, .vc-fields label select { width: 100%; min-width: 0; box-sizing: border-box; margin: auto 0 0; padding: 8px 11px; font-size: 13px; font-weight: 400; background: var(--surface-2); border-color: transparent; text-overflow: ellipsis; }
.vc-fields label input:focus, .vc-fields label select:focus { background: var(--surface); border-color: var(--accent-deep); }
.vc-fields label input:disabled { opacity: .6; cursor: not-allowed; }
.vc-fields .vc-wide { grid-column: span 2; min-width: 0; }
.vc-po-chips { min-height: 38px; margin-top: auto; }
.vc-po-hint { padding: 8px 2px; }
.vc-po-block { margin-bottom: 18px; }
.vc-po-block:last-child { margin-bottom: 0; }
.vc-po-block-head { font-size: 13px; font-weight: 700; margin-bottom: 6px; }
.vc-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.vc-table th { text-align: left; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding: 5px 8px; border-bottom: 1px solid var(--line); }
.vc-table td { padding: 5px 8px; border-bottom: 1px solid var(--line-soft, #f0ece6); vertical-align: middle; }
.vc-table td.num, .vc-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.vc-po-table tfoot td { font-weight: 700; border-top: 1px solid var(--line); border-bottom: none; padding-top: 7px; }
.vc-payee-row { display: flex; gap: 8px; align-items: center; }
.vc-payee-row select { flex: 1; min-width: 0; }
.vc-payee-row .btn { flex: none; padding: 8px 12px; }
.vc-chip-locked { cursor: default; opacity: .85; }
.vc-evidence { margin: 4px 0 6px; }
.vc-evi-list { list-style: none; margin: 0 0 10px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.vc-evi-list li { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 6px 10px; background: var(--surface-2); border-radius: var(--r-sm); }
.vc-evi-list li a { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vc-evi-empty { margin: 0 0 8px; }
.vc-evi-upload-btn { display: inline-block; cursor: pointer; }
.recv-receipt-evidence { margin: 10px 0; padding: 10px 0 0; border-top: 1px solid var(--line-soft, #f0ece6); }
.recv-evi-label { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; margin-bottom: 6px; }
.recv-cancel-receipt { margin-top: 8px; }
.recv-cancel-reason { font-size: 12.5px; margin: 4px 0 8px; }
.vc-totals { margin: 16px 0 4px; max-width: 420px; box-sizing: border-box; }
.vc-tot-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 5px 0; font-size: 13px; }
.vc-tot-row span { flex: none; }
.vc-tot-row strong { font-variant-numeric: tabular-nums; text-align: right; word-break: break-word; }
.vc-rate { width: 56px; margin: 0 2px; padding: 3px 6px; font-size: 12px; text-align: right; }
.vc-tot-net { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 9px; font-size: 15px; }
.vc-tot-net strong { color: var(--accent-deep, #c2557f); }
.vc-tot-words { text-align: right; font-size: 12px; margin-top: 4px; }
.vc-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }

/* Size remap selector + edit-product modal */
.msr-remap { width: auto; min-width: 60px; margin: 0; padding: 4px 6px; font-size: 11.5px; color: var(--muted); background: var(--bg); border: 1px solid var(--line); border-radius: 6px; }
.msr-remap:hover { color: var(--accent-deep); border-color: var(--accent); }
.ep-patterns-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0 18px; }
.ep-pattern-block label { margin-bottom: 8px; }
.ep-barcodes { max-height: 130px; overflow-y: auto; margin: 0 0 16px; padding: 8px 10px; background: var(--surface-2); border-radius: var(--r-sm); }
.ep-bc-row { display: flex; justify-content: space-between; gap: 10px; font-size: 12px; padding: 2px 0; }
.ep-bc-cw { color: var(--muted); }
.ep-bc-row code { font-size: 11.5px; color: var(--ink); }

/* ---- Toast notifications (non-blocking success confirmations) ---- */
.toast-root { position: fixed; bottom: 24px; right: 24px; z-index: var(--z-toast); display: flex; flex-direction: column-reverse; gap: 10px; pointer-events: none; max-width: min(360px, calc(100vw - 32px)); }
.toast { display: flex; align-items: flex-start; gap: 10px; background: var(--ink); color: #fff; padding: 12px 14px 12px 16px; border-radius: var(--r-sm); font-size: 13.5px; font-weight: 500; line-height: 1.4; box-shadow: var(--shadow-lg); pointer-events: auto; animation: toast-in .18s ease; max-height: 50vh; overflow-y: auto; }
.toast-icon { font-size: 15px; flex-shrink: 0; margin-top: 1px; }
.toast-body { flex: 1; min-width: 0; }
.toast-msg { white-space: pre-line; }
.toast-close { background: none; border: none; color: rgba(255,255,255,.7); cursor: pointer; font-size: 12px; padding: 2px 4px; flex-shrink: 0; }
.toast-close:hover { color: #fff; }
.toast-detail { margin-top: 4px; font-size: 12px; opacity: .85; }
.toast-detail summary { cursor: pointer; }
.toast-action { margin-top: 6px; background: rgba(255,255,255,.16); border: none; color: #fff; padding: 4px 10px; border-radius: 6px; font-size: 12px; font-weight: 700; cursor: pointer; }
.toast-action:hover { background: rgba(255,255,255,.26); }
.toast.success { background: #2f7d52; }
.toast.error { background: #b23a3a; }
.toast.warn { background: #a9762c; }
.toast.info { background: #3567b0; }
.toast.leaving { animation: toast-out .16s ease forwards; }
@keyframes toast-in { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(6px) scale(.98); } }
@media (max-width: 640px) { .toast-root { left: 16px; right: 16px; bottom: 16px; max-width: none; } }

/* ---- States (Phase 5) — empty / error / loading collapsed to one visual family. The bug
   this fixes: a failed query and a genuinely-empty result used to render identically (both
   plain centered text), so a user had no way to tell "nothing here" from "the app is
   broken" — and only one of those has anything to retry. `.state` IS `.empty-state`
   (renderState() in app.js targets both classes so existing empty-state markup keeps
   working); `.state-error` adds the danger icon colour + Retry action. `.state-inline` is
   the compact variant for a zero/failed-row message inside a table (keeps `.sx-empty`
   working the same way). */
.empty-state, .state { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; padding: 48px 24px; color: var(--muted); }
.empty-state-icon, .state-icon { font-size: 32px; opacity: .5; }
.empty-state-icon .ic, .state-icon .ic { width: 32px; height: 32px; }
.empty-state-title, .state-title { font-family: var(--serif); font-size: 17px; color: var(--ink); }
.empty-state-hint, .state-hint { font-size: 13.5px; max-width: 380px; line-height: 1.6; }
.empty-state .btn, .state .btn { margin-top: 4px; }
.state-error .state-icon { color: var(--danger); opacity: 1; }
.state-error .state-title { color: var(--danger); }
.state-detail { max-width: 480px; font-size: 12px; color: var(--muted); }
.state-detail summary { cursor: pointer; font-weight: 600; }
.state-detail pre { white-space: pre-wrap; word-break: break-word; text-align: left; margin: 6px 0 0; font-family: "SF Mono", ui-monospace, monospace; }
.state-inline, .sx-empty { padding: 40px 20px; text-align: center; color: var(--muted); }
.state-inline.state-error, .sx-empty.state-error { color: var(--danger); }
.state-inline .btn-sm, .sx-empty .btn-sm { margin-left: 8px; }

/* ---- Loading skeletons (shimmering placeholder blocks while a tab's data loads) ---- */
.skel-row { height: 15px; border-radius: 5px; margin: 8px 0; background: linear-gradient(90deg, var(--surface-2) 25%, var(--line) 37%, var(--surface-2) 63%); background-size: 400% 100%; animation: skel-shimmer 1.4s ease infinite; }
.skel-card { height: 96px; border-radius: var(--r-sm); background: linear-gradient(90deg, var(--surface-2) 25%, var(--line) 37%, var(--surface-2) 63%); background-size: 400% 100%; animation: skel-shimmer 1.4s ease infinite; }
.skel-table td { padding: 10px 12px; }
@keyframes skel-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .skel-row, .skel-card, .toast { animation: none; } }

/* =====================================================================
   SALE ANALYSIS v2 — rebuilt module. .sx-root is a pure ALIAS layer onto the
   platform tokens (legacy compatibility shim — new CSS should use platform
   tokens directly, this never grows). Dark mode was removed: it only ever
   covered these two modules, leaving the rest of the app light, so a device
   set to dark got a dark Projects tab inside a white sidebar/shell. An unused
   `html[data-theme="dark"]` hook is left on :root above if it's ever wanted
   platform-wide. */
.sx-root {
  --sx-bg: var(--bg); --sx-surface: var(--surface); --sx-surface-2: var(--surface-2);
  --sx-ink: var(--ink); --sx-ink-soft: var(--ink-soft); --sx-muted: var(--muted);
  --sx-line: var(--line); --sx-line-strong: var(--line-strong);
  --sx-accent: var(--accent-deep); --sx-accent-soft: var(--accent-soft);
  --sx-good: var(--ok); --sx-warn: var(--warn); --sx-bad: var(--danger);
}
.sx-root { color: var(--sx-ink); }
.sx-root .muted { color: var(--sx-muted); }

/* Sticky filter bar */
.sx-filterbar { position: sticky; top: 0; z-index: 5; display: flex; flex-wrap: wrap; gap: 8px;
  background: var(--sx-bg); padding: 10px 0 12px; margin-bottom: 4px; border-bottom: 1px solid var(--sx-line); }
.sx-filterbar select, .sx-filterbar input { background: var(--sx-surface); color: var(--sx-ink); border: 1px solid var(--sx-line-strong); }

/* Sub-tabs */
.sx-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 18px; }
.sx-tab { border: 1.5px solid var(--sx-line-strong); background: var(--sx-surface); color: var(--sx-ink-soft);
  border-radius: 999px; padding: 7px 16px; font: inherit; font-weight: 600; font-size: 13px; cursor: pointer; transition: all .14s; }
.sx-tab:hover { border-color: var(--sx-accent); color: var(--sx-ink); }
.sx-tab.on { background: var(--sx-accent); border-color: var(--sx-accent); color: #fff; }
.sx-panel { animation: sx-fade .15s ease; }
@keyframes sx-fade { from { opacity: 0; } to { opacity: 1; } }

/* KPI cards */
.sx-kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 20px; }
.sx-kpi { background: var(--sx-surface); border: 1px solid var(--sx-line); border-radius: var(--r-sm); padding: 14px 16px; }
.sx-kpi-label { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--sx-muted); margin-bottom: 6px; }
.sx-kpi-value { font-family: var(--serif); font-size: 24px; font-weight: 600; color: var(--sx-ink); line-height: 1.15; }
.sx-kpi-delta { font-size: 12px; margin-top: 4px; font-weight: 600; }
.sx-kpi-delta.up { color: var(--sx-good); } .sx-kpi-delta.down { color: var(--sx-bad); } .sx-kpi-delta.flat { color: var(--sx-muted); }
.sx-kpi-note { font-size: 11px; color: var(--sx-muted); margin-top: 4px; }

/* Generic cards / sections */
.sx-card { background: var(--sx-surface); border: 1px solid var(--sx-line); border-radius: var(--r); padding: 18px 20px; margin-bottom: 16px; }
.sx-card-title { font-family: var(--serif); font-size: 16px; font-weight: 600; margin: 0 0 4px; }
.sx-card-sub { font-size: 12.5px; color: var(--sx-muted); margin: 0 0 14px; }
.sx-grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; }
.sx-grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 900px) { .sx-grid-2, .sx-grid-3 { grid-template-columns: minmax(0, 1fr); } }

/* Chart canvas containers */
.sx-chart-wrap { position: relative; height: 280px; }
.sx-chart-wrap.short { height: 200px; }

/* Tables */
.sx-table-wrap { overflow-x: auto; }
.sx-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.sx-table th { text-align: left; color: var(--sx-muted); font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
  padding: 8px 12px; border-bottom: 1px solid var(--sx-line); white-space: nowrap; position: sticky; top: 0; background: var(--sx-surface); }
.sx-table td { padding: 7px 12px; border-bottom: 1px solid var(--sx-line); vertical-align: middle; }
.sx-table tbody tr { cursor: pointer; }
.sx-table tbody tr:hover { background: var(--sx-surface-2); }
.sx-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.sx-table tfoot td { font-weight: 700; border-top: 2px solid var(--sx-line-strong); border-bottom: none; }

/* Colourway photo + label. One photo represents a whole ลาย (all its sizes share it), so the
   thumbnail sits on the colourway row rather than being repeated per size. */
.sx-thumb-cell { width: 52px; padding-right: 0 !important; }
.sx-thumb { width: 44px; height: 56px; border-radius: 6px; object-fit: cover; display: block;
  background: var(--sx-surface-2); border: 1px solid var(--sx-line); }
.sx-thumb-empty { display: flex; align-items: center; justify-content: center; color: var(--sx-muted); font-size: 15px; }
.sx-cw-sub { font-size: 11.5px; color: var(--sx-muted); margin-top: 2px; }

/* Top movers — the Overview's visual "what's selling" strip. */
.sx-mover-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 12px; }
.sx-mover-card { cursor: pointer; border: 1px solid var(--sx-line); border-radius: 10px; padding: 8px;
  background: var(--sx-surface); transition: border-color .14s, transform .14s; }
.sx-mover-card:hover { border-color: var(--sx-accent); transform: translateY(-2px); }
.sx-mover-card .sx-thumb { width: 100%; height: 148px; margin-bottom: 8px; }
.sx-mover-name { font-size: 12.5px; font-weight: 600; line-height: 1.3; }
.sx-mover-sub { font-size: 11px; color: var(--sx-muted); margin-top: 1px; }
.sx-mover-stat { font-size: 11.5px; color: var(--sx-accent); font-weight: 600; margin-top: 4px; }

/* Lifecycle / status badges */
.sx-badge { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; }
.sx-badge.new { background: #e3edfb; color: #3567b0; }
.sx-badge.hero { background: var(--sx-accent-soft); color: var(--sx-accent); }
.sx-badge.fast { background: #e6f4ec; color: var(--sx-good); }
.sx-badge.normal { background: var(--sx-surface-2); color: var(--sx-ink-soft); }
.sx-badge.slow { background: #fbeee0; color: var(--sx-warn); }
.sx-badge.clearance { background: #f9e4e1; color: var(--sx-bad); }
.sx-badge.disc { background: var(--sx-surface-2); color: var(--sx-muted); }

/* Drill-down breadcrumb */
.sx-drill-crumb { display: flex; align-items: center; gap: 6px; font-size: 13px; margin-bottom: 12px; color: var(--sx-muted); }
.sx-drill-crumb button { background: none; border: none; color: var(--sx-accent); font-weight: 600; cursor: pointer; padding: 0; font: inherit; }

.sx-empty { padding: 40px 20px; text-align: center; color: var(--sx-muted); }

/* =====================================================================
   PROJECT MANAGEMENT — reuses .sx-* primitives (kpi cards, tabs, panels,
   tables, badges, charts) for visual consistency; .pj-* covers what's
   unique to this module: the project list, type picker, and task board. */
.pj-root { --sx-bg: var(--bg); --sx-surface: var(--surface); --sx-surface-2: var(--surface-2);
  --sx-ink: var(--ink); --sx-ink-soft: var(--ink-soft); --sx-muted: var(--muted);
  --sx-line: var(--line); --sx-line-strong: var(--line-strong);
  --sx-accent: var(--accent-deep); --sx-accent-soft: var(--accent-soft);
  --sx-good: var(--ok); --sx-warn: var(--warn); --sx-bad: var(--danger); color: var(--sx-ink); }
.pj-root .muted { color: var(--sx-muted); }
.pj-filterbar { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 16px; }
.pj-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.pj-card { background: var(--sx-surface); border: 1px solid var(--sx-line); border-radius: var(--r); padding: 16px 18px; cursor: pointer; transition: border-color .14s, transform .1s; }
.pj-card:hover { border-color: var(--sx-accent); transform: translateY(-1px); }
.pj-card-type { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: var(--sx-accent); font-weight: 700; margin-bottom: 6px; }
.pj-card-name { font-family: var(--serif); font-size: 17px; font-weight: 600; margin: 0 0 8px; }
.pj-card-meta { display: flex; justify-content: space-between; align-items: center; font-size: 12px; color: var(--sx-muted); }
.pj-type-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 16px; }
@media (max-width: 700px) { .pj-type-grid { grid-template-columns: 1fr; } }
.pj-type-card { display: flex; flex-direction: column; gap: 6px; text-align: left; padding: 16px; border: 1.5px solid var(--sx-line-strong); border-radius: var(--r-sm); background: var(--sx-surface); cursor: pointer; font: inherit; }
.pj-type-card:hover { border-color: var(--sx-accent); }
.pj-type-card.on { border-color: var(--sx-accent); background: var(--sx-accent-soft); }
.pj-type-card strong { font-family: var(--serif); font-size: 15px; }
.pj-type-card .muted { font-size: 12px; line-height: 1.4; }
/* Hotfix (Phase 0 of the platform UX plan; full .dt table system lands in Phase 3):
   under table-layout:auto a width:100% text input contributes ~0 to a column's
   intrinsic size while input[type=date] has a non-overridable ~110-140px floor, so
   date columns always win and text columns collapse to their <th> width ("De…").
   table-layout:fixed with an explicit <colgroup> stops the browser consulting cell
   contents at all — columns are exactly what the colgroup says, always. */
.pj-fixed-table { table-layout: fixed; }
.pj-fixed-table th, .pj-fixed-table td { overflow-wrap: break-word; }
.pj-editable-table input, .pj-editable-table select, .pj-editable-table textarea { width: 100%; border: 1px solid transparent; background: transparent; color: var(--sx-ink); padding: 4px 6px; border-radius: 6px; font: inherit; }
/* Working tab's Task Name — a plain <input> clips overflow text with no visual cue at all
   (no ellipsis, just silently cut off, e.g. "Send KOLs Menu to KOLs (for Ch..."); a
   textarea wraps instead, so a long task name is actually readable without opening it. */
.pj-task-name { resize: none; line-height: 1.35; }
.pj-editable-table input:hover, .pj-editable-table select:hover, .pj-editable-table textarea:hover,
.pj-editable-table input:focus, .pj-editable-table select:focus, .pj-editable-table textarea:focus { border-color: var(--sx-line-strong); background: var(--sx-surface-2); }
.pj-editable-table tbody tr:hover { background: transparent; } /* override sx-table's row hover — inputs already show focus */
/* nowrap: the Add sub-task control's label is the two glyphs "＋↳". In a narrow actions
   column they wrapped onto separate lines and read as TWO buttons doing the same thing,
   which is exactly how the user reported it. They are one control. */
.pj-row-del { background: none; border: none; color: var(--sx-muted); cursor: pointer; font-size: 15px; padding: 2px 6px; white-space: nowrap; }
/* Two controls only, and each is ONE glyph: ＋ adds a sub-task, ✕ deletes the row.
   The add button previously read "＋↳" — two characters that looked like two separate
   buttons doing the same job, which is how it kept being reported. */
.pj-row-sub { font-weight: 600; }
.pj-row-sub:hover { color: var(--sx-accent, var(--accent-deep)); }
/* Actions stay on one line beside each other rather than stacking. */
.pj-row-acts { white-space: nowrap; text-align: right; }
/* Done: a real, green, easy-to-hit checkbox — the single "this task is finished" control. */
.pj-done-cell { text-align: center; }
.pj-done { display: inline-flex; align-items: center; justify-content: center; cursor: pointer; padding: 4px; }
.pj-done input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; accent-color: var(--ok); margin: 0; }
/* A finished row recedes, so the eye lands on what is still outstanding. */
tr.pj-task-done > td { background: rgba(74, 143, 107, .07); }
tr.pj-task-done .pj-task-name { color: var(--sx-muted); text-decoration: line-through; text-decoration-color: rgba(74,143,107,.6); }
.pj-row-del:hover { color: var(--sx-bad); }
.pj-status-chip { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; }
.pj-status-chip.not_started, .pj-status-chip.pending { background: var(--sx-surface-2); color: var(--sx-muted); }
.pj-status-chip.in_progress { background: #fbeee0; color: var(--sx-warn); }
.pj-status-chip.complete, .pj-status-chip.done { background: #e6f4ec; color: var(--sx-good); }
.pj-section-title { font-family: var(--serif); font-size: 15px; font-weight: 600; margin: 20px 0 10px; }
.pj-section-title:first-child { margin-top: 0; }
.pj-checklist-row td { background: var(--sx-surface-2); }
.pj-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.pj-cal-head { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: var(--sx-muted); text-align: center; padding-bottom: 4px; }
.pj-cal-cell { min-height: 64px; border: 1px solid var(--sx-line); border-radius: 6px; padding: 4px; font-size: 11px; }
.pj-cal-cell.empty { border-color: transparent; }
.pj-cal-day { font-weight: 700; font-size: 11px; color: var(--sx-muted); }

/* ---- My Tasks (cross-project) ---------------------------------------------
   Two views share one visual language: the due-date chip and the status colour
   mean the same thing in the Focus list and on the Board. */

/* Lens strip — the four numbers worth knowing before reading any row. Each is a
   toggle filter, so the count and the way to act on it are the same control. */
.mt-lenses { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 16px; }
@media (max-width: 820px) { .mt-lenses { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.mt-lens { text-align: left; font: inherit; color: var(--sx-ink); cursor: pointer;
  background: var(--sx-surface); border: 1.5px solid var(--sx-line); border-radius: var(--r-sm);
  padding: 12px 14px; transition: border-color .14s, background .14s; }
.mt-lens:hover { border-color: var(--sx-line-strong); }
.mt-lens.on { border-color: var(--sx-accent); background: var(--sx-accent-soft); }
.mt-lens-num { display: block; font-family: var(--serif); font-size: 28px; line-height: 1; }
.mt-lens-label { display: block; font-size: 11px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--sx-muted); margin-top: 6px; }
.mt-lens.tone-late .mt-lens-num { color: var(--sx-bad); }
.mt-lens.tone-today .mt-lens-num { color: var(--sx-warn); }
.mt-lens.tone-review .mt-lens-num { color: #3567b0; }
/* An empty count shouldn't shout — zero overdue is good news, not a data point. */
.mt-lens.zero .mt-lens-num { color: var(--sx-muted); opacity: .5; }

/* Focus view — grouped by when, not by status. */
.mt-group { margin-bottom: 22px; }
.mt-group-head { display: flex; align-items: center; gap: 10px; margin: 0 0 8px;
  font-family: var(--serif); font-size: 15px; font-weight: 600; }
.mt-group-count { font-size: 12px; color: var(--sx-muted); font-weight: 700; }
.mt-group-rule { flex: 1; height: 1px; background: var(--sx-line); }
.mt-group-hint { font-size: 12px; color: var(--sx-muted); margin: -2px 0 8px; }
.mt-group-overdue .mt-group-head { color: var(--sx-bad); }
.mt-rows { display: flex; flex-direction: column; gap: 6px; }
/* Status lives in the left edge: present at a glance, never competing with the task name. */
.mt-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: var(--sx-surface); border: 1px solid var(--sx-line); border-left: 3px solid var(--sx-line-strong);
  border-radius: var(--r-sm); padding: 10px 14px; transition: border-color .14s; }
.mt-row:hover { border-color: var(--sx-line-strong); }
.mt-row.st-in_progress { border-left-color: var(--sx-warn); }
.mt-row.st-pending_approval { border-left-color: #3567b0; }
.mt-row.st-complete { border-left-color: var(--sx-good); }
.mt-row-main { flex: 1; min-width: 220px; }
.mt-row-name { font-weight: 600; font-size: 13.5px; color: var(--sx-ink); text-decoration: none; }
.mt-row-name:hover { color: var(--sx-accent); }
.mt-row.st-complete .mt-row-name { color: var(--sx-muted); text-decoration: line-through; text-decoration-color: rgba(74,143,107,.6); }
.mt-row-sub { font-size: 11.5px; color: var(--sx-muted); margin-top: 3px; }
.mt-row-proj { color: var(--sx-accent); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; font-size: 10.5px; }
.mt-prio { margin-left: 8px; font-size: 9.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; padding: 1px 6px; border-radius: 4px; }
.mt-prio.urgent { background: #f9e4e1; color: var(--sx-bad); }
.mt-prio.high { background: #fbeee0; color: var(--sx-warn); }
.mt-row-acts { display: flex; gap: 6px; flex-wrap: wrap; }
.mt-row-acts .btn { padding: 4px 10px; font-size: 11.5px; white-space: nowrap; }

/* Due chip — relative wording ("4 days late") carries the urgency; the exact date is the tooltip. */
.mt-due { font-size: 11.5px; font-weight: 700; white-space: nowrap; padding: 3px 10px; border-radius: 999px; }
.mt-due.late { background: #f9e4e1; color: var(--sx-bad); }
.mt-due.today { background: #fbeee0; color: var(--sx-warn); }
.mt-due.soon { background: var(--sx-surface-2); color: var(--sx-ink-soft); }
.mt-due.later, .mt-due.none { color: var(--sx-muted); padding-left: 0; padding-right: 0; }
.mt-due.done { background: #e6f4ec; color: var(--sx-good); }

/* Finished work: reachable, not resident. */
.mt-done { border-top: 1px solid var(--sx-line); padding-top: 14px; margin-top: 4px; }
.mt-done > summary { cursor: pointer; display: flex; align-items: center; gap: 10px;
  font-family: var(--serif); font-size: 15px; font-weight: 600; margin-bottom: 10px; }
.mt-done > summary::marker { color: var(--sx-muted); }
.mt-done[open] > summary { margin-bottom: 12px; }

/* Board view — the status kanban, kept for scanning a whole team at a glance. */
.mt-board { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 14px; align-items: start; }
@media (max-width: 1200px) { .mt-board { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .mt-board { grid-template-columns: minmax(0, 1fr); } }
.mt-col-head { display: flex; align-items: center; justify-content: space-between; margin: 0 0 10px; }
.mt-col-count { font-size: 12px; color: var(--sx-muted); font-weight: 700; }
.mt-col-body { display: flex; flex-direction: column; gap: 8px; }
.mt-card { background: var(--sx-surface); border: 1px solid var(--sx-line); border-radius: var(--r-sm); padding: 12px 14px; }
.mt-card-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 4px; }
.mt-card-project { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--sx-accent); font-weight: 700; }
.mt-card-name { display: block; font-weight: 600; font-size: 13.5px; color: var(--sx-ink); text-decoration: none; margin-bottom: 6px; }
.mt-card-name:hover { color: var(--sx-accent); }
.mt-card-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.mt-card-acts .btn { padding: 4px 10px; font-size: 11.5px; }

/* ---- Budget Production: payment select tinted by value (the select IS the badge) ---- */
.pj-editable-table select.pj-pay-paid { background: #e6f4ec; color: var(--sx-good); border-color: var(--sx-good); }
.pj-editable-table select.pj-pay-partial { background: #fbeee0; color: var(--sx-warn); border-color: var(--sx-warn); }
.pj-editable-table select.pj-pay-unpaid { background: var(--sx-surface-2); color: var(--sx-ink-soft); }

/* ---- Cross-project Timeline (Gantt) ---- */
.tlv-toolbar { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 12px; }
.tlv-toolbar select { width: auto; min-width: 120px; max-width: 190px; background: var(--sx-surface); color: var(--sx-ink); border: 1px solid var(--sx-line-strong); border-radius: 8px; padding: 6px 10px; }
.tlv-wrap { overflow: auto; border: 1px solid var(--sx-line); border-radius: 10px; background: var(--sx-surface); max-height: calc(100vh - 250px); position: relative; }
.tlv-grid { display: grid; min-width: max-content; position: relative; }
.tlv-cell-head { font-size: 10px; text-align: center; color: var(--sx-muted); border-left: 1px solid var(--sx-line); border-bottom: 1px solid var(--sx-line); padding: 2px 1px; background: var(--sx-surface); position: sticky; z-index: 3; white-space: nowrap; overflow: hidden; }
.tlv-cell-head.tier1 { top: 0; font-weight: 700; color: var(--sx-ink-soft); cursor: pointer; }
.tlv-cell-head.tier2 { top: 19px; font-weight: 600; cursor: pointer; }
.tlv-cell-head.tier3 { top: 38px; }
.tlv-sticky-col { position: sticky; left: 0; z-index: 4; background: var(--sx-surface); border-right: 2px solid var(--sx-line-strong); border-bottom: 1px solid var(--sx-line); padding: 3px 10px; font-size: 12px; min-width: 210px; max-width: 210px; overflow: hidden; line-height: 1.3; }
.tlv-sticky-col.head { z-index: 5; position: sticky; top: 0; }
.tlv-row-track { position: relative; border-bottom: 1px solid var(--sx-line); background-image: linear-gradient(to right, var(--sx-line) 1px, transparent 1px); }
.tlv-name { font-weight: 600; cursor: pointer; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
.tlv-name .tlv-chev { display: inline-block; width: 13px; color: var(--sx-muted); }
.tlv-sub { font-size: 11px; color: var(--sx-muted); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
.tlv-indent-1 { padding-left: 24px; }
.tlv-indent-2 { padding-left: 40px; font-weight: 400; }
.tlv-bar { position: absolute; top: 11px; height: 15px; border-radius: 4px; cursor: pointer; min-width: 4px; }
.tlv-bar .tlv-cap { position: absolute; right: 0; top: 0; bottom: 0; border-radius: 0 4px 4px 0; }
.tlv-bar.clip-left { clip-path: polygon(6px 0, 100% 0, 100% 100%, 6px 100%, 0 50%); border-radius: 0 4px 4px 0; }
.tlv-bar.clip-right { clip-path: polygon(0 0, calc(100% - 6px) 0, 100% 50%, calc(100% - 6px) 100%, 0 100%); border-radius: 4px 0 0 4px; }
.tlv-bar.fast { background: rgba(74, 143, 107, .3); } .tlv-bar.fast .tlv-cap { background: var(--sx-good); }
.tlv-bar.hero { background: var(--sx-accent-soft); } .tlv-bar.hero .tlv-cap { background: var(--sx-accent); }
.tlv-bar.new { background: rgba(53, 103, 176, .25); } .tlv-bar.new .tlv-cap { background: #3567b0; }
.tlv-bar.clearance { background: rgba(192, 86, 75, .3); } .tlv-bar.clearance .tlv-cap { background: var(--sx-bad); }
.tlv-diamond { position: absolute; top: 13px; width: 11px; height: 11px; background: var(--sx-accent); transform: rotate(45deg); cursor: pointer; border-radius: 2px; }
.tlv-diamond-label { position: absolute; top: 12px; font-size: 10px; color: var(--sx-ink-soft); white-space: nowrap; pointer-events: none; }
.tlv-today { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--sx-bad); opacity: .65; z-index: 2; pointer-events: none; }
.tlv-undated { display: inline-block; background: var(--sx-surface-2); color: var(--sx-muted); border-radius: 999px; padding: 0 8px; font-size: 10px; font-weight: 700; cursor: pointer; }
.tlv-tooltip { position: fixed; z-index: var(--z-tooltip); background: var(--sx-ink); color: var(--sx-bg); border-radius: 8px; padding: 8px 12px; font-size: 12px; max-width: 280px; pointer-events: none; box-shadow: 0 4px 16px rgba(0,0,0,.25); }
.tlv-tooltip .muted2 { opacity: .7; font-size: 11px; }
.tlv-empty-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 6; pointer-events: none; }
.tlv-empty-overlay > div { pointer-events: auto; background: var(--sx-surface); border: 1px solid var(--sx-line-strong); border-radius: 12px; padding: 20px 28px; max-width: 420px; text-align: center; box-shadow: 0 8px 30px rgba(0,0,0,.12); }


/* ---- KOL Seeding product picker ---------------------------------------------------- */
.modal-wide { max-width: 900px; width: 92vw; }
.pp-body { max-height: 58vh; overflow: auto; padding-right: 4px; }
.pp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
/* The tile is the control: a big tap target with the photo doing the identifying, since
   picking a garment by name alone is exactly what this feature exists to avoid. */
.pp-tile { display: flex; flex-direction: column; gap: 6px; padding: 8px;
  background: var(--surface); border: 1.5px solid var(--line-strong); border-radius: var(--r-sm);
  text-align: left; font-family: var(--sans); transition: border-color .12s, box-shadow .12s; }
/* The photo/name area is the toggle; sizes sit below so picking a size never un-picks
   the garment by accident. */
.pp-tile-main { display: flex; flex-direction: column; gap: 6px; padding: 0; cursor: pointer;
  background: none; border: none; text-align: left; font-family: var(--sans); }
/* Sizes come from the Product Master, so only sizes that exist can be chosen. */
.pp-sizes { display: flex; flex-wrap: wrap; gap: 4px; padding-top: 6px; border-top: 1px solid var(--line); align-items: center; }
.pp-size { font-family: var(--sans); font-size: 11.5px; font-weight: 600; cursor: pointer;
  padding: 3px 8px; border-radius: 999px; background: var(--surface-2);
  border: 1px solid var(--line-strong); color: var(--ink-soft); }
.pp-size:hover { border-color: var(--accent); color: var(--accent-deep); }
.pp-size.on { background: var(--accent-deep); border-color: var(--accent-deep); color: #fff; }
.pp-tile:hover { border-color: var(--accent); }
.pp-tile.on { border-color: var(--accent-deep); box-shadow: var(--focus-ring); background: var(--accent-soft); }
.pp-thumb { display: flex; align-items: center; justify-content: center; aspect-ratio: 1;
  background: var(--surface-2); border-radius: var(--r-sm); overflow: hidden; color: var(--muted); font-size: 22px; }
.pp-thumb img { width: 100%; height: 100%; object-fit: cover; }
.pp-label { font-size: 12.5px; font-weight: 600; line-height: 1.3; }
.pp-price { font-size: 12px; color: var(--ink-soft); }
/* Selected tiles carry a tick so the state survives a colour-blind reading of the border. */
.pp-tile.on .pp-label::after { content: " ✓"; color: var(--accent-deep); }
.pj-pick-btn { white-space: nowrap; }

/* Import preview — rows rejected by a validation rule (canonical product mapping, or a
   sub-code already owned by a different ลาย). Listed individually so the source sheet can be
   corrected; the valid rows still import. */
.imp-rejects { border: 1px solid var(--danger, #c0564b); border-radius: var(--r-sm, 8px);
  background: color-mix(in srgb, var(--danger, #c0564b) 7%, transparent);
  padding: 10px 14px; margin-bottom: 14px; font-size: 13px; }
.imp-rejects ul { margin: 6px 0 0; padding-left: 18px; }
.imp-rejects li { margin: 3px 0; line-height: 1.45; }

/* Move-colourway modal — read-only list of the barcodes that will travel, so the person can see
   exactly what moves (and that the numbers are unchanged) before confirming. */
.mcw-barcodes { border: 1px solid var(--line); border-radius: var(--r-sm, 8px); padding: 8px 10px;
  max-height: 210px; overflow-y: auto; }
.mcw-bc-row { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 3px 0; font-size: 12.5px; }
.mcw-bc-row span { color: var(--muted); }
.mcw-bc-row code { font-weight: 600; letter-spacing: .02em; }

/* ===================== Merchandiser Tracking ===========================
   22 spreadsheet columns cannot fit a screen as a table, and forcing them
   to made the page scroll sideways -- so the row carries only what you scan
   for (who, which factory, how far along, what is outstanding) and the full
   date set lives in a panel you open per product. Nothing scrolls
   horizontally at any width. */
/* Every control shares one height so the label-less Clear button lines up with the
   inputs instead of sitting a few pixels low -- flex-end alone cannot do it, because
   the button's box and the inputs' boxes were different heights. */
.trk-filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; padding: 12px 14px; margin-bottom: 12px; --trk-ctl-h: 32px; }
/* margin-bottom:0 is load-bearing. The global :where(label) rule gives every label
   14px of bottom margin, and align-items:end aligns MARGIN boxes -- so the labels' inputs
   sat 14px above the alignment line while the margin-less Clear button sat on it, which is
   what made the button look dropped. :where() has zero specificity, so this rule wins the
   properties it names but inherits the ones it does not. */
.trk-filters label { display: flex; flex-direction: column; gap: 4px; font-size: 11px;
  color: var(--muted); margin-bottom: 0; }
.trk-filters select, .trk-filters input, .trk-filters .btn {
  height: var(--trk-ctl-h); box-sizing: border-box; font-size: 12.5px; padding: 0 10px;
  line-height: calc(var(--trk-ctl-h) - 2px); }
.trk-filters select, .trk-filters input { min-width: 140px; max-width: 200px; }
.trk-filters .btn { align-self: end; padding: 0 14px; }

.trk-warn { background: #fdf3d6; border: 1px solid #e6cf8a; color: #6b4e0e; border-radius: var(--r-sm, 8px);
  padding: 10px 14px; font-size: 12.5px; margin-bottom: 12px; }
.trk-warn code { background: rgba(0,0,0,.06); padding: 1px 4px; border-radius: 3px; }

.trk-summary { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.trk-stat { background: var(--card, #fff); border: 1px solid var(--line); border-radius: var(--r-sm, 8px);
  padding: 8px 14px; display: flex; flex-direction: column; min-width: 92px; }
.trk-stat strong { font-size: 19px; line-height: 1.15; }
.trk-stat span { font-size: 11px; color: var(--muted); }
.trk-stat-ok strong { color: #2e7d32; }

.trk-list { display: flex; flex-direction: column; gap: 8px; }
.trk-card { background: var(--card, #fff); border: 1px solid var(--line); border-radius: var(--r-sm, 10px);
  overflow: hidden; transition: border-color .12s ease; }
.trk-card:hover { border-color: color-mix(in srgb, var(--muted) 35%, transparent); }
.trk-card-open { border-color: color-mix(in srgb, var(--muted) 45%, transparent); }
.trk-card-done { border-left: 3px solid #4c9a52; }

/* Grid, not a table: it reflows instead of overflowing. */
.trk-head { display: grid; gap: 12px; align-items: center; padding: 10px 14px;
  grid-template-columns: minmax(210px, 1.6fr) minmax(150px, 1fr) minmax(180px, 1.3fr) auto; }
.trk-id { display: flex; align-items: center; gap: 10px; min-width: 0; }
.trk-thumb { width: 38px; height: 38px; object-fit: cover; border-radius: 6px; flex: none; }
.trk-thumb-empty { display: grid; place-items: center; background: rgba(0,0,0,.04);
  color: color-mix(in srgb, var(--muted) 45%, transparent); font-size: 13px; }
.trk-names { min-width: 0; }
.trk-prod { font-weight: 600; font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trk-code { color: var(--muted); font-weight: 400; margin-left: 6px; font-size: 12px; }
.trk-sub { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.trk-statwrap { min-width: 0; }
.trk-status { display: inline-block; padding: 2px 9px; border-radius: 99px; font-size: 11px; font-weight: 600;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; background: #ececf0; color: #3a3a44; }
.trk-s0 { background: transparent; color: color-mix(in srgb, var(--muted) 60%, transparent); font-weight: 400; padding-left: 0; }
.trk-s1, .trk-s2, .trk-s3, .trk-s4, .trk-s5    { background: #fdeecf; color: #7a5312; }
.trk-s6, .trk-s7                               { background: #e6e2fb; color: #40358f; }
.trk-s8, .trk-s9, .trk-s10, .trk-s11, .trk-s12 { background: #dbe8fb; color: #1c3f70; }
.trk-s13 { background: #d7f0d9; color: #1f5c25; }
.trk-bar { height: 3px; border-radius: 2px; background: rgba(0,0,0,.07); margin-top: 6px; max-width: 150px; overflow: hidden; }
.trk-bar i { display: block; height: 100%; border-radius: 2px; background: currentColor; opacity: .4; }
.trk-auto { font-size: 9px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
  background: rgba(0,0,0,.05); border-radius: 3px; padding: 1px 4px; margin-left: 5px; vertical-align: middle; }

.trk-meta { display: flex; flex-wrap: wrap; gap: 6px 10px; font-size: 11.5px; align-items: center; min-width: 0; }
.trk-po { font-variant-numeric: tabular-nums; color: var(--muted); }
.trk-next { font-size: 10.5px; color: #7a5312; background: #fdeecf; border-radius: 99px; padding: 1px 7px; }
.trk-none { color: color-mix(in srgb, var(--muted) 45%, transparent); font-style: normal; }
.trk-act { display: flex; gap: 6px; justify-self: end; }

/* Two groups, not three: the only distinction that matters is who owns a field -- the same
   yellow/blue split as the source spreadsheet. Grouping by ownership retires the per-field
   dot, which forced you to decode every row one at a time. */
.trk-detail { border-top: 1px solid var(--line); padding: 14px; background: rgba(0,0,0,.012);
  display: flex; flex-direction: column; gap: 14px; }
.trk-grp { background: var(--card, #fff); border: 1px solid var(--line); border-radius: 8px; padding: 11px 13px; }
.trk-grp-live { background: rgba(111, 154, 214, .05); border-color: rgba(111, 154, 214, .28); }
.trk-grp h4 { margin: 0 0 10px; font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); font-weight: 600; display: flex; align-items: center; gap: 7px; }
.trk-ro { text-transform: none; letter-spacing: normal; font-weight: 500; font-size: 10px;
  color: #40699f; background: rgba(111, 154, 214, .16); border-radius: 99px; padding: 1px 7px; }

/* Label above value, both left-aligned: the old label-left / value-right split stranded a
   dash mid-row and wrapped longer labels. auto-fit wraps instead of overflowing. */
.trk-fields { display: grid; gap: 10px 16px; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
.trk-f { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.trk-f span { font-size: 10.5px; color: var(--muted); line-height: 1.3; }
.trk-f strong { font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; }
.trk-f-empty strong { color: color-mix(in srgb, var(--muted) 40%, transparent); font-weight: 400; }

/* PO numbers are a set, not a sentence -- one chip each, wrapping across the full width
   rather than crushed into a third of it. */
.trk-pos { margin-top: 11px; padding-top: 10px; border-top: 1px dashed rgba(111, 154, 214, .3); }
.trk-pos-lbl { display: block; font-size: 10.5px; color: var(--muted); margin-bottom: 6px; }
.trk-pos-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.trk-po-chip { font-size: 11.5px; font-variant-numeric: tabular-nums; background: var(--card, #fff);
  border: 1px solid rgba(111, 154, 214, .4); color: #2c5182; border-radius: 5px; padding: 2px 7px; }
.trk-grp-note { background: #fffdf5; border-color: #ecdfae; }
.trk-note { margin: 0; font-size: 12.5px; line-height: 1.55; white-space: pre-wrap; }

.trk-live { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 12px; }
.trk-live-title { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-bottom: 8px; }
.trk-live-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.trk-live-grid span { display: block; font-size: 10.5px; color: var(--muted); }
.trk-live-grid strong { font-size: 12.5px; }
.trk-live-note { font-size: 12px; color: var(--muted); margin: 10px 0 0; }

@media (max-width: 860px) {
  .trk-head { grid-template-columns: 1fr; gap: 8px; }
  .trk-act { justify-self: start; }
  .trk-bar { max-width: none; }
}

/* Pipeline strip — the 13 stages with a live count each, doubling as the main filter.
   Counts are of the whole catalogue (minus collection/merchandiser/MNF/search), not of
   what is currently on screen, so a stage never reads zero merely because you filtered
   it away. Stages with nothing in them are dimmed and unclickable. */
.trk-pipe { display: flex; flex-wrap: wrap; gap: 6px; align-items: stretch; margin-bottom: 14px; }
.trk-pipe-div { width: 1px; background: var(--line); margin: 2px 4px; }
.trk-chip { display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  background: var(--card, #fff); border: 1px solid var(--line); border-radius: 8px;
  padding: 5px 10px; cursor: pointer; font: inherit; text-align: left;
  transition: border-color .12s ease, background .12s ease; }
.trk-chip strong { font-size: 15px; line-height: 1.1; }
.trk-chip span { font-size: 10.5px; color: var(--muted); white-space: nowrap; }
.trk-chip:hover:not(:disabled) { border-color: color-mix(in srgb, var(--muted) 40%, transparent); }
.trk-chip:disabled { opacity: .38; cursor: default; }
.trk-chip-on { border-color: #3a3a44; background: #3a3a44; }
.trk-chip-on strong, .trk-chip-on span { color: #fff; }
.trk-chip-all strong { color: #1c3f70; }
.trk-chip-late { border-color: #e6b4b4; }
.trk-chip-late strong { color: #a33a3a; }
.trk-chip-late.trk-chip-on { background: #a33a3a; border-color: #a33a3a; }
.trk-chip-s13 strong { color: #2e7d32; }
.trk-chip-ns strong { color: color-mix(in srgb, var(--muted) 70%, transparent); }

.trk-card-late { border-left: 3px solid #c96a6a; }
.trk-late { font-size: 10.5px; color: #a33a3a; background: #f7e3e3; border-radius: 99px; padding: 1px 7px; font-weight: 600; }
.trk-toggle-lbl { flex-direction: row !important; align-items: center; gap: 6px !important;
  font-size: 11.5px; color: var(--muted); height: var(--trk-ctl-h); cursor: pointer; }
.trk-toggle-lbl input { width: auto; min-width: 0; height: auto; }

/* The row itself opens its dates, so there is one button (Edit) rather than two. */
.trk-head { cursor: pointer; }
.trk-head:focus-visible { outline: 2px solid #6f9ad6; outline-offset: -2px; border-radius: 8px; }
.trk-caret { color: var(--muted); font-size: 14px; line-height: 1; transition: transform .15s ease;
  display: inline-block; }
.trk-card-open .trk-caret { transform: rotate(180deg); }

/* Note — its own block below the field grid, not a cell inside it. As a grid item it had to
   share a 190px column track, which is why it sat beside its label looking like an
   afterthought. The app's base control rule is `input, select` and never covered textarea,
   so it also needs its box styled explicitly to match the fields above it. */
.trk-note-block { margin-top: 6px; }
.trk-note-block label { display: block; font-weight: 600; font-size: 12px; letter-spacing: .03em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 7px; }
.trk-note-block textarea {
  display: block; width: 100%; box-sizing: border-box; padding: 11px 13px;
  font-family: var(--sans); font-size: 14px; font-weight: 500; line-height: 1.55;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink); resize: vertical; min-height: 76px;
}
.trk-note-block textarea::placeholder { color: var(--muted); opacity: .7; font-weight: 400; }
.trk-note-block textarea:focus { border-color: var(--accent); outline: none; }

/* The date a row shows follows its status: a due date while the order is live, the actual
   receive date once it has landed. Green reads as settled, neutral as still owed. */
.trk-date { font-size: 11px; font-variant-numeric: tabular-nums; border-radius: 99px;
  padding: 1px 8px; background: rgba(0,0,0,.05); color: var(--muted); }
.trk-date-got { background: #d7f0d9; color: #1f5c25; font-weight: 600; }

/* A tracking row is one PRODUCT; the Collection page lists one card per COLOURWAY and calls
   them products. Showing the colourway count here reconciles "6 products" there with 2 rows
   here without anyone having to work it out. */
.trk-cw-count { font-size: 10px; font-weight: 500; color: var(--muted); background: rgba(0,0,0,.05);
  border-radius: 99px; padding: 1px 7px; margin-left: 7px; vertical-align: middle; white-space: nowrap; }

/* A tracking row is now one colourway, so the colour is part of its identity, not a detail. */
.trk-colour { color: var(--accent, #b4527a); font-weight: 600; }

/* PO History multi-select — bulk PDF/Excel export of several purchase orders at once. */
.pos-bulk { display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 10px 14px; margin: 12px 0; }
.pos-bulk-all { display: flex; align-items: center; gap: 7px; margin: 0; font-size: 12.5px;
  font-weight: 600; text-transform: none; letter-spacing: normal; color: var(--ink); cursor: pointer; }
.pos-bulk-all input { width: auto; margin: 0; cursor: pointer; }
#pos-bulk-count { font-size: 12.5px; }
.pos-bulk-act { display: flex; gap: 8px; margin-left: auto; flex-wrap: wrap; }
.pos-bulk-act .btn:disabled { opacity: .45; cursor: default; }

.po-hist { position: relative; }
/* .po-hist is justify-content:space-between, which was fine with two children (details
   left, buttons right). Adding the checkbox made three, so the free space was shared
   BETWEEN all three and shoved the PO details into the middle of the card. Letting the
   details absorb the free space instead puts them back beside their checkbox, with the
   buttons still pushed to the right edge. */
.po-hist-main { flex: 1; min-width: 0; }
/* Negative margin tightens only the checkbox-to-details gap; the card's 16px gap still
   applies between the details and the action buttons. */
.po-hist-pick { display: flex; align-items: center; margin: 0 -6px 0 0; }
.po-hist-pick input { width: auto; margin: 0; cursor: pointer; }
.po-hist-sel { border-color: var(--accent, #b4527a); background: rgba(180, 82, 122, .04); }

/* Payment Voucher — goods-receipt reconciliation (receipt trail, delivery evidence,
   price variance) so finance can verify a payment against its proof of delivery. */
.vc-variance-note { background: #fdf3d6; border: 1px solid #e6cf8a; color: #6b4e0e;
  border-radius: var(--r-sm, 8px); padding: 9px 13px; font-size: 12.5px; margin-bottom: 10px; }
.vc-checked { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.vc-checked-state { font-size: 12.5px; }
.vc-checked-yes { color: #1f5c25; font-weight: 700; }

.vc-recon { margin: 8px 0 4px; border: 1px solid var(--line); border-radius: var(--r-sm, 8px);
  background: rgba(0, 0, 0, .012); }
.vc-recon > summary { cursor: pointer; padding: 8px 12px; display: flex; gap: 10px;
  align-items: baseline; flex-wrap: wrap; font-size: 12px; }
.vc-recon-title { font-weight: 700; text-transform: uppercase; letter-spacing: .04em; font-size: 10.5px; }
.vc-recon-sum { color: var(--muted); }
.vc-recon-diff { color: #a33a3a; font-weight: 600; }
.vc-recon-warn { margin: 0 12px 8px; font-size: 12px; color: #6b4e0e;
  background: #fdf3d6; border-radius: 6px; padding: 7px 10px; }
.vc-recon-table { margin: 0 12px 12px; width: calc(100% - 24px); font-size: 12px; }
.vc-rc-cancelled td { opacity: .55; }
.vc-evi-chip { display: inline-block; font-size: 11.5px; background: var(--surface, #fff);
  border: 1px solid rgba(111, 154, 214, .45); color: #2c5182; border-radius: 5px;
  padding: 1px 7px; margin: 1px 2px 1px 0; text-decoration: none; }
.vc-evi-chip:hover { border-color: #2c5182; }
.vc-evi-none { font-size: 11.5px; color: #a33a3a; }
.vc-var { white-space: nowrap; }
.vc-var s { color: var(--muted); font-weight: 400; margin-right: 3px; }
.vc-var-row { background: rgba(253, 243, 214, .5); }

/* PO History search — which lines inside a PO matched, so finding the PO also shows where
   in it the product sits. */
.po-hits { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-top: 8px; }
.po-hits-lbl { font-size: 11px; font-weight: 600; color: var(--accent, #b4527a); margin-right: 2px; }
.po-hit { font-size: 11px; background: rgba(180, 82, 122, .07); border: 1px solid rgba(180, 82, 122, .22);
  border-radius: 5px; padding: 1px 7px; color: var(--ink); }
.po-hit strong { font-variant-numeric: tabular-nums; }
.po-hit-more { background: transparent; color: var(--muted); }
#pos-search { max-width: 560px; }
