/* ─── Design Tokens ─────────────────────────────────────── */
/* 2026-08-26: tried a warm-slate palette for --bg/--border/--text/--danger/
   --success across several rounds (see git history) but it never read
   right on the user's actual display/screenshots despite checking out
   correctly server-side every time -- reverted the whole app-wide palette
   back to its original values. --sidebar-bg (dark obsidian) stays, since
   that specific change was separately requested and confirmed good. */
:root {
  --sidebar-bg:   #0A0F1D;
  --sidebar-w:    240px;
  --accent:       #26B99A;
  --accent-light: #D4F0EB;
  --bg:           #F0F4F8;
  --card:         #FFFFFF;
  --text:         #2C3E50;
  --text-muted:   #5C6F7F;
  --border:       #E1E8ED;
  --danger:       #E74C3C;
  --warning:      #F39C12;
  --success:      #27AE60;
  --info:         #2980B9;
  --radius:       8px;
  --shadow:       0 2px 8px rgba(0,0,0,.08);
}

/* ─── Reset ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* Mobile Chrome/Android auto-boosts font-size on text blocks it judges "too
   small to read" (per-element, based on its own heuristics) -- inconsistent
   from one cell to another even when their CSS font-size is identical, which
   is what actually made table columns look "staggered"/misaligned on phones
   even though the underlying CSS/grid was always correct. Disabling it keeps
   every element exactly at the size this stylesheet declares. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* Plus Jakarta Sans first -- it has no Thai glyphs, so Thai text falls
   through to Noto Sans Thai automatically per normal font-stack fallback;
   only Latin/number text (which is most of this app's UI chrome) actually
   switches face. */
/* 100vh on mobile/tablet browsers is the LAYOUT viewport, which includes
   space the address bar/toolbar actually occupies -- the page ends up
   taller than what's really visible, pushing the bottom out of reach.
   100dvh (dynamic viewport height) tracks the real visible area instead;
   kept 100vh first as a fallback for browsers that don't support dvh. */
body { font-family: 'Plus Jakarta Sans', 'Noto Sans Thai', 'Segoe UI', sans-serif; background: var(--bg); color: var(--text); display: flex; height: 100vh; height: 100dvh; overflow: hidden; font-size: 14px; }
a { color: inherit; text-decoration: none; }
button { cursor: pointer; border: none; outline: none; }
input, select, textarea { outline: none; font-family: inherit; font-size: 13px; }

/* ─── Sidebar ────────────────────────────────────────────── */
#sidebar {
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  background: var(--sidebar-bg);
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  transition: width .18s ease, min-width .18s ease;
}
/* On shorter laptop screens (~700px tall viewport after browser chrome),
   the full nav -- Main section + collapsible Dashboard group + Master
   Data + System -- genuinely doesn't fit in 100vh. Scoping the scroll to
   just .sidebar-nav (logo and the user/logout footer pinned outside it)
   instead of the whole #sidebar means the footer -- which doubles as the
   "there's more below" affordance -- never scrolls out of view itself;
   previously the whole sidebar scrolled as one block, so on a short
   screen the footer could disappear along with the missing menu items,
   making it look like the menu was broken rather than just needing a
   scroll. min-height:0 is required here -- a flex child won't shrink
   below its content's height on its own, and without that overflow-y:auto
   has nothing to trigger on. */
.sidebar-nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,.25) transparent;
}
.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.25); border-radius: 3px; }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
/* Toggled via the topbar's hide/show button (toggleSidebar() in app.js) --
   collapses the sidebar to zero width instead of the more common
   translateX(-100%) off-canvas approach, since #sidebar sits in a normal
   flex row next to #main (not a separate overlay layer): shrinking its own
   width is what actually gives #main the freed-up space, which matters
   most on a narrow phone screen where 240px of fixed sidebar is a big
   chunk of the whole viewport. */
