/* ============================================================
   Codex Platform — Global Stylesheet
   asset/css/customs.css
   ============================================================ */

/* ---- CSS Variables ---- */
:root {
  --sidebar-w:       240px;
  --sidebar-w-col:    64px;
  --sidebar-w-tablet: 220px;
  --topbar-h:         56px;
  --brand-dark:      #1a2a4a;
  --brand-blue:      #2d7dd2;
  --brand-accent:    #38bdf8;
  --sidebar-bg:      #1a2a4a;
  --sidebar-text:    #b8c8e8;
  --sidebar-active:  #2d7dd2;
  --sidebar-hover:   rgba(255,255,255,.07);
  --content-bg:      #f4f6fb;
  --card-bg:         #ffffff;
  --card-shadow:     0 2px 12px rgba(17,24,39,.07);
  --radius-card:     16px;
  --radius-btn:      10px;

  /* Module accent colours */
  --col-shipment:    #2563eb;
  --col-air:         #0891b2;
  --col-customs:     #7c3aed;
  --col-ocr:         #059669;
  --col-billing:     #d97706;
  --col-reports:     #dc2626;
  --col-wms:         #ca8a04;
}

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font-family: 'Segoe UI', system-ui, sans-serif; background: var(--content-bg); color: #1f2937; }
a { text-decoration: none; color: inherit; }

/* ============================================================
   LAYOUT: sidebar + main
   ============================================================ */
.codex-layout { display: flex; min-height: 100vh; }

/* ---- Sidebar ---- */
.codex-sidebar {
  width: var(--sidebar-w);
  background: var(--sidebar-bg);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  position: fixed;
  top: 0; left: 0; bottom: 0;   /* fill exactly the visible viewport — fixes iOS chrome cropping */
  height: 100vh;
  height: 100dvh;               /* dynamic viewport (iOS Safari respects browser chrome) */
  z-index: 1000;
  transition: transform .25s ease;
  overflow: hidden;             /* let .sidebar-nav own the scrolling */
}

/* Tablet (iPad): slimmer sidebar */
@media (min-width: 992px) and (max-width: 1199px) {
  .codex-sidebar { width: var(--sidebar-w-tablet); }
  .codex-main    { margin-left: var(--sidebar-w-tablet); }
}

/* Mobile: sidebar hidden off-screen */
@media (max-width: 991.98px) {
  .codex-sidebar { transform: translateX(-100%); box-shadow: 4px 0 24px rgba(0,0,0,.3); }
  .codex-sidebar.open { transform: translateX(0); }
  .codex-main { margin-left: 0 !important; }
}

/* Desktop collapsed (toggle): slide off-screen, no margin */
@media (min-width: 992px) {
  body.sidebar-collapsed .codex-sidebar { transform: translateX(-100%); box-shadow:none; }
  body.sidebar-collapsed .codex-main    { margin-left: 0 !important; }
}

.codex-main {
  margin-left: var(--sidebar-w);
  flex: 1;
  min-width: 0;            /* allow flex item to shrink below intrinsic content width */
  overflow-x: hidden;      /* horizontal overflow stays inside child cards, never the page */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  transition: margin-left .25s ease;
}
.codex-content { max-width: 100%; min-width: 0; }
.content-card  { max-width: 100%; }

/* DataTables: scroll wrappers must respect their card's width on tablet/phone.

   .dataTables_scrollHeadInner is DELIBERATELY NOT in this list. With
   scrollX, DataTables renders two tables — the header table inside
   .dataTables_scrollHead > .dataTables_scrollHeadInner, and the body
   table inside .dataTables_scrollBody — and sizes BOTH to the measured
   natural content width, then keeps them aligned by mirroring the
   body's scrollLeft onto the head on every scroll.

   Clamping the head INNER to 100% broke that contract whenever the
   table's natural width exceeded the card: the body table kept its
   full width and scrolled, while the head table was squeezed down to
   the card width and re-laid-out its columns proportionally. Header
   and body then drifted apart, worsening left-to-right. Measured on
   wms/review at an 820px viewport: head table 740.8px vs body table
   899px, columns off by up to 158px.

   The card is still contained: .dataTables_scrollHead above IS clamped
   to 100% and carries overflow:hidden, so the oversized inner is
   clipped, not expanded into the page. Verified no document-level
   horizontal overflow after this change. */
.content-card .dataTables_wrapper,
.content-card .dataTables_scroll,
.content-card .dataTables_scrollHead,
.content-card .dataTables_scrollBody { max-width: 100%; }
.content-card.card-fit .dataTables_wrapper { overflow-x: hidden; }

/* ---- Sidebar Brand ---- */
.sidebar-brand {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem;
  padding: .75rem 1rem;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.brand-link {
  display: flex; align-items: center; gap: .55rem;
  color: #fff; text-decoration: none; min-width: 0; flex: 1;
}
.brand-logo {
  width: 28px; height: 28px; object-fit: contain; flex-shrink: 0;
  background: #fff; border-radius: 6px; padding: 2px;
}
.brand-text {
  font-size: 1rem; font-weight: 600; color: #fff; letter-spacing: .2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand-accent { color: var(--brand-accent); }
.sidebar-toggle {
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12);
  color: #fff; font-size: .8rem; cursor: pointer;
  width: 28px; height: 28px; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: background .15s;
}
.sidebar-toggle:hover { background: rgba(255,255,255,.15); }

/* ---- Company Badge ---- */
.sidebar-company {
  display: flex; align-items: center; gap: .65rem;
  padding: .75rem 1rem;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.company-avatar {
  width: 36px; height: 36px; border-radius: 8px;
  background: #fff; color: var(--brand-dark);
  display: flex; align-items: center; justify-content: center;
  font-size: .78rem; font-weight: 700; flex-shrink: 0;
  overflow: hidden;
}
.company-avatar img { width: 100%; height: 100%; object-fit: contain; padding: 2px; }
.company-info { min-width: 0; flex: 1; }
.company-name {
  font-size: .82rem; font-weight: 600; color: #fff; line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.company-role { font-size: .72rem; color: var(--sidebar-text); text-transform: capitalize; }

/* ---- Nav ---- */
.sidebar-nav { flex: 1; overflow-y: auto; padding: .5rem 0; scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.2) transparent; }
.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.18); border-radius: 4px; }
.sidebar-nav::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.32); }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }

