:root {
  /* Brand accent — violet/indigo, matching the home dashboard's palette
     (see templates/dashboard.html's --dh-accent/#6a53f0 and hero gradient).
     Every button, link, badge, sidebar and mobile nav surface in the app
     reads off these two tokens, so updating them here is what carries the
     new look everywhere at once. --navy keeps its old name for the sake of
     every existing var(--navy) reference below — only its value changed. */
  --navy: #443592;
  --navy-light: #6a53f0;
  --brand-hero-a: #8b7cf5;
  --brand-hero-b: #5a3fd6;
  --brand-hero-c: #241f5c;
  --bg: #F4F6F9;
  --card: #FFFFFF;
  --border: #E1E5EB;
  --text: #1C2530;
  --muted: #6B7684;
  --green: #1E8E5A;
  --green-bg: #E6F4EC;
  --red: #C0392B;
  --red-bg: #FBEAE8;
  --yellow-bg: #FFF6D9;
  --yellow-border: #E9C64B;

  /* Chart tokens — dataviz reference palette (light mode only) */
  --series-1: #2a78d6; /* blue */
  --series-2: #1baf7a; /* aqua */
  --series-3: #eda100; /* yellow */
  --series-4: #008300; /* green */
  --series-5: #4a3aa7; /* violet */
  --series-6: #e34948; /* red */
  --series-7: #e87ba4; /* magenta */
  --series-8: #eb6834; /* orange */
  --div-pos: #2a78d6;
  --div-neg: #e34948;
  --div-mid: #c3c2b7;
  --status-good: #0ca30c;
  --status-warning: #b9790c;
  --status-warning-fill: #fab219;
  --status-serious: #ec835a;
  --status-critical: #d03b3b;
  --chart-surface: #fcfcfb;
  --chart-grid: #e1e0d9;
  --chart-baseline: #c3c2b7;
  --chart-muted: #898781;
  --chart-ink: #0b0b0b;
  --chart-ink-2: #52514e;
}
* { box-sizing: border-box; }
body {
  font-family: -apple-system, "Segoe UI", Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  margin: 0;
  font-size: 14px;
}
a { color: var(--navy-light); text-decoration: none; }
a:hover { text-decoration: underline; }

/* =====================================================================
   APP SHELL — left sidebar (desktop) / off-canvas drawer + bottom bar
   (mobile). See the "SIDEBAR & MOBILE NAV" section near the end of this
   file for the full responsive behavior; these are the shared base rules.
   ===================================================================== */
.app-shell { display: flex; min-height: 100vh; align-items: stretch; }
.app-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

.container { max-width: 1180px; margin: 0 auto; padding: 20px; width: 100%; }
.container.narrow { max-width: 640px; }
/* The home dashboard draws its own full-bleed hero/board layout (see
   dashboard.html's own <style>), so it opts out of the app's normal
   centered/padded content column entirely. */
.container.dashboard-home { max-width: none; padding: 0; margin: 0; }
/* The login screen is also its own full-bleed layout (a centered card over
   a full-viewport gradient) -- same opt-out as dashboard-home above, so the
   gradient isn't capped at 1180px and boxed in with gray margins. */
.container.login-page { max-width: none; padding: 0; margin: 0; }
/* Data-dense pages (many numeric columns, e.g. the Reorder Calculator)
   opt into this instead of the default centered 1180px column -- on a
   wide monitor, capping at 1180px and centering it left a big block of
   unused space on both sides while the wide table still had to scroll
   internally for columns that would otherwise fit. max-width: none lets
   it use the app-main flex child's full remaining width (right up to the
   sidebar); margin: 0 keeps it left-aligned there instead of re-centering;
   padding stays the same plain 20px on all four sides as every other
   page, so this is purely a width change, not a "different page" look. */
.container.wide { max-width: none; margin: 0; }
/* base.html always renders the app's generic top-of-page flash banner
   (unconditionally, outside the {% if g.user %} gate) directly inside
   .container -- including on the logged-out login page. login.html renders
   its own flash message styled to match the two-panel design (.flash-demo,
   inside the form panel), so the generic banner would just duplicate it in
   a mismatched style sitting above the full-bleed layout. Suppress it here
   rather than restructuring base.html, which is shared by every page. */
.container.login-page .flash { display: none; }

/* App-wide footer -- on every logged-in page, desktop and mobile alike.
   This USED to be position:fixed to the viewport bottom, but a fixed
   element sits on top of whatever happens to be scrolled into that same
   screen slot at ANY scroll position, not just at the true end of the page
   -- on a long list (e.g. the Reorder Calculator with 200+ rows) that meant
   the footer visibly overlapped table rows the entire time someone
   scrolled through the middle of the page. Swapping to a plain in-flow
   element fixed that overlap, but created a different complaint: on a
   SHORT page (a five-row Orders list, say) it then sat right after the
   content with a wall of empty space below it, reading as "stuck in the
   middle" instead of anchored to the bottom of the screen.
   The fix is the standard flexbox "sticky footer" technique instead of
   position:fixed: .app-shell is min-height:100vh with align-items:stretch,
   so .app-main (display:flex;flex-direction:column, a direct child) is
   always at least a full viewport tall. .app-footer is a sibling of
   .container inside .app-main (see base.html) with margin-top:auto below,
   which eats all of .app-main's leftover vertical space -- so on a short
   page the footer gets pushed all the way down to the true bottom of the
   screen (no fixed positioning involved, so it can never overlap scrolled
   content), and on a page taller than one viewport there's no leftover
   space to eat, so margin-top:auto collapses to 0 and it just sits right
   after the content, exactly like before. Same reasoning applies on mobile
   once .app-shell stops being a flex row at the 880px breakpoint below --
   .app-main's height there is just its natural content height, so the
   auto margin is always a no-op there and the footer stays in-flow at
   the real end of the page, per how it was already asked to behave. */
.app-footer {
  flex-shrink: 0; margin-top: auto; width: 100%; max-width: 1180px; margin-left: auto; margin-right: auto;
  box-sizing: border-box; padding: 16px 20px 6px; text-align: center; font-size: 12px; color: var(--muted);
  border-top: 1px solid var(--border);
}
.app-footer a { color: var(--muted); text-decoration: none; }
.app-footer a:hover { text-decoration: underline; }
/* Slow, subtle zoom pulse on the heart/brain -- just enough to notice, not
   enough to look gimmicky. Staggered so the two don't beat in lockstep.
   Margin reserves room for the scaled-up glyph to grow into (a transform
   doesn't affect layout, so with no margin the enlarged emoji paints
   straight over the neighboring "with"/"by" text instead of just growing
   in place) and z-index keeps it above that text on the rare pixel where
   they'd still touch. Unscoped (not just .app-footer .pulse-emoji) so the
   same "Made with..." credit can reuse it on the logged-out login page too. */
.pulse-emoji {
  display: inline-block; margin: 0 4px; position: relative; z-index: 1;
  animation: veletsFooterPulse 2.6s ease-in-out infinite;
}
.pulse-emoji.pulse-emoji-brain { animation-delay: .5s; }
@keyframes veletsFooterPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.2); }
}

h1 { font-size: 21px; margin: 0 0 4px; }
h2 { font-size: 16px; margin: 24px 0 10px; }
.page-sub { color: var(--muted); margin-bottom: 18px; font-size: 13px; }

.card { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 18px; margin-bottom: 18px; }