body.sidebar-collapsed #sidebar { width: 0; min-width: 0; overflow: hidden; border: none; }
.sidebar-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 16px 12px;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.sidebar-logo-icon { width: 32px; height: 32px; border-radius: 9px; background: #10B981; color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; flex-shrink: 0; }
.sidebar-logo .logo-title { color: #fff; font-size: 15px; font-weight: 700; letter-spacing: .3px; }
.sidebar-logo .logo-sub   { color: #7F8C8D; font-size: 11px; margin-top: 2px; }

.sidebar-section-label {
  color: #475569;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  padding: 12px 16px 5px;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 16px;
  color: #94A3B8;
  font-size: 13px;
  cursor: pointer;
  border-left: 3px solid transparent;
  transition: all .15s;
}
.nav-item i { font-size: 16px; width: 18px; text-align: center; }
.nav-item:hover  { background: rgba(255,255,255,.05); color: #fff; }
.nav-item.active { background: rgba(16,185,129,.10); color: #34D399; border-left-color: #10B981; font-weight: 600; }
.nav-badge { margin-left: auto; background: var(--danger); color: #fff; font-size: 10px; padding: 1px 6px; border-radius: 10px; }
.nav-group-arrow { margin-left: auto; font-size: 11px; transition: transform .15s; }
.nav-subitems { overflow: hidden; }
.nav-item.nav-subitem { padding-left: 40px; font-size: 12.5px; }
.nav-item.nav-subitem i { font-size: 8px; width: 18px; }

/* ─── Main ───────────────────────────────────────────────── */
#main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }

.topbar {
  background: var(--card);
  border-bottom: 1px solid var(--border);
  padding: 0 24px;
  height: 54px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}
.topbar-title { font-size: 16px; font-weight: 700; color: var(--text); }
.topbar-right { display: flex; align-items: center; gap: 12px; }

#content { flex: 1; overflow-y: auto; padding: 24px; }

/* ─── Pages ──────────────────────────────────────────────── */
.page { display: none; }
.page.active { display: block; }

/* ─── KPI Cards ──────────────────────────────────────────── */
.kpi-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; margin-bottom: 20px; }
.kpi-card {
  background: var(--card);
  border-radius: var(--radius);
  padding: 16px;
  box-shadow: var(--shadow);
  border-left: 3px solid transparent;
}
.kpi-label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 6px; }
.kpi-value { font-size: 22px; font-weight: 700; color: var(--text); line-height: 1.1; }
.kpi-sub   { font-size: 11px; color: var(--text-muted); margin-top: 3px; }
.kpi-card.accent  { border-left-color: var(--accent); }
.kpi-card.warning { border-left-color: var(--warning); }
.kpi-card.danger  { border-left-color: var(--danger); }
.kpi-card.info    { border-left-color: var(--info); }

/* ─── Pipeline ───────────────────────────────────────────── */
.pipeline-wrap {
  background: var(--card);
  border-radius: var(--radius);
  padding: 16px 20px;
  box-shadow: var(--shadow);
  margin-bottom: 20px;
}
.pipeline-title { font-size: 12px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 12px; }
.pipeline-steps { display: flex; align-items: center; gap: 0; }
.pipeline-step {
  flex: 1;
  text-align: center;
  padding: 10px 8px;
  cursor: pointer;
  border-radius: 6px;
  transition: background .15s;
  position: relative;
}
.pipeline-step:not(:last-child)::after {
  content: '';
  position: absolute;
  right: -1px;
  top: 50%;
  transform: translateY(-50%);
  width: 8px;
  height: 8px;
  border-top: 2px solid var(--border);
  border-right: 2px solid var(--border);
  transform: translateY(-50%) rotate(45deg);
}
.pipeline-step:hover { background: var(--bg); }
.pipeline-count { font-size: 20px; font-weight: 700; color: var(--text); }
.pipeline-label { font-size: 10px; color: var(--text-muted); margin-top: 2px; }
.pipeline-step.st-1 .pipeline-count { color: #B7770D; }
.pipeline-step.st-2 .pipeline-count { color: #73879C; }
.pipeline-step.st-3 .pipeline-count { color: #2471A3; }
.pipeline-step.st-4 .pipeline-count { color: #E67E22; }
.pipeline-step.st-5 .pipeline-count { color: var(--accent); }
.pipeline-step.st-6 .pipeline-count { color: #8E44AD; }
.pipeline-step.st-7 .pipeline-count { color: #16A085; }
.pipeline-step.st-8 .pipeline-count { color: #C0392B; }

/* ─── Cards & Grid ───────────────────────────────────────── */
.card {
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  margin-bottom: 20px;
}
.card-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

/* ─── Alerts ─────────────────────────────────────────────── */
.alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 6px;
  margin-bottom: 8px;
  font-size: 13px;
}
.alert-danger  { background: #FDECEA; border-left: 3px solid var(--danger); color: #C0392B; }
.alert-warning { background: #FEF9E7; border-left: 3px solid var(--warning); color: #7D6608; }
.alert-success { background: #E9F7EF; border-left: 3px solid var(--success); color: #1E8449; }
.alert i { margin-top: 1px; flex-shrink: 0; }

/* ─── Tables ─────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
thead th {
  background: #F8FAFC;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .5px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  text-align: left;
}
tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  font-size: 13px;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: #F8FAFC; }
.tr-expand { background: #F8FCFB !important; }
.tr-expand td { padding: 8px 12px 8px 32px; font-size: 12px; color: var(--text-muted); }

/* ─── Badges ─────────────────────────────────────────────── */
.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.b-preparing    { background: #FEF3E2; color: #B7770D; }
.b-waitingpi    { background: #EAF0F6; color: #73879C; }
.b-waitingdep   { background: #EBF5FB; color: #2471A3; }
.b-inprod       { background: #FEF9E7; color: #E67E22; }
.b-readycol     { background: #FFF3E0; color: #E65100; }
.b-intransit    { background: #E8F8F5; color: #1ABC9C; }
.b-customs      { background: #F4ECF7; color: #8E44AD; }
.b-delivered    { background: #E9F7EF; color: #059669; }
.b-draft        { background: #F2F3F4; color: #7F8C8D; }
.b-cancelled    { background: #FDEDEC; color: #C0392B; text-decoration: line-through; }
.b-eur          { background: #EBF5FB; color: #2471A3; }
.b-usd          { background: #E9F7EF; color: #1E8449; }
.b-thb          { background: #FEF9E7; color: #B7770D; }

/* ─── Buttons ────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
  transition: all .15s;
}
.btn-primary   { background: var(--accent); color: #fff; }
.btn-primary:hover { background: #1E9E87; }
.btn-secondary { background: var(--bg); color: var(--text); border: 1px solid var(--border); }
.btn-secondary:hover { background: #E5ECF1; }
.btn-danger    { background: var(--danger); color: #fff; }
.btn-danger:hover { background: #C0392B; }
.btn-warning   { background: #F59E0B; color: #fff; }
.btn-warning:hover { background: #D97706; }
.btn-sm { padding: 4px 10px; font-size: 12px; }
.btn-ghost { background: transparent; color: var(--text-muted); padding: 4px 8px; }
.btn-ghost:hover { color: var(--text); background: var(--bg); }

/* ─── Filter Bar ─────────────────────────────────────────── */
.filter-bar {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.filter-bar input, .filter-bar select {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  background: var(--card);
  color: var(--text);
}
.filter-bar input:focus, .filter-bar select:focus { border-color: var(--accent); }
.filter-bar input { min-width: 200px; }

/* ─── Form ───────────────────────────────────────────────── */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; margin-bottom: 16px; }
.form-grid-3 { grid-template-columns: 1fr 1fr 1fr; }
.form-group { display: flex; flex-direction: column; gap: 4px; }
.form-label { font-size: 11px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .4px; }
.form-control {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  background: var(--card);
  color: var(--text);
  transition: border .15s;
  width: 100%;
}
.form-control:focus { border-color: var(--accent); }
.form-control:disabled { background: var(--bg); color: var(--text-muted); }

/* ─── Order Form ─────────────────────────────────────────── */
.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
  margin-bottom: 16px;
}
.section-title { font-size: 13px; font-weight: 700; color: var(--text); display: flex; align-items: center; gap: 8px; }

/* MOS Search */
.mos-search-wrap { position: relative; }
.mos-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,.12);
  z-index: 100;
  max-height: 280px;
  overflow-y: auto;
}
.mos-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
  transition: background .1s;
}
.mos-item:last-child { border-bottom: none; }
.mos-item:hover { background: var(--bg); }
.mos-img { width: 40px; height: 40px; border-radius: 4px; background: var(--bg); display: flex; align-items: center; justify-content: center; flex-shrink: 0; overflow: hidden; }
.mos-img img { width: 100%; height: 100%; object-fit: cover; }
.mos-code { font-size: 11px; color: var(--text-muted); font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace; }
.mos-model { font-size: 13px; font-weight: 600; color: var(--text); }
.mos-price { font-size: 12px; color: var(--accent); margin-left: auto; white-space: nowrap; }

/* Items Table */
.items-table { margin-bottom: 12px; }
.items-table th { font-size: 10px; }
.items-table thead th { position: sticky; top: 0; z-index: 1; }
.items-table td { padding: 6px 8px; }
/* Keeps # / Model pinned to the left edge while the rest of a wide item row
   scrolls underneath — without this, confirming "am I on the right row" and
   reaching the reserve button on the far right meant scrolling all the way
   left then all the way right, easy to lose track of which row on a long
   list. MOS Code / Model name / Short Description are stacked into a single
   sticky "Model" cell (rather than 3 separate sticky columns) specifically
   because the table isn't table-layout:fixed — with auto layout, any single
   unbreakable token inside a sticky cell (e.g. Thai text with no spaces, or
   underscore-joined codes) silently widens the real column to fit it and
   desyncs it from the hardcoded cumulative `left` offsets below, which is
   what caused headers/cells to visibly overlap. Combining them into one
   sticky column removes the need for those offsets to line up with each
   other; overflow-wrap:anywhere on all text inside still guards against any
   single cell growing unbounded. */
.items-table .col-sticky { position: sticky; background: var(--card); box-sizing: border-box; overflow: hidden; overflow-wrap: anywhere; }
.items-table thead th.col-sticky { z-index: 2; background: #F8FAFC; }
.items-table tbody tr:hover .col-sticky { background: #F8FAFC; }
.items-table .col-sticky-cb    { left: 0; width: 32px; max-width: 32px; padding-left: 4px; padding-right: 4px; text-align: center; }
.items-table .col-sticky-num   { left: 32px; width: 34px; max-width: 34px; padding-left: 4px; padding-right: 4px; text-align: center; }
.items-table .col-sticky-model { left: 66px; width: 210px; max-width: 210px; border-right: 1px solid var(--border); }
.items-table input[type=number],
.items-table input[type=text] {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 4px 6px;
  width: 100%;
  background: var(--card);
}
.items-table input:focus { border-color: var(--accent); }
.items-table .calc-field { background: var(--bg); color: var(--text-muted); padding: 4px 6px; border-radius: 4px; display: block; font-size: 12px; white-space: nowrap; }
.item-img-cell { width: 40px; height: 36px; background: var(--bg); border-radius: 4px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.item-img-cell img { width: 40px; height: 36px; object-fit: cover; border-radius: 4px; }

.adj-row { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.adj-row input { flex: 1; }
.adj-row .adj-amount { width: 120px; }

/* Summary Box */
.order-summary {
  background: var(--bg);
  border-radius: var(--radius);
  padding: 16px;
  margin-top: 16px;
}
.summary-row { display: flex; justify-content: space-between; align-items: center; padding: 5px 0; font-size: 13px; }
.summary-row.total { border-top: 2px solid var(--border); margin-top: 8px; padding-top: 10px; font-weight: 700; font-size: 15px; }
.summary-row.thb { color: var(--text-muted); font-size: 12px; }

/* ─── Modal ──────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.4);
  display: none;
  align-items: center;
  justify-content: center;
  overflow-y: auto;
  z-index: 1000;
}
.modal-overlay.open { display: flex; }
.modal {
  background: var(--card);
  border-radius: var(--radius);
  padding: 24px;
  width: 560px;
  max-width: 95vw;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0,0,0,.2);
}
.modal-lg { width: 880px; }
.modal-xl { width: 1100px; }
.modal-xxl { width: 1360px; }
.modal-product-view { padding: 0; overflow: hidden; display: flex; flex-direction: column; max-height: 88vh; height: 88vh; }
.modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
.modal-title { font-size: 16px; font-weight: 700; }
.modal-footer { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border); }

/* ─── Misc ───────────────────────────────────────────────── */
.text-right { text-align: right; }
.text-muted  { color: var(--text-muted); }
.text-accent { color: var(--accent); }
.text-danger { color: var(--danger); }
.fw-bold { font-weight: 700; }
.mono { font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace; font-size: 12px; }
.row-actions-menu { display:none; background:#fff; border:1px solid var(--border); border-radius:8px; box-shadow:0 6px 20px rgba(0,0,0,.15); z-index:9999; min-width:190px; padding:4px; }
.row-actions-item { display:flex; align-items:center; gap:8px; width:100%; padding:7px 10px; border:none; background:transparent; border-radius:6px; font-size:12px; text-align:left; cursor:pointer; color:var(--text); }
.row-actions-item:hover { background:var(--bg); }
.row-actions-item.text-danger:hover { background:#FEF2F2; }
.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
.page-header h2 { font-size: 18px; font-weight: 700; }
.divider { border: none; border-top: 1px solid var(--border); margin: 16px 0; }
.empty-state { text-align: center; padding: 48px; color: var(--text-muted); }
.empty-state i { font-size: 48px; display: block; margin-bottom: 12px; opacity: .3; }
.tag { display: inline-block; background: var(--bg); border: 1px solid var(--border); border-radius: 4px; padding: 1px 6px; font-size: 11px; color: var(--text-muted); }

/* ─── Status Inline Select ───────────────────────────────── */
.status-select-inline {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  background: var(--bg);
  cursor: pointer;
  color: var(--text);
  transition: border-color .15s;
  width: 100%;
}
.status-select-inline:hover { border-color: var(--accent); }

/* ─── Report Cards ───────────────────────────────────────── */
.report-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px; }
.report-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: box-shadow .15s;
}
.report-card:hover { box-shadow: var(--shadow); }
.report-icon { font-size: 28px; }
.report-card-title { font-weight: 700; font-size: 14px; }
.report-card-desc { font-size: 12px; color: var(--text-muted); flex: 1; line-height: 1.5; }

/* ─── Product Link ───────────────────────────────────────── */
.product-link:hover { color: #1A8A7A !important; }

/* ─── Scrollbar ──────────────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #C5D0D8; border-radius: 3px; }

/* ─── Brand Summary (executive report look, matches the Print/Export PDF
   output's visual language) — hand-written to match, not Tailwind, so this
   stays scoped to this one page and can't affect anything else in the app. */
.bs-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 700; border: 1px solid #BFDBFE; background: #EFF6FF; color: #1D4ED8; }
.bs-kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 20px; }
.bs-kpi { border-radius: 16px; padding: 16px; border: 1px solid #CBD5E1; background: #F8FAFC; }
.bs-kpi-dark { background: #0F172A; color: #fff; border: none; box-shadow: 0 4px 14px rgba(0,0,0,.15); }
.bs-kpi-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: #94A3B8; }
.bs-kpi:not(.bs-kpi-dark) .bs-kpi-label { color: #94A3B8; }
.bs-kpi-value { margin-top: 8px; font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
.bs-kpi:not(.bs-kpi-dark) .bs-kpi-value { color: #0F172A; }
.bs-kpi-sub { margin-top: 6px; font-size: 11px; color: #64748B; display: flex; justify-content: space-between; align-items: center; border-top: 1px solid #CBD5E1; padding-top: 6px; }
.bs-kpi-dark .bs-kpi-sub { color: #94A3B8; border-top-color: #1E293B; }
.bs-yoy { font-size: 10px; font-weight: 700; padding: 2px 6px; border-radius: 4px; font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace; }
.bs-yoy-up { background: rgba(16,185,129,.2); color: #6EE7B7; }
.bs-yoy-down { background: rgba(225,29,72,.2); color: #FDA4AF; }
.bs-split-bar { width: 100%; height: 8px; background: #FDE68A; border-radius: 99px; overflow: hidden; margin-top: 8px; display: flex; }
.bs-progress-bar { width: 100%; height: 8px; background: #E2E8F0; border-radius: 99px; overflow: hidden; }
.bs-progress-fill { height: 100%; border-radius: 99px; }
.bs-panel { border: 1px solid #CBD5E1; border-radius: 16px; overflow: hidden; margin-top: 20px; }
.bs-panel-head { background: #F8FAFC; padding: 10px 16px; border-bottom: 1px solid #CBD5E1; display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.bs-panel-head.bs-dark { background: #0F172A; color: #fff; }
.bs-table { width: 100%; border-collapse: collapse; font-size: 12px; text-align: left; }
.bs-table th { padding: 8px 12px; font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: #64748B; border-bottom: 1px solid #CBD5E1; background: #fff; white-space: nowrap; }
.bs-table td { padding: 8px 12px; border-top: 1px solid #CBD5E1; }
.bs-table tr.bs-top-row { background: rgba(16,185,129,.06); font-weight: 600; }
.bs-tag { display: inline-block; padding: 1px 6px; border-radius: 4px; background: #F1F5F9; color: #334155; font-size: 9px; font-weight: 700; }
.bs-blue { color: #1D4ED8; }
.bs-amber { color: #B45309; }
.bs-muted { color: #94A3B8; }

/* ─── Shipments page (2026-08-26) — "modern executive" reskin, scoped to
   .ship-page so it only touches the Shipments list/detail and can't leak
   into other pages sharing #page-orders. Structure (table, all columns,
   all tabs/functionality) stays intact -- this only restyles shape/color/
   typography, same spirit as the .bs-* Brand Summary reskin above.
   Uses Plus Jakarta Sans (matches the mockup) instead of the app's default
   Noto Sans Thai/Segoe UI, sized up a step from the first pass -- initial
   sizes (9-13px, tight spacing) read as cramped/crowded against the airier
   mockup, this brings it closer. */
.ship-page .page-header h2 { font-weight: 800; letter-spacing: -.02em; }
.ship-page .card { border-radius: 14px; box-shadow: 0 1px 3px rgba(15,23,42,.06); }
.ship-page table tbody tr:not(.tr-expand):hover td { background: #F8FAFC; }
.ship-page table tbody tr:not(.tr-expand) td { padding-top: 10px; padding-bottom: 10px; }

.ship-toptabs { display: flex; gap: 6px; margin-bottom: 18px; }
.ship-toptab {
  padding: 9px 18px; border-radius: 10px; border: 1px solid transparent; background: none;
  cursor: pointer; font-size: 13px; font-weight: 700; color: var(--text-muted);
  display: inline-flex; align-items: center; gap: 8px;
}
.ship-toptab.active { background: #fff; border-color: var(--border); color: var(--text); box-shadow: 0 1px 2px rgba(15,23,42,.05); }
.ship-toptab-count { display: inline-block; padding: 1px 8px; border-radius: 99px; font-size: 11px; font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace; font-weight: 700; background: #E2E8F0; color: #475569; }
.ship-toptab.active .ship-toptab-count { background: var(--text); color: #fff; }

.ship-milestone-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 14px; background: #fff; border: 1px solid var(--border); border-radius: 12px; padding: 12px 18px; }
.ship-milestone { text-align: center; }
.ship-milestone-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #94A3B8; }
.ship-milestone-value { font-size: 13px; font-weight: 700; margin-top: 4px; font-variant-numeric: tabular-nums; }
.ship-milestone-cls  .ship-milestone-value { color: #E11D48; }
.ship-milestone-etd  .ship-milestone-value { color: var(--text); }
.ship-milestone-port .ship-milestone-value { color: #1D4ED8; }
.ship-milestone-wh   .ship-milestone-value { color: #059669; }

.ship-dtabs { display: flex; gap: 6px; padding: 12px 24px 0; background: #F8FAFC; }
.ship-dtab { padding: 9px 18px; border-radius: 10px 10px 0 0; border: 1px solid transparent; border-bottom: none; background: none; cursor: pointer; font-size: 13px; font-weight: 700; color: var(--text-muted); white-space: nowrap; }
.ship-dtab.active { background: #fff; border-color: var(--border); color: var(--text); }

.ship-order-card { border: 1px solid var(--border); border-radius: 12px; margin-bottom: 10px; overflow: hidden; box-shadow: 0 1px 2px rgba(15,23,42,.04); }
.ship-order-card-head { background: #F8FAFC; padding: 9px 16px; }

/* List view -- real card-per-shipment layout (2026-08-26), replacing the
   dense table entirely per the mockup. All the old table's columns are
   still reachable: the 4 headline dates live in the milestone grid,
   ATD/ATA/customs/WH-arrival "actual vs estimate" nuance folds into those
   same 4 boxes (_shipMilestoneGridHTML prefers the actual date once known),
   and anything more detailed is one click away in the expand panel. */
.ship-list { display: flex; flex-direction: column; gap: 18px; }
.ship-card { background: #fff; border: 1px solid var(--border); border-radius: 16px; overflow: hidden; box-shadow: 0 1px 3px rgba(15,23,42,.06); cursor: pointer; transition: border-color .15s; }
.ship-card:hover { border-color: #CBD5E1; }
.ship-card-top { display: flex; align-items: center; gap: 20px; padding: 22px 24px; border-bottom: 1px solid #CBD5E1; background: #FAFBFC; flex-wrap: wrap; }
.ship-card-icon { width: 48px; height: 48px; border-radius: 14px; background: #EFF6FF; border: 1px solid #DBEAFE; display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.ship-card-info { flex: 1; min-width: 240px; }
.ship-card-title-row { display: flex; align-items: center; gap: 10px; }
.ship-card-bl { font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace; font-weight: 800; font-size: 15px; }
.ship-card-sub { font-size: 13px; color: var(--text-muted); margin-top: 5px; line-height: 1.5; }
.ship-card-route { font-size: 13px; font-weight: 600; margin-top: 6px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ship-card-line { display: inline-block; font-size: 10px; color: #059669; background: #ECFDF5; padding: 2px 7px; border-radius: 4px; font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace; font-weight: 700; white-space: nowrap; }
.ship-card-milestones .ship-milestone-grid { padding: 10px 16px; margin: 0; }
.ship-card-actions { display: flex; align-items: center; gap: 6px; }
.ship-btn-view { background: #0F172A; color: #fff; border-radius: 10px; font-weight: 700; font-size: 13px; padding: 11px 20px; border: none; cursor: pointer; white-space: nowrap; }
.ship-btn-view:hover { background: #1E293B; }
.ship-card-bottom { padding: 18px 24px; }
.ship-card-bottom-head { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; font-size: 13px; font-weight: 700; margin-bottom: 14px; }
.ship-card-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.ship-chip { display: inline-block; white-space: nowrap; background: #F1F5F9; padding: 7px 14px; border-radius: 8px; font-size: 13px; font-weight: 600; cursor: pointer; color: var(--text); }
.ship-chip:hover { background: #E2E8F0; }
.ship-chip-more { background: #ECFDF5; color: #047857; border: 1px solid #A7F3D0; font-weight: 700; }
.ship-expand-wrap { background: #fff; border: 1px solid var(--border); border-radius: 16px; overflow: hidden; margin-top: 12px; }

/* ─── Order Preview modal (2026-08-26) — read-only order summary, reached
   by clicking an order chip anywhere (currently: Shipments list) instead
   of jumping straight into the edit form. Same Plus Jakarta Sans/slate
   language as .ship-*, self-contained since it's a modal, not a page. */
.opv-wrap { position: relative; padding: 4px 2px; color: #0F172A; }
.opv-close { position: absolute; top: -6px; right: -6px; background: #F1F5F9; color: #64748B; border: none; border-radius: 50%; width: 30px; height: 30px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 13px; }
.opv-close:hover { background: #E2E8F0; }
.opv-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; margin-bottom: 18px; padding-right: 30px; }
.opv-title { font-size: 20px; font-weight: 800; letter-spacing: -.01em; }
.opv-head-tags { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.opv-btn-edit { background: #0F172A; color: #fff; border: none; border-radius: 10px; padding: 10px 18px; font-size: 13px; font-weight: 700; cursor: pointer; white-space: nowrap; }
.opv-btn-edit:hover { background: #1E293B; }
.opv-btn-po { background: #fff; color: #0F172A; border: 1px solid #CBD5E1; border-radius: 10px; padding: 10px 18px; font-size: 13px; font-weight: 700; cursor: pointer; white-space: nowrap; }
.opv-btn-po:hover { background: #F8FAFC; }
.opv-tag { display: inline-block; background: #F1F5F9; color: #334155; padding: 3px 10px; border-radius: 6px; font-size: 11px; font-weight: 700; }
.opv-info-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; background: #F8FAFC; border: 1px solid #CBD5E1; border-radius: 12px; padding: 16px 20px; margin-bottom: 20px; }
.opv-info-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #94A3B8; }
.opv-info-val { font-size: 13px; font-weight: 600; margin-top: 4px; }
.opv-section-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #94A3B8; margin-bottom: 10px; }
.opv-table-wrap { border: 1px solid #CBD5E1; border-radius: 12px; overflow: hidden; max-height: 300px; overflow-y: auto; }
.opv-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.opv-table th { padding: 10px 14px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #94A3B8; background: #F8FAFC; text-align: left; border-bottom: 1px solid #CBD5E1; position: sticky; top: 0; }
.opv-table td { padding: 10px 14px; border-top: 1px solid #F8FAFC; }
.opv-mono { font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace; font-size: 11px; }
.opv-muted { color: #94A3B8; }
.opv-item-model { font-weight: 600; }
.opv-link { color: #1D4ED8; cursor: pointer; text-decoration: underline dotted; text-underline-offset: 2px; }
.opv-footer { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 20px; padding-top: 18px; border-top: 1px solid #CBD5E1; align-items: flex-start; }
.opv-footer-col { flex: 1; min-width: 120px; }
.opv-footer-total { text-align: right; margin-left: auto; }
.opv-money { font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace; font-weight: 700; font-size: 14px; }
.opv-paid { color: #059669; }
.opv-unpaid { color: #E11D48; }
.opv-money-date { font-size: 10px; color: #94A3B8; margin-top: 2px; }

/* ─── Document Attachments (Order/Shipment "Documents" tab) ──────── */
.doc-tabbar { display: flex; gap: 2px; margin-bottom: 10px; border-bottom: 1px solid var(--border); }
.doc-tabbtn {
  border: none; background: none; cursor: pointer; padding: 7px 16px; font-size: 12.5px; font-weight: 600;
  color: var(--text-muted); border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.doc-tabbtn.active { color: var(--accent); border-bottom-color: var(--accent); }
.doc-missing-banner {
  display: flex; gap: 10px; align-items: flex-start; background: #FEF9E7; border: 1px solid #F5D78A;
  border-radius: 8px; padding: 10px 14px; margin-bottom: 12px; font-size: 13px;
}
.doc-missing-banner.ok { background: #E9F7EF; border-color: #A9DFBF; }
.doc-missing-banner b { display: block; font-size: 13.5px; margin-bottom: 2px; }
.doc-card { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--card); box-shadow: 0 1px 2px rgba(44,62,80,.05), 0 1px 1px rgba(44,62,80,.04); }
.doc-row { display: flex; gap: 12px; padding: 12px 14px; border-bottom: 1px solid var(--border); align-items: flex-start; }
.doc-row:last-child { border-bottom: none; }
.doc-row.empty-required { background: #FFFBEF; }
.doc-icon {
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  background: #F8FAFC; color: var(--text-muted); border: 1px solid var(--border); font-size: 14px;
}
/* "Has content" state -- a filled/checked doc-icon was rendering in the
   same flat gray as an untouched one (only the empty-required/warning
   state had its own color), which read as "nothing here is actually
   colored" even once files were attached. Applied via .ok wherever the
   JS already computes "has files"/"has a slip" (page_orders.js/
   page_shipments.js). */
.doc-icon.ok { background: #E9F7EF; color: #1E8449; border-color: transparent; }
.doc-icon.cn { background: #F4ECF7; color: #8E44AD; border-color: transparent; }
.doc-row.empty-required .doc-icon { background: #FEF3E2; color: #B7770D; border-color: transparent; }
.doc-main { flex: 1; min-width: 0; }
.doc-label-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 2px; }
.doc-label { font-size: 13.5px; font-weight: 700; }
.doc-tag-req, .doc-tag-opt, .doc-tag-custom {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; padding: 1px 6px; border-radius: 4px;
}
.doc-tag-req { background: #FDEDEC; color: #C0392B; border: 1px solid #F5C6C0; }
.doc-tag-opt { background: #F2F3F4; color: #7F8C8D; border: 1px solid #E1E4E6; }
.doc-tag-custom { background: #F4ECF7; color: #8E44AD; border: 1px solid #E3CCEE; }
.doc-warn-msg { font-size: 12px; color: #B7770D; font-weight: 600; margin-top: 2px; }
.doc-file-list { display: flex; flex-direction: column; gap: 5px; margin-top: 4px; }
.doc-file-chip {
  display: flex; align-items: center; gap: 9px; border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 9px; background: #F8FAFC; text-decoration: none; color: inherit;
}
.doc-file-chip:hover { border-color: #CBD5E1; }
.doc-file-meta { flex: 1; min-width: 0; }
.doc-file-name { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.doc-file-sub { font-size: 11px; color: #94A3B8; margin-top: 1px; }
.doc-file-remove {
  border: none; background: none; color: #94A3B8; cursor: pointer; width: 22px; height: 22px; border-radius: 5px;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.doc-file-remove:hover { background: #FDEDEC; color: #C0392B; }
.doc-actions { flex-shrink: 0; display: flex; flex-direction: column; gap: 5px; }
.doc-add-btn {
  display: inline-flex; align-items: center; gap: 5px; border: 1px dashed #CBD5E1; background: var(--card);
  color: var(--text-muted); font-size: 11.5px; font-weight: 600; padding: 6px 10px; border-radius: 6px; cursor: pointer; white-space: nowrap;
}
.doc-add-btn:hover { border-color: var(--accent); color: var(--accent); background: #E8F8F5; }
.doc-add-category-row {
  display: flex; align-items: center; justify-content: center; gap: 6px; padding: 10px 14px; cursor: pointer;
  color: #94A3B8; font-size: 12px; font-weight: 600; border-top: 1px dashed var(--border); background: none; width: 100%;
}
.doc-add-category-row:hover { color: var(--accent); background: #E8F8F5; }
.doc-add-category-form { padding: 12px 14px; border-top: 1px dashed var(--border); display: flex; flex-direction: column; gap: 8px; }
.doc-add-category-form input[type="text"] { border: 1px solid var(--border); border-radius: 6px; padding: 7px 9px; font-size: 12.5px; width: 100%; }
.doc-add-category-form-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.doc-add-category-checkbox { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-muted); }
.doc-add-category-actions { display: flex; gap: 6px; margin-left: auto; }
.doc-cancel-btn { border: 1px solid var(--border); background: var(--card); color: var(--text-muted); font-size: 11.5px; font-weight: 600; padding: 6px 10px; border-radius: 6px; cursor: pointer; }
.doc-file-card { border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; background: #F8FAFC; transition: border-color .12s; }
.doc-file-card:hover { border-color: #CBD5E1; }
.doc-file-card-head { display: flex; align-items: center; gap: 9px; }
.doc-kind-pill { font-size: 9px; font-weight: 700; padding: 1px 7px; border-radius: 999px; flex-shrink: 0; }
.doc-kind-pill.ci { background: #EBF5FB; color: #2471A3; border: 1px solid #BFE0F5; }
.doc-kind-pill.pl { background: #E9F7EF; color: #1E8449; border: 1px solid #B4E5C9; }
.doc-link-block { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.doc-link-label { font-size: 10px; color: #94A3B8; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 5px; }
.doc-link-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.doc-order-chip {
  display: inline-flex; align-items: center; gap: 4px; background: #EBF5FB; color: #2471A3;
  font-size: 11px; font-weight: 600; padding: 3px 8px; border-radius: 999px;
}
.doc-link-add-btn {
  display: inline-flex; align-items: center; gap: 3px; border: 1px dashed #CBD5E1; background: none;
  color: #94A3B8; font-size: 10.5px; font-weight: 600; padding: 3px 8px 3px 6px; border-radius: 999px; cursor: pointer;
}
.doc-link-add-btn:hover { color: var(--accent); border-color: var(--accent); }
.doc-collapse-toggle { background: none; border: none; cursor: pointer; color: var(--accent); font-size: 11.5px; font-weight: 700; padding: 5px 2px 0; }
.doc-backlink-card { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--card); box-shadow: 0 1px 2px rgba(44,62,80,.05), 0 1px 1px rgba(44,62,80,.04); }
.doc-backlink-row { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--border); }
.doc-backlink-row:last-child { border-bottom: none; }
.doc-link-pop {
  position: fixed; background: var(--card); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 12px 28px rgba(20,30,40,.16); padding: 5px; width: 220px; z-index: 1200; display: none; max-height: 260px; overflow-y: auto;
}
.doc-link-pop.open { display: block; }
.doc-link-pop button { display: block; width: 100%; text-align: left; border: none; background: none; cursor: pointer; padding: 6px 8px; border-radius: 5px; font-size: 12px; }
.doc-link-pop button:hover { background: #F8FAFC; }
.doc-link-pop .lp-empty { padding: 7px 8px; font-size: 11px; color: #94A3B8; }