/* Collapsible nav groups */
.nav-group { border-top: 1px solid rgba(255,255,255,.04); }
.nav-group-header {
  display:flex; align-items:center; justify-content:space-between;
  font-size:.72rem; font-weight:700; letter-spacing:.02em; text-transform:lowercase;
  color: var(--sidebar-text); padding:.85rem 1.25rem .35rem 1.25rem;
  cursor:pointer; user-select:none;
}
.nav-group-header > span::first-letter { text-transform: uppercase; }
.nav-group-header:hover { color:#fff; }
.nav-group-header .chev { transition:transform .2s; font-size:.7rem; opacity:.6; }
.nav-group.collapsed .nav-group-header .chev { transform:rotate(-90deg); }
.nav-group.collapsed .nav-group-items { display:none; }
.nav-group-items { padding-bottom:.25rem; }

/* Nested subgroup (e.g. Billing > AR/AP) */
.nav-subgroup { margin-left:.5rem; border-left:1px solid rgba(255,255,255,.06); }
.nav-subgroup-header {
  display:flex; align-items:center; justify-content:space-between;
  font-size:.7rem; font-weight:600; text-transform:none; letter-spacing:0;
  color: var(--sidebar-text); padding:.35rem 1rem .25rem 1rem;
  cursor:pointer; user-select:none;
}
.nav-subgroup-header:hover { color:#fff; }
.nav-subgroup-header .chev { transition:transform .2s; font-size:.65rem; opacity:.5; }
.nav-subgroup.collapsed .nav-subgroup-header .chev { transform:rotate(-90deg); }
.nav-subgroup.collapsed .nav-subgroup-items { display:none; }
.nav-subgroup-items .nav-link { padding-left:2.3rem; font-size:.82rem; }

/* Leaf variant: subgroup header that looks like a nav-link (icon + label
 * + chevron) rather than a small all-caps section header. Used when the
 * subgroup sits next to other leaf nav-links and should match them.
 * The header is flush-left like a top-level nav-link; children are
 * indented + left-bordered like a regular subgroup so they read as
 * sub-items (matching the Billing AR look). */
.nav-subgroup--leaf { margin-left:0; border-left:none; }
.nav-subgroup--leaf > .nav-subgroup-items {
  margin-left:.5rem;
  border-left:1px solid rgba(255,255,255,.06);
}
.nav-subgroup-header--leaf {
  display:flex; align-items:center; gap:.75rem;
  padding:.35rem 1.25rem;
  color: var(--sidebar-text);
  font-size:.875rem; font-weight:500;
  text-transform:none; letter-spacing:0;
  border-left:3px solid transparent;
  transition: background .15s, color .15s;
}
.nav-subgroup-header--leaf i.bi:first-child { font-size:1rem; flex-shrink:0; }
.nav-subgroup-header--leaf .nav-label { flex:1; }
.nav-subgroup-header--leaf .chev { font-size:.65rem; opacity:.55; transition:transform .2s; }
.nav-subgroup-header--leaf:hover { background: var(--sidebar-hover); color:#fff; }
.nav-subgroup--leaf.collapsed .nav-subgroup-header--leaf .chev { transform:rotate(-90deg); }

.nav-divider {
  font-size: .72rem; font-weight: 700; letter-spacing: .02em;
  text-transform: lowercase; color: rgba(255,255,255,.35);
  padding: .9rem 1.25rem .3rem;
}
.nav-divider::first-letter { text-transform: uppercase; }

.sidebar-nav .nav-link {
  display: flex; align-items: center; gap: .75rem;
  padding: .35rem 1.25rem;
  color: var(--sidebar-text);
  border-radius: 0;
  font-size: .875rem; font-weight: 500;
  transition: background .15s, color .15s;
  border-left: 3px solid transparent;
}
.sidebar-nav .nav-link i { font-size: 1rem; flex-shrink: 0; }
.sidebar-nav .nav-link:hover  { background: var(--sidebar-hover); color: #fff; }
.sidebar-nav .nav-link.active {
  background: rgba(45,125,210,.2);
  color: #fff;
  border-left-color: var(--brand-blue);
}

/* ---- Sidebar Footer ---- */
.sidebar-footer {
  border-top: 1px solid rgba(255,255,255,.08);
  padding: .85rem 1.25rem;
}
.user-row { display: flex; align-items: center; gap: .6rem; }
.user-name  { font-size: .8rem; font-weight: 600; color: #fff; }
.user-email { font-size: .7rem; color: var(--sidebar-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 150px; }
.btn-signout {
  margin-left: auto; color: var(--sidebar-text); font-size: 1.1rem;
  flex-shrink: 0; padding: .25rem;
  transition: color .15s;
}
.btn-signout:hover { color: #f87171; }

/* ---- Mobile Overlay ---- */
.sidebar-overlay {
  display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 999;
}
.sidebar-overlay.visible { display: block; }

/* iPhone-size: full-width slide-in sidebar */
@media (max-width: 480px) {
  .codex-sidebar { width: 86vw; max-width: 320px; }
}

/* ============================================================
   TOPBAR
   ============================================================ */
.codex-topbar {
  height: var(--topbar-h);
  background: var(--card-bg);
  border-bottom: 1px solid #e5e7eb;
  display: flex; align-items: center;
  padding: 0 1.5rem;
  position: sticky; top: 0; z-index: 100;
  box-shadow: 0 1px 4px rgba(0,0,0,.06);
}
/* Topbar hamburger: hidden on desktop when sidebar is visible; shown on mobile or when sidebar is collapsed */
@media (min-width: 992px) {
  #sidebarOpenBtn { display: none; }
  body.sidebar-collapsed #sidebarOpenBtn { display: inline-flex; }
}
.topbar-title { font-size: 1.1rem; font-weight: 700; color: #111827; flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-right { display: flex; align-items: center; gap: 1rem; }
.topbar-greeting { font-size: .85rem; color: #6b7280; }

@media (max-width: 991px) {
  .codex-topbar { padding: 0 .85rem; }
  .topbar-right { gap: .4rem; }
}
@media (max-width: 575px) {
  .codex-topbar { padding: 0 .65rem; }
  .topbar-title { font-size: .95rem; }
  .topbar-right { gap: .3rem; }
  .topbar-right .btn { padding: .25rem .5rem; font-size: .78rem; }
  .topbar-right .btn .bi { font-size: .9rem; }
}

/* ============================================================
   MAIN CONTENT
   ============================================================ */
.codex-content { flex: 1; padding: 1.5rem; max-width: 1300px; width: 100%; margin: 0 auto; }
@media (max-width: 991px) {
  .codex-content { padding: 1rem; }
}
@media (max-width: 575px) {
  .codex-content { padding: .65rem; }
}

/* Common KPI/stat card responsive polish (used inline by many pages) */
@media (max-width: 575px) {
  .kpi-card { padding: .65rem .8rem !important; }
  .kpi-value { font-size: 1.4rem !important; }
  .kpi-label, .kpi-foot { font-size: .65rem !important; }
}

/* ============================================================
   MODULE TILES (dashboard)
   ============================================================ */
.module-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
  padding: 1.5rem 1rem;
  border-radius: var(--radius-card);
  background: var(--card-bg);
  box-shadow: var(--card-shadow);
  transition: transform .15s, box-shadow .15s;
  cursor: pointer;
  border: 2px solid transparent;
  min-height: 130px;
}
.module-tile:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(0,0,0,.12); }

.module-icon { font-size: 2rem; margin-bottom: .5rem; }
.module-label { font-weight: 700; font-size: .95rem; color: #1f2937; }
.module-sub   { font-size: .72rem; color: #6b7280; margin-top: .15rem; }

.module-shipment { border-color: var(--col-shipment); }
.module-shipment .module-icon { color: var(--col-shipment); }
.module-air      { border-color: var(--col-air); }
.module-air      .module-icon { color: var(--col-air); }
.module-customs  { border-color: var(--col-customs); }
.module-customs  .module-icon { color: var(--col-customs); }
.module-ocr      { border-color: var(--col-ocr); }
.module-ocr      .module-icon { color: var(--col-ocr); }
.module-billing  { border-color: var(--col-billing); }
.module-billing  .module-icon { color: var(--col-billing); }
.module-reports  { border-color: var(--col-reports); }
.module-reports  .module-icon { color: var(--col-reports); }
.module-wms      { border-color: var(--col-wms); }
.module-wms      .module-icon { color: var(--col-wms); }

/* ============================================================
   CONTENT CARDS
   ============================================================ */
.content-card {
  background: var(--card-bg);
  border-radius: var(--radius-card);
  box-shadow: var(--card-shadow);
  overflow: hidden;
}
.card-header-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: .9rem 1.25rem;
  border-bottom: 1px solid #f0f2f7;
  flex-wrap: wrap; gap: .5rem;
}
.card-title { font-weight: 700; font-size: .95rem; color: #111827; }
@media (max-width: 575px) {
  .card-header-row { padding: .65rem .85rem; }
  .card-title { font-size: .9rem; }
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn { border-radius: var(--radius-btn); }
.btn-primary { background: var(--brand-blue); border-color: var(--brand-blue); }
.btn-primary:hover { background: #1a6ab8; border-color: #1a6ab8; }

/* ============================================================
   FORMS
   ============================================================ */
.form-control, .form-select {
  border-radius: 8px;
  border-color: #d1d5db;
  font-size: .875rem;
}
.form-control:focus, .form-select:focus {
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 3px rgba(45,125,210,.15);
}
.form-control[readonly], .form-select:disabled, .form-control:disabled {
  background-color: #fff;
  opacity: 1;
  color: #374151;
}
.form-label { font-weight: 600; font-size: .8rem; color: #374151; margin-bottom: .3rem; }

/* ============================================================
   TABLES
   ============================================================ */
.table { font-size: .875rem; }
.table thead th { background: #f8faff; font-weight: 700; font-size: .78rem; letter-spacing: .02em; color: #6b7280; border-bottom: 2px solid #e5e7eb; }

/* ============================================================
   Global rule for ALL table headers — display literal HTML text so
   acronyms (HAWB, MAWB, HS, PO) read correctly. Previous convention
   was `lowercase + ::first-letter uppercase` which mangled "HAWB"
   into "Hawb" — operators asked for the acronyms to be preserved.
   `!important` stays so page-level styles can't accidentally
   re-lowercase things; per-table overrides that WANT a case change
   still work if they use higher specificity or their own
   !important.
   ============================================================ */
table thead th,
table thead td,
.table thead th,
table.dataTable thead th,
.dataTables_wrapper table thead th,
.modal table thead th {
  text-transform: none !important;
  letter-spacing: .02em !important;
}
.table tbody tr:hover { background: #f8faff; }

/* ============================================================
   GLOBAL DATATABLES THEME — applies to every .dataTables_wrapper
   so all pages share the same font, padding, pagination style.
   Override-free: pages no longer need their own per-table CSS.
   ============================================================ */
.dataTables_wrapper { padding: .4rem .9rem; }

/* ---- CARD TABLE INSET — one number for the whole card ----------------
   Inside a .content-card the table area must line up with the card title.
   .content-card has no horizontal padding of its own; the insets come from
   THREE stacked rules, which is why they drifted apart:

     .card-header-row              1.25rem   (line ~360)
     .content-card .table-responsive  .9rem  (line ~531)   ← nests, and
     .dataTables_wrapper              .9rem  (above)       ← nests again

   DataTables inserts .dataTables_wrapper *inside* .table-responsive, so a
   DataTable actually sat at .9 + .9 = 1.8rem while the title sat at
   1.25rem. Fix: the table area gets ONE inset equal to the header's, no
   matter which of the two nestings a page uses —

     wrapped   .table-responsive 1.25rem + wrapper 0        = 1.25rem
     unwrapped wrapper 1.25rem                              = 1.25rem

   .sec-card is deliberately left on its original .9rem — this is the
   .content-card surface only. Global rule, not per-page CSS (CLAUDE.md
   §4.2). Cache-buster: customs.css?v=47.

   The .table-responsive half of this lives with the rule it overrides,
   further down under "Tables inside cards" — it MUST come after that
   shorthand or the shorthand (same specificity, later in the file) wins. */
.content-card .dataTables_wrapper { padding: .4rem 1.25rem; }
.content-card .table-responsive .dataTables_wrapper,
.content-card .table-wrap .dataTables_wrapper { padding-left: 0; padding-right: 0; }
@media (max-width: 575px) {
  /* Mirror the .card-header-row step-down, or the two edges drift apart
     again below 576px. */
  .content-card .dataTables_wrapper { padding: .4rem .85rem; }
  .content-card .table-responsive .dataTables_wrapper,
  .content-card .table-wrap .dataTables_wrapper { padding-left: 0; padding-right: 0; }
}
.dataTables_wrapper th,
.dataTables_wrapper td {
  white-space: nowrap;
  padding: .4rem .55rem;
  font-size: .82rem;
  vertical-align: middle;
  color: #1a2a4a;
}
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_paginate {
  padding: .35rem 0;
  font-size: .72rem;
}
.dataTables_wrapper .dataTables_paginate .paginate_button {
  border-radius: 6px !important;
  margin: 0 1px !important;
  padding: .1rem .42rem !important;
  min-width: 24px;
  font-size: .7rem !important;
  line-height: 1.2;
  border: 1px solid #e5e7eb !important;
  background: #fff !important;
  color: #374151 !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
  background: #eef4ff !important;
  border-color: #2d7dd2 !important;
  color: #1a2a4a !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
  background: #2d7dd2 !important;
  border-color: #2d7dd2 !important;
  color: #fff !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover {
  background: #f9fafb !important;
  color: #d1d5db !important;
  cursor: not-allowed;
  border-color: #f3f4f6 !important;
}
.dataTables_wrapper table.dataTable { margin: 0 !important; }
/* DataTables search/length inputs — match the form-control-sm size used in filter bars */
.dataTables_wrapper .dataTables_filter input[type="search"],
.dataTables_wrapper .dataTables_length select {
  font-size: .75rem !important;
  padding: .15rem .5rem !important;
  height: auto !important;
  border-radius: 6px !important;
  border: 1px solid #c7d0e8 !important;
  margin-left: .35rem !important;
}
.dataTables_wrapper .dataTables_filter input[type="search"] { width: 180px; }

/* Freeze header inside any scrollable card table (booking list pattern).
   Force every <th> to be sticky AND opaque white so that the scrolled body
   doesn't bleed through the middle cells (Bootstrap's .table sets a CSS
   variable on cells which leaves them transparent by default). */
.content-card .table-responsive thead tr th,
.sec-card     .table-responsive thead tr th {
  position: sticky !important;
  top: 0 !important;
  z-index: 5 !important;
  background-color: #fff !important;
  background-clip: padding-box !important;
  box-shadow: inset 0 -1px 0 #e5e7eb !important;
  --bs-table-bg: #fff;
  --bs-table-accent-bg: #fff;
}

/* Sidebar nested sub-link (for sub-menu items under a parent nav item) */
.codex-sidebar .nav-sublink {
  padding-left: 2.1rem !important;
  font-size: .8rem;
}
.codex-sidebar .nav-sublink i { font-size: .85rem; }

/* Filter bar (used in card headers) — single row, tight gap */
.filter-bar {
  display: flex !important;
  flex-wrap: nowrap !important;
  gap: .2rem !important;
  align-items: center;
}

/* Tables inside cards — breathing room from card edges (global) */
.content-card .table-responsive,
.content-card .table-wrap,
.sec-card .table-responsive,
.sec-card .table-wrap {
  padding: 0 .9rem .75rem;
}
/* …but inside a .content-card that inset must equal the .card-header-row's
   1.25rem so the card title and the table share one left/right edge. See
   "CARD TABLE INSET" in the DataTables theme block above — this half must
   sit AFTER the shorthand it overrides. .sec-card keeps its .9rem. */
.content-card .table-responsive,
.content-card .table-wrap { padding-left: 1.25rem; padding-right: 1.25rem; }
@media (max-width: 575px) {
  .content-card .table-responsive,
  .content-card .table-wrap { padding-left: .85rem; padding-right: .85rem; }
}
.content-card .table,
.sec-card .table { margin-bottom: 0; }

/* ============================================================
   BADGES & STATUS
   ============================================================ */
.status-badge {
  display: inline-block; padding: .2em .65em;
  border-radius: 999px; font-size: .72rem; font-weight: 700;
}
.status-active    { background: #d1fae5; color: #065f46; }
.status-inactive  { background: #f3f4f6; color: #6b7280; }
.status-pending   { background: #fef3c7; color: #92400e; }
.status-completed { background: #d1fae5; color: #065f46; }
.status-billed    { background: #dbeafe; color: #1e40af; }
.status-cancelled { background: #fee2e2; color: #991b1b; }

/* ============================================================
   RESPONSIVE — Tablet & Mobile tweaks
   ============================================================ */
@media (max-width: 767px) {
  .codex-content { padding: 1rem .75rem; }
  .module-tile { min-height: 100px; padding: 1rem .75rem; }
  .module-icon { font-size: 1.5rem; }
  .module-label { font-size: .82rem; }
  .module-sub { display: none; }
}

@media (max-width: 575px) {
  .codex-topbar { padding: 0 .75rem; }
  .topbar-title { font-size: .95rem; }
}

/* ---- Global KPI cards (reusable across all list pages) ---- */
.kpi-card{border-radius:14px;padding:1rem 1.1rem;background:#fff;border:1px solid #e9ecef;display:flex;flex-direction:column;gap:.4rem}
.kpi-label{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em}
.kpi-value{font-size:1.8rem;font-weight:800;line-height:1}
.kpi-foot{font-size:.7rem}
.kpi-draft    {border-left:4px solid #d1d5db} .kpi-draft .kpi-label{color:#6b7280}    .kpi-draft .kpi-value{color:#374151}
.kpi-confirmed{border-left:4px solid #93c5fd} .kpi-confirmed .kpi-label{color:#1d4ed8} .kpi-confirmed .kpi-value{color:#1d4ed8}
.kpi-pending  {border-left:4px solid #fcd34d} .kpi-pending .kpi-label{color:#b45309}   .kpi-pending .kpi-value{color:#d97706}
.kpi-completed{border-left:4px solid #6ee7b7} .kpi-completed .kpi-label{color:#047857} .kpi-completed .kpi-value{color:#059669}
.kpi-billed   {border-left:4px solid #c4b5fd} .kpi-billed .kpi-label{color:#5b21b6}    .kpi-billed .kpi-value{color:#7c3aed}
.kpi-unbilled {border-left:4px solid #fcd34d} .kpi-unbilled .kpi-label{color:#b45309}   .kpi-unbilled .kpi-value{color:#d97706}
.kpi-partial  {border-left:4px solid #93c5fd} .kpi-partial .kpi-label{color:#1d4ed8}    .kpi-partial .kpi-value{color:#1d4ed8}
.kpi-invoiced {border-left:4px solid #6ee7b7} .kpi-invoiced .kpi-label{color:#047857}   .kpi-invoiced .kpi-value{color:#059669}
.kpi-margin   {border-left:4px solid #c4b5fd} .kpi-margin .kpi-label{color:#5b21b6}     .kpi-margin .kpi-value{color:#7c3aed}

/* ---- Global status badges (reusable across all modules) ---- */
.badge-status-draft     { background: #fef9c3; color: #a16207; }
.badge-status-confirmed { background: #dbeafe; color: #1d4ed8; }
.badge-status-active    { background: #dbeafe; color: #1d4ed8; }
.badge-status-issued    { background: #dbeafe; color: #1d4ed8; }
.badge-status-invoiced  { background: #dcfce7; color: #15803d; }
.badge-status-paid      { background: #dcfce7; color: #15803d; }
.badge-status-partial   { background: #dbeafe; color: #1d4ed8; }
.badge-status-unbilled  { background: #fef9c3; color: #a16207; }
.badge-status-void      { background: #fee2e2; color: #dc2626; }
.badge-status-cancelled { background: #f3f4f6; color: #6b7280; }
.badge-status-delivered { background: #dcfce7; color: #15803d; }
.badge-status-pod       { background: #e0e7ff; color: #4338ca; }
.badge-status-dispatched{ background: #fef3c7; color: #a16207; }
.badge-status-in_transit{ background: #fef3c7; color: #a16207; }
.badge-status-arrived   { background: #dbeafe; color: #1d4ed8; }
.badge-status-completed { background: #dcfce7; color: #15803d; }
.badge-status-booked    { background: #dbeafe; color: #1d4ed8; }
.badge-status-manifested{ background: #dbeafe; color: #1d4ed8; }
.badge-status-sent      { background: #e0e7ff; color: #4338ca; }
.badge-status-accepted  { background: #dcfce7; color: #15803d; }
.badge-status-rejected  { background: #fee2e2; color: #dc2626; }
.badge-status-expired   { background: #f3f4f6; color: #6b7280; }
.badge-status-pending   { background: #fef3c7; color: #a16207; }
.badge-status-planned   { background: #e0e7ff; color: #4338ca; }
.badge-status-assigned  { background: #dbeafe; color: #1d4ed8; }

/* Key reference columns — bold colored links */
.key-ref { font-weight: 600; color: #1d4ed8; text-decoration: none; }
.key-ref:hover { text-decoration: underline; }
.key-ref code, code.key-ref { font-weight: 600; color: #1d4ed8; background: transparent; font-size: inherit; }
/* Source badges */
.badge-src-contract     { background: #dbeafe; color: #1d4ed8; }
.badge-src-tariff       { background: #dcfce7; color: #15803d; }
.badge-src-adhoc        { background: #fef9c3; color: #a16207; }
.badge-src-quotation    { background: #e0e7ff; color: #4338ca; }
/* Type badges */
.badge-type-shipment    { background: #dbeafe; color: #1d4ed8; }
.badge-type-order       { background: #dcfce7; color: #15803d; }
.badge-type-global      { background: #dbeafe; color: #1d4ed8; }
.badge-type-tenant      { background: #dcfce7; color: #15803d; }

/* Hide native number-input spinner that can overlap values */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button { -webkit-appearance:none; margin:0 }
input[type=number] { -moz-appearance:textfield }

/* type="search" — show a polished clear (×) button when the input has
 * a value. Webkit hides it under default Bootstrap form-control resets,
 * so re-enable it explicitly. Firefox renders its own × natively. */
input[type="search"] { -webkit-appearance: textfield; appearance: textfield; }
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: 14px; height: 14px;
  margin-left: 4px;
  background-color: #6c757d;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4.293 4.293a1 1 0 011.414 0L8 6.586l2.293-2.293a1 1 0 111.414 1.414L9.414 8l2.293 2.293a1 1 0 01-1.414 1.414L8 9.414l-2.293 2.293a1 1 0 01-1.414-1.414L6.586 8 4.293 5.707a1 1 0 010-1.414z'/></svg>") center/contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4.293 4.293a1 1 0 011.414 0L8 6.586l2.293-2.293a1 1 0 111.414 1.414L9.414 8l2.293 2.293a1 1 0 01-1.414 1.414L8 9.414l-2.293 2.293a1 1 0 01-1.414-1.414L6.586 8 4.293 5.707a1 1 0 010-1.414z'/></svg>") center/contain no-repeat;
  cursor: pointer;
  opacity: .55;
}
input[type="search"]::-webkit-search-cancel-button:hover { opacity: 1; }
/* DataTables length picker: cleaner spacing around <select> */
.dataTables_length select { padding-right:1.5rem !important; background-position:right .4rem center !important }

/* ────────────────────────────────────────────────────────────────────
   Bootstrap doesn't ship .btn-xs — define it globally here so action
   buttons inside DataTable rows are consistently compact across Codex.
   Pattern matches shipment/list (camera / billing / delete icon row).
   ──────────────────────────────────────────────────────────────────── */
.btn-xs {
  padding: .1rem .35rem;
  font-size: .72rem;
  line-height: 1.4;
  border-radius: .35rem;
}
.btn-xs > .bi { font-size: .85rem; line-height: 1; vertical-align: -.1em }
/* Compact icon button — no text, square aspect, hover lifts slightly */
.btn-xs.btn-icon { width: 28px; height: 24px; padding: 0; display: inline-flex; align-items: center; justify-content: center }
.btn-xs:hover { transform: translateY(-1px); transition: transform .12s ease }

/* ────────────────────────────────────────────────────────────────────
   DataTables — Codex global polish (paging + info + filter chips)
   Borderless rounded pagination buttons. Solid blue active.
   Grey prev/next. Background lives on .page-item (LI), not the inner
   anchor — so the whole button is the colored area. !important is
   needed to override Bootstrap's own .page-item.active .page-link rule.
   Applies to every DataTable in the app.
   ──────────────────────────────────────────────────────────────────── */
.dataTables_info { font-size:.72rem; color:#6b7280; padding-top:.5rem !important }
.dataTables_paginate { padding-top:.4rem !important }
.dataTables_paginate .pagination { margin:0; font-size:.75rem; gap:.4rem }

/* Each page-item is a separate floating button (uniform size; min-width
   keeps single-digit numbers from being narrower than chevrons; flex
   centers content vertically/horizontally regardless of font-size). */
.dataTables_paginate .page-item {
  border-radius:6px !important; background:#fff; overflow:hidden;
  display:inline-flex; align-items:stretch;
  min-width:30px; min-height:28px;
}
.dataTables_paginate .page-item .page-link {
  padding:0 .55rem !important; margin:0 !important; border:0 !important;
  background:transparent !important; color:#0d6efd !important;
  display:inline-flex; align-items:center; justify-content:center;
  width:100%; line-height:1; box-shadow:none !important;
}

.dataTables_paginate .page-item.previous,
.dataTables_paginate .page-item.next { background:#f3f4f6 }
.dataTables_paginate .page-item.previous .page-link,
.dataTables_paginate .page-item.next .page-link {
  color:#374151 !important;
  font-size:0 !important;       /* hide "Previous" / "Next" text */
}
.dataTables_paginate .page-item.previous .page-link::before,
.dataTables_paginate .page-item.next .page-link::before {
  font-family:'bootstrap-icons' !important;
  font-size:.72rem;             /* compact chevron — same visual weight as the numbers */
  font-weight:700;
  line-height:1;
  display:inline-flex;
  align-items:center;
}
.dataTables_paginate .page-item.previous .page-link::before { content:'\F284' } /* bi-chevron-left */
.dataTables_paginate .page-item.next .page-link::before     { content:'\F285' } /* bi-chevron-right */

.dataTables_paginate .page-item.active { background:#0d6efd !important }
.dataTables_paginate .page-item.active .page-link { color:#fff !important; font-weight:600 }

.dataTables_paginate .page-item.disabled { background:#e5e7eb !important }
.dataTables_paginate .page-item.disabled .page-link { color:#9ca3af !important }

.dataTables_paginate .page-item:not(.active):not(.disabled):hover { background:#eff6ff }
.dataTables_paginate .page-item.previous:not(.disabled):hover,
.dataTables_paginate .page-item.next:not(.disabled):hover { background:#e5e7eb }

/* Filter-bar chips & multi-select tag pills used across shipment list,
   order list, billing reports, etc. */
.ms-tag { display:inline-flex; align-items:center; gap:4px; padding:.15rem .45rem; border-radius:6px; background:#e0e7ff; color:#3730a3; font-size:.72rem; cursor:pointer }
.ms-tag .ms-x { opacity:.6 }
.ms-tag:hover .ms-x { opacity:1 }
.date-quick { display:flex; gap:.25rem; flex-wrap:wrap }
.date-quick .btn { font-size:.72rem; padding:.2rem .5rem }
.date-quick .btn.active { background:#0d6efd; color:#fff; border-color:#0d6efd }
.filter-bar { display:flex; gap:.4rem; flex-wrap:wrap; align-items:center }

/* `.filter-card` — the filter `.content-card` on list screens. Keeps
   dropdown menus from being clipped by the card and sets the compact
   control density shared by air/jobs, air/mawbs and air/templates.
   (Promoted here per CLAUDE.md §4.2 once a third page needed it; the
   inline copies in jobs.php / mawbs.php are byte-identical and simply
   become redundant.) */
.filter-card { overflow:visible !important }
.filter-card .dropdown-menu { z-index:1050 }
.filter-card .form-control-sm,
.filter-card .form-select-sm { font-size:.78rem }

/* ────────────────────────────────────────────────────────────────────
   DataTables — hide built-in "Show entries" and "Search:" rows globally.
   Pages use a custom search input in the card header instead.
   To keep them on a specific page, override with display:flex !important
   on .dataTables_length / .dataTables_filter inside that page.
   ──────────────────────────────────────────────────────────────────── */
.dataTables_length, .dataTables_filter { display:none !important }

/* ────────────────────────────────────────────────────────────────────
   .card-fit — bound a content-card to the viewport so it doesn't
   push pagination off-screen. We rely on DataTables' built-in
   scrollY for the actual scrolling region — this just gives the
   card a sensible max-height and ensures BOTH X+Y scrollbars
   appear on .dataTables_scrollBody.

   Card max-height (calc(100vh - 100px)) is generous enough to
   accommodate KPI rows above + card header + scrollY body + paging
   row + padding without clipping. DataTables' scrollY is typically
   set to 'calc(100vh - 320px)' which leaves ~220px for the rest.
   Apply to <div class="content-card">.
   ──────────────────────────────────────────────────────────────────── */
.content-card.card-fit { max-height: calc(100vh - 100px); overflow: hidden }

/* DataTables scrollY: scrollBody is where X+Y scroll happens. Force both axes. */
.content-card.card-fit .dataTables_scrollBody {
  overflow-x: auto !important;
  overflow-y: auto !important;
  scrollbar-gutter: stable;            /* reserve scrollbar space */
}

/* Custom-named scroll areas (Job P&L uses .pnl-tbl-wrap with its own logic) */
.content-card.card-fit .pnl-tbl-wrap,
.content-card.card-fit .dt-scroll { overflow:auto }

/* Soft divider above paging row */
.content-card.card-fit .dataTables_wrapper > .row:last-child { border-top:1px solid #e5e7eb; padding:.4rem .25rem 0; background:#fff }

/* ============================================================
   SPLIT-PANE MODAL — thread list + reading pane
   ------------------------------------------------------------
   The Outlook-style two-pane shell: a scrolling list on the left,
   a reading pane on the right, both inside a tall modal whose
   chrome (header, strips, footer) stays put while only the panes
   scroll.

   Extracted from the production Send Pre-Alert modal
   (shipment/form.php `.pa-modal`) when the global email panel
   became the second copy. Two hand-maintained copies had already
   drifted on border-radius and header treatment — CLAUDE.md §4.2.
   THIS IS THE CANONICAL ONE. `.pa-modal` is the follow-up to
   migrate (tracked in TODO); do not add a third copy.

   USAGE — the dialog carries `modal-xl` per design-system §9;
   the width below is a cap, not a replacement for the size class.

     <div class="modal fade codex-splitpane" id="…">
       <div class="modal-dialog modal-xl modal-dialog-centered">
         <div class="modal-content">
           <div class="modal-header py-2">…</div>
           <div class="modal-body">
             <div class="codex-splitpane-bar">…optional strips…</div>
             <div class="codex-splitpane-panes">
               <div class="codex-splitpane-list">
                 <div class="codex-splitpane-list-head">…</div>
                 <div class="codex-splitpane-list-body">
                   <div class="codex-splitpane-row">…</div>
                 </div>
               </div>
               <div class="codex-splitpane-read">
                 <div class="codex-splitpane-empty">…</div>
                 <div class="codex-splitpane-read-head">…</div>
                 <div class="codex-splitpane-read-body">…</div>
               </div>
             </div>
           </div>
           <div class="modal-footer py-2">…</div>
         </div>
       </div>
     </div>
   ============================================================ */
.codex-splitpane .modal-dialog { max-width: 90vw; height: 88vh; max-height: 88vh }
/* Bootstrap's modal-dialog-centered sets min-height:calc(100% - 1rem),
   which fights the explicit height and can push the footer off-screen. */
.codex-splitpane .modal-dialog.modal-dialog-centered { min-height: 0; display: flex }
.codex-splitpane .modal-content {
  border: 0;
  box-shadow: var(--card-shadow);
  border-radius: var(--radius-card);
  overflow: hidden; width: 100%; height: 100%;
  display: flex; flex-direction: column;
}
.codex-splitpane .modal-header,
.codex-splitpane .modal-footer { flex: 0 0 auto }
.codex-splitpane .modal-body {
  display: flex; flex-direction: column;
  overflow: hidden; padding: 0; min-height: 0;
}

/* Any full-width strip between the header and the panes. */
.codex-splitpane-bar { flex: 0 0 auto }

.codex-splitpane-panes {
  display: flex; flex: 1 1 auto; min-height: 0;
  background: var(--card-bg);
}

.codex-splitpane-list {
  flex: 0 0 38%; max-width: 38%;
  border-right: 1px solid #e5e7eb;
  background: var(--content-bg);
  display: flex; flex-direction: column;
}
.codex-splitpane-list-head {
  padding: .5rem .75rem;
  font-size: .78rem; font-weight: 700; letter-spacing: .02em;
  color: #6b7280; background: var(--card-bg);
  border-bottom: 1px solid #e5e7eb;
  display: flex; justify-content: space-between; align-items: center;
}
.codex-splitpane-list-body { flex: 1; overflow-y: auto; padding: .25rem 0 }
.codex-splitpane-row {
  padding: .5rem .75rem;
  border-bottom: 1px solid #e5e7eb;
  cursor: pointer; font-size: .82rem; color: #1a2a4a;
}
.codex-splitpane-row:hover { background: #f8faff }
.codex-splitpane-row.active { background: #dbeafe; border-left: 3px solid var(--brand-blue) }
.codex-splitpane-row-title { font-weight: 600; color: #1a2a4a }
.codex-splitpane-row-meta {
  font-size: .78rem; color: #6b7280;
  display: flex; gap: .5rem; flex-wrap: wrap; align-items: center;
}

.codex-splitpane-read {
  flex: 1; min-width: 0;
  background: var(--card-bg);
  display: flex; flex-direction: column; overflow: hidden;
}
.codex-splitpane-empty {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .5rem;
  color: #6b7280; font-size: .82rem; text-align: center; padding: 1.5rem;
}
.codex-splitpane-read-head {
  flex: 0 0 auto;
  padding: .75rem 1rem .5rem;
  border-bottom: 1px solid #e5e7eb;
  background: var(--content-bg);
}
.codex-splitpane-read-title {
  font-size: .95rem; font-weight: 700; color: #111827;
  margin-bottom: .25rem; line-height: 1.35;
}
.codex-splitpane-read-meta {
  font-size: .78rem; color: #6b7280;
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
}
.codex-splitpane-read-body {
  flex: 1 1 0; min-height: 0; min-width: 0;
  overflow: auto;
  font-size: .82rem; color: #1f2937; line-height: 1.55;
  background: var(--card-bg);
}
/* Wide content (mail tables, code blocks) scrolls inside the pane, never
   the page — design-system §13. */
.codex-splitpane-read-body table { max-width: none; width: auto }

/* Compose view: swapped in for the panes by the consumer's own class. */
.codex-splitpane-compose { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow-y: auto }

@media (max-width: 991.98px) {
  .codex-splitpane .modal-dialog { max-width: 100%; height: 94vh; max-height: 94vh; margin: .5rem }
  .codex-splitpane-panes { flex-direction: column }
  .codex-splitpane-list {
    flex: 0 0 42%; max-width: 100%;
    border-right: 0; border-bottom: 1px solid #e5e7eb;
  }
}

/* Type badges — a dimension that is not a status. Palette from
   design-system §7's Type-badge row. */
.badge-type-in  { background: #eef2ff; color: #3730a3 }
.badge-type-out { background: #fef3c7; color: #78350f }
.badge-type-ref { background: #eef2ff; color: #3730a3 }

/* ==========================================================================
   Chip system — promoted from customs/entries.php's inline <style>.
   Design-system §7 names it the canonical status convention and §12's DON'T
   explicitly says an inline block defining these belongs in customs.css.
   CLAUDE.md §4.2: a style needed by a third page is promoted, not copied.
   Values are byte-identical to entries.php:46-55; nothing new is invented.
   ========================================================================== */
.chip { display:inline-flex; align-items:center; gap:4px; padding:.12rem .5rem;
        border-radius:999px; font-size:.7rem; font-weight:600 }
.chip-dot { width:6px; height:6px; border-radius:50% }
.chip-draft      { background:#f3f4f6; color:#374151 } .chip-draft .chip-dot      { background:#9ca3af }
.chip-submitted  { background:#dbeafe; color:#1d4ed8 } .chip-submitted .chip-dot  { background:#2563eb }
.chip-processing { background:#fef3c7; color:#92400e } .chip-processing .chip-dot { background:#f59e0b }
.chip-success    { background:#d1fae5; color:#065f46 } .chip-success .chip-dot    { background:#10b981 }
.chip-failed, .chip-error { background:#fee2e2; color:#991b1b }
.chip-failed .chip-dot, .chip-error .chip-dot { background:#ef4444 }
.chip-type-export { background:#eef2ff; color:#3730a3 }
.chip-type-import { background:#fef3c7; color:#78350f }

/* ==========================================================================
   File dropzone — promoted from shipment/import.php's inline <style>
   (.drop-zone, import.php:500-513). Design-system §14 lists "File upload
   dropzone" as an undocumented gap; rather than invent one, this is the
   existing pattern lifted verbatim, with its hex values swapped for the
   tokens they were already copying (#2d7dd2 IS --brand-blue).
   Advisor: promote this into the skill so ui-reviewer has a spec.
   ========================================================================== */
.cw1-drop {
  border: 2px dashed #c7d0e8;
  border-radius: 14px;
  padding: 52px 32px;
  text-align: center;
  cursor: pointer;
  transition: all .2s;
  background: #f8f9fd;
}
.cw1-drop:hover, .cw1-drop.dragging { border-color: var(--brand-blue); background: #eef4ff }
.cw1-drop:focus-visible { outline: 2px solid var(--brand-blue); outline-offset: 2px }
.cw1-drop.disabled { opacity: .55; cursor: default }
.cw1-drop.disabled:hover { border-color: #c7d0e8; background: #f8f9fd }
.cw1-drop-icon  { font-size: 2.5rem; color: #7c8db5; display: block; margin-bottom: .35rem }
.cw1-drop-title { font-weight: 600; color: #374151; font-size: .95rem }
.cw1-drop-hint  { font-size: .72rem; color: #6b7280; margin-top: .15rem }

/* ---- STM grid (shared table look: Daily Report + Daily Planning) ----
   Promoted from the stm_daily_reports page style (#stmTbl_wrapper) so
   both STM tables render identically without page-level style blocks. */
.stm-grid thead th {
  background: #f8fafc;
  font-size: .66rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: #475569;
  font-weight: 700;
}

/* OCR upload picker — a file the profile's skip_patterns matched. It stays
   in the list so the operator can see what was held back and force it
   through; the amber reads as "held", not "failed".
   Lives here rather than in the OCR page's legacy <style> block: new rules
   go in the stylesheet (CLAUDE.md § Assets), never in a page. */
#upFileList .up-row .src-skip { background:#f1f5f9; color:#475569; border:1px solid #cbd5e1 }
#upFileList .up-row .up-unskip { color:#b45309; text-decoration:underline }

/* Pack rows read as one list with the file rows beneath them, because
   they are one list to the operator — the same decision, at two
   granularities. Geometry is copied from the file-row block still living
   in the OCR page's legacy <style> (ocr.php:961): same height, type size,
   gap, padding and divider. When that block is promoted here the two
   should merge into one selector; until then the values are duplicated
   deliberately rather than the pack rows being left unstyled. */
#upGroupList .up-row { display:flex; align-items:center; gap:.5rem;
                       padding:.35rem .55rem; border-bottom:1px solid #f0f2f7;
                       font-size:.78rem }
#upGroupList .up-row:last-child { border-bottom:none }
#upGroupList .up-row .name { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
#upGroupList .up-row .size { color:#9ca3af; font-size:.7rem }
#upGroupList .up-row .src  { font-size:.62rem; padding:.05rem .3rem; border-radius:6px }
#upGroupList .up-row .src-eml  { background:#fef3c7; color:#92400e }
#upGroupList .up-row .src-zip  { background:#dbeafe; color:#1d4ed8 }
#upGroupList .up-row .src-skip { background:#f1f5f9; color:#475569; border:1px solid #cbd5e1 }

/* The two controls a pack row carries. Sized to the row rather than the
   other way round: a full-height Bootstrap select would make pack rows
   taller than file rows, which is the mismatch the operator reported. */
#upGroupList .up-row .grp-pick { font-size:.72rem; padding:.05rem 1.3rem .05rem .35rem;
                                 height:auto; line-height:1.35; width:auto; min-width:8.5rem }
#upGroupList .up-row .grp-go   { font-size:.7rem; padding:.05rem .5rem; line-height:1.35 }
#upGroupList .up-row .status   { font-size:.7rem; white-space:nowrap }