.changelog-current { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; }
.changelog-current .version-pill {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-weight: 700; font-size: 13px;
  background: #1F2A44; color: white; padding: 4px 11px; border-radius: 20px; letter-spacing: .3px;
}
.changelog-entry { padding: 16px 0; border-bottom: 1px solid var(--border); }
.changelog-entry:last-child { border-bottom: none; padding-bottom: 0; }
.changelog-entry-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 4px; }
.changelog-entry-version {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-weight: 700; font-size: 12.5px;
  background: #ECECEC; color: #444; padding: 2px 8px; border-radius: 5px;
}
.changelog-entry-title { font-weight: 600; font-size: 14.5px; }
.changelog-entry-date { color: var(--muted); font-size: 12px; margin-left: auto; }
.changelog-entry ul { margin: 6px 0 0 18px; padding: 0; font-size: 13px; color: #333; }
.changelog-entry li { margin-bottom: 3px; }

.flash { padding: 10px 14px; border-radius: 6px; margin-bottom: 14px; font-size: 13.5px; }
.flash.success { background: var(--green-bg); color: var(--green); border: 1px solid #BFE6CE; }
.flash.error { background: var(--red-bg); color: var(--red); border: 1px solid #F0C4BE; }

table { border-collapse: collapse; width: 100%; font-size: 13px; }
th, td { padding: 7px 10px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle; }
th { background: #F0F2F6; color: var(--muted); font-weight: 600; text-transform: uppercase; font-size: 11px; letter-spacing: .3px; }
tr:hover td { background: #FAFBFD; }

.btn {
  display: inline-block; padding: 7px 14px; border-radius: 6px; border: 1px solid var(--navy);
  background: var(--navy); color: white; font-size: 13px; cursor: pointer; font-family: inherit;
}
.btn:hover { background: var(--navy-light); text-decoration: none; }
.btn.secondary { background: white; color: var(--navy); border-color: var(--border); }
.btn.secondary:hover { background: #F0F2F6; }
.btn.danger { background: var(--red); border-color: var(--red); }
.btn.small { padding: 4px 10px; font-size: 12px; }
.btn.green { background: var(--green); border-color: var(--green); }

label { display: block; font-size: 12.5px; color: var(--muted); margin-bottom: 4px; font-weight: 600; }
input, select, textarea {
  width: 100%; padding: 7px 9px; border: 1px solid var(--border); border-radius: 5px;
  font-size: 13.5px; font-family: inherit; margin-bottom: 12px; background: white;
}
textarea { resize: vertical; min-height: 60px; }
.field-row { display: flex; gap: 14px; flex-wrap: wrap; }
.field-row > div { flex: 1; min-width: 160px; }

.badge { display: inline-block; padding: 2px 9px; border-radius: 20px; font-size: 11px; font-weight: 700; letter-spacing: .2px; }
.badge.reorder { background: var(--red-bg); color: var(--red); }
.badge.ok { background: var(--green-bg); color: var(--green); }
.badge.draft { background: #ECECEC; color: #555; }
.badge.pending_approval { background: var(--yellow-bg); color: #8A6D1D; border: 1px solid var(--yellow-border);}
.badge.needs_revision { background: var(--red-bg); color: var(--red); }
.badge.approved { background: var(--green-bg); color: var(--green); }
.badge.sent_to_supplier { background: #E4EEFB; color: #205297; }
.badge.arrived { background: var(--yellow-bg); color: #8A6D1D; border: 1px solid var(--yellow-border); }
.badge.received_pending_review { background: var(--red-bg); color: var(--red); }
.badge.received { background: var(--green-bg); color: var(--green); }
.badge.cancelled { background: #ECECEC; color: #7a231c; text-decoration: line-through; }
.badge.pending_label { background: #ECECEC; color: #555; }
.badge.label_created { background: #E4EEFB; color: #205297; }
.badge.picked_up { background: var(--yellow-bg); color: #8A6D1D; border: 1px solid var(--yellow-border); }
.badge.in_transit { background: #E0F5F2; color: #0E7C6B; }
.badge.delivered { background: var(--green-bg); color: var(--green); }
.badge.returned_non_delivery { background: var(--red-bg); color: var(--red); }
/* Shipping Rates redesign (v1.39.0) -- freight quote validity status */
.badge.valid { background: var(--green-bg); color: var(--green); }
.badge.expiring_soon { background: var(--yellow-bg); color: #8A6D1D; border: 1px solid var(--yellow-border); }
.badge.expired { background: #ECECEC; color: #555; }
.badge.undated { background: #ECECEC; color: #555; }
.badge.matches { background: #E4EEFB; color: #205297; }

.stat-row { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.stat-tile { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 14px 18px; min-width: 150px; flex: 1; }
.stat-tile .num { font-size: 26px; font-weight: 700; color: var(--navy); }
.stat-tile .lbl { font-size: 12px; color: var(--muted); margin-top: 2px; }

.filters { display: flex; gap: 10px; align-items: end; margin-bottom: 14px; flex-wrap: wrap; }
.filters > div { min-width: 160px; }
.filters label { margin-bottom: 3px; }
.filters input, .filters select { margin-bottom: 0; }

/* Collapsible filter panel toggle (mobile only) -- injected by JS in base.html
   before every .filters element, so any filter form on any page gets the same
   tap-to-reveal treatment on small screens without needing per-page markup. */
.filters-toggle { display: none; }

.approval-box { border: 1px solid var(--border); border-radius: 7px; padding: 12px; margin-bottom: 10px; }
.approval-box .role { font-weight: 700; font-size: 13px; }

/* Vessel Tracking timeline (v1.42.0) -- one step per location a container's
   milestone events group into (see po_bp.py's _grouped_tracking_events),
   consecutive dots joined by a vertical line, same look-and-feel as the
   rest of the app's card/badge tokens rather than a new design system. */
.tracking-timeline { position: relative; padding-left: 22px; }
.tracking-step { position: relative; padding-bottom: 16px; }
.tracking-step:last-child { padding-bottom: 0; }
.tracking-step::before {
  content: ""; position: absolute; left: -18px; top: 4px; bottom: -16px; width: 2px; background: var(--border);
}
.tracking-step:last-child::before { display: none; }
.tracking-step-marker {
  position: absolute; left: -22px; top: 2px; width: 10px; height: 10px; border-radius: 50%;
  background: var(--green); border: 2px solid var(--card);
}
.tracking-step-body ul { list-style: none; }
.tracking-step-body li { padding: 3px 0; font-size: 13px; border-bottom: 1px dashed var(--border); }
.tracking-step-body li:last-child { border-bottom: none; }
.muted { color: var(--muted); }
.right { text-align: right; }
.nowrap { white-space: nowrap; }

/* The login screen's own styling lives entirely inside templates/login.html
   (scoped under .login-v2), the same way dashboard.html keeps its styling
   self-contained -- so nothing login-specific needs to live here anymore. */

.help-box { background: #EEF3FC; border: 1px solid #CBDCF5; border-radius: 7px; padding: 12px 14px; font-size: 13px; margin-bottom: 16px; }

.item-rows-table input, .item-rows-table select { margin-bottom: 0; }
.item-rows-table td { vertical-align: top; padding: 6px 8px; }
.row-qty.stock-hint::placeholder { color: var(--navy-light); opacity: .55; font-weight: 600; }

/* ---------------- Customers ---------------- */
/* v1.38.0 -- a real, hard-to-miss bar for "a location filter (map click /
   city drilldown) is currently applied," reusing .help-box's info-blue
   look (same visual language the app already uses for "here's a state
   that isn't the default") but as a flex row with a real .btn on the end,
   not a sentence with a link buried inside it. */
.active-filter-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: #EEF3FC; border: 1px solid #CBDCF5; border-radius: 7px;
  padding: 10px 14px; font-size: 13px; margin: -6px 0 16px;
}
.active-filter-bar .active-filter-icon { font-size: 15px; line-height: 1; }
.active-filter-bar .btn { margin-left: auto; }

.geo-tree { font-size: 13px; }
.geo-tree .geo-level { margin-left: 16px; }
.geo-tree a { display: inline-block; padding: 2px 0; }
.geo-tree .count { color: var(--muted); font-size: 12px; }
/* position+isolation contain Leaflet's internally z-indexed panes/tiles (which use
   translate3d, each creating its own stacking context) so they can never paint over
   page content below the map on scroll -- a well-known Leaflet-on-mobile-Safari bug. */
#customer-map { height: 460px; border-radius: 8px; border: 1px solid var(--border); position: relative; z-index: 0; overflow: hidden; isolation: isolate; }
.leaflet-marker-count {
  background: var(--navy); color: white; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; font-size: 11px; font-weight: 700; width: 100%; height: 100%; border: 2px solid white;
}
/* v1.37.0 -- Markers/Heat map toggle above the customer map. Reuses
   .btn.small.secondary's exact look, just adds a pressed/active state
   (same navy-fill treatment .subtabs a.active already uses) rather than
   inventing a new toggle-button component. */
.btn.small.secondary.active { background: var(--navy); color: white; border-color: var(--navy); }

/* v1.37.0 -- ranked city lists (Top / Emerging / Declining / Potential
   panels on the Customers dashboard). A lighter-weight sibling of
   .meter-list -- these are RANKINGS with a single headline figure per
   row, not a %-of-total breakdown, so a progress bar doesn't apply. */
.city-rank-list { display: flex; flex-direction: column; gap: 4px; }
.city-rank-item { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.city-rank-item:last-child { border-bottom: none; padding-bottom: 0; }
.city-rank-rank {
  width: 20px; height: 20px; border-radius: 50%; background: #EDEDE7; color: var(--muted); font-size: 11px;
  font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.city-rank-body { flex: 1 1 auto; min-width: 0; }
.city-rank-name { font-size: 13px; font-weight: 600; }
.city-rank-name a { color: var(--text); }
.city-rank-name a:hover { color: var(--navy-light); }
.city-rank-sub { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.city-rank-figure { text-align: right; flex-shrink: 0; }
.city-rank-value { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.city-rank-delta { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.city-rank-delta.up { color: var(--status-good); }
.city-rank-delta.down { color: var(--status-critical); }
.city-rank-empty { color: var(--muted); font-size: 12.5px; padding: 14px 0; text-align: center; }

/* Leaflet tooltip (hover card on a city marker) -- default Leaflet chrome
   looks out of place against this app's card styling, so it's restyled to
   match .sh-modal/.dispatch-checklist-item's plain rounded-card look. */
.leaflet-tooltip {
  background: var(--card) !important; border: 1px solid var(--border) !important; color: var(--text) !important;
  border-radius: 7px !important; font-size: 12px !important; padding: 8px 10px !important;
  box-shadow: 0 6px 18px rgba(0,0,0,.14) !important; line-height: 1.5 !important;
}
.leaflet-tooltip-top:before { border-top-color: var(--border) !important; }

/* ---------------- Analytics dashboard ---------------- */
.section-title { font-size: 15px; font-weight: 700; margin: 30px 0 12px; color: var(--text); }
.section-title:first-of-type { margin-top: 8px; }
.section-sub { font-size: 12px; color: var(--muted); margin: -8px 0 12px; }

.stat-tile.wide { flex-basis: 220px; }
.stat-tile .delta { font-size: 12px; font-weight: 700; margin-top: 2px; }
.stat-tile .delta.up { color: var(--status-good); }
.stat-tile .delta.down { color: var(--status-critical); }
.stat-tile .delta.flat { color: var(--muted); }
.stat-tile .spark { display: block; margin-top: 6px; }
.stat-tile .spark polyline { fill: none; stroke: var(--chart-baseline); stroke-width: 1.5; }
.stat-tile .spark circle { fill: var(--series-1); }

.chart-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 18px; }
.chart-grid.thirds { grid-template-columns: 1fr 1fr 1fr; }
.chart-grid.quarters { grid-template-columns: repeat(4, 1fr); }
.chart-grid.full { grid-template-columns: 1fr; }
@media (max-width: 1100px) {
  .chart-grid.quarters { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 860px) {
  .chart-grid, .chart-grid.thirds, .chart-grid.quarters { grid-template-columns: 1fr; }
}

/* Grid items default to min-width:auto, which prevents them shrinking below
   their content's intrinsic (min-content) size -- the classic cause of grid
   overflow on narrow viewports. Force them shrinkable. */
.chart-grid > * { min-width: 0; }

.chart-card { background: var(--chart-surface); border: 1px solid var(--border); border-radius: 8px; padding: 16px 18px; margin-bottom: 0; min-width: 0; }
.chart-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.chart-card-head h3 { font-size: 13.5px; margin: 0; color: var(--text); }
.chart-card-head .chart-note { font-size: 11.5px; color: var(--chart-muted); }
.chart-canvas-wrap { position: relative; width: 100%; min-width: 0; }
.chart-canvas-wrap.h220 { height: 220px; }
.chart-canvas-wrap.h260 { height: 260px; }
.chart-canvas-wrap.h300 { height: 300px; }
.chart-canvas-wrap canvas { max-width: 100% !important; }

.table-toggle { background: none; border: none; color: var(--navy-light); font-size: 11.5px; cursor: pointer; font-family: inherit; padding: 0; text-decoration: underline; }
.table-twin { display: none; margin-top: 12px; }
.table-twin.shown { display: block; }
.table-twin table { font-size: 12px; }
.chart-empty { color: var(--muted); font-size: 12.5px; padding: 30px 0; text-align: center; }

/* Meter / status bar list (health buckets, warehouse utilization) */
.meter-list { display: flex; flex-direction: column; gap: 12px; }
.meter-row .meter-top { display: flex; align-items: center; justify-content: space-between; font-size: 12.5px; margin-bottom: 4px; }
.meter-row .meter-label { display: flex; align-items: center; gap: 6px; color: var(--text); }
.meter-row .meter-value { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.meter-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.meter-track { background: #EDEDE7; border-radius: 5px; height: 10px; overflow: hidden; }
.meter-fill { height: 100%; border-radius: 5px; }
.meter-row .meter-sub { font-size: 11px; color: var(--chart-muted); margin-top: 3px; }

.dot-good { background: var(--status-good); }
.dot-warning { background: var(--status-warning-fill); }
.dot-serious { background: var(--status-serious); }
.dot-critical { background: var(--status-critical); }

/* Overdue spot-check attention marker */
.nav-alert {
  display: inline-block; background: var(--status-critical); color: white; font-weight: 800;
  border-radius: 50%; width: 15px; height: 15px; line-height: 15px; text-align: center; font-size: 11px;
  animation: veletsBlink 1.1s ease-in-out infinite;
}
@keyframes veletsBlink { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

.warning-banner {
  display: flex; align-items: center; gap: 10px; background: #FBEAE8; border: 1px solid var(--status-critical);
  color: #7a231c; border-radius: 7px; padding: 10px 14px; margin-bottom: 16px; font-size: 13.5px; font-weight: 600;
}
.warning-banner .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--status-critical);
  flex-shrink: 0; animation: veletsBlink 1.1s ease-in-out infinite; }

/* Pending-decision banner (e.g. a channel order awaiting its ship-from
   store) -- deliberately the softer yellow/pending palette, not
   warning-banner's red/critical one: this is an expected, normal state
   for a freshly-imported order, not an error. */
.pending-banner {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; background: var(--yellow-bg);
  border: 1px solid var(--yellow-border); color: #6b551a; border-radius: 7px; padding: 10px 14px;
  margin-bottom: 16px; font-size: 13.5px;
}
.pending-banner form { display: inline-flex; gap: 6px; align-items: center; margin-left: auto; }

/* Sales entry SKU typeahead */
.typeahead-wrap { position: relative; }
.typeahead-results {
  position: absolute; top: 100%; left: 0; right: 0; background: white; border: 1px solid var(--border);
  border-radius: 6px; box-shadow: 0 6px 18px rgba(0,0,0,0.12); z-index: 20; max-height: 260px; overflow-y: auto; display: none;
}
.typeahead-results.open { display: block; }
.typeahead-item { padding: 8px 12px; cursor: pointer; font-size: 13px; border-bottom: 1px solid var(--border); }
.typeahead-item:last-child { border-bottom: none; }
.typeahead-item:hover, .typeahead-item.active { background: #F0F2F6; }
.typeahead-item .code { font-weight: 700; color: var(--navy); }
.typeahead-item .desc { color: var(--muted); font-size: 12px; }
.typeahead-selected {
  display: none; align-items: center; justify-content: space-between; background: #EEF3FC; border: 1px solid #CBDCF5;
  border-radius: 6px; padding: 8px 12px; margin-bottom: 12px; font-size: 13px;
}
.typeahead-selected.shown { display: flex; }
.typeahead-selected .clear-btn { color: var(--red); cursor: pointer; font-weight: 700; background:none; border:none; font-family:inherit; }

.badge.unicorn { background: #F3E8FF; color: #6B21A8; }
.badge.turtle { background: #E9F0E6; color: #3F6B2E; }
.badge.newsku { background: #ECECEC; color: #555; }

/* =====================================================================
   SIDEBAR & MOBILE NAV
   ===================================================================== */
:root { --sidebar-w: 232px; --sidebar-w-collapsed: 68px; --mobile-bar-h: 60px; --mobile-top-h: 52px; }

.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: linear-gradient(180deg, var(--navy) 0%, var(--brand-hero-c) 100%);
  color: #D7E2F5;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  z-index: 45;
  transition: width .16s ease;
  overflow: hidden;
}
.sidebar.collapsed { width: var(--sidebar-w-collapsed); }

.sidebar-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 14px 10px; flex-shrink: 0; }
.sidebar-brand { display: flex; align-items: center; gap: 10px; color: white; min-width: 0; }
.sidebar-brand:hover { text-decoration: none; }
.brand-mark {
  width: 30px; height: 30px; border-radius: 8px; background: var(--brand-hero-a); color: white; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px;
}
.brand-text { font-weight: 700; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar.collapsed .brand-text { display: none; }

.sidebar-collapse-btn {
  background: rgba(255,255,255,.08); border: none; color: #D7E2F5; width: 26px; height: 26px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0;
}
.sidebar-collapse-btn:hover { background: rgba(255,255,255,.16); color: white; }
.sidebar-collapse-btn svg { width: 16px; height: 16px; flex-shrink: 0; display: block; }
.sidebar.collapsed .sidebar-collapse-btn svg { transform: rotate(180deg); }
.sidebar.collapsed .sidebar-head { flex-direction: column; justify-content: center; gap: 10px; padding: 14px 8px 12px; }
.sidebar.collapsed .sidebar-brand { justify-content: center; width: 100%; }

.sidebar-nav { flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; padding: 6px 8px; }
.sidebar-nav::-webkit-scrollbar { width: 5px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.15); border-radius: 3px; }

.sidebar-link {
  display: flex; align-items: center; gap: 12px; padding: 9px 10px; border-radius: 7px; margin-bottom: 2px;
  color: #D7E2F5; font-size: 13.5px; white-space: nowrap; cursor: pointer; background: none; border: none;
  width: 100%; text-align: left; font-family: inherit; position: relative;
}
.sidebar-link .ic { flex-shrink: 0; display: flex; width: 20px; height: 20px; }
.sidebar-link .label { overflow: hidden; text-overflow: ellipsis; flex: 1 1 auto; }
.sidebar-link:hover { background: rgba(255,255,255,.08); text-decoration: none; color: white; }
.sidebar-link.active { background: rgba(255,255,255,.14); color: white; }
.sidebar-link.active::before {
  content: ""; position: absolute; left: -8px; top: 6px; bottom: 6px; width: 3px; border-radius: 3px; background: var(--brand-hero-a);
}
.sidebar.collapsed .sidebar-link { justify-content: center; padding: 9px 0; }
.sidebar.collapsed .sidebar-link .label, .sidebar.collapsed .sidebar-link .chevron { display: none; }
.sidebar.collapsed .sidebar-link.active::before { left: 0; }

.sidebar-group-toggle .chevron { flex-shrink: 0; display: flex; transition: transform .15s ease; opacity: .7; }
.sidebar-group-toggle .chevron svg { width: 16px; height: 16px; flex-shrink: 0; display: block; }
.sidebar-group.open .sidebar-group-toggle .chevron { transform: rotate(90deg); }
.sidebar-submenu { max-height: 0; overflow: hidden; transition: max-height .18s ease; padding-left: 14px; }
.sidebar-group.open .sidebar-submenu { max-height: 480px; }
.sidebar-submenu .sidebar-link { font-size: 13px; padding: 7px 10px; opacity: .92; }
.sidebar-submenu .sidebar-link::before { display: none; }
.sidebar-submenu .sidebar-link.active { font-weight: 600; opacity: 1; }
.sidebar.collapsed .sidebar-submenu { display: none; }

.sidebar-nav-alert {
  display: inline-flex; align-items: center; justify-content: center; background: var(--status-critical); color: white;
  font-weight: 800; border-radius: 50%; width: 15px; height: 15px; font-size: 10px; flex-shrink: 0;
  animation: veletsBlink 1.1s ease-in-out infinite;
}
/* Collapsed sidebar: .label is hidden and .sidebar-link centers its
   remaining children, which would otherwise put this badge floating beside
   the icon instead of overlaid on its corner like a normal notification
   dot. Pin it to the icon's top-right corner instead (.sidebar-link is
   already position:relative). */
.sidebar.collapsed .sidebar-nav-alert {
  position: absolute; top: 4px; right: 10px; margin: 0;
}

.sidebar-foot { flex-shrink: 0; border-top: 1px solid rgba(255,255,255,.12); padding: 10px 8px; }
.sidebar-version { color: #A9BEDD; font-size: 10.5px; padding: 0 10px 8px; letter-spacing: .2px; }
.sidebar.collapsed .sidebar-version { display: none; }
.sidebar-user { display: flex; align-items: center; gap: 10px; padding: 6px; border-radius: 7px; }
.sidebar-user .avatar {
  width: 32px; height: 32px; border-radius: 50%; background: rgba(255,255,255,.14); color: white; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px;
}
.sidebar-user .user-meta { min-width: 0; overflow: hidden; }
.sidebar-user .user-meta .name { color: white; font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-user .user-meta .role { color: #A9BEDD; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar.collapsed .sidebar-user .user-meta { display: none; }
.sidebar.collapsed .sidebar-user { justify-content: center; }
.sidebar-foot-links { display: flex; gap: 4px; margin-top: 4px; }
.sidebar-foot-links a {
  flex: 1; text-align: center; color: #A9BEDD; font-size: 11px; padding: 6px 2px; border-radius: 6px;
}
.sidebar-foot-links a:hover { background: rgba(255,255,255,.08); color: white; text-decoration: none; }
.sidebar.collapsed .sidebar-foot-links { display: none; }

/* Off-canvas overlay backdrop (mobile drawer only) */
.sidebar-overlay {
  display: none; position: fixed; inset: 0; background: rgba(15,23,42,.45); z-index: 40; opacity: 0; transition: opacity .18s ease;
}
.sidebar-overlay.show { display: block; opacity: 1; }

/* ---- Setup / Settings: two-column layout (secondary vertical nav +
   panel), replacing the old horizontal link row that used to sit above
   every Setup page. Deliberately its own, simpler component rather than
   reusing .sidebar -- this one never collapses/goes off-canvas, it just
   stacks above the panel on narrow screens (see the media query below). */
.settings-shell { display: flex; align-items: flex-start; gap: 18px; }
.settings-sidebar {
  flex: 0 0 208px; background: var(--card); border: 1px solid var(--border);
  border-radius: 8px; overflow: hidden; position: sticky; top: 18px;
}
.settings-sidebar-title {
  font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px;
  color: var(--muted); padding: 12px 16px 8px;
}
.settings-sidebar-links { display: flex; flex-direction: column; }
.settings-sidebar a {
  display: block; padding: 10px 16px; font-size: 13.5px; color: var(--text);
  border-left: 3px solid transparent; white-space: nowrap;
}
.settings-sidebar a:hover { background: var(--bg); text-decoration: none; }
.settings-sidebar a.active {
  background: var(--navy); color: white; border-left-color: var(--navy-light); font-weight: 600;
}
.settings-sidebar-foot { border-top: 1px solid var(--border); padding: 10px 16px; }
.settings-sidebar-foot a { font-size: 12px; }
.settings-panel { flex: 1 1 auto; min-width: 0; }

/* Setup > Themes picker cards */
.theme-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; max-width: 900px;
}
.theme-card {
  background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 18px 20px;
}
.theme-card.is-active { border-color: var(--navy-light); box-shadow: 0 0 0 1px var(--navy-light); }
.theme-card-swatches { display: flex; gap: 6px; margin-bottom: 12px; }
.theme-swatch { width: 24px; height: 24px; border-radius: 7px; border: 1px solid rgba(0,0,0,.08); display: inline-block; }
.theme-card h2 { margin: 0 0 6px; font-size: 15.5px; display: flex; align-items: center; gap: 8px; }
.theme-card-desc { font-size: 12.5px; color: var(--muted); line-height: 1.5; margin: 0 0 14px; min-height: 52px; }

@media (max-width: 880px) {
  .settings-shell { flex-direction: column; gap: 12px; }
  .settings-sidebar { position: static; flex: 0 0 auto; width: 100%; }
  .settings-sidebar-title { display: none; }
  .settings-sidebar-links {
    flex-direction: row; overflow-x: auto; -webkit-overflow-scrolling: touch;
  }
  .settings-sidebar a {
    flex: 0 0 auto; border-left: none; border-bottom: 3px solid transparent;
  }
  .settings-sidebar a.active { border-left: none; border-bottom-color: var(--navy-light); }
  .settings-sidebar-foot { border-top: 1px solid var(--border); }
}

/* Mobile top bar (hidden on desktop) */
.mobile-topbar { display: none; }
.mobile-menu-btn, .mobile-user-btn {
  background: none; border: none; color: white; width: 36px; height: 36px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0;
}
.mobile-menu-btn:hover, .mobile-user-btn:hover { background: rgba(255,255,255,.12); }
/* Explicit size on the icon svg itself -- unlike the sidebar/bottom-bar icons (which sit
   inside a sized .ic wrapper span), these two topbar icons are bare <svg> elements with no
   width/height attributes. Some mobile browsers (notably iOS Safari) don't give an unsized
   inline SVG a sane intrinsic size inside a flex container and can collapse it to invisible,
   which is why only the alert dot was showing. Force it explicitly so it's reliable everywhere. */
.mobile-menu-btn svg, .mobile-user-btn svg { width: 22px; height: 22px; flex-shrink: 0; display: block; }
.mobile-menu-btn .dot {
  position: absolute; top: 6px; right: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--status-critical);
  animation: veletsBlink 1.1s ease-in-out infinite;
}
.mobile-brand { font-weight: 700; font-size: 15px; color: white; }

/* iOS-only "install as an app" nudge (see base.html for the JS that shows
   it) -- deliberately plain in-flow, not position:fixed, so it can never
   collide with the fixed bottom bar or need its own safe-area-inset math. */
.ios-install-banner {
  display: none; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--navy); color: #fff; padding: 10px 14px; font-size: 13px; line-height: 1.35;
}
.ios-install-banner button {
  background: none; border: none; color: #fff; font-size: 16px; line-height: 1;
  cursor: pointer; padding: 4px 6px; flex-shrink: 0; opacity: .85; -webkit-tap-highlight-color: transparent;
}
.ios-install-banner button:hover { opacity: 1; }

/* Mobile bottom quick-action bar (hidden on desktop) */
.mobile-bottom-bar { display: none; }
.mobile-bottom-bar a, .mobile-bottom-bar button {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: 7px 2px 8px; color: var(--muted); font-size: 10px; background: none; border: none; font-family: inherit;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.mobile-bottom-bar a:hover, .mobile-bottom-bar button:hover { text-decoration: none; }
.mobile-bottom-bar .ic { display: flex; width: 21px; height: 21px; }
.mobile-bottom-bar a.active, .mobile-bottom-bar button.active { color: var(--navy); }
.mobile-bottom-bar .fab-wrap { margin-top: -20px; }
.mobile-bottom-bar .fab-circle {
  width: 46px; height: 46px; border-radius: 50%; background: var(--navy); color: white;
  display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 12px rgba(68,53,146,.4);
  border: 3px solid var(--bg);
}
.mobile-bottom-bar .fab-circle .ic { width: 22px; height: 22px; }

@media (max-width: 880px) {
  .sidebar {
    position: fixed; top: 0; left: 0; height: 100dvh; width: 260px; max-width: 82vw;
    transform: translateX(-100%); transition: transform .2s ease; box-shadow: 0 0 30px rgba(0,0,0,.3);
  }
  .sidebar.collapsed { width: 260px; }
  .sidebar.mobile-open { transform: translateX(0); }
  .sidebar.collapsed .brand-text,
  .sidebar.collapsed .sidebar-link .label,
  .sidebar.collapsed .sidebar-link .chevron,
  .sidebar.collapsed .sidebar-user .user-meta,
  .sidebar.collapsed .sidebar-foot-links { display: revert; }
  .sidebar.collapsed .sidebar-link { justify-content: flex-start; padding: 9px 10px; }
  .sidebar.collapsed .sidebar-link.active::before { left: -8px; }
  .sidebar-collapse-btn { display: none; }
  .sidebar-head { padding: 14px 14px 10px 20px; }

  .app-shell { display: block; }
  .mobile-topbar {
    display: flex; align-items: center; justify-content: space-between; height: var(--mobile-top-h);
    background: var(--navy); padding: 0 8px 0 4px; position: sticky; top: 0; z-index: 30;
  }
  .container { padding: 14px 14px calc(var(--mobile-bar-h) + env(safe-area-inset-bottom, 0) + 18px); }
  .container.dashboard-home { padding-bottom: calc(var(--mobile-bar-h) + env(safe-area-inset-bottom, 0)); }

  /* Height must ADD the home-indicator inset, not just pad into a fixed
     height -- everything on this page uses box-sizing:border-box (see the
     global `*` rule up top), so a fixed height + padding-bottom would eat
     that padding out of the row's own content area instead of adding extra
     clearance below it. On an iPhone with a safe-area inset (any Face ID
     iPhone), that squeezed the 60px-tall icon+label row down into ~26px,
     which is the "deshaped"/cramped bottom bar reported when running as an
     iOS home-screen web app (Safari's own chrome normally absorbs that
     space, so this only shows up once the browser UI is gone in standalone
     mode). Adding the inset to height instead keeps the icons/labels at
     their normal 60px and just adds clearance underneath them. */
  .mobile-bottom-bar {
    display: flex; position: fixed; bottom: 0; left: 0; right: 0;
    height: calc(var(--mobile-bar-h) + env(safe-area-inset-bottom, 0));
    background: var(--card); border-top: 1px solid var(--border); z-index: 35;
    padding-bottom: env(safe-area-inset-bottom, 0);
  }

  .app-footer { font-size: 11px; margin: 28px 0 4px; padding-top: 14px; }
}
@media (min-width: 881px) {
  .mobile-menu-btn, .sidebar-overlay { display: none !important; }
}

/* =====================================================================
   MOBILE / SMALL-SCREEN CONTENT POLISH
   ===================================================================== */
.table-scroll { width: 100%; }

@media (max-width: 700px) {
  body { font-size: 14.5px; }
  h1 { font-size: 18px; }
  h2 { font-size: 15px; margin: 20px 0 8px; }
  .card { padding: 14px; border-radius: 10px; }

  .field-row { flex-direction: column; gap: 0; }
  .field-row > div { min-width: 0; width: 100%; }
  .field-row[style*="flex"] > div { width: auto; }

  .filters { flex-direction: column; align-items: stretch; }
  .filters > div { min-width: 0; width: 100%; }
  .filters > div:has(button), .filters > div:has(a.btn) { width: auto; align-self: flex-start; }

  .filters-toggle {
    display: flex; align-items: center; gap: 8px; width: 100%; background: var(--card);
    border: 1px solid var(--border); border-radius: 8px; padding: 11px 14px; margin-bottom: 12px;
    font-size: 13.5px; font-weight: 600; color: var(--text); font-family: inherit; cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .filters-toggle svg { width: 16px; height: 16px; flex-shrink: 0; display: block; }
  .filters-toggle .filters-toggle-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--navy); flex-shrink: 0; }
  .filters-toggle .filters-toggle-chev { margin-left: auto; opacity: .55; transition: transform .15s ease; }
  .filters-toggle.open .filters-toggle-chev { transform: rotate(90deg); }
  .filters.filters-collapsed { display: none; }

  .stat-row { gap: 10px; }
  .stat-tile { min-width: 0; flex-basis: calc(50% - 5px); }
  .stat-tile.wide { flex-basis: calc(50% - 5px); }

  .btn { padding: 10px 16px; font-size: 14px; }
  .btn.small { padding: 8px 12px; font-size: 12.5px; }
  input, select, textarea { font-size: 16px; padding: 9px 10px; } /* 16px prevents iOS auto-zoom on focus */
  label { font-size: 12.5px; }

  .table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 -2px; }
  .table-scroll table { min-width: 560px; }
  .table-scroll.compact table { min-width: 420px; }
  table { font-size: 12.5px; }
  th, td { padding: 8px; }

  .page-sub { font-size: 12.5px; }

  .chart-grid { gap: 10px; }
  .chart-card { padding: 12px 14px; }
  .chart-canvas-wrap.h220 { height: 190px; }
  .chart-canvas-wrap.h260 { height: 210px; }
  .chart-canvas-wrap.h300 { height: 230px; }

  .subtabs { overflow-x: auto; -webkit-overflow-scrolling: touch; flex-wrap: nowrap !important; }

  .stat-tile .num { font-size: 21px; }
  .stat-tile { padding: 12px 14px; }

  .approval-box { padding: 10px; }
  .help-box { padding: 10px 12px; font-size: 12.5px; }

  .app-footer { font-size: 11px; margin: 28px 0 4px; padding-top: 14px; }
}

/* Accounts sub-navigation (Cash / E-transfer / Clover switcher, etc.) */
.subtabs { display: flex; gap: 6px; margin-bottom: 16px; flex-wrap: wrap; }
.subtabs a {
  padding: 7px 14px; border-radius: 20px; font-size: 12.5px; font-weight: 600; color: var(--muted); background: #EDF0F5;
}
.subtabs a:hover { background: #E3E7EE; text-decoration: none; }

/* ---------------- Products module ---------------- */
.product-thumb {
  width: 44px; height: 44px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border); display: block;
}
.product-thumb-lg { width: 140px; height: 140px; }
.product-thumb-empty {
  display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 10px;
  background: #F5F5F0; text-align: center; padding: 2px;
}
.location-box, .stock-box {
  display: inline-block; border-radius: 6px; padding: 4px 10px; font-size: 12px; line-height: 1.4;
}
.location-box { background: #EEF3FC; border: 1px solid #CBDCF5; color: #205297; }
.stock-box { background: #F5F5F0; border: 1px solid var(--border); color: var(--text); }
.gallery-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.gallery-item { position: relative; display: inline-block; }
.gallery-item .btn.danger {
  position: absolute; top: -6px; right: -6px; padding: 0 6px; line-height: 18px; border-radius: 50%; font-size: 11px;
}

/* Stock-history popup (Products list / detail) */
.sh-modal-overlay {
  position: fixed; inset: 0; background: rgba(20, 20, 30, .45); z-index: 400;
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.sh-modal {
  background: var(--card); border-radius: 10px; padding: 20px; width: 100%; max-width: 920px;
  max-height: 88vh; overflow-y: auto; box-shadow: 0 20px 60px rgba(0,0,0,.3);
}
.sh-modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.sh-modal-close {
  background: none; border: none; font-size: 16px; cursor: pointer; color: var(--muted); padding: 4px 8px;
}
.sh-modal-close:hover { color: var(--text); }

/* Dispatch scan modal (Shipping > order detail Verify/Mark Delivered flow) */
.dispatch-modal { max-width: 480px; position: relative; }
.dispatch-checklist { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.dispatch-checklist-item {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--border);
  border-radius: 8px; background: #FAFAFC;
}
.dispatch-checklist-item.complete { border-color: var(--green); background: var(--green-bg); }
.dispatch-check-icon {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center;
  justify-content: center; font-size: 13px; font-weight: 700; background: var(--border); color: white;
}
.dispatch-checklist-item.complete .dispatch-check-icon { background: var(--green); }
.dispatch-checklist-item-body { flex: 1; }
.dispatch-checklist-item-body .sku { font-weight: 600; font-size: 13px; }
.dispatch-checklist-item-body .box { font-size: 12px; color: var(--muted); }
.dispatch-checklist-item-count { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.dispatch-scan-btn {
  width: 100%; padding: 14px; font-size: 15px; font-weight: 700; border-radius: 10px; border: none;
  background: var(--navy); color: white; cursor: pointer; margin-top: 4px;
}
.dispatch-scan-btn:disabled { background: var(--border); color: var(--muted); cursor: not-allowed; }
.dispatch-scan-status {
  margin: 10px 0; padding: 10px 12px; border-radius: 8px; font-size: 13px; display: none;
}
.dispatch-scan-status.ok { display: block; background: var(--green-bg); color: var(--green); }
.dispatch-scan-status.fail { display: block; background: var(--red-bg); color: var(--red); }
.dispatch-scan-status.ambiguous { display: block; background: var(--yellow-bg); color: #8A6D1D; }
.dispatch-scan-status.busy { display: block; background: #EEF3FC; color: var(--navy); }
.dispatch-step-title { font-size: 13px; font-weight: 700; color: var(--muted); text-transform: uppercase;
  letter-spacing: .4px; margin: 16px 0 8px; }
.dispatch-signature-pad {
  width: 100%; height: 160px; border: 1px dashed var(--border); border-radius: 8px; touch-action: none;
  background: white;
}
.dispatch-abandon-link { font-size: 12px; color: var(--red); text-align: center; margin-top: 14px; }
.dispatch-payment-total-info {
  font-size: 12.5px; background: #EEF3FC; color: var(--navy); border-radius: 8px; padding: 8px 12px;
  margin: 0 0 10px;
}
.dispatch-assembly-timer {
  font-size: 34px; font-weight: 800; text-align: center; font-variant-numeric: tabular-nums;
  color: var(--navy); background: #EEF3FC; border-radius: 10px; padding: 14px; letter-spacing: 1px;
}
.dispatch-assembly-timer.over-limit { color: var(--red); background: var(--red-bg); }
.dispatch-payment-total-info strong { font-variant-numeric: tabular-nums; }

/* Live camera capture block -- shared by all 3 capture points (box scan,
   courier label scan, self-delivery proof photo). Shown as an in-modal
   overlay while a getUserMedia stream is active. */
.dispatch-camera-block {
  position: absolute; inset: 0; z-index: 5; background: #000; border-radius: 10px;
  display: flex; flex-direction: column; align-items: stretch; justify-content: flex-end;
  overflow: hidden;
}
.dispatch-camera-video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: #000;
}
.dispatch-camera-controls {
  position: relative; z-index: 1; display: flex; gap: 10px; padding: 14px;
  background: linear-gradient(to top, rgba(0,0,0,.65), rgba(0,0,0,0));
}
.dispatch-camera-controls .btn { flex: 0 0 auto; }
.dispatch-camera-controls .dispatch-scan-btn { flex: 1; margin-top: 0; }
.dispatch-camera-block .dispatch-scan-status.fail {
  position: relative; z-index: 1; margin: 0 14px 14px; background: var(--red-bg); color: var(--red);
}

@media print {
  body * { visibility: hidden; }
  .sh-modal, .sh-modal * { visibility: visible; }
  .sh-modal { position: absolute; left: 0; top: 0; max-height: none; box-shadow: none; }
  .sh-modal-close, #sh-export-excel, #sh-export-pdf, .sh-modal-head button, .field-row #sh-store-select { display: none !important; }
}
.subtabs a.active { background: var(--navy); color: white; }

/* =====================================================================
   ORDERS LIST TOOLBAR (v1.29.0 redesign) — page-size select, export
   links, and the "Columns ▾" show/hide dropdown that sits above the
   Orders table. col-toggle-* mirrors the order-detail-page's own
   menu-wrap/dropdown-menu look (a small anchored card) but is its own,
   unscoped set of classes since sales_orders_list.html isn't part of
   that page's .order-detail-page-scoped block below.
   ===================================================================== */
.orders-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.orders-toolbar .spacer { flex: 1 1 auto; }
.col-toggle-wrap { position: relative; display: inline-block; }
.col-toggle-menu {
  display: none; position: absolute; right: 0; top: calc(100% + 4px); background: var(--card);
  border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 6px 18px rgba(0,0,0,.14);
  min-width: 210px; max-height: 320px; overflow-y: auto; z-index: 20; padding: 8px 0;
}
.col-toggle-menu.shown { display: block; }
.col-toggle-menu label {
  display: flex; align-items: center; gap: 8px; padding: 6px 12px; font-size: 12.5px; font-weight: 400;
  color: var(--text); cursor: pointer; white-space: nowrap;
}
.col-toggle-menu label:hover { background: #F0F2F6; }
.col-toggle-menu .col-toggle-reset {
  display: block; width: 100%; text-align: left; padding: 8px 12px; font-size: 12px; background: none;
  border: none; border-top: 1px solid var(--border); margin-top: 6px; color: var(--muted); cursor: pointer;
  font-family: inherit;
}
.col-toggle-menu .col-toggle-reset:hover { background: #F0F2F6; color: var(--text); }

/* v1.31.0 -- Orders list page's manual "Fetch Orders" panel (see
   channel_sync.js / sales_tx_bp.py's channel_fetch_now()). Reuses
   .col-toggle-wrap for the anchor/positioning (same trigger-button pattern
   as "Columns ▾" on this same page), with its own wider menu since each
   row needs room for a name, a status line, and a refresh button. */
.fetch-orders-menu {
  display: none; position: absolute; right: 0; top: calc(100% + 4px); background: var(--card);
  border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 6px 18px rgba(0,0,0,.14);
  min-width: 300px; max-height: 360px; overflow-y: auto; z-index: 20; padding: 8px 0;
}
.fetch-orders-menu.shown { display: block; }
.fetch-orders-menu .fetch-orders-header {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 2px 12px 8px; margin-bottom: 4px; border-bottom: 1px solid var(--border);
}
.fetch-orders-menu .fetch-orders-header strong { font-size: 12.5px; }
.fetch-orders-menu .fetch-orders-update-all {
  background: none; border: none; color: #205297; font-size: 12px; font-weight: 700;
  cursor: pointer; font-family: inherit; padding: 2px 4px; white-space: nowrap;
}
.fetch-orders-menu .fetch-orders-update-all:hover { text-decoration: underline; }
.fetch-orders-menu .fetch-orders-update-all:disabled { opacity: .5; cursor: default; text-decoration: none; }
.fetch-orders-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 12px;
}
.fetch-orders-row .fo-name { font-size: 12.5px; font-weight: 700; }
.fetch-orders-row .fo-status { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.fetch-orders-row .fo-status .fo-ok { color: var(--green); }
.fetch-orders-row .fo-status .fo-error { color: var(--red); }
.fetch-orders-row .fo-refresh {
  flex: none; background: none; border: none; cursor: pointer; font-size: 15px; line-height: 1;
  padding: 5px; border-radius: 6px; color: var(--muted);
}
.fetch-orders-row .fo-refresh:hover { background: #F0F2F6; color: var(--text); }
.fetch-orders-row .fo-refresh:disabled { cursor: default; }
.fetch-orders-row .fo-refresh.fo-spinning { animation: fetchOrdersSpin .8s linear infinite; color: var(--text); }
@keyframes fetchOrdersSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* v1.29.1 -- checkbox row-selection column + the "N selected / select all
   matching" banner it drives (Gmail-style bulk selection), and the
   date-range preset buttons next to the existing date_from/date_to
   filter inputs. Reuses .help-box's exact look (info-blue) for the
   banner rather than inventing a new color. */
.orders-select-col { width: 28px; text-align: center; }
#ordersTable input[type="checkbox"] { width: 15px; height: 15px; cursor: pointer; vertical-align: middle; }
.selection-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: #EEF3FC;
  border: 1px solid #CBDCF5; border-radius: 7px; padding: 9px 14px; font-size: 12.5px; margin-bottom: 12px;
}
.selection-banner button {
  background: none; border: none; padding: 0; color: var(--navy); font-weight: 700; font-size: 12.5px;
  cursor: pointer; text-decoration: underline; font-family: inherit;
}
.date-presets { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.date-presets button {
  background: #ECEFF4; border: 1px solid var(--border); border-radius: 20px; padding: 4px 11px; font-size: 11.5px;
  color: var(--text); cursor: pointer; font-family: inherit; white-space: nowrap;
}
.date-presets button:hover { background: #E3E7EE; }

/* =====================================================================
   ORDER DETAIL PAGE (Shopify-style redesign) — scoped under
   .order-detail-page so only templates/sales_order_detail.html is
   affected; every other page's cards/tables/badges are untouched.
   Reference: a real Shopify order page (#VEL-1635) shared by the user --
   white cards with a soft shadow instead of a hard border, a nested
   bordered "inset box" for grouped info (fulfillment meta, line items,
   totals), and a quiet uppercase label for each card's header.
   ===================================================================== */
/* v1.29.0 opted this page into .container.wide (like the Orders list) so
   its cards aren't squeezed by the old 1180px cap on a big monitor --
   but .container.wide (static/style.css, ".container.wide") sets
   `margin: 0` (no auto-centering at all, by design -- the Orders list's
   table genuinely wants to run edge-to-edge). This page's content is
   NOT a wide data table though, so that left it flush against the left
   edge with a dead gap on the right on any screen wider than ~1400px --
   the regression the user flagged (screenshot: page shifted left,
   noticeably off-center vs. before v1.29.0). Capping and centering the
   whole page block HERE (title + breadcrumb + cards together, not just
   the card grid below) restores the original centered look while
   keeping the wider cap than the old 1180px container gave it. */
.order-detail-page { max-width: 1400px; margin: 0 auto; }

.order-detail-page .order-header {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: 20px; margin: 0 0 4px;
}
.order-detail-page .badge { padding: 3px 10px; }

.order-detail-page .order-layout {
  display: grid; grid-template-columns: 1fr 320px; gap: 18px; align-items: start;
}
.order-detail-page .order-main, .order-detail-page .order-side { min-width: 0; }
@media (max-width: 980px) {
  .order-detail-page .order-layout { grid-template-columns: 1fr; }
}

.order-detail-page .card {
  border: 1px solid #ECEDF0; border-radius: 10px; box-shadow: 0 1px 2px rgba(16,24,40,.04); padding: 20px;
}

/* Quiet, uppercase section labels instead of bold black headings --
   applies to every card's first h2 on this page without needing to
   touch each card individually in the template. */
.order-detail-page .card > h2:first-child {
  font-size: 12.5px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted);
  font-weight: 700; margin: 0 0 14px;
}

/* Nested bordered "inset box" -- groups related rows (fulfillment meta,
   line items, order totals) the way Shopify nests them inside the outer
   white card, instead of everything floating at the same level. */
.order-detail-page .inset-box {
  border: 1px solid var(--border); border-radius: 8px; padding: 4px 14px; margin-bottom: 14px;
}
.order-detail-page .inset-box:last-child { margin-bottom: 0; }

.order-detail-page .meta-list { padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }
.order-detail-page .meta-list-row { font-size: 13.5px; display: flex; align-items: center; gap: 8px; }
.order-detail-page .meta-ic { display: inline-block; width: 18px; text-align: center; flex-shrink: 0; }

/* Line items -- Shopify-style rows: a product "thumbnail" (a plain icon
   glyph, since Velets SKUs have no per-line photo on this page today),
   title/qty meta, and a right-aligned price -- with clean row dividers
   instead of table borders. */
.order-detail-page .line-items { display: flex; flex-direction: column; }
.order-detail-page .line-item {
  display: flex; align-items: flex-start; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--border);
}
.order-detail-page .line-item:last-child { border-bottom: none; }
.order-detail-page .line-item-icon {
  width: 48px; height: 48px; border-radius: 8px; background: var(--bg); border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center; font-size: 19px; flex-shrink: 0;
}
.order-detail-page .line-item-body { flex: 1; min-width: 0; }
.order-detail-page .line-item-title { font-weight: 600; font-size: 13.5px; }
.order-detail-page .line-item-sub { color: var(--muted); font-size: 12px; margin-top: 2px; }
.order-detail-page .line-item-price { text-align: right; font-size: 13.5px; font-weight: 600; white-space: nowrap; flex-shrink: 0; }

/* Order Summary sidebar card -- Subtotal/Shipping/Tax/Total inside the
   inset box (mirroring Shopify's own grouping), Paid/collected status as
   its own row below the box, same as the real reference order page. */
.order-detail-page .summary-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.order-detail-page .summary-table td { padding: 7px 0; border: none; }
.order-detail-page .summary-table tr.muted-row td { color: var(--muted); }
.order-detail-page .summary-table tr.total td { border-top: 1px solid var(--border); padding-top: 11px; font-weight: 700; font-size: 15px; }
.order-detail-page .summary-payment-status { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Gray pill tags for short categorical facts (fulfillment type, store
   location, channel, source) -- mirrors Shopify's "Fulfilled" / "Toronto
   Store" pills at the top of its fulfillment card, instead of plain
   label:value text rows for things that are really short, discrete tags. */
.order-detail-page .tag-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.order-detail-page .tag-pill {
  display: inline-flex; align-items: center; gap: 5px; background: #F0F2F6; color: var(--text);
  border-radius: 20px; padding: 5px 12px; font-size: 12.5px; font-weight: 600; line-height: 1.3;
}

/* A card's own inline header row (title + a small action button on the
   right) -- used by the Notes and Customer cards' edit/"..." controls. */
.order-detail-page .card-head-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.order-detail-page .icon-btn {
  background: none; border: 1px solid var(--border); border-radius: 6px; width: 28px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; font-size: 13px;
  color: var(--muted); padding: 0;
}
.order-detail-page .icon-btn:hover { background: #F0F2F6; color: var(--text); }

/* Customer card "..." menu -- two actions: edit the real customer record
   (customers.edit permission) vs. the existing "change customer for just
   this order" flow (kept as-is, unchanged behavior). */
.order-detail-page .menu-wrap { position: relative; }
.order-detail-page .dropdown-menu {
  display: none; position: absolute; right: 0; top: calc(100% + 4px); background: var(--card);
  border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 6px 18px rgba(0,0,0,.14);
  min-width: 175px; z-index: 20; overflow: hidden;
}
.order-detail-page .dropdown-menu.shown { display: block; }
.order-detail-page .dropdown-menu a, .order-detail-page .dropdown-menu button {
  display: block; width: 100%; text-align: left; padding: 9px 12px; font-size: 13px; background: none;
  border: none; color: var(--text); cursor: pointer; font-family: inherit;
}
.order-detail-page .dropdown-menu a:hover, .order-detail-page .dropdown-menu button:hover {
  background: #F0F2F6; text-decoration: none;
}
/* v1.30.0 -- "Send Invoice" menu's Email/WhatsApp items disable individually
   (whichever contact info is missing on the customer), same reasoning the
   single-button version already used for a missing email. */
.order-detail-page .dropdown-menu button:disabled {
  color: var(--muted); cursor: not-allowed;
}
.order-detail-page .dropdown-menu button:disabled:hover { background: none; }

/* Customer card sub-sections (Contact information / Shipping address) --
   a quiet bold label above the block, same grouping Shopify's own
   Customer card uses. */
.order-detail-page .side-section { padding-top: 12px; margin-top: 12px; border-top: 1px solid var(--border); }
.order-detail-page .side-section:first-of-type { padding-top: 0; margin-top: 10px; border-top: none; }
.order-detail-page .side-section-label { font-size: 11.5px; font-weight: 700; color: var(--muted); margin-bottom: 6px; }

/* ==========================================================================
   Ship-shipment modal (v1.18.0) -- the "Create Shipment / Browse Rates /
   Create Label" flow used to be a page navigation (create-shipment inline
   box -> a separate /browse-rates page -> back to the order). Replaced
   with a single large in-page modal, styled after the customer's
   ShipStation reference (dark floating rate/action card, 416px config
   sidebar, system font scale) but built in plain CSS/JS -- no framework
   in this app, so the modal's HTML is server-rendered (a Jinja partial,
   see _shipment_modal.html) and swapped in via fetch(), same "progressive
   enhancement over a normal form" pattern the rest of this app already
   uses (typeahead-selected boxes, dropdown-menu, etc). Every action
   inside still posts to the exact same routes as before -- only the
   response rendering branches on an X-Requested-With: fetch header. */
.ss-modal-backdrop {
  display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 200;
  align-items: center; justify-content: center;
}
.ss-modal-backdrop.shown { display: flex; }
.ss-modal-panel {
  width: 90vw; height: 90vh; max-width: 1400px; background: #F9FAFB; border-radius: 10px;
  box-shadow: 0 20px 60px rgba(0,0,0,.35); display: flex; flex-direction: column; overflow: hidden;
}
.ss-modal-header {
  display: flex; align-items: center; justify-content: space-between; padding: 14px 20px;
  background: #fff; border-bottom: 1px solid #CBD5DE; flex: 0 0 auto;
}
.ss-modal-header-title { font-size: 15px; font-weight: 600; color: var(--text); }
.ss-modal-header-sub { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.ss-modal-close {
  background: none; border: none; font-size: 20px; line-height: 1; cursor: pointer; color: var(--muted);
  padding: 4px 8px; border-radius: 4px;
}
.ss-modal-close:hover { background: #F0F2F6; color: var(--text); }
.ss-modal-body { flex: 1 1 auto; overflow: hidden; position: relative; }
.ss-modal-loading { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--muted); font-size: 13px; }

/* Inner layout rendered by _shipment_modal.html: grid main (flex) + a
   fixed 416px "Configure Shipment" sidebar, matching ShipStation's own
   grid-template-columns: 1fr 416px. */
.ss-grid { display: grid; grid-template-columns: 1fr 416px; height: 100%; }
.ss-main { overflow-y: auto; padding: 20px; }
.ss-side { overflow-y: auto; border-left: 1px solid #CBD5DE; background: #fff; display: flex; flex-direction: column; }
.ss-side-scroll { flex: 1 1 auto; overflow-y: auto; padding: 16px; }

.ss-banner { margin: 0 0 14px; padding: 10px 14px; border-radius: 6px; font-size: 12.5px; }
.ss-banner.success { background: var(--green-bg); color: var(--green); border: 1px solid #BFE3C8; }
.ss-banner.error { background: var(--red-bg); color: var(--red); border: 1px solid #F0C4BE; }

.ss-card { background: #fff; border: 1px solid #CBD5DE; border-radius: 8px; padding: 16px; margin-bottom: 14px; }
.ss-card h4 { margin: 0 0 12px; font-size: 1rem; font-weight: 500; color: var(--text); }
.ss-label { font-size: .875rem; font-weight: 500; color: var(--text); }
.ss-body-text { font-size: .875rem; color: var(--text); }
.ss-caption { font-size: .75rem; color: var(--muted); }
.ss-pill {
  display: inline-flex; align-items: center; gap: 5px; background: #F1F3F5; border: 1px solid #D6E1E9;
  border-radius: 20px; padding: 3px 10px; font-size: .75rem; color: #48525C; font-weight: 500;
}
.ss-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: #48525C; }
.ss-divider { height: 1px; background: #E1E6EA; margin: 10px 0; }

.ss-cost-row { display: flex; justify-content: space-between; font-size: .875rem; padding: 4px 0; }
.ss-cost-row.total { font-weight: 700; border-top: 1px solid #E1E6EA; margin-top: 6px; padding-top: 8px; }

.ss-item-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-top: 1px solid #F0F2F4; }
.ss-item-row:first-child { border-top: none; }
.ss-item-icon {
  width: 40px; height: 40px; border-radius: 6px; background: #F4F1EC; display: flex; align-items: center;
  justify-content: center; font-size: 18px; flex: 0 0 auto;
}

.ss-field { margin-bottom: 12px; }
.ss-field label { display: block; font-size: .875rem; font-weight: 500; margin-bottom: 4px; color: var(--text); }
.ss-field select, .ss-field input {
  width: 100%; padding: 7px 9px; border: 1px solid #AFB3B6; border-radius: 4px; font-size: 13.5px; font-family: inherit;
}

.ss-rate-list { margin-top: 4px; }
.ss-rate-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px;
  border: 1px solid #CBD5DE; border-radius: 6px; margin-bottom: 8px; background: #fff;
}
.ss-rate-row.current { border-color: #0D6E3F; background: #F1FAF4; }
.ss-rate-row .name { font-size: 13.5px; font-weight: 500; }
.ss-rate-row .transit { font-size: 11.5px; color: var(--muted); }
.ss-rate-row .price { font-size: 14px; font-weight: 600; white-space: nowrap; }

/* The floating rate/action card -- the single most distinctive element of
   the reference: sticky to the bottom of the sidebar's own scroll
   container (not the viewport), dark navy, rounded top corners only. */
.ss-rate-card {
  position: sticky; bottom: 0; background: #212C36; color: #fff; padding: 16px; border-radius: 16px 16px 0 0;
  box-shadow: 0 -4px 12px rgba(0,0,0,.25); flex: 0 0 auto;
}
.ss-rate-card .warn {
  display: flex; gap: 8px; align-items: flex-start; font-size: 11.5px; color: #F5D7A8; margin-bottom: 10px;
}
.ss-rate-card .price-row { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.ss-rate-card .price { font-size: 1.5rem; font-weight: 400; }
.ss-rate-card .service-name { font-size: .875rem; color: #B2E0FA; margin-bottom: 10px; }
.ss-rate-card .divider { height: 1px; background: #48525C; margin: 12px 0; }
.ss-rate-card .caption { font-size: .75rem; color: #AEB7BF; }
.ss-btn-primary {
  display: block; width: 100%; text-align: center; height: 36px; line-height: 36px; border-radius: 4px;
  background: #0D6E3F; color: #fff; border: none; font-size: 14px; font-weight: 500; cursor: pointer;
}
.ss-btn-primary:hover { background: #0A5A33; }
.ss-btn-primary:disabled { opacity: .6; cursor: default; }
.ss-btn-ghost-dark {
  display: block; width: 100%; text-align: center; height: 34px; line-height: 34px; border-radius: 4px;
  background: transparent; color: #fff; border: 1px solid #48525C; font-size: 13.5px; cursor: pointer; margin-top: 8px;
}
.ss-btn-ghost-dark:hover { background: rgba(255,255,255,.06); }

@media (max-width: 900px) {
  .ss-modal-panel { width: 98vw; height: 96vh; }
  .ss-grid { grid-template-columns: 1fr; }
  .ss-side { border-left: none; border-top: 1px solid #CBD5DE; }
}

@media (max-width: 700px) {
  .order-detail-page .order-header { font-size: 17px; }
  .order-detail-page .card { padding: 16px; }
}

/* ==========================================================================
   Setup > Themes — palette overrides
   ==========================================================================
   Everything below re-points the app's color tokens per active theme,
   selected on html[data-theme] (set in base.html from app.py's
   inject_active_theme() context processor). This is deliberately kept as
   pure attribute-selector overrides rather than editing the base rules
   in place, for one reason: an attribute+class selector like
   `html[data-theme="slate_lime"] .dash-home` is *always* higher specificity
   than the plain `.dash-home` / `:root` / `.login-v2` rules those variables
   are first declared on (attribute selector + type selector beats a bare
   class or :root every time, regardless of which rule appears later in the
   cascade) -- so these overrides work correctly no matter where this block
   sits in the file, and dashboard.html / login.html never needed their own
   per-theme edits at all. Only the logo mark and wordmark font (which need
   an <img> swap / a CSS class, not just a color) are handled with small
   conditionals in base.html and login.html themselves -- see
   `active_theme.logo` / `.lora-wordmark` below.

   No rule exists for the "default" theme: html[data-theme="default"] simply
   never matches these selectors, so the plain :root / .dash-home / .login-v2
   values already in this file (the app's original palette) keep applying
   unchanged -- that's what makes "default" a real, always-available theme
   without a single line of override CSS. */

/* ---- Slate & Lime ---- */
html[data-theme="slate_lime"] {
  --navy: #1F2937;
  --navy-light: #65A30D;
  --brand-hero-a: #111827;
  --brand-hero-b: #3F6212;
  --brand-hero-c: #0B0F17;
}
html[data-theme="slate_lime"] .dash-home {
  --dh-accent: #65A30D;
  --dh-accent-soft: #ECFCCB;
}
html[data-theme="slate_lime"] .login-v2 {
  --grad-1: #111827; --grad-2: #365314; --grad-3: #A3E635;
  --accent: #65A30D; --accent-2: #3F6212; --accent-soft: #ECFCCB;
}
html[data-theme="slate_lime"] .login-v2 .blob.b1 { background: #A3E635; }
html[data-theme="slate_lime"] .login-v2 .blob.b2 { background: #65A30D; }
html[data-theme="slate_lime"] .login-v2 .blob.b3 { background: #D9F99D; }

/* ---- Executive Mono ---- */
html[data-theme="executive_mono"] {
  --navy: #18181B;
  --navy-light: #52525B;
  --brand-hero-a: #0B0B0D;
  --brand-hero-b: #3F3F46;
  --brand-hero-c: #000000;
}
html[data-theme="executive_mono"] .dash-home {
  --dh-accent: #3F3F46;
  --dh-accent-soft: #F4F4F5;
}
html[data-theme="executive_mono"] .login-v2 {
  --grad-1: #0B0B0D; --grad-2: #27272A; --grad-3: #71717A;
  --accent: #3F3F46; --accent-2: #18181B; --accent-soft: #F4F4F5;
}
html[data-theme="executive_mono"] .login-v2 .blob.b1 { background: #A1A1AA; }
html[data-theme="executive_mono"] .login-v2 .blob.b2 { background: #D4D4D8; }
html[data-theme="executive_mono"] .login-v2 .blob.b3 { background: #71717A; }

/* ---- Logo mark + wordmark font, shared by every theme that sets them ---- */
.brand-mark.has-logo { padding: 3px; }
.brand-mark.has-logo img { width: 100%; height: 100%; object-fit: contain; }
.lora-wordmark {
  font-family: 'Lora', Georgia, 'Times New Roman', serif;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}

/* ==========================================================================
   Small ambient loading animation (v1.23.0)
   ==========================================================================
   A compact, never-full-page version of the brand's "orbit" loading
   animation (see the loading-animations/ brand kit) -- three small dots
   orbiting a softly-pulsing brand mark. Built entirely from CSS variables
   that already flip per active theme (--navy / --navy-light, set at :root
   and overridden per html[data-theme="..."] above), so this one block of
   markup automatically matches whichever theme is active without any
   theme-specific CSS of its own -- only the center mark's content (brain
   logo image vs. plain "V") is chosen in JS, from
   window.veletsLoaderHTML() in base.html, mirroring the exact same
   .brand-mark / .brand-mark.has-logo pattern the sidebar logo already
   uses. Markup shape (matches veletsLoaderHTML()'s output exactly):
     .vlt-loader > .vlt-loader-stage > .vlt-loader-orbit > i, i, i
                                       > .vlt-loader-mark
                 > .vlt-loader-caption (optional) */
.vlt-loader { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; }
.vlt-loader-stage { position: relative; width: 34px; height: 34px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.vlt-loader-orbit { position: absolute; inset: 0; animation: vltSpin 1.6s linear infinite; }
.vlt-loader-orbit i { position: absolute; border-radius: 50%; display: block; }
.vlt-loader-orbit i:nth-child(1) { top: 0; left: 50%; width: 6px; height: 6px; margin-left: -3px; background: var(--navy-light); }
.vlt-loader-orbit i:nth-child(2) { bottom: 12%; left: 9%; width: 5px; height: 5px; background: var(--navy); }
.vlt-loader-orbit i:nth-child(3) { bottom: 12%; right: 9%; width: 4px; height: 4px; background: var(--navy-light); opacity: .75; }
@keyframes vltSpin { to { transform: rotate(360deg); } }
.vlt-loader-mark {
  width: 17px; height: 17px; border-radius: 5px; background: var(--brand-hero-a); color: #fff;
  display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 8px;
  animation: vltPulse 2s ease-in-out infinite;
}
.vlt-loader-mark.has-logo { background: transparent; padding: 1px; }
.vlt-loader-mark.has-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
@keyframes vltPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.14); } }
.vlt-loader-caption { font-size: 11px; color: var(--muted); font-weight: 600; white-space: nowrap; }

/* .small modifier -- used for the fixed nav pill and any other tight inline spot */
.vlt-loader.small .vlt-loader-stage { width: 22px; height: 22px; }
.vlt-loader.small .vlt-loader-mark { width: 11px; height: 11px; border-radius: 3px; font-size: 6px; }
.vlt-loader.small .vlt-loader-orbit i:nth-child(1) { width: 4px; height: 4px; margin-left: -2px; }
.vlt-loader.small .vlt-loader-orbit i:nth-child(2) { width: 3px; height: 3px; }
.vlt-loader.small .vlt-loader-orbit i:nth-child(3) { width: 3px; height: 3px; }
.vlt-loader.small .vlt-loader-caption { font-size: 10.5px; }

/* Fixed ambient pill shown during ordinary page-to-page navigation --
   bottom-right, small, never blocks the page underneath (pointer-events
   stay off even while shown, since it's purely informational). */
.vlt-nav-loader {
  position: fixed; right: 18px; bottom: 18px; z-index: 9999;
  background: var(--card); border: 1px solid var(--border); border-radius: 999px;
  padding: 7px 14px 7px 10px; box-shadow: 0 8px 24px rgba(20, 20, 30, .16);
  display: flex; align-items: center; opacity: 0; transform: translateY(8px);
  pointer-events: none; transition: opacity .18s ease, transform .18s ease;
}
.vlt-nav-loader.shown { opacity: 1; transform: translateY(0); }
@media (max-width: 700px) {
  .vlt-nav-loader { right: 12px; bottom: 78px; } /* clears the mobile bottom nav bar */
}

/* ---------------- Reorder Calculator upgrade (v1.25.0) ---------------- */

/* 5-band inventory color zone badge. Deliberately reuses the app's
   existing --red/--green/--yellow tokens for the Red/Green/Yellow zones
   (the exact same colors already used for the "REORDER NOW"/"OK" flag
   badge elsewhere, and the Operations dashboard's health-bucket dots) so
   this doesn't introduce a competing color language -- only the two
   extremes (No Stock, Overstock) get a bolder solid treatment, matching
   how the reference funnel diagram bookends the lighter middle bands with
   solid dark banners top and bottom. */
.zone-badge {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px 3px 8px;
  border-radius: 20px; font-size: 11px; font-weight: 700; letter-spacing: .2px; white-space: nowrap;
}
.zone-badge .zone-icon { font-size: 11px; line-height: 1; }
.zone-badge.zone-nostock { background: #7A1F1F; color: #fff; }
.zone-badge.zone-red { background: var(--red-bg); color: var(--red); }
.zone-badge.zone-yellow { background: var(--yellow-bg); color: #8A6D1D; border: 1px solid var(--yellow-border); }
.zone-badge.zone-green { background: var(--green-bg); color: var(--green); }
.zone-badge.zone-overstock { background: var(--green); color: #fff; }

/* ABC (Pareto, by 6-month revenue) classification -- a small badge next to
   the SKU code, not a whole column, since it's context for the row rather
   than something you'd filter a whole column on. */
.abc-badge {
  display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px;
  border-radius: 4px; font-size: 10px; font-weight: 800; margin-left: 6px; vertical-align: middle;
}
.abc-badge.abc-a { background: #E6F4EC; color: var(--green); }
.abc-badge.abc-b { background: #FFF6D9; color: #8A6D1D; }
.abc-badge.abc-c { background: #ECECEC; color: #6b6b66; }

/* Trend arrow (recent 3 of the last 6 completed months vs. the earlier 3). */
.trend-badge { font-size: 12px; font-weight: 700; white-space: nowrap; }
.trend-badge.trend-up { color: var(--status-good); }
.trend-badge.trend-down { color: var(--status-critical); }
.trend-badge.trend-flat { color: var(--muted); }

/* Item thumbnail column -- same .product-thumb sizing as the Products
   page, just referenced from a different table. */
.reorder-page .table-scroll table { font-size: 12.5px; }
.reorder-page .table-scroll th { white-space: nowrap; }

/* Sales-graph trigger button -- a plain small icon button sitting inline
   in a table cell, not a full .btn (those are sized for standalone
   actions, too heavy for a dense table row). */
.chart-trigger {
  border: 1px solid var(--border); background: #fff; color: var(--muted); cursor: pointer;
  border-radius: 6px; padding: 4px 6px; display: inline-flex; align-items: center; justify-content: center;
  line-height: 0;
}
.chart-trigger svg { width: 15px; height: 15px; }
.chart-trigger:hover { background: #F0F2F6; color: var(--text); }

/* Toolbar above the table: search box + result count + CSV export,
   consistent with the filters form's spacing above it. */
.reorder-toolbar {
  display: flex; align-items: center; gap: 12px; margin-bottom: 12px; flex-wrap: wrap;
}
.reorder-toolbar input[type="search"] { max-width: 280px; margin-bottom: 0; }
.reorder-toolbar .muted { font-size: 12px; }

/* Sortable column headers -- a plain button-look span, not a real <button>
   (keeps the existing <th> text flow/alignment identical to the
   non-sortable headers around it). */
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--text); }
th.sortable .sort-arrow { font-size: 9px; opacity: .5; margin-left: 3px; }
th.sortable.sort-active .sort-arrow { opacity: 1; }

/* Per-row sales-history graph modal -- same backdrop/panel visual
   language as the shipment workspace's ss-modal-*, deliberately under a
   separate rc- (Reorder Calculator) namespace so its JS/CSS never
   collides with the shipment modal's own, but sized for a single chart
   rather than a full workspace. */
.rc-modal-backdrop {
  display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 200;
  align-items: center; justify-content: center;
}
.rc-modal-backdrop.shown { display: flex; }
.rc-modal-panel {
  width: 92vw; max-width: 720px; background: #fff; border-radius: 10px;
  box-shadow: 0 20px 60px rgba(0,0,0,.35); display: flex; flex-direction: column; overflow: hidden;
}
.rc-modal-header {
  display: flex; align-items: center; justify-content: space-between; padding: 14px 20px;
  border-bottom: 1px solid var(--border); flex: 0 0 auto;
}
.rc-modal-header-title { font-size: 15px; font-weight: 600; color: var(--text); }
.rc-modal-header-sub { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.rc-modal-close {
  background: none; border: none; font-size: 20px; line-height: 1; cursor: pointer; color: var(--muted);
  padding: 4px 8px; border-radius: 4px;
}
.rc-modal-close:hover { background: #F0F2F6; color: var(--text); }
.rc-modal-body { padding: 18px 20px 22px; min-height: 260px; position: relative; }
.rc-modal-loading { display: flex; align-items: center; justify-content: center; height: 260px; color: var(--muted); font-size: 13px; }
@media (max-width: 700px) {
  .rc-modal-panel { width: 96vw; }
}

/* =====================================================================
   PO DETAIL — BENTO LAYOUT (v1.43.0)
   Scoped to templates/po_detail.html only (per the redesign mockup's
   "Direction 4 — Bento grid dashboard"). Reuses the app's existing
   tokens (--navy/--navy-light/--green/--border/--muted/--card) rather
   than introducing a new palette -- this is a layout change, not a
   re-theme, so it stays consistent with whatever theme is active via
   Setup > Themes. All classes are prefixed `po-` to avoid collisions.
   ===================================================================== */

/* v1.43.2: this page opted into .container.wide (base.html's
   {% block containerclass %}) so the Bento grid isn't capped at the old
   1180px on a wide monitor -- but .container.wide sets `margin: 0` with
   no auto-centering (by design, for pages like the Orders list whose
   table genuinely wants to run edge-to-edge). This page's content is a
   card grid, not a wide table, so that left it flush against the left
   edge with a dead gray gap on the right on any screen wider than
   ~1400px -- exactly the "tiles look like they moved / the layout
   changed" complaint the user flagged with screenshots, and the same
   regression already solved once before for the Order Detail page (see
   ".order-detail-page" below). Same fix here: cap-and-center the whole
   page block at a wider-than-1180px value so the grid's own 12-column
   math (which already sums correctly at every tile) is what determines
   tile shape/position at every desktop width from ~1400px up to the
   largest monitor, instead of the browser's raw viewport width. Tablet
   and mobile are untouched -- the max-width simply never binds below
   1400px, so nothing here affects the existing 1024px/700px breakpoints. */
.po-detail-page { max-width: 1400px; margin: 0 auto; }

/* ---- Header: back link, title+badge, key-fact chips, actions ---- */
.po-header { margin-bottom: 20px; }
.po-header-back { color: var(--muted); font-size: 12.5px; text-decoration: none; display: inline-block; margin-bottom: 6px; }
.po-header-back:hover { text-decoration: underline; }
.po-header-titlerow { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 4px 0 14px; }
.po-header-titlerow h1 { margin: 0; }
/* v1.43.3: the plain-language status summary (po_summary.py) used to be its
   own grid tile ("Summary"), but the approved Bento mockup's Approvals /
   Supplier stock check / Vessel Tracking row never had a 4th box for it --
   adding one back to match the mockup exactly would either break that
   row's 5+4+3=12 math again or force yet another special-cased span. It
   reads naturally as a one-line subtitle under the plan number instead. */
.po-header-summary { margin: -8px 0 14px; font-size: 13.5px; color: var(--muted); }
.po-chips { display: flex; gap: 26px; flex-wrap: wrap; margin-bottom: 16px; }
.po-chip { display: flex; flex-direction: column; gap: 2px; }
.po-chip .k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); font-weight: 700; }
.po-chip .v { font-size: 14px; font-weight: 700; color: var(--text); }
.po-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 6px; }
.po-actions form { display: inline-flex; margin: 0; }
.po-actions .muted-note { width: 100%; margin: 2px 0 0; font-size: 11.5px; }
.po-cancel-box { margin-top: 14px; }

/* ---- Segmented status bar (accordion-style progress strip) ---- */
.po-segwrap { margin: 4px 0 22px; }
.po-segbar { display: flex; gap: 4px; margin-bottom: 6px; }
.po-seg { flex: 1; height: 7px; border-radius: 4px; background: var(--border); }
.po-seg.done { background: var(--green); }
.po-seg.current { background: var(--navy); }
.po-seglabels { display: flex; justify-content: space-between; font-size: 10.5px; color: var(--muted); font-weight: 600; }
.po-seglabels .on { color: var(--navy); }

/* ---- KPI tile row (5 tiles) ---- */
.po-kpis { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; margin-bottom: 20px; }
.po-kpi { background: var(--card); border: 1px solid var(--border); border-left: 4px solid var(--border); border-radius: 8px; padding: 12px 14px; min-width: 0; }
.po-kpi.accent { border-left-color: var(--navy-light); }
.po-kpi .k { font-size: 10.5px; text-transform: uppercase; color: var(--muted); letter-spacing: .4px; font-weight: 700; }
.po-kpi .v { font-size: 19px; font-weight: 800; margin-top: 4px; }
.po-kpi.accent .v { color: var(--navy); }
.po-kpi .s { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

/* ---- Bento grid of cards ---- */
.po-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 16px; }
.po-tile { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 16px 18px; display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.po-tile .hd { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
.po-tile .hd h3 { margin: 0; font-size: 13.5px; display: flex; align-items: center; gap: 8px; }
.po-tile .hd .tag { font-size: 10.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; font-weight: 700; background: #F0F2F6; padding: 2px 8px; border-radius: 10px; }
.po-icwrap { width: 24px; height: 24px; border-radius: 6px; background: #EEF0FB; color: var(--navy); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.po-icwrap svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* v1.43.4: .table-scroll's overflow-x:auto only ever kicked in below the
   app's 700px mobile breakpoint (see that media query further down) --
   fine everywhere else in the app, where a table always lived in a
   full-width card. Now that Bento tiles can be as narrow as po-span-4
   (~1/3 of the grid), a wide table (e.g. Supplier stock check's 6
   columns) no longer fits and was spilling out past the card's border on
   desktop instead of scrolling inside it. Scope the always-on scroll
   fix to just these tiles rather than changing the shared .table-scroll
   rule everywhere. */
.po-tile .table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* v1.43.5: v1.43.4's color pass only did a 2-variable --navy/--navy-light
   swap, which was an approximation, not the mockup's actual palette --
   the mockup uses THREE distinct tones depending on context (a vivid
   lime for "done"/primary-action surfaces, a near-black slate for
   "current"/active indicators, and a dark olive-lime for icon glyphs
   and small text), not one accent color standing in for everything.
   It also treats "approved" as part of the same lime family rather than
   a separate green, and uses an OUTLINE style (not filled) for danger
   buttons. Replaced the variable-swap approach with explicit per-element
   overrides straight from the mockup's own CSS values, scoped to
   .po-detail-page only -- every other page's navy/green/red are
   completely untouched. */
.po-detail-page .po-icwrap { background: #ecfccb; color: #3f6212; }

.po-detail-page .btn:not(.secondary):not(.green):not(.danger) { background: #84cc16; border-color: #65a30d; color: #0f172a; }
.po-detail-page .btn:not(.secondary):not(.green):not(.danger):hover { background: #a3e635; }
.po-detail-page .btn.green { background: #4d7c0f; border-color: #4d7c0f; color: #fff; }
.po-detail-page .btn.green:hover { background: #3f6212; }
.po-detail-page .btn.danger { background: #fff; color: #C0392B; border-color: #FBEAE8; font-weight: 600; }
.po-detail-page .btn.danger:hover { background: #FBEAE8; }

.po-detail-page .po-seg.done { background: #84cc16; }
.po-detail-page .po-seg.current { background: #0f172a; }
.po-detail-page .po-seglabels .on { color: #3f6212; }

.po-detail-page .po-tstep.done::before { background: #84cc16; }
.po-detail-page .po-tdot { background: #84cc16; border-color: #65a30d; }
.po-detail-page .po-tstep.current .po-tdot { background: #0f172a; border-color: #0f172a; box-shadow: 0 0 0 4px #ecfccb; }

.po-detail-page .po-approvalpill { background: #f7fee7; border-color: #d9f99d; color: #3f6212; }
.po-detail-page .badge.approved { background: #ecfccb; color: #3f6212; }

.po-detail-page .po-kpi.accent { border-left-color: #84cc16; }
.po-detail-page .po-kpi.accent .v { color: #3f6212; }

.po-detail-page .po-progress > div { background: #84cc16; }
.po-detail-page .po-hist-item::before { background: #84cc16; }

/* The mockup gives exactly one tile -- Plan status -- a highlighted
   border+glow treatment (its ".accent" tile modifier) to draw the eye to
   the primary status indicator. No other tile gets it. */
.po-detail-page .po-tile.accent { border-color: #bef264; box-shadow: 0 0 0 1px #d9f99d inset; }
.po-span-3 { grid-column: span 3; } .po-span-4 { grid-column: span 4; } .po-span-5 { grid-column: span 5; }
.po-span-6 { grid-column: span 6; } .po-span-7 { grid-column: span 7; } .po-span-8 { grid-column: span 8; }
.po-span-12 { grid-column: span 12; }
.po-kpis > *, .po-grid > * { min-width: 0; }

/* ---- 6-step "Plan status" tracker (lives inside a po-tile) ---- */
.po-tracker { display: flex; flex-direction: column; gap: 0; }
.po-tstep { display: flex; gap: 10px; position: relative; padding-bottom: 18px; }
.po-tstep::before { content: ""; position: absolute; left: 8px; top: 20px; bottom: 0; width: 2px; background: var(--border); }
.po-tstep:last-child { padding-bottom: 0; }
.po-tstep:last-child::before { display: none; }
.po-tstep.done::before { background: var(--green); }
.po-tdot { width: 18px; height: 18px; border-radius: 50%; background: var(--green); border: 2px solid var(--green); flex-shrink: 0; margin-top: 1px; }
.po-tstep.current .po-tdot { background: var(--navy); border-color: var(--navy); box-shadow: 0 0 0 4px rgba(106, 83, 240, .15); }
.po-tstep.todo .po-tdot { background: #fff; border-color: var(--border); }
.po-tstep .lab { font-size: 12.5px; font-weight: 700; }
.po-tstep.todo .lab { color: var(--muted); font-weight: 600; }

/* ---- Approvals pills ---- */
.po-approvalrow { display: flex; gap: 10px; flex-wrap: wrap; }
.po-approvalpill { display: flex; align-items: center; gap: 7px; background: var(--green-bg); border: 1px solid #BFE6CE; color: var(--green); padding: 6px 12px; border-radius: 20px; font-size: 12.5px; font-weight: 700; }
.po-approvalpill.pending { background: #ECECEC; color: #555; border-color: var(--border); }
.po-approvalpill.needs_revision { background: var(--red-bg); color: var(--red); border-color: #F0C4BE; }

/* ---- Volume/capacity progress bar (KPI + Items tile) ---- */
.po-progress { height: 8px; border-radius: 4px; background: #ECEFF4; overflow: hidden; margin: 8px 0; }
.po-progress > div { height: 100%; background: var(--navy-light); }
.po-progress.over > div { background: var(--red); }

/* ---- History: vertical top-to-bottom timeline (was a flat stack of cards) ---- */
.po-histline { border-left: 2px solid var(--border); padding-left: 16px; display: flex; flex-direction: column; gap: 14px; }
.po-hist-item { position: relative; font-size: 13px; }
.po-hist-item::before { content: ""; position: absolute; left: -21px; top: 4px; width: 9px; height: 9px; border-radius: 50%; background: var(--navy-light); }
.po-hist-item .t { font-size: 11.5px; color: var(--muted); }

/* Below ~1024px, a partial rebalance of individual tile spans (e.g.
   span-4 -> span-6) tends to pair up tiles that were never meant to sit
   together (see the bug report: "Plan status" and "Items" -- a 4+8=12
   pair designed to sit side by side on desktop -- split apart with a
   big dead gap once an in-between breakpoint changed their spans
   independently). Simplest robust fix: below this width, every tile
   just goes full-width and stacks in DOM order -- no partial-credit
   in-between state to get wrong. This is scoped to .po-grid/.po-kpis
   only (via the `po-` prefix), not the app's shared 700px mobile
   breakpoint below, so it doesn't touch any other page. */
@media (max-width: 1024px) {
  .po-kpis { grid-template-columns: repeat(2, 1fr); }
  .po-grid { grid-template-columns: 1fr; }
  .po-span-3, .po-span-4, .po-span-5, .po-span-6, .po-span-7, .po-span-8, .po-span-12 { grid-column: 1 / -1; }
}

@media (max-width: 700px) {
  .po-kpis { grid-template-columns: repeat(2, 150px); overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 8px; scroll-snap-type: x proximity; }
  .po-kpi { scroll-snap-align: start; }
  .po-chips { flex-direction: column; gap: 10px; }
  .po-actions { flex-direction: column; align-items: stretch; }
  .po-actions .btn, .po-actions a.btn { width: 100%; text-align: center; }
  .po-seglabels { font-size: 9px; }
  .po-seglabels span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 1px; }
}
