/* Reset and Base Styles */

:root {
  /* The fixed navbar's height. Anything sticky under it docks at exactly
   * this, so no band of page content can scroll through the gap between the
   * two. sticky-nav.js overwrites it with the measured height as soon as the
   * page is on screen - the navbar grows by 9px when Inter loads - so this
   * value only covers the frames before that. */
  --navbar-h: 66px;

  /* ---------------------------------------------------------------------
   * Palette. The app used to paint a purple gradient across the whole body
   * and float white cards on it, which meant every piece of text outside a
   * card had to be white and no two surfaces could sit next to each other
   * without one of them glowing. This is the opposite arrangement: one quiet
   * neutral canvas, white surfaces separated by a hairline border rather than
   * by a drop shadow, and the accent reserved for things you can act on.
   *
   * Anything added here should keep that rule - if a new colour is not
   * carrying meaning (state, action, warning), it belongs in the neutrals.
   * ------------------------------------------------------------------- */

  --canvas: #f2f3f5;
  --surface: #ffffff;
  --surface-sunken: #f7f8f9;
  --surface-hover: #eff1f4;
  --border: #e3e5e9;
  --border-strong: #d1d5dc;

  --text: #12161f;
  --text-muted: #5b6472;
  /* 4.5:1 on white, on --surface-sunken and on --canvas. The obvious lighter
   * grey for a small-caps table header failed all three, and these are the
   * labels on every column of every table in the app. */
  --text-faint: #646f85;

  /* Green is the action colour, and the only place it appears is on something
   * you can do: the primary button, the selected row in the rail, a link.
   * --accent is the fill (white on it clears 4.8:1); --accent-strong is both
   * the hover fill and the shade green takes when it has to be *text* on a
   * light background, where the fill shade only reaches 3.9:1. */
  --accent: #25805a;
  --accent-2: #2b8a5f;
  --accent-strong: #1b6b47;
  --accent-soft: #eaf5ef;
  --accent-border: #b9dfcb;

  /* The chrome. Navbar and side rail are one dark surface wrapping a light
   * page: navigation drops back and the white data panels are the only lit
   * thing on screen. Their neutrals are separate tokens from the page's -
   * they answer to a dark background, so they cannot share a scale with the
   * text that sits on white. */
  --rail: #151b24;
  --rail-border: #232b38;
  --rail-text: #c8cfd9;
  --rail-faint: #8b97a8;
  --rail-hover: rgba(255, 255, 255, 0.07);

  --ok: #15803d;
  --ok-soft: #ecfdf3;
  --warn: #b45309;
  --warn-soft: #fffaeb;
  --danger: #b42318;
  --danger-soft: #fef3f2;

  /* Three depths, and only three. A dashboard reads as one plane with things
   * resting on it; a card that lifts 12px off the page competes with the data
   * printed inside it. */
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.04);
  --shadow-md: 0 1px 3px rgba(16, 24, 40, 0.07), 0 1px 2px rgba(16, 24, 40, 0.04);
  --shadow-lg: 0 4px 12px rgba(16, 24, 40, 0.08), 0 2px 4px rgba(16, 24, 40, 0.04);

  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 12px;

  /* Sticky bars are opaque surfaces, same as everything else now - the old
   * value was an opaque purple because it had to hide the gradient scrolling
   * underneath it. It no longer has anything to hide, so it matches the
   * cards and marks itself with a border instead. */
  --sticky-bar-bg: var(--surface);
  --sticky-bar-border: var(--border);
}


* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Print Styles */
@media print {
  @page {
    margin: 0.5in;
    size: A4;
  }

  body {
    background: white !important;
    color: black !important;
    font-family: Arial, sans-serif !important;
    font-size: 12pt !important;
    line-height: 1.4 !important;
    margin: 0 !important;
    padding: 0 !important;
  }

  body.printing {
    overflow: visible !important;
  }

  body.printing * {
    visibility: hidden !important;
  }

  body.printing .print-content,
  body.printing .print-content * {
    visibility: visible !important;
  }

  .print-content {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    width: 100% !important;
    background: white !important;
    padding: 0 !important;
    margin: 0 !important;
  }

  .print-header {
    text-align: center;
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 2px solid #333;
  }

  .print-header h1 {
    font-size: 18pt !important;
    font-weight: bold !important;
    margin: 0 0 5px 0 !important;
    color: black !important;
  }

  .print-section {
    margin-bottom: 20px !important;
    page-break-inside: avoid;
  }

  .print-section h2 {
    font-size: 14pt !important;
    font-weight: bold !important;
    margin-bottom: 10px !important;
    color: black !important;
    border-bottom: 1px solid #666;
    padding-bottom: 5px;
  }

  .print-grid {
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    gap: 10px !important;
    margin-bottom: 15px !important;
  }

  .print-item {
    display: flex !important;
    justify-content: space-between !important;
    padding: 3px 0 !important;
    border-bottom: 1px dotted #ccc;
  }

  .print-item .label {
    font-weight: bold !important;
    color: black !important;
  }

  .print-item .value {
    color: black !important;
  }

  .print-items-list {
    margin-top: 10px !important;
  }

  .print-order-item {
    display: flex !important;
    justify-content: space-between !important;
    padding: 5px 0 !important;
    border-bottom: 1px solid #ddd;
  }

  .print-summary {
    margin-top: 20px !important;
    padding-top: 15px !important;
    border-top: 2px solid #333;
  }

  .print-summary .total-row {
    font-size: 14pt !important;
    font-weight: bold !important;
    display: flex !important;
    justify-content: space-between !important;
    padding: 5px 0 !important;
  }

  /* Hide all non-print elements */
  .navbar,
  .modal-actions,
  .modal-close,
  .btn,
  .loading-screen,
  .toast-container {
    display: none !important;
  }
}

body {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    sans-serif;
  background: var(--canvas);
  min-height: 100vh;
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  line-height: 1.6;
  font-weight: 400;
  overflow-x: hidden;
  position: relative;
}

/* Loading Screen */
.loading-screen {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--canvas);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.loading-content {
  text-align: center;
  color: var(--text-muted);
}

.loading-content h2 {
  margin-top: 20px;
  font-weight: 500;
}

/* Pages */
.page {
  min-height: 100vh;
  display: block;
  /* clip, not hidden, and the difference is the whole reason the side nav
   * works. `overflow-x: hidden` forces the other axis to `auto`, which makes
   * this element a scroll container - and a `position: sticky` child anchors
   * itself to its nearest scrolling ancestor. That was this, which has no
   * height of its own and so never scrolls, so the nav never stuck to
   * anything: at 1200px down it sat 1028px above the viewport. `clip` does the
   * same job horizontally without creating a scroll container, so sticky
   * children go back to holding against the viewport.
   *
   * Declared twice on purpose: a browser too old for `clip` (pre-16 Safari)
   * keeps the `hidden` it has today rather than dropping to `visible` and
   * letting a wide table scroll the page sideways. It loses the sticky nav,
   * which is exactly where it stands now. */
  overflow-x: hidden;
  overflow-x: clip;
  position: relative;
}

.page.hidden {
  display: none;
}

/* Container */
.container {
  max-width: 1280px;
  margin: 0 auto;
  padding: 86px 24px 48px 24px;
  width: 100%;
}

/* ---------------------------------------------------------------------------
 * Auth pages: /login and the analytics unlock.
 *
 * These two carried their own inline <style> blocks - the only pages in the
 * app that did - and that is how they kept the purple gradient for a whole
 * pass after everything else had been repainted. Same markup on both, so the
 * styles live here once. Class names are unchanged and are used by nothing
 * else, which is what made the move safe.
 *
 * Neither page loads Font Awesome. The brand mark is an inline SVG rather
 * than an icon font, so a sign-in screen does not block on a CDN for one
 * glyph, and the error panel carries no icon at all.
 * ------------------------------------------------------------------------ */
.login-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: 24px;
  background: var(--canvas);
}

.login-card {
  width: 100%;
  max-width: 380px;
  padding: 32px 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

/* The mark, at the size the navbar uses it plus a step - this is the one
   screen where it is the only thing identifying the app. */
.login-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: 0 auto 16px;
  border-radius: var(--radius);
  background: var(--accent);
  color: #ffffff;
}

.login-brand svg {
  width: 22px;
  height: 22px;
  display: block;
}

.login-header {
  text-align: center;
  margin-bottom: 24px;
}

.login-header h1 {
  margin-bottom: 4px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.3px;
  color: var(--text);
}

.login-header p {
  font-size: 13px;
  color: var(--text-muted);
}

.form-group {
  margin-bottom: 16px;
}

.form-group label {
  display: block;
  margin-bottom: 6px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
}

.form-group input {
  width: 100%;
  padding: 9px 12px;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form-group input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.login-btn {
  width: 100%;
  margin-top: 4px;
  padding: 10px 16px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: #ffffff;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.login-btn:hover:not(:disabled) {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}

.login-btn:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}

/* Both forms swap this button's own label while they wait, so there is no
   separate spinner block underneath it - the page used to show two loading
   indicators for one request. */
.login-btn:disabled {
  background: var(--surface-hover);
  border-color: var(--border-strong);
  color: var(--text-faint);
  cursor: not-allowed;
}

/* Hidden until there is something to say; the scripts flip it to `block`, so
   this stays a block-level panel rather than a flex row. */
.error-message {
  display: none;
  margin-top: 16px;
  padding: 10px 12px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--danger);
  background: var(--danger-soft);
  border: 1px solid #fecdc9;
  border-radius: var(--radius-sm);
}

.login-foot {
  margin-top: 18px;
  font-size: 12px;
  color: var(--text-faint);
  text-align: center;
}

/* Sign In Page */
.signin-card {
  background: white;
  border-radius: 16px;
  padding: 48px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
  text-align: center;
  max-width: 480px;
  margin: 100px auto;
}

.logo {
  margin-bottom: 24px;
}

.logo i {
  font-size: 48px;
  color: var(--accent-strong);
  margin-bottom: 16px;
  display: block;
}

.logo h1 {
  font-size: 32px;
  font-weight: 700;
  color: var(--text);
}

.subtitle {
  color: var(--text-muted);
  font-size: 16px;
  margin-bottom: 40px;
}

.auth-section {
  text-align: left;
}

.auth-section h3 {
  font-size: 20px;
  font-weight: 600;
  margin-bottom: 12px;
  color: var(--text);
}

.auth-section p {
  color: var(--text-muted);
  margin-bottom: 24px;
  line-height: 1.6;
}

.auth-status {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  color: var(--accent-strong);
  font-weight: 500;
}

/* Token Status Styles */
.token-status-section {
  margin-top: 24px;
  padding: 16px;
  background: var(--surface-sunken);
  border-radius: 8px;
  border-left: 4px solid var(--accent);
}

.token-status h4 {
  margin: 0 0 12px 0;
  font-size: 16px;
  color: var(--text);
}

.token-status p {
  margin: 4px 0;
  font-size: 14px;
  color: var(--text-muted);
}

.token-status .success {
  color: #28a745;
  font-weight: 600;
}

.token-status .warning {
  color: #ffc107;
  font-weight: 600;
}

.token-status .error {
  color: #dc3545;
  font-weight: 600;
}

.token-status .btn {
  margin-top: 8px;
}

/* Dashboard */
.navbar {
  background: var(--rail);
  box-shadow: none;
  border-bottom: 1px solid var(--rail);
  padding: 12px 0;
  overflow-x: hidden;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  width: 100%;
}

.nav-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 20px;
  position: relative;
}

.nav-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 18px;
  font-weight: 600;
  color: #ffffff;
  letter-spacing: -0.1px;
}

/* A small gradient mark rather than a bare icon, so the brand reads as an
   identity - "you are here" - distinct from the row of destinations next to
   it. Every page sets its own icon here, so this is the one place that marks
   which page is current; the links beside it never link back to it. */
.nav-brand i {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--accent);
  color: white;
  font-size: 14px;
  flex-shrink: 0;
}

/* Nothing else in the navbar is a shape, so the mark alone carries the
   accent - it is the "you are here", not a control. */

.nav-auth {
  display: flex;
  align-items: center;
  gap: 4px;
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

/*
 * Nav links, restyled as flat pills rather than reusing .btn-outline as-is.
 * .btn-outline is the app's real call-to-action style (bordered, fills solid
 * on hover) and stays exactly as it is everywhere else - "Generate Report"
 * and the like still need to look like actions. Inside the navbar every item
 * used that same heavy treatment regardless of what it did, so a page link,
 * the cart and Logout all looked like three equally weighted buttons. These
 * rules are scoped to .nav-actions/.nav-auth only, so nothing outside the
 * navbar changes.
 */
.nav-actions a.btn,
.nav-actions button.btn,
.nav-auth a.btn,
.nav-auth button.btn {
  border: none;
  background: transparent;
  color: var(--rail-text);
  padding: 9px 14px;
  border-radius: 999px;
  font-weight: 500;
  box-shadow: none;
}

.nav-actions a.btn:hover,
.nav-actions button.btn:hover,
.nav-auth a.btn:hover,
.nav-auth button.btn:hover {
  background: var(--rail-hover);
  color: #ffffff;
  transform: none;
}

.nav-actions a.btn i,
.nav-actions button.btn i,
.nav-auth a.btn i,
.nav-auth button.btn i {
  color: var(--rail-faint);
  font-size: 13px;
  transition: color 0.2s ease;
}

.nav-actions a.btn:hover i,
.nav-actions button.btn:hover i,
.nav-auth a.btn:hover i,
.nav-auth button.btn:hover i {
  color: #ffffff;
}

.nav-actions a.btn:focus-visible,
.nav-actions button.btn:focus-visible,
.nav-auth a.btn:focus-visible,
.nav-auth button.btn:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 2px;
}

/* Cart carries a live count and opens a drawer rather than leaving the page,
   so it reads as the one actual action in the row - filled and a touch
   bolder, where every plain destination stays a flat pill. */
#cart-btn {
  background: var(--accent);
  color: #ffffff;
  font-weight: 600;
}

#cart-btn:hover {
  background: var(--accent-2);
  color: #ffffff;
}

#cart-btn i,
#cart-btn:hover i {
  color: inherit;
}

/* Logout/Sign Out ends the session rather than going somewhere, so it should
   not sit at the same visual weight as "go to Analytics" - muted at rest,
   and a quiet warning tint on hover. On the dark navbar the old #fdeeee
   panel was a white slab, so the warning is carried by the text instead. */
#logout-btn,
#signout-btn {
  color: var(--rail-faint);
}

#logout-btn:hover,
#signout-btn:hover {
  background: rgba(240, 68, 56, 0.16);
  color: #ff9c94;
}

#logout-btn:hover i,
#signout-btn:hover i {
  color: #ff9c94;
}

/* Mobile Menu */
.mobile-menu-toggle {
  display: none;
  background: none;
  border: none;
  font-size: 18px;
  color: var(--rail-text);
  cursor: pointer;
  padding: 6px;
  border-radius: 4px;
  transition: background-color 0.2s ease;
  min-width: 36px;
  height: 36px;
}

.mobile-menu-toggle:hover {
  background-color: #f5f5f5;
}

.mobile-nav {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: white;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border-top: 1px solid #eee;
  z-index: 999;
}

.mobile-nav.show {
  display: block;
}

.mobile-nav-content {
  padding: 16px 20px;
}

.mobile-nav-item {
  display: block;
  padding: 12px 0;
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid var(--border);
  font-weight: 500;
  transition: color 0.2s ease;
}

.mobile-nav-item:last-child {
  border-bottom: none;
}

.mobile-nav-item:hover {
  color: var(--accent-strong);
}

.mobile-nav-item i {
  margin-right: 8px;
  width: 16px;
}

@media (max-width: 768px) {
  .mobile-menu-toggle {
    display: block;
  }

  .nav-actions {
    display: none;
  }

  .nav-actions.show {
    display: grid;
    grid-template-columns: 1fr 1fr;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--rail);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
    border-top: 1px solid var(--rail-border);
    padding: 12px 16px;
    gap: 8px;
  }

  .nav-actions .btn {
    justify-content: center;
    text-align: center;
    padding: 8px 4px;
    font-size: 12px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .nav-actions .btn i {
    margin-right: 4px;
    font-size: 12px;
  }

  /* Special handling for cart button in mobile */
  #cart-btn {
    grid-column: 1 / -1;
    margin-bottom: 4px;
  }
}

.dashboard-header {
  text-align: center;
  padding: 40px 0 30px;
  color: var(--text);
}

.dashboard-header p {
  color: var(--text-muted);
}

.dashboard-header h1 {
  font-size: 36px;
  font-weight: 700;
  margin-bottom: 12px;
  letter-spacing: -0.5px;
}

.dashboard-header p {
  font-size: 16px;
  opacity: 0.9;
  font-weight: 400;
}

.dashboard-content {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  padding-bottom: 40px;
}

@media (max-width: 768px) {
  .dashboard-content {
    grid-template-columns: 1fr;
  }
}

/* Links.
 *
 * There was no rule for these at all, so every link in a card body rendered
 * in the browser's default blue - a colour that belonged to none of the
 * palettes this page has ever had, sitting next to an accent that did.
 *
 * Takes --accent-strong rather than --accent: the fill shade is chosen so
 * that *white sits on it*, which puts it at 3.9:1 as text on a card and
 * under the 4.5:1 body-text bar. Scoped away from the chrome, which sets
 * its own colours on a dark background. */
a {
  color: var(--accent-strong);
  text-decoration-color: var(--accent-border);
  text-underline-offset: 2px;
}

a:hover {
  text-decoration-color: currentColor;
}

.navbar a,
.analytics-nav a {
  text-decoration: none;
}

/* Cards */
/* A card is a surface on the canvas, not an object hovering above it. The
 * border does the separating; the shadow only stops it looking pasted on.
 * It deliberately does not move on hover - a card is not a control. */
.card {
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  border: 1px solid var(--border);
}

.card-header {
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
}

.card-header h3 {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 4px;
  color: var(--text);
  letter-spacing: -0.2px;
}

.card-header p {
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 400;
}

.card-body {
  padding: 20px;
}

/* Catalog Info */
.catalog-info {
  margin-bottom: 20px;
}

.catalog-info p {
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.5;
  margin-bottom: 16px;
}

.catalog-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 20px;
}

.stat-item {
  background: var(--surface-sunken);
  padding: 12px;
  border-radius: 8px;
  text-align: center;
  border: 1px solid var(--border);
}

.stat-label {
  display: block;
  font-size: 11px;
  color: var(--text-muted);
  margin-bottom: 3px;
  text-transform: uppercase;
  font-weight: 500;
  letter-spacing: 0.5px;
}

.stat-value {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

.card-actions {
  display: flex;
  justify-content: flex-start;
}

/* Report Options Section */
.report-options-section {
  margin-top: 32px;
}

.report-options-section h4 {
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 20px;
  letter-spacing: -0.2px;
}

.options-grid {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-bottom: 32px;
}

.option-group {
  padding: 20px;
  background: var(--surface-sunken);
  border-radius: 12px;
  border: 1px solid var(--border);
  transition: all 0.2s ease;
}

.option-group:hover {
  background: #f0f2f5;
  border-color: #d1d5db;
}

/* Unified Report Options */
.report-options-unified {
  margin-top: 20px;
  padding: 16px;
  background: var(--surface-sunken);
  border-radius: 8px;
  border: 1px solid var(--border);
}

.options-content {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
}

.options-left {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.checkbox-group {
  display: flex;
  gap: 24px;
  align-items: flex-start;
}

.checkbox-group .checkbox-label {
  margin: 0;
  font-size: 14px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  line-height: 1.4;
}

.checkbox-group .checkbox-label .checkmark {
  margin-top: 2px;
  flex-shrink: 0;
}

.options-right {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: flex-end;
  flex-shrink: 0;
}

.period-selector {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-end;
}

.period-selector .period-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  margin: 0;
}

.period-selector .period-select {
  width: 140px;
  padding: 8px 12px;
  font-size: 13px;
  border-radius: 6px;
  border: 1px solid var(--border-strong);
  background: white;
}

.options-right .btn {
  padding: 10px 20px;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
}

@media (max-width: 768px) {
  .options-content {
    flex-direction: column;
    gap: 16px;
  }

  .checkbox-group {
    flex-direction: column;
    gap: 12px;
    align-items: stretch;
  }

  .checkbox-group .checkbox-label {
    align-items: flex-start;
  }

  .options-right {
    align-items: stretch;
  }

  .period-selector {
    align-items: stretch;
  }

  .period-selector .period-select {
    width: 100%;
  }
}

.checkbox-label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
  font-weight: 500;
  color: var(--text);
  font-size: 15px;
  margin-bottom: 8px;
}

.checkbox-label input[type="checkbox"] {
  display: none;
}

.checkmark {
  width: 20px;
  height: 20px;
  border: 2px solid #ddd;
  border-radius: 4px;
  position: relative;
  flex-shrink: 0;
  margin-top: 2px;
  transition: all 0.2s ease;
}

.checkbox-label input[type="checkbox"]:checked + .checkmark {
  background: var(--accent);
  border-color: var(--accent);
}

.checkbox-label input[type="checkbox"]:checked + .checkmark::after {
  content: "✓";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: white;
  font-size: 12px;
  font-weight: bold;
}

.option-group small {
  display: block;
  margin-top: 8px;
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.4;
  margin-left: 32px;
}

/* Period Select */
.period-label {
  display: block;
  font-weight: 500;
  color: var(--text);
  margin-bottom: 8px;
  font-size: 15px;
}

.period-select {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--text);
  background: var(--surface);
  cursor: pointer;
  font-family: inherit;
  margin-bottom: 8px;
}

.period-select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.14);
}

/* Generate Section */
.generate-section {
  display: flex;
  justify-content: center;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border: none;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  text-decoration: none;
  font-family: inherit;
  letter-spacing: 0.2px;
}

/* Flat fill, 1px borders, no lift. Buttons that jump on hover read as
 * playful; on a page of numbers that is noise. Colour and a background
 * change carry the affordance instead. */
.btn-primary {
  background: var(--accent);
  color: white;
  border: 1px solid var(--accent);
  box-shadow: var(--shadow-sm);
}

.btn-primary:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}

.btn-outline {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
}

.btn-outline:hover {
  background: var(--surface-hover);
  color: var(--text);
  border-color: var(--border-strong);
}

.btn-sm {
  padding: 8px 16px;
  font-size: 13px;
}

.btn-large {
  padding: 16px 32px;
  font-size: 16px;
  width: 100%;
  justify-content: center;
}

/* Last Report Section */
.last-report-section {
  margin-bottom: 20px;
  padding: 16px;
  background: var(--surface-sunken);
  border-radius: 8px;
  border: 1px solid var(--border);
}

.last-report-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.last-report-header h4 {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  margin: 0;
}

.last-report-info {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.4;
}

.last-report-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}

.report-info {
  flex: 1;
}

.info-item {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  font-size: 12px;
  color: var(--text-muted);
}

.info-item:last-child {
  margin-bottom: 0;
}

.info-item i {
  color: var(--accent-strong);
  width: 14px;
  text-align: center;
}

.report-actions {
  flex-shrink: 0;
}

.report-download-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  text-decoration: none;
  box-shadow: 0 2px 8px rgba(79, 70, 229, 0.14);
}

.report-download-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(79, 70, 229, 0.14);
}

.report-download-btn i {
  font-size: 14px;
}

/* Activity Log */
.activity-log {
  min-height: 200px;
}

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

.empty-state i {
  font-size: 48px;
  margin-bottom: 16px;
  color: #ddd;
}

.empty-state p {
  font-size: 16px;
  margin-bottom: 8px;
}

.empty-state small {
  font-size: 14px;
}

/* Modal */
.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-content {
  background: white;
  border-radius: 16px;
  padding: 24px;
  max-width: 800px;
  width: 90%;
  text-align: center;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid #eee;
}

.modal-header h3 {
  font-size: 24px;
  font-weight: 600;
  color: var(--text);
  margin: 0;
}

.modal-close {
  background: none;
  border: none;
  font-size: 20px;
  color: var(--text-muted);
  cursor: pointer;
  padding: 8px;
  border-radius: 4px;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
}

.modal-close:hover {
  background: #f0f0f0;
  color: var(--text);
}

.progress-section {
  text-align: center;
}

.progress-section h4 {
  font-size: 18px;
  font-weight: 600;
  margin: 16px 0 6px;
  color: var(--text);
}

.progress-section p {
  color: var(--text-muted);
  margin-bottom: 16px;
}

.progress-bar {
  width: 100%;
  height: 8px;
  background: #f0f0f0;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 20px;
}

.progress-fill {
  height: 100%;
  background: var(--accent);
  width: 0%;
  transition: width 0.3s ease;
}

.progress-steps {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.step {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px;
  border-radius: 8px;
  transition: all 0.2s ease;
  opacity: 0.5;
}

.step.active {
  background: #f8f9ff;
  opacity: 1;
  color: var(--accent-strong);
}

.step.completed {
  opacity: 0.8;
  color: #28a745;
}

.step i {
  width: 20px;
  text-align: center;
}

/* Spinners */
.spinner {
  border: 3px solid #f3f3f3;
  border-top: 3px solid var(--accent);
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: spin 1s linear infinite;
  margin: 0 auto;
}

.spinner.small {
  width: 20px;
  height: 20px;
  border-width: 2px;
}

.spinner.large {
  width: 60px;
  height: 60px;
  border-width: 4px;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* Responsive Design */
@media (max-width: 768px) {
  .signin-card {
    margin: 40px auto;
    padding: 32px 24px;
  }

  .dashboard-header {
    padding: 40px 0 30px;
  }

  .dashboard-header h1 {
    font-size: 32px;
  }

  .card-body {
    padding: 24px;
  }

  .modal-content {
    padding: 24px;
    max-width: 95%;
  }

  .catalog-stats {
    grid-template-columns: 1fr;
  }

  .card-actions {
    justify-content: center;
  }

  .generate-section {
    justify-content: center;
  }

  .btn {
    width: 100%;
    justify-content: center;
  }
}

/* Utility Classes */
.hidden {
  display: none !important;
}

/* Success/Error States */
.success {
  color: #28a745;
}

.error {
  color: #dc3545;
}

.warning {
  color: #ffc107;
}

/* Download Section */
.download-section {
  margin-top: 32px;
  text-align: center;
  display: none; /* Hidden by default */
}

.download-section:not(.hidden) {
  display: block !important;
}

.download-content {
  padding: 24px;
  background: #f8fff9;
  border-radius: 12px;
  border: 2px solid #28a745;
  box-shadow: 0 4px 12px rgba(40, 167, 69, 0.2);
}

.success-icon {
  font-size: 48px;
  color: #28a745;
  margin-bottom: 16px;
}

.download-content h4 {
  font-size: 20px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 8px;
}

.download-content p {
  color: var(--text-muted);
  margin-bottom: 24px;
}

.download-content .btn {
  margin-top: 8px;
  font-size: 16px;
  padding: 12px 24px;
  font-weight: 600;
  background: #28a745;
  border-color: #28a745;
}

.download-content .btn:hover {
  background: #218838;
  border-color: #1e7e34;
}

/* Shopify Status Section */
.shopify-status-section {
  margin-top: 24px;
  padding: 20px;
  background: var(--surface-sunken);
  border-radius: 12px;
  border-left: 4px solid var(--accent);
}

.shopify-status-content h5 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  color: var(--text);
  font-size: 16px;
  font-weight: 600;
}

.shopify-status-content h5 i {
  color: var(--accent-strong);
}

.shopify-progress {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.shopify-progress-bar {
  width: 100%;
  height: 8px;
  background: #e9ecef;
  border-radius: 4px;
  overflow: hidden;
}

.shopify-progress-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 4px;
  transition: width 0.3s ease;
  width: 0%;
}

#shopify-status-text {
  font-size: 14px;
  color: var(--text-muted);
  font-weight: 500;
}

/* Dashboard Shopify Status */
#shopify-dashboard-card.active {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
}

.shopify-dashboard-progress {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.shopify-dashboard-progress-bar {
  width: 100%;
  height: 12px;
  background: #e9ecef;
  border-radius: 6px;
  overflow: hidden;
}

.shopify-dashboard-progress-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 6px;
  transition: width 0.3s ease;
  width: 0%;
}

.shopify-dashboard-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 14px;
  color: var(--text-muted);
}

#shopify-dashboard-status-text {
  font-weight: 500;
}

#shopify-dashboard-progress-text {
  font-weight: 600;
  color: var(--accent-strong);
}

/* Progress Logs */
.progress-logs {
  margin-top: 6px;
  background: var(--surface-sunken);
  border-radius: 6px;
  border: 1px solid var(--border);
  overflow: hidden;
  max-width: 100%;
  width: 100%;
}

.log-header {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: var(--accent);
  color: white;
  font-weight: 600;
  font-size: 11px;
}

.log-content {
  max-height: 80px;
  overflow-y: auto;
  overflow-x: auto;
  padding: 6px 10px;
  font-family: "Courier New", monospace;
  font-size: 10px;
  line-height: 1.2;
  background: #1e1e1e;
  color: #d4d4d4;
  scrollbar-width: thin;
  scrollbar-color: var(--accent) #1e1e1e;
  white-space: nowrap;
}

.log-content::-webkit-scrollbar {
  width: 6px;
}

.log-content::-webkit-scrollbar-track {
  background: #1e1e1e;
}

.log-content::-webkit-scrollbar-thumb {
  background: var(--accent);
  border-radius: 3px;
}

.log-content::-webkit-scrollbar-thumb:hover {
  background: var(--accent-strong);
}

.log-entry {
  margin-bottom: 2px;
  padding: 2px 0;
  border-bottom: 1px solid #333;
  white-space: nowrap;
}

.log-entry:last-child {
  border-bottom: none;
}

.log-entry.info {
  color: #4fc3f7;
}

.log-entry.success {
  color: #4caf50;
}

.log-entry.warning {
  color: #ff9800;
}

.log-entry.error {
  color: #f44336;
}

/* Product Catalog Styles */
.catalog-header {
  text-align: center;
  padding: 40px 0 30px;
  color: var(--text);
}

.catalog-header p {
  color: var(--text-muted);
}

.catalog-header h1 {
  font-size: 32px;
  font-weight: 700;
  margin-bottom: 12px;
}

.catalog-header p {
  font-size: 16px;
  opacity: 0.9;
}

/* Catalog Layout */
.catalog-layout {
  max-width: 1400px;
  margin: 0 auto;
  padding: 80px 20px 0 20px;
  min-height: calc(100vh - 80px);
  position: relative;
}

.catalog-main {
  display: block;
}

/* Catalog Filters */
.catalog-filters {
  background: white;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 20px;
  border: 1px solid var(--border);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
  margin-top: 10px;
}

.filters-content {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.filters-content .search-box {
  flex: 1;
  max-width: 300px;
  margin: 0;
}

.filters-content .search-box input {
  padding: 8px 12px 8px 36px;
  font-size: 14px;
  border-radius: 6px;
}

.filters-content .filter-controls {
  display: flex;
  gap: 8px;
  margin: 0;
}

.filters-content .filter-controls select {
  padding: 8px 12px;
  font-size: 14px;
  border-radius: 6px;
  border: 1px solid var(--border-strong);
}

.category-filters {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  overflow-x: auto;
  padding-bottom: 4px;
}

.category-filter-btn {
  background: #f0f2f5;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  transition: all 0.2s ease;
  white-space: nowrap;
  flex-shrink: 0;
}

.category-filter-btn:hover {
  background: #e9ecef;
  border-color: #adb5bd;
  color: var(--text);
}

.category-filter-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}

.category-filter-list {
  display: flex;
  gap: 6px;
  flex-wrap: nowrap;
  overflow-x: auto;
}

.category-item {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  background: #f0f2f5;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 500;
  white-space: nowrap;
  flex-shrink: 0;
}

.category-item:hover {
  background: #e9ecef;
  border-color: #adb5bd;
  color: var(--text);
}

.category-item.active {
  background: #e6eaff;
  color: #3a4ca8;
  border-color: #bfcfff;
}

.category-item .category-name {
  font-weight: 500;
}

.category-item .category-count {
  background: #ececec;
  padding: 1px 4px;
  border-radius: 6px;
  font-size: 9px;
  font-weight: 500;
  color: var(--text-faint);
}

.category-item.active .category-count {
  background: #dbe6ff;
  color: #3a4ca8;
}

.category-item:not(.active) .category-count {
  background: #ececec;
  color: var(--text-faint);
}

/* Category Header */
.category-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
}

.category-header h2 {
  font-size: 20px;
  font-weight: 600;
  color: var(--text);
  margin: 0;
}

.category-header span {
  font-size: 14px;
  color: var(--text-muted);
  font-weight: 500;
}

.catalog-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  gap: 20px;
  flex-wrap: wrap;
}

.search-box {
  position: relative;
  flex: 1;
  max-width: 400px;
}

.search-box i {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
}

.search-box input {
  width: 100%;
  padding: 12px 16px 12px 48px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  font-size: 16px;
  background: white;
}

.search-box input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.14);
}

.filter-controls {
  display: flex;
  gap: 12px;
}

.filter-controls select {
  padding: 12px 16px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  font-size: 16px;
  background: white;
  cursor: pointer;
}

.filter-controls select:focus {
  outline: none;
  border-color: var(--accent);
}

.products-container {
  position: relative;
  min-height: 400px;
}

.products-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;
  margin-bottom: 40px;
}

.product-card {
  background: white;
  border-radius: 12px;
  padding: 16px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  cursor: pointer;
  border: 2px solid transparent;
  display: flex;
  flex-direction: column;
  min-height: 280px;
  overflow: visible;
  word-wrap: break-word;
  overflow-wrap: break-word;
}

.product-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  border-color: var(--accent);
}

.product-image {
  margin-bottom: 12px;
}

.product-image-placeholder {
  width: 100%;
  height: 120px;
  background: var(--surface-sunken);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
}

.product-image-placeholder i {
  font-size: 32px;
  margin-bottom: 4px;
  opacity: 0.6;
}

.product-image-placeholder p {
  font-size: 12px;
  margin: 0;
}

.product-image-img {
  width: 100%;
  height: 120px;
  object-fit: cover;
  border-radius: 8px;
  background: var(--surface-sunken);
}

.product-info h3 {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 8px;
  color: var(--text);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-wrap: break-word;
  overflow-wrap: break-word;
  max-width: 100%;
  min-height: 36px;
}

.product-stats {
  height: 60px;
  margin-bottom: 12px;
  overflow: visible;
  word-wrap: break-word;
  overflow-wrap: break-word;
  flex: 1;
  position: relative;
}

.stat-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
  gap: 8px;
}

.stat {
  display: flex;
  justify-content: space-between;
  margin-bottom: 4px;
  font-size: 12px;
  word-wrap: break-word;
  overflow-wrap: break-word;
  min-height: 16px;
}

.stat .label {
  color: var(--text-muted);
  flex-shrink: 0;
  min-width: 50px;
}

.stat .value {
  font-weight: 600;
  color: var(--text);
  text-align: right;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: calc(100% - 55px);
  flex-shrink: 1;
  min-width: 0;
}

.stock-level {
  font-weight: 600;
  font-size: 12px;
  word-wrap: break-word;
  overflow-wrap: break-word;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.stock-level.in-stock {
  color: #28a745;
}

.stock-level.low-stock {
  color: #ffc107;
}

.stock-level.out-of-stock {
  color: #dc3545;
}

.cart-indicator {
  font-size: 10px;
  color: var(--accent-strong);
  font-weight: 500;
  background: rgba(79, 70, 229, 0.14);
  padding: 2px 6px;
  border-radius: 4px;
  z-index: 1;
  white-space: nowrap;
}

.cart-stat {
  margin-top: 2px;
  position: relative;
}

.stock-info-note {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 12px 0;
  padding: 8px 12px;
  background: var(--surface-sunken);
  border-radius: 6px;
  border-left: 3px solid var(--accent);
}

.stock-info-note i {
  color: var(--accent-strong);
  font-size: 14px;
}

.stock-info-note small {
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.4;
}

.product-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: auto;
  align-items: stretch;
  justify-content: flex-end;
  min-height: 80px;
  position: relative;
}

.product-actions .quantity-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 8px;
  background: white;
  border: 1px solid #333;
  border-radius: 20px;
  padding: 4px;
  width: fit-content;
  margin: 0 auto 8px auto;
}

.product-actions .quantity-btn {
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 14px;
  font-weight: bold;
  color: var(--text);
  padding: 0;
}

.product-actions .quantity-btn:hover {
  background: #f0f0f0;
}

.product-actions .quantity-btn:active {
  background: #e0e0e0;
}

.product-actions .quantity-input {
  width: 40px;
  height: 24px;
  border: none;
  background: transparent;
  text-align: center;
  font-size: 14px;
  font-weight: bold;
  color: var(--text);
  padding: 0;
  margin: 0 8px;
}

.product-actions .quantity-input:focus {
  outline: none;
}

.btn-sm {
  padding: 6px 12px;
  font-size: 12px;
}

.products-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  color: var(--text-muted);
}

.products-loading p {
  margin-top: 16px;
  font-size: 16px;
}

.products-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  color: var(--text-muted);
  text-align: center;
}

.products-empty i {
  font-size: 64px;
  margin-bottom: 16px;
  opacity: 0.6;
}

.products-empty h3 {
  font-size: 24px;
  font-weight: 600;
  margin-bottom: 8px;
}

.products-empty p {
  font-size: 16px;
  opacity: 0.8;
}

/* Responsive Design */
@media (max-width: 1200px) {
  .products-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

@media (max-width: 992px) {
  .products-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 768px) {
  .products-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
  }

  .product-card {
    padding: 8px;
    min-height: 200px;
    width: 100%;
    max-width: none;
    margin: 0;
  }

  .product-image-placeholder {
    height: 70px;
  }

  .product-image-img {
    height: 70px;
  }

  .product-info h3 {
    font-size: 11px;
    margin-bottom: 4px;
    line-height: 1.2;
    min-height: 26px;
    -webkit-line-clamp: 2;
  }

  .product-stats {
    height: auto;
    margin-bottom: 8px;
  }

  .stat {
    margin-bottom: 1px;
    padding: 1px 0;
    font-size: 9px;
  }

  .stat .label {
    font-size: 9px;
    min-width: 35px;
    flex-shrink: 0;
  }

  .stat .value {
    font-size: 9px;
    max-width: calc(100% - 40px);
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex-shrink: 1;
    min-width: 0;
  }

  .product-actions {
    margin-top: 6px;
  }

  .product-actions .quantity-controls {
    margin-bottom: 4px;
    border-radius: 12px;
    padding: 2px;
  }

  .product-actions .quantity-btn {
    width: 18px;
    height: 18px;
    font-size: 10px;
  }

  .product-actions .quantity-input {
    width: 28px;
    height: 18px;
    font-size: 10px;
    margin: 0 4px;
  }

  .action-buttons .btn {
    padding: 6px 8px;
    font-size: 10px;
  }

  .catalog-controls {
    flex-direction: column;
    align-items: stretch;
  }

  .search-box {
    max-width: none;
  }

  .filter-controls {
    justify-content: space-between;
  }

  .catalog-filters {
    padding: 12px;
  }

  .filters-content {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .filters-content .search-box {
    max-width: none;
  }

  .category-filters {
    justify-content: flex-start;
    overflow-x: auto;
  }

  .last-report-content {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .report-actions {
    align-self: flex-end;
  }
}

@media (max-width: 480px) {
  /* Extra small screen improvements */
  .nav-content {
    padding: 0 12px;
  }

  .nav-brand {
    font-size: 14px;
  }

  .nav-brand span {
    display: none;
  }

  .nav-actions.show {
    grid-template-columns: 1fr 1fr;
    padding: 8px 12px;
    gap: 6px;
  }

  .nav-actions .btn {
    padding: 6px 2px;
    font-size: 10px;
    min-height: 32px;
  }

  .nav-actions .btn i {
    margin-right: 2px;
    font-size: 10px;
  }

  /* Cart button spans full width on very small screens */
  #cart-btn {
    grid-column: 1 / -1;
    margin-bottom: 4px;
    font-size: 11px;
  }

  .catalog-main {
    padding: 0 4px;
    overflow-x: hidden;
  }

  .catalog-filters {
    padding: 8px;
    overflow-x: hidden;
  }

  .filters-content {
    gap: 8px;
    overflow-x: hidden;
  }

  .filters-content .search-box input {
    padding: 8px 10px 8px 32px;
    font-size: 14px;
  }

  .filter-controls {
    grid-template-columns: 1fr 1fr;
    gap: 6px;
  }

  .filter-controls select {
    padding: 8px 6px;
    font-size: 12px;
  }

  .category-filters {
    gap: 4px;
    overflow-x: hidden;
  }

  .category-filter-btn {
    padding: 4px 8px;
    font-size: 11px;
  }

  .products-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 6px;
    overflow-x: hidden;
  }

  .product-card {
    padding: 6px;
    min-height: 180px;
    overflow-x: hidden;
    width: 100%;
    max-width: none;
    margin: 0;
  }

  .product-image-placeholder {
    height: 60px;
  }

  .product-image-img {
    height: 60px;
  }

  .product-info h3 {
    font-size: 10px;
    margin-bottom: 3px;
    word-wrap: break-word;
    overflow-wrap: break-word;
    line-height: 1.2;
    min-height: 24px;
    -webkit-line-clamp: 2;
  }

  .stat {
    padding: 2px 0;
    margin-bottom: 1px;
    word-wrap: break-word;
    overflow-wrap: break-word;
    min-height: auto;
  }

  .stat .label {
    font-size: 9px;
    min-width: 40px;
    flex-shrink: 0;
  }

  .stat .value {
    font-size: 9px;
    word-wrap: break-word;
    overflow-wrap: break-word;
    max-width: calc(100% - 50px);
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex-shrink: 1;
    min-width: 0;
    max-width: 80px;
  }

  .product-actions {
    margin-top: 6px;
    gap: 4px;
  }

  .product-actions .quantity-controls {
    margin-bottom: 4px;
    border-radius: 14px;
    padding: 2px;
  }

  .product-actions .quantity-btn {
    width: 18px;
    height: 18px;
    font-size: 10px;
  }

  .product-actions .quantity-input {
    width: 28px;
    height: 18px;
    font-size: 10px;
    margin: 0 4px;
  }

  .action-buttons .btn {
    padding: 6px 8px;
    font-size: 11px;
    min-height: 28px;
  }

  .modal-content {
    margin: 8px;
    max-height: calc(100vh - 16px);
  }

  .product-stats {
    grid-template-columns: 1fr;
    gap: 6px;
  }

  .quantity-controls input {
    width: 50px;
  }

  .category-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
}

@media (max-width: 360px) {
  .navbar {
    padding: 10px 0;
  }

  .nav-content {
    padding: 0 8px;
  }

  .catalog-layout {
    padding-top: 60px;
  }

  .mobile-menu-toggle {
    font-size: 16px;
    padding: 4px;
    min-width: 32px;
    height: 32px;
  }

  .nav-actions.show {
    padding: 6px 8px;
    gap: 4px;
  }

  .nav-actions .btn {
    padding: 4px 1px;
    font-size: 9px;
    min-height: 28px;
  }

  .nav-actions .btn i {
    margin-right: 1px;
    font-size: 9px;
  }

  #cart-btn {
    font-size: 10px;
  }

  .product-card {
    padding: 6px;
    min-height: 180px;
    width: 100%;
    max-width: none;
    margin: 0;
  }

  .product-image-placeholder {
    height: 50px;
  }

  .product-image-img {
    height: 50px;
  }

  .product-info h3 {
    font-size: 10px;
    margin-bottom: 3px;
    min-height: 24px;
  }

  .stat {
    padding: 1px 0;
    margin-bottom: 1px;
  }

  .stat .label {
    font-size: 8px;
    min-width: 35px;
  }

  .stat .value {
    font-size: 8px;
    max-width: calc(100% - 40px);
    max-width: 60px;
  }

  .action-buttons .btn {
    padding: 4px 6px;
    font-size: 10px;
    min-height: 24px;
  }

  .product-actions .quantity-controls {
    margin-bottom: 3px;
    border-radius: 12px;
    padding: 2px;
  }

  .product-actions .quantity-btn {
    width: 16px;
    height: 16px;
    font-size: 8px;
  }

  .product-actions .quantity-input {
    width: 24px;
    height: 16px;
    font-size: 8px;
    margin: 0 3px;
  }
}

/* Product Modal Styles */
.product-modal {
  max-width: 800px;
  width: 90%;
}

.product-detail-content {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
  align-items: start;
}

@media (max-width: 768px) {
  .product-detail-content {
    grid-template-columns: 1fr;
  }
}

.product-image-section {
  text-align: center;
}

.product-image-section .product-image-placeholder {
  height: 300px;
}

.product-image-section .product-image-img {
  width: 100%;
  height: 300px;
  object-fit: cover;
  border-radius: 8px;
  background: var(--surface-sunken);
}

.product-info-section {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.product-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.stat-item {
  background: var(--surface-sunken);
  padding: 16px;
  border-radius: 8px;
  text-align: center;
}

.stat-item label {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 4px;
  text-transform: uppercase;
  font-weight: 500;
}

.stat-item span {
  display: block;
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}

.product-actions {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.quantity-selector {
  display: flex;
  align-items: center;
  gap: 12px;
}

.quantity-selector label {
  font-weight: 500;
  color: var(--text);
}

.quantity-controls {
  display: flex;
  align-items: center;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  overflow: hidden;
}

.quantity-controls button {
  padding: 8px 12px;
  border: none;
  background: var(--surface-sunken);
  cursor: pointer;
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
}

.quantity-controls button:hover {
  background: #e9ecef;
}

.quantity-controls input {
  width: 60px;
  padding: 8px;
  border: none;
  text-align: center;
  font-size: 16px;
  font-weight: 500;
}

.quantity-controls input:focus {
  outline: none;
}

.action-buttons {
  display: flex;
  gap: 12px;
}

.action-buttons .btn {
  flex: 1;
}

/* Cart Modal Styles */
.cart-modal {
  max-width: 600px;
  width: 90%;
}

.cart-items {
  max-height: 400px;
  overflow-y: auto;
  margin-bottom: 24px;
}

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

.cart-empty i {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.6;
}

.cart-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-bottom: 1px solid #eee;
  gap: 16px;
}

.cart-item:last-child {
  border-bottom: none;
}

.cart-item-info {
  flex: 1;
}

.cart-item-info h4 {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 4px;
  color: var(--text);
}

.cart-item-info p {
  font-size: 14px;
  color: var(--text-muted);
}

.cart-item-quantity {
  font-size: 14px;
  color: var(--text-muted);
}

.cart-item-total {
  display: flex;
  align-items: center;
  gap: 12px;
}

.cart-item-total span {
  font-weight: 600;
  color: var(--text);
}

.cart-summary {
  border-top: 2px solid #eee;
  padding-top: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.cart-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}

.cart-total span:last-child {
  color: var(--accent-strong);
}

.checkout-note {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  background: var(--surface-sunken);
  border-radius: 6px;
  border-left: 3px solid var(--accent);
}

.checkout-note i {
  color: var(--accent-strong);
  font-size: 14px;
}

.checkout-note small {
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.4;
}

/* Orders Section Styles */
.orders-section {
  margin-top: 40px;
  padding-top: 40px;
  border-top: 2px solid #eee;
}

.section-header {
  margin-bottom: 24px;
}

.section-header h2 {
  font-size: 24px;
  font-weight: 600;
  color: var(--text);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 12px;
}

.section-header h2 i {
  color: var(--accent-strong);
}

.orders-container {
  position: relative;
  min-height: 200px;
}

.orders-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
  gap: 20px;
}

.order-card {
  background: white;
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  border: 2px solid transparent;
  transition: all 0.3s ease;
}

.order-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  border-color: var(--accent);
}

.order-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid #eee;
}

.order-number {
  font-weight: 600;
  color: var(--accent-strong);
  font-size: 14px;
}

.order-date {
  font-size: 12px;
  color: var(--text-muted);
}

.order-customer {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-weight: 500;
  color: var(--text);
}

.order-customer i {
  color: var(--accent-strong);
}

.order-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.order-items {
  font-size: 14px;
  color: var(--text-muted);
}

.order-total {
  font-weight: 600;
  color: var(--text);
  font-size: 16px;
}

.order-items-preview {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.4;
  max-height: 60px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.orders-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  color: var(--text-muted);
}

.orders-loading .spinner {
  margin-bottom: 16px;
}

.orders-loading p {
  margin: 0;
  font-size: 16px;
}

.orders-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  text-align: center;
  color: var(--text-muted);
}

.orders-empty i {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.6;
}

.orders-empty h3 {
  margin: 0 0 8px 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}

.orders-empty p {
  margin: 0;
  font-size: 14px;
}

/* Navigation Actions */
.nav-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.cart-count {
  background: var(--accent);
  color: white;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  margin-left: 4px;
}

@media (max-width: 768px) {
  .cart-count {
    width: 18px;
    height: 18px;
    font-size: 10px;
    margin-left: 2px;
  }

  .navbar {
    padding: 12px 0;
  }

  .nav-content {
    padding: 0 12px;
  }

  .catalog-layout {
    padding-top: 70px;
  }
}

/* Responsive Design */
@media (max-width: 768px) {
  /* Navbar mobile improvements */
  .nav-content {
    padding: 0 16px;
  }

  .nav-brand {
    font-size: 18px;
  }

  .nav-actions {
    gap: 8px;
  }

  .nav-actions .btn {
    padding: 8px 12px;
    font-size: 14px;
  }

  .nav-actions .btn i {
    margin-right: 4px;
  }

  /* Catalog layout mobile improvements */
  .catalog-layout {
    padding: 0;
    overflow-x: hidden;
    max-width: 100%;
  }

  .catalog-main {
    padding: 0 8px;
    overflow-x: hidden;
  }

  .catalog-filters {
    padding: 12px;
    margin-bottom: 16px;
    overflow-x: hidden;
  }

  .filters-content {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    overflow-x: hidden;
  }

  .filters-content .search-box {
    max-width: none;
  }

  .filters-content .search-box input {
    padding: 10px 12px 10px 36px;
    font-size: 14px;
  }

  .filter-controls {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }

  .filter-controls select {
    padding: 10px 8px;
    font-size: 14px;
  }

  .category-filters {
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-start;
    overflow-x: hidden;
  }

  .category-filter-btn {
    padding: 8px 12px;
    font-size: 14px;
    white-space: nowrap;
    flex-shrink: 0;
  }

  /* Product grid mobile improvements */
  .products-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
    padding: 0;
    overflow-x: hidden;
  }

  .product-card {
    padding: 16px;
    overflow-x: hidden;
    word-wrap: break-word;
  }

  .product-info h3 {
    font-size: 16px;
    line-height: 1.4;
    word-wrap: break-word;
    overflow-wrap: break-word;
  }

  .product-stats {
    gap: 8px;
    overflow-x: hidden;
  }

  .stat {
    padding: 8px;
    word-wrap: break-word;
    overflow-wrap: break-word;
  }

  .stat .label {
    font-size: 12px;
  }

  .stat .value {
    font-size: 14px;
    word-wrap: break-word;
    overflow-wrap: break-word;
    max-width: 100%;
  }

  .product-actions {
    gap: 12px;
  }

  .action-buttons {
    flex-direction: column;
  }

  .action-buttons .btn {
    width: 100%;
    padding: 12px;
    font-size: 16px;
  }

  /* Cart modal mobile improvements */
  .cart-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .cart-summary {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
  }

  /* Modal mobile improvements */
  .modal-content {
    margin: 20px;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
  }

  .product-detail-content {
    grid-template-columns: 1fr;
    gap: 20px;
  }

  .product-stats {
    grid-template-columns: 1fr 1fr;
    gap: 12px;
  }

  .quantity-selector {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .quantity-controls {
    width: 100%;
    justify-content: center;
  }

  .quantity-controls input {
    width: 80px;
  }
}

/* Very small mobile screens - use 1 column only for tiny screens */
@media (max-width: 350px) {
  .products-grid {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .product-card {
    padding: 8px;
    min-height: 160px;
  }

  .product-image-placeholder,
  .product-image-img {
    height: 80px;
  }

  .product-info h3 {
    font-size: 12px;
    min-height: 28px;
  }

  .stat {
    font-size: 10px;
  }

  .stat .label {
    font-size: 10px;
    min-width: 40px;
  }

  .stat .value {
    font-size: 10px;
  }

  .action-buttons .btn {
    padding: 8px 10px;
    font-size: 11px;
  }
}

/* Animation for product cards */
.product-card {
  animation: fadeInUp 0.6s ease-out;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Loading animation for products */
.products-loading .spinner {
  margin-bottom: 16px;
}

/* Catalog reuses the base button styles verbatim; this block used to
 * redeclare them with a heavier border and a hover lift, which is why the
 * same button looked different on two pages. */
.btn-outline {
  border: 1px solid var(--border-strong);
  color: var(--text);
  background: var(--surface);
  transition: all 0.15s ease;
}

.btn-outline:hover {
  background: var(--surface-hover);
  color: var(--text);
}

.btn-primary {
  background: var(--accent);
  border: 1px solid var(--accent);
  color: white;
  transition: all 0.15s ease;
}

.btn-primary:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}

.btn-primary:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* Toast Notifications */
.toast-container {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 400px;
}

.toast {
  background: white;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  padding: 16px 20px;
  display: flex;
  align-items: center;
  gap: 12px;
  border-left: 4px solid #ddd;
  transform: translateX(100%);
  opacity: 0;
  transition: all 0.3s ease;
  max-width: 400px;
  word-wrap: break-word;
}

.toast.show {
  transform: translateX(0);
  opacity: 1;
}

.toast.success {
  border-left-color: #28a745;
  background: var(--ok-soft);
}

.toast.error {
  border-left-color: #dc3545;
  background: var(--danger-soft);
}

.toast.info {
  border-left-color: var(--accent);
  background: var(--accent-soft);
}

.toast.warning {
  border-left-color: #ffc107;
  background: var(--warn-soft);
}

.toast-icon {
  font-size: 18px;
  flex-shrink: 0;
}

.toast.success .toast-icon {
  color: #28a745;
}

.toast.error .toast-icon {
  color: #dc3545;
}

.toast.info .toast-icon {
  color: var(--accent-strong);
}

.toast.warning .toast-icon {
  color: #ffc107;
}

.toast-content {
  flex: 1;
  min-width: 0;
}

.toast-title {
  font-weight: 600;
  font-size: 14px;
  margin-bottom: 4px;
  color: var(--text);
}

.toast-message {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.4;
}

.toast-close {
  background: none;
  border: none;
  color: var(--text-faint);
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  font-size: 16px;
  flex-shrink: 0;
  transition: color 0.2s ease;
}

.toast-close:hover {
  color: var(--text-muted);
  background: rgba(0, 0, 0, 0.05);
}

/* Animation for toast entry and exit */
@keyframes toastSlideIn {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes toastSlideOut {
  from {
    transform: translateX(0);
    opacity: 1;
  }
  to {
    transform: translateX(100%);
    opacity: 0;
  }
}

.toast-enter {
  animation: toastSlideIn 0.3s ease forwards;
}

.toast-exit {
  animation: toastSlideOut 0.3s ease forwards;
}

/* Download Page Styles */
.download-page {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: 20px;
  background: var(--accent);
}

.download-card {
  background: white;
  border-radius: 16px;
  padding: 40px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
  text-align: center;
  max-width: 500px;
  width: 100%;
}

.download-card h1 {
  color: var(--text);
  margin-bottom: 16px;
  font-size: 28px;
  font-weight: 600;
}

.download-card h1 i {
  color: var(--accent-strong);
  margin-right: 12px;
}

.download-card p {
  color: var(--text-muted);
  margin-bottom: 32px;
  font-size: 16px;
  line-height: 1.5;
}

.download-actions {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 24px;
}

.download-actions .btn {
  padding: 16px 24px;
  font-size: 16px;
  font-weight: 500;
  border-radius: 8px;
  transition: all 0.3s ease;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.status-message {
  margin-top: 20px;
}

.status-message .info {
  color: var(--accent-strong);
  font-weight: 500;
}

.status-message .success {
  color: #28a745;
  font-weight: 500;
}

.status-message .error {
  color: #dc3545;
  font-weight: 500;
}

@media (max-width: 768px) {
  .download-card {
    padding: 24px;
    margin: 20px;
  }

  .download-card h1 {
    font-size: 24px;
  }

  .download-actions .btn {
    padding: 14px 20px;
    font-size: 14px;
  }
}

/* Analytics Page */
.analytics-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 20px;
}

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}

/* Left-aligned, not centred. A row of KPI tiles is read by scanning the
 * numbers down one edge; centring makes every value start in a different
 * place and the eye has to hunt for each one. */
.kpi-card {
  background: var(--surface);
  border-radius: var(--radius);
  padding: 12px 14px;
  text-align: left;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}

.kpi-card-warn {
  border-color: #fedf89;
  background: var(--warn-soft);
}

.kpi-value {
  font-size: 21px;
  font-weight: 650;
  color: var(--text);
  margin-bottom: 2px;
  line-height: 1.2;
  letter-spacing: -0.4px;
  /* Tabular figures, so a column of numbers lines up on the decimal instead
   * of shuffling by a pixel or two per digit. */
  font-variant-numeric: tabular-nums;
}

.kpi-label {
  font-size: 10.5px;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.3px;
  font-weight: 500;
  line-height: 1.3;
}

.charts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}

.chart-card {
  background: var(--surface);
  border-radius: var(--radius);
  padding: 14px 16px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  height: 240px;
  display: flex;
  flex-direction: column;
}

.chart-card h3 {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.chart-card h3 i {
  color: var(--accent-strong);
}

.chart-canvas-wrap {
  position: relative;
  flex: 1;
  min-height: 0;
}

.chart-canvas-wrap canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100% !important;
  height: 100% !important;
}

.chart-placeholder {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--text-muted);
  padding: 16px;
}

.chart-placeholder i {
  font-size: 28px;
  margin-bottom: 12px;
  opacity: 0.6;
}

.analytics-filters {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  background: white;
  border-radius: 8px;
  padding: 8px 10px;
  margin-bottom: 12px;
  border: 1px solid var(--border);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
}

.analytics-filters .search-box input {
  padding: 8px 12px 8px 38px;
  font-size: 14px;
}

.analytics-filters .search-box i {
  left: 13px;
}

.analytics-filters .filter-controls {
  gap: 8px;
}

.analytics-filters .filter-controls select {
  padding: 8px 10px;
  font-size: 13px;
}

.analytics-table-wrapper {
  background: var(--surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  overflow: auto;
  max-height: 640px;
}

.analytics-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.analytics-table th {
  position: sticky;
  top: 0;
  text-align: left;
  padding: 9px 14px;
  background: var(--surface-sunken);
  color: var(--text-faint);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  cursor: pointer;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
  user-select: none;
  z-index: 1;
}

.analytics-table th:hover {
  background: var(--surface-hover);
  color: var(--accent-strong);
}

.analytics-table th i {
  margin-left: 4px;
  font-size: 11px;
  opacity: 0.6;
}

.analytics-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  white-space: nowrap;
  /* Every table on this app is mostly figures. Tabular numerals cost nothing
   * on the words and make the columns of money actually line up. */
  font-variant-numeric: tabular-nums;
}

/* No zebra striping. Banding is a crutch for tables with no row separators;
 * this one has a hairline under every row, and the stripes only added a
 * second, competing rhythm to scan against. The hover band does the
 * "which row am I on" job, on demand, for the one row that needs it. */
.analytics-table tr:hover {
  background: var(--accent-soft);
}

.analytics-row-count {
  padding: 12px 16px;
  font-size: 13px;
  color: var(--text-muted);
}

.text-warn {
  color: #dc9800;
  font-weight: 600;
}

.text-danger {
  color: #dc3545;
  font-weight: 600;
}

/* Inline qualifier inside a table cell - "with PO", "after PO". Carries the
   reason a figure differs from the raw stock number without competing with
   it for attention. */
.cell-note {
  color: var(--text-faint);
  font-weight: 400;
  font-size: 12px;
}

/* Status pills are tinted, not saturated. A table of forty rows with four
 * solid traffic-light chips in it reads as an alarm; the tint carries the
 * same three states while letting the numbers stay the loudest thing on the
 * row. Text sits at the full-strength colour, so contrast goes up, not down. */
.badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  border: 1px solid transparent;
}

.badge-abc-a {
  background: var(--ok-soft);
  border-color: #abefc6;
  color: var(--ok);
}

.badge-abc-b {
  background: var(--warn-soft);
  border-color: #fedf89;
  color: var(--warn);
}

.badge-abc-c {
  background: var(--danger-soft);
  border-color: #fecdc9;
  color: var(--danger);
}

@media (max-width: 768px) {
  .analytics-filters {
    flex-direction: column;
    align-items: stretch;
  }

  .analytics-filters .search-box {
    max-width: none;
  }

  .analytics-filters .filter-controls {
    flex-wrap: wrap;
  }
}

#analytics-page .container {
  /* Wide tables, and no side nav competing for the row. */
  max-width: 1440px;
  /* The fixed navbar is ~72px; the rest is breathing room, so the nav and
   * the control strip do not sit flush against it. */
  padding-top: 100px;
}

/* Analytics layout
 *
 * Ten sections in one wrapping row of pills pushed the actual numbers below
 * the fold and re-flowed every time the window changed width. Down the side
 * they hold still, group into the order the day is worked in, and leave the
 * content column free for wide tables.
 */
.analytics-shell {
  display: grid;
  grid-template-columns: 208px minmax(0, 1fr);
  gap: 22px;
  align-items: start;
}

.analytics-nav {
  position: sticky;
  top: var(--navbar-h);
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--rail);
  border: 1px solid var(--rail);
  border-radius: var(--radius-lg);
  box-shadow: none;
  padding: 8px;
  /* Analytics carries 21 entries across six groups, which is taller than a
   * laptop viewport. Sticky alone would pin the top and leave the last few
   * unreachable without scrolling the page back up - the thing being fixed. So
   * the nav scrolls inside itself once it runs out of room. Temu and eBay are
   * short enough that this never engages. */
  max-height: calc(100vh - var(--navbar-h) - 14px);
  overflow-y: auto;
}

.nav-group-label {
  color: var(--rail-faint);
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin: 10px 0 2px 8px;
}

.nav-group-label:first-child {
  margin-top: 2px;
}

.tab-btn {
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 7px 10px;
  font-size: 13px;
  font-weight: 500;
  color: var(--rail-text);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
  display: flex;
  align-items: center;
  gap: 9px;
  text-align: left;
  width: 100%;
}

.tab-btn i {
  width: 15px;
  text-align: center;
  opacity: 0.85;
}

.tab-btn:hover {
  background: var(--rail-hover);
  color: #ffffff;
}

/* Filled, not tinted. A tint that reads as "selected" against white has
 * nothing to work with on a dark rail - the whole rail is already low
 * contrast - so the selected row takes the accent solid. */
.tab-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #ffffff;
  font-weight: 600;
}

.tab-btn.active i {
  opacity: 1;
}

/* One strip per tab: what you are looking at, and the controls that change
 * it. Sticky, so a filter is never more than a glance away in a long table. */
.analytics-controls {
  position: sticky;
  /* Flush against the navbar, not 94px down. The old 37px of clear air was
   * only clear while the page sat at the top: once scrolled, page content ran
   * through the band between the navbar and the strip, so a line of table text
   * hung above a bar that is supposed to be the topmost thing on the page. */
  top: var(--navbar-h);
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 10px 14px;
  margin-bottom: 14px;
}

.analytics-controls h1 {
  color: var(--text);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.2px;
  margin: 0;
}

.controls-right {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.tab-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* Hoisted into the sticky strip, per-tab controls read like the period
 * selector next to them rather than like a stray form. */
.analytics-controls .period-selector {
  flex-direction: row;
  align-items: center;
  gap: 0;
}

.analytics-controls .period-label {
  color: var(--text-muted);
  font-size: 12px;
  margin: 0 6px 0 0;
}

.analytics-controls .period-select {
  padding: 6px 10px;
  font-size: 13px;
}

/* Stands in for the period selector on tabs whose window is fixed. Matches
 * the label it replaces so the strip does not shift. */
.analytics-controls .period-fixed {
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 500;
  cursor: help;
  white-space: nowrap;
  border-bottom: 1px dotted var(--border-strong);
}

/* Every table gets the same instant row filter, injected by script rather
 * than repeated in markup. */
.charts-toggle {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  margin-bottom: 10px;
}

.charts-toggle:hover {
  background: var(--surface-hover);
  color: var(--text);
}

.charts-grid.collapsed {
  display: none;
}

.table-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 6px;
}

.table-filter {
  flex: 1;
  max-width: 280px;
  padding: 6px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
}

.table-filter:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.table-count {
  color: var(--text-muted);
  font-size: 12px;
  white-space: nowrap;
}

.table-count-inline {
  color: var(--text-muted);
  margin-left: auto;
}

@media (max-width: 768px) {
  /* The site navbar stacks its four links on a phone, so anything sticky
   * underneath ends up behind it. Let the strip scroll away instead. */
  .analytics-controls {
    position: static;
  }

  #analytics-page .container {
    /* Shorter navbar on a phone. */
    padding-top: 76px;
  }

  .analytics-controls h1 {
    font-size: 16px;
  }
}

@media (max-width: 1024px) {
  /* Below the split, the nav becomes one swipeable row rather than wrapping
   * into four lines of pills. */
  .analytics-shell {
    grid-template-columns: minmax(0, 1fr);
  }

  .analytics-nav {
    position: static;
    flex-direction: row;
    overflow-x: auto;
    gap: 6px;
    padding: 6px;
  }

  .nav-group-label {
    display: none;
  }

  .tab-btn {
    width: auto;
    white-space: nowrap;
  }
}

.section-heading {
  color: var(--text);
  font-size: 15px;
  letter-spacing: -0.1px;
  font-weight: 600;
  margin: 18px 0 4px;
  /* So the link button sits on the baseline beside the text rather than
     starting a line of its own. */
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Copy a link to this table.
 *
 * Every heading has an id and every id is linkable, but nobody can guess
 * `buylist-line-by-line` by looking at the page - so the page hands it over.
 *
 * Shown only on hover or keyboard focus: 70 headings each wearing a permanent
 * icon is a lot of furniture for something used occasionally. `opacity` rather
 * than `display`, so it does not reflow the heading when it appears, and
 * focus-within keeps it reachable by tab. */
.section-link {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  font: inherit;
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  padding: 4px 7px;
  opacity: 0;
  transition: opacity 0.12s ease, background 0.12s ease;
}

.section-heading:hover .section-link,
.section-heading:focus-within .section-link,
.section-link.section-link-done {
  opacity: 1;
}

.section-link:hover {
  background: var(--surface-hover);
  color: var(--text);
}

.section-link-done {
  background: var(--ok-soft);
  border-color: var(--ok);
  color: var(--ok);
  cursor: default;
}

/* Coarse pointers have no hover, so the button would be unreachable. */
@media (hover: none) {
  .section-link {
    opacity: 1;
  }
}

.section-note {
  color: var(--text-muted);
  font-size: 12px;
  margin-bottom: 8px;
  /* Full width, like the tables and KPI rows it sits above. The 80ch cap was
     a readability measure, but against a content column this wide it just
     left a ragged half-width block of text beside empty space. */
  max-width: none;
}

/* The one-line answer to "what is this tab for", at the top of every section.
   Distinct from .section-note, which explains an individual table below it. */
.tab-intro {
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.55;
  margin: 0 0 16px;
  max-width: none;
}

.tab-intro strong {
  color: var(--text);
}

.flag-suspect {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  background: #ffe9b8;
  color: #8a5a00;
  cursor: help;
}

.data-warning {
  display: flex;
  align-items: center;
  gap: 14px;
  background: #fff4e0;
  border: 1px solid #f0c072;
  border-left: 4px solid #dc9800;
  border-radius: 8px;
  padding: 14px 18px;
  margin-bottom: 20px;
  color: #6b4500;
  font-size: 14px;
}

.data-warning i {
  font-size: 20px;
  color: #dc9800;
}

.backfill-status {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 10px;
  min-height: 18px;
}

.backfill-status.running {
  color: var(--accent-strong);
  font-weight: 500;
}

.backfill-status.error {
  color: #dc3545;
  font-weight: 500;
}

.pnl-table td { font-size: 15px; }
.pnl-table .pnl-subtotal td {
  border-top: 2px solid #e9ecef;
  background: var(--surface-sunken);
}
.pnl-table .pnl-total td {
  border-top: 2px solid var(--accent);
  background: #eef0fa;
  font-size: 16px;
}

/* KPI drill-down */
.kpi-card.kpi-clickable {
  cursor: pointer;
  transition: all 0.15s ease;
  position: relative;
}

.kpi-card.kpi-clickable:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
  border-color: var(--accent);
}

.kpi-card.kpi-clickable::after {
  content: "\f105";
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  position: absolute;
  top: 10px;
  right: 12px;
  font-size: 12px;
  color: #b9bfd4;
}

.drill-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 40, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
  padding: 24px;
}

.drill-panel {
  background: #fff;
  border-radius: 14px;
  width: min(1100px, 100%);
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

.drill-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding: 20px 24px;
  border-bottom: 1px solid #eee;
}

.drill-header h3 {
  font-size: 19px;
  font-weight: 600;
  color: var(--text);
}

.drill-header p {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 4px;
  max-width: 70ch;
}

.drill-body {
  overflow: auto;
  padding: 0 24px 24px;
}

.drill-body .analytics-table-wrapper {
  max-height: none;
  border: none;
  box-shadow: none;
}

.risk-card {
  background: #fff;
  border-radius: 10px;
  padding: 14px 18px;
  margin-bottom: 10px;
  border-left: 4px solid #ffc107;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.risk-card.risk-high { border-left-color: #dc3545; }

.risk-label {
  font-weight: 600;
  color: var(--text);
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.risk-card.risk-high .risk-label i { color: #dc3545; }
.risk-card.risk-medium .risk-label i { color: #dc9800; }

.risk-detail {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 4px;
}

.text-up { color: #28a745; font-size: 15px; }
.text-down { color: #dc3545; font-size: 15px; }

.risk-card.risk-clickable {
  cursor: pointer;
  transition: all 0.15s ease;
}

.risk-card.risk-clickable:hover {
  transform: translateX(2px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.1);
}

.risk-go {
  margin-left: auto;
  font-size: 12px;
  font-weight: 500;
  color: var(--accent-strong);
  display: flex;
  align-items: center;
  gap: 5px;
}

.risk-label { justify-content: flex-start; }

.sortable-th { cursor: pointer; user-select: none; }
.sortable-th:hover { background: var(--surface-hover); color: var(--accent-strong); }
.sort-icon { margin-left: 4px; font-size: 11px; opacity: 0.55; }

/* Analytics navbar on a phone.
 *
 * The shared .nav-actions rule turns four full-width buttons into a 300px
 * stack on this page, because analytics has no mobile menu toggle to hide
 * them behind. One scrollable row keeps every link reachable and gives the
 * numbers the screen back. */
@media (max-width: 768px) {
  #analytics-page .nav-content {
    gap: 10px;
  }

  #analytics-page .nav-brand span {
    display: none;
  }

  #analytics-page .nav-actions {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 6px;
    -webkit-overflow-scrolling: touch;
  }

  #analytics-page .nav-actions .btn {
    padding: 6px 10px;
    font-size: 12px;
    white-space: nowrap;
  }
}

/* A flagged line opens the invoice it came from. */
.row-clickable {
  cursor: pointer;
}

.row-clickable:hover {
  background: #eef0fa;
}

.drill-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.drill-body .row-flagged td {
  background: #fff5f5;
}

/* Views added alongside the action list. */

.risk-card.risk-low { border-left-color: #6c757d; }
.risk-card.risk-low .risk-label i { color: #6c757d; }

/* The action list carries a pound figure in the slot the risk cards use for
   "see detail", so it needs to read as a number rather than as a link. */
#actions-list .risk-go,
#workingcapital-actions .risk-go,
#quality-issues .risk-go {
  color: var(--text);
  font-weight: 600;
  font-size: 13px;
  white-space: nowrap;
}

.target-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  background: #fff;
  border-radius: 10px;
  padding: 14px 18px;
  margin-bottom: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.target-form label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
}

.target-form input {
  padding: 7px 10px;
  border: 1px solid #d8dce6;
  border-radius: 6px;
  font-size: 13px;
  min-width: 130px;
}

.fee-input {
  width: 110px;
  padding: 6px 8px;
  border: 1px solid #d8dce6;
  border-radius: 6px;
  font-size: 13px;
}

/* Row-level emphasis inside dense tables, where a full risk card would not
   fit but the number still needs to be read as good or bad. */
.analytics-table .text-up,
.analytics-table .text-down {
  font-size: 13px;
  font-weight: 600;
}

/* Row drill-downs. */

.row-clickable {
  cursor: pointer;
}

.analytics-table tbody tr.row-clickable:hover td {
  background: #eef0fb;
}

/* Invoices that look already settled: present, but visibly not the point. */
.row-muted td {
  opacity: 0.55;
  font-style: italic;
}

/* Loss-making rows on the eBay page - a wash of red down the left edge. */
.row-bad td:first-child {
  box-shadow: inset 3px 0 0 #dc3545;
}
.row-bad td {
  background: rgba(220, 53, 69, 0.05);
}

/* eBay Movement tab: two columns on wide screens, one on narrow. */
.ebay-split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 8px 18px;
  align-items: start;
}
.ebay-split .section-heading {
  margin-top: 14px;
}
/* Long listing titles wrap; the figures beside them stay on one line and
   right-align so the eye can run down the column. */
.ebay-split .analytics-table td:first-child,
#tab-losses .analytics-table td:first-child,
#tab-pricechanges .analytics-table td:first-child {
  white-space: normal;
  min-width: 160px;
}
.ebay-split .analytics-table td:not(:first-child),
#tab-losses .analytics-table td:not(:first-child),
#tab-pricechanges .analytics-table td:not(:first-child) {
  white-space: nowrap;
  text-align: right;
}
#tab-losses .analytics-table th:not(:first-child),
#tab-pricechanges .analytics-table th:not(:first-child),
.ebay-split .analytics-table th:not(:first-child) {
  text-align: right;
}

/* Price-check severities. Every line is coloured, so a clean line reads as
   "checked and fine" rather than "not looked at". */
.sev-row-3 td { background: #fdecec; }
.sev-row-2 td { background: #fdf3e3; }
.sev-row-1 td { background: #fcfae3; }
.sev-row-0 td { background: #eefaf0; }

.sev-ok {
  color: #1d7a3d;
  font-size: 12px;
}

.severity-key {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 14px;
  font-size: 12px;
  color: var(--text-muted);
}

.severity-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.severity-chip i {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  display: inline-block;
  border: 1px solid rgba(0, 0, 0, 0.12);
}

.severity-chip.sev-3 i { background: #fdecec; border-color: #dc3545; }
.severity-chip.sev-2 i { background: #fdf3e3; border-color: #dc9800; }
.severity-chip.sev-1 i { background: #fcfae3; border-color: #c9b800; }
.severity-chip.sev-0 i { background: #eefaf0; border-color: #28a745; }

/* Detail panel internals. */

.detail-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
}

.detail-stat {
  background: #f5f6fa;
  border-radius: 8px;
  padding: 10px 14px;
  min-width: 110px;
}

.detail-stat-warn {
  background: #fff8e6;
}

.detail-stat-value {
  font-size: 17px;
  font-weight: 700;
  color: #222;
}

.detail-stat-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  margin-top: 2px;
}

.drill-body .detail-heading {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  margin: 20px 0 8px;
}

.drill-body .section-note {
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.5;
  margin-bottom: 14px;
}

/* Monthly bars, drawn as elements so the panel can be opened and closed
   without tracking and destroying a chart instance each time. */
.detail-bars {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 120px;
  padding: 8px 0 0;
  margin-bottom: 8px;
}

.detail-bar {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  height: 100%;
  min-width: 0;
}

.detail-bar-fill {
  width: 100%;
  background: var(--accent);
  border-radius: 3px 3px 0 0;
  min-height: 2px;
}

.detail-bar-label {
  font-size: 9px;
  color: var(--text-faint);
  margin-top: 4px;
  white-space: nowrap;
}

/* ---------- Stock Changes worklist ---------- */

/* Everything outside a card sits straight on the purple gradient, where the
   greys used inside cards drop to about 1.05:1. On-gradient text is white or
   a high-alpha white; dark text only ever appears on a white surface. */

.sc-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 20px;
  flex-wrap: wrap;
}

/* Let the blurb take a column and the sync badge sit off to the right,
   rather than wrapping underneath and reading as part of the first section. */
.sc-header > div:first-child {
  flex: 1 1 420px;
}

.sc-header {
  margin-bottom: 28px;
}

.sc-header h1,
.sc-header p {
  color: var(--text);
}

.sc-header p {
  color: var(--text-muted);
}

.sc-sync {
  margin-left: auto;
}

.sc-sync {
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
  padding-top: 6px;
}

.sc-sync.stale {
  color: var(--danger);
  background: var(--danger-soft);
  border: 1px solid #f5c9c4;
  font-weight: 700;
  border-radius: 999px;
  padding: 5px 12px;
}

.sc-section {
  margin-bottom: 40px;
}

.sc-section-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.sc-section-head h2 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
  letter-spacing: -0.2px;
  margin: 0;
  color: var(--text);
}

.sc-icon-out {
  color: var(--danger);
}

.sc-icon-in {
  color: var(--ok);
}

.sc-count {
  background: var(--accent-soft);
  color: var(--accent-strong);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 13px;
  font-weight: 700;
}

.sc-count.zero {
  background: var(--surface-hover);
  color: var(--text-faint);
}

.sc-section-sub {
  color: var(--text-muted);
  font-size: 14px;
  margin: 4px 0 16px;
}

.sc-bulk {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* The shared outline button now sits on the same neutral canvas everywhere,
   so this no longer needs an on-gradient variant - it only keeps the block
   so the selector stays available for bulk-action tweaks. */
.sc-bulk .btn-outline {
  color: var(--text);
  border-color: var(--border-strong);
  background: var(--surface);
}

.sc-bulk .btn-outline:hover {
  color: var(--text);
  border-color: var(--border-strong);
  background: var(--surface-hover);
}

.sc-section .orders-empty {
  color: var(--text-muted);
}

.sc-section .orders-empty h3 {
  color: var(--text);
}

.sc-day-heading {
  grid-column: 1 / -1;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
  margin: 8px 0 0;
}

/* The SKU is the lookup key on Amazon and eBay, so it leads the card. */
.sc-sku {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 13px;
  font-weight: 700;
  color: #212529;
  background: #f1f3f5;
  border-radius: 4px;
  padding: 2px 8px;
}

.sc-sku.missing {
  color: #adb5bd;
  font-style: italic;
  font-family: inherit;
  font-weight: 400;
}

.sc-name {
  font-weight: 600;
  color: #212529;
  margin: 10px 0 4px;
  line-height: 1.35;
}

.sc-meta {
  font-size: 13px;
  color: #6c757d;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
}

.sc-inactive {
  display: inline-block;
  margin-top: 8px;
  font-size: 12px;
  font-weight: 600;
  color: #b8860b;
  background: #fff3cd;
  border-radius: 4px;
  padding: 3px 8px;
}

.sc-platforms {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid #eee;
}

.sc-plat-btn {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 2px solid #dee2e6;
  background: white;
  color: #495057;
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: all 0.2s ease;
}

.sc-plat-btn:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent-strong);
}

.sc-plat-btn.handled {
  border-color: #28a745;
  background: #eaf7ee;
  color: #1e7e34;
}

.sc-plat-btn:disabled {
  opacity: 0.55;
  cursor: default;
}

.sc-done-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  padding: 8px 0;
}

.sc-done-toggle:hover {
  color: var(--text);
}

.sc-done-toggle i {
  transition: transform 0.2s ease;
}

.sc-done-toggle.open i {
  transform: rotate(90deg);
}

.sc-done-list {
  margin-top: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
}

.sc-done-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  font-size: 13px;
  border-bottom: 1px solid #f1f3f5;
  flex-wrap: wrap;
}

.sc-done-row:last-child {
  border-bottom: none;
}

.sc-done-row .sc-done-who {
  color: #6c757d;
  margin-left: auto;
}

.sc-undo {
  background: none;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  color: #6c757d;
  font-family: inherit;
  font-size: 12px;
  padding: 4px 10px;
  cursor: pointer;
}

.sc-undo:hover {
  border-color: #dc3545;
  color: #dc3545;
}

@media (max-width: 600px) {
  .sc-header {
    flex-direction: column;
  }
  .sc-platforms {
    flex-direction: column;
  }
}

/* Stock Changes navbar on a phone.
 *
 * Same problem the analytics page has: the shared rule hides .nav-actions
 * behind a .mobile-menu-toggle this page does not have, and is in any case
 * overridden by the later base .nav-actions display:flex, so four full-width
 * buttons stack and cover the header. One scrollable row, matching the fix
 * already used for #analytics-page. */
@media (max-width: 768px) {
  #stock-changes-page .nav-content {
    gap: 10px;
  }

  #stock-changes-page .nav-brand span {
    display: none;
  }

  #stock-changes-page .nav-actions {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 6px;
    -webkit-overflow-scrolling: touch;
  }

  #stock-changes-page .nav-actions .btn {
    padding: 6px 10px;
    font-size: 12px;
    white-space: nowrap;
  }
}

/* ---------- Sage connection (admin) ---------- */

.sage-card {
  background: #fff;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.sage-status,
.sage-help {
  font-size: 14px;
  color: #495057;
}

.sage-good,
.sage-bad {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 16px;
}

.sage-good {
  background: #eaf7ee;
  color: #1e7e34;
}

.sage-bad {
  background: #fdecee;
  color: #b02a37;
  margin-bottom: 0;
}

.sage-facts {
  display: grid;
  grid-template-columns: minmax(120px, auto) 1fr;
  gap: 8px 20px;
  margin: 0;
  font-size: 14px;
}

.sage-facts dt {
  font-weight: 600;
  color: #6c757d;
}

.sage-facts dd {
  margin: 0;
  color: #212529;
}

.sage-label {
  display: block;
  font-weight: 600;
  font-size: 13px;
  margin: 18px 0 6px;
  color: #212529;
}

/* Monospace so a pasted JWT can be eyeballed for truncation. */
.sage-input {
  width: 100%;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 13px;
  line-height: 1.5;
  padding: 12px;
  border: 2px solid #dee2e6;
  border-radius: 8px;
  resize: vertical;
  background: var(--surface-sunken);
  color: #212529;
}

.sage-input:focus {
  outline: none;
  border-color: var(--accent);
  background: #fff;
}

.sage-actions {
  display: flex;
  gap: 10px;
  margin-top: 16px;
}

@media (max-width: 768px) {
  #sage-page .nav-brand span {
    display: none;
  }

  #sage-page .nav-actions {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 6px;
  }

  .sage-facts {
    grid-template-columns: 1fr;
    gap: 2px 0;
  }

  .sage-facts dd {
    margin-bottom: 10px;
  }
}

/* ---------- Stock Changes: table layout ---------- */

/* Wide tables scroll inside their own box so the page body never does. */
.sc-table-wrap {
  overflow-x: auto;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.sc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  min-width: 720px;
}

.sc-table thead th {
  text-align: left;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #6c757d;
  padding: 14px 16px;
  border-bottom: 2px solid #e9ecef;
  white-space: nowrap;
}

.sc-table td {
  padding: 12px 16px;
  border-bottom: 1px solid #f1f3f5;
  vertical-align: middle;
}

.sc-table tbody tr:last-child td {
  border-bottom: none;
}

.sc-table tbody tr:hover td {
  background: #f8f9fb;
}

.sc-table .sc-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.sc-name-cell {
  font-weight: 600;
  color: #212529;
  min-width: 220px;
}

.sc-day-row td {
  background: #f1f3f5;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #6c757d;
  padding: 8px 16px;
}

.sc-table tbody tr.sc-day-row:hover td {
  background: #f1f3f5;
}

.sc-plat-col {
  width: 1%;
  white-space: nowrap;
  text-align: center;
}

/* Compact the shared button for table cells. */
.sc-table .sc-plat-btn {
  padding: 6px 12px;
  font-size: 12px;
  min-width: 92px;
}

.sc-icon-new {
  color: #ffe08a;
}

@media (max-width: 768px) {
  .sc-table {
    min-width: 620px;
  }

  .sc-name-cell {
    min-width: 160px;
  }

  .sc-table .sc-plat-btn {
    min-width: 0;
  }

  .sc-table .sc-plat-btn span {
    display: none;
  }
}

.sage-warn {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 16px;
  background: #fff8e1;
  color: #8a6100;
}

/* Two-column layout for remove from sale and put back on sale */
.sc-two-column {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 40px;
}

.sc-column {
  display: flex;
  flex-direction: column;
}

.sc-column .sc-section {
  margin-bottom: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.sc-column .sc-table-wrap {
  flex: 1;
}

/* Mobile: stack columns vertically */
@media (max-width: 1024px) {
  .sc-two-column {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   Temu page
   ==========================================================================
   Reuses the analytics shell wholesale - side nav, control strip, KPI grid,
   chart cards, tables - so only what is genuinely new to this page lives
   here. */

#temu-page .container {
  /* Wide tables, and no side nav competing for the row. */
  max-width: 1440px;
  padding-top: 100px;
}

/* Same reasoning as #analytics-page: the shared .nav-actions rule stacks four
 * full-width buttons on a phone, and this page has no menu toggle to hide them
 * behind, so the header ends up underneath them. One scrollable row instead. */
@media (max-width: 768px) {
  #temu-page .container {
    padding-top: 76px;
  }

  #temu-page .nav-content {
    gap: 10px;
  }

  #temu-page .nav-brand span {
    display: none;
  }

  #temu-page .nav-actions {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 6px;
    -webkit-overflow-scrolling: touch;
  }

  #temu-page .nav-actions .btn {
    padding: 6px 10px;
    font-size: 12px;
    white-space: nowrap;
  }
}

/* How old the imported file is. Nothing on this page syncs on its own, so a
 * quiet channel and a stale export look identical without this. */
.temu-stale {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

/* Now that the header strip is white rather than purple, the tint alone is
   too faint to read as a chip - each state carries a border of its own. */
.temu-stale.stale-ok {
  background: var(--ok-soft);
  border: 1px solid #abefc6;
  color: var(--ok);
}

.temu-stale.stale-warn {
  background: var(--warn-soft);
  border: 1px solid #fedf89;
  color: var(--warn);
}

.temu-stale.stale-bad {
  background: var(--danger-soft);
  border: 1px solid #fecdc9;
  color: var(--danger);
}

/* The worklist. Each row is a button because each row goes somewhere. */
.temu-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
}

.temu-action {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  background: white;
  border: 1px solid var(--border);
  border-left: 4px solid #adb5bd;
  border-radius: 10px;
  padding: 12px 16px;
  cursor: pointer;
  font-family: inherit;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.temu-action:hover {
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.09);
  transform: translateY(-1px);
}

.temu-action > i {
  font-size: 18px;
  width: 22px;
  text-align: center;
  color: #adb5bd;
}

.temu-action-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.temu-action-text strong {
  font-size: 14px;
  color: var(--text);
}

.temu-action-text span {
  font-size: 12.5px;
  color: var(--text-muted);
  line-height: 1.4;
}

.temu-action-value {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  flex-shrink: 0;
  max-width: 190px;
}

.temu-action-amount {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
}

.temu-action-unit {
  font-size: 10.5px;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.3px;
  line-height: 1.3;
}

.temu-action-out { border-left-color: #dc3545; }
.temu-action-out > i { color: #dc3545; }
.temu-action-critical { border-left-color: #fd7e14; }
.temu-action-critical > i { color: #fd7e14; }
.temu-action-cancel { border-left-color: #dc3545; }
.temu-action-cancel > i { color: #dc3545; }
.temu-action-falling { border-left-color: #ffc107; }
.temu-action-falling > i { color: #c79100; }
.temu-action-unmapped { border-left-color: var(--accent); }
.temu-action-unmapped > i { color: var(--accent-strong); }
.temu-action-fading { border-left-color: #6c757d; }
.temu-action-stale { border-left-color: #0d6efd; }
.temu-action-stale > i { color: #0d6efd; }

.temu-action-clear {
  border-left-color: #28a745;
  cursor: default;
}

.temu-action-clear > i { color: #28a745; }
.temu-action-clear:hover { box-shadow: none; transform: none; }

/* A second line inside a KPI card, for the comparison the headline invites. */
.kpi-sub {
  font-size: 10.5px;
  color: var(--text-faint);
  margin-top: 3px;
  line-height: 1.3;
}

.temu-up { color: #1c7c33; font-weight: 600; }
.temu-down { color: #b02a37; font-weight: 600; }
.temu-muted { color: var(--text-faint); font-size: 12px; }

.temu-empty {
  text-align: center;
  color: var(--text-muted);
  padding: 22px 12px;
  font-style: italic;
}

.temu-rowcount {
  font-size: 12px;
  color: var(--text-muted);
  margin-left: auto;
  white-space: nowrap;
}

/* Days of cover, as a colour before it is a number. Tinted for the same
   reason as .badge above - four of these per row, forty rows to a table. */
.badge-out { background: var(--danger-soft); border-color: #fecdc9; color: var(--danger); }
.badge-critical { background: #fff4ed; border-color: #f9dbaf; color: #b93815; }
.badge-low { background: var(--warn-soft); border-color: #fedf89; color: var(--warn); }
.badge-ok { background: var(--ok-soft); border-color: #abefc6; color: var(--ok); }
.badge-partial { background: var(--surface-hover); border-color: var(--border); color: var(--text-muted); }

.temu-row-out td { background: rgba(220, 53, 69, 0.05); }
.temu-row-critical td { background: rgba(253, 126, 20, 0.05); }

/* Two charts need the vertical room a ranked bar list takes; the rest fit the
 * shared 240px card. */
.chart-card.temu-chart-tall {
  height: 430px;
  grid-column: 1 / -1;
}

/* Upload */
.temu-upload {
  background: white;
  border: 2px dashed #cbd5e0;
  border-radius: 12px;
  padding: 30px 24px;
  text-align: center;
  margin-bottom: 16px;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.temu-upload.dragging {
  border-color: var(--accent);
  background: #f5f6ff;
}

.temu-upload > i {
  font-size: 34px;
  color: var(--accent-strong);
  margin-bottom: 10px;
}

.temu-upload h3 {
  font-size: 16px;
  color: var(--text);
  margin-bottom: 8px;
}

.temu-upload p {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.55;
  max-width: 640px;
  margin: 0 auto 16px;
}

.temu-upload .btn {
  margin: 0 4px;
}

.temu-upload-status {
  border-radius: 10px;
  padding: 12px 16px;
  font-size: 13.5px;
  line-height: 1.5;
  margin-bottom: 20px;
}

.temu-status-info { background: #eef1ff; color: #3c4a9e; border: 1px solid #c9d1ff; }
.temu-status-success { background: #e8f7ec; color: #1c7c33; border: 1px solid #b7e4c2; }
.temu-status-error { background: #fdecee; color: #b02a37; border: 1px solid #f3c2c8; }

/* Smoothness for the Action List jumps lives here rather than in the
 * scrollIntoView call, so a browser that does not animate scrolling still moves
 * the page instead of silently doing nothing. */
#temu-page {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  #temu-page { scroll-behavior: auto; }
}

/* Clears the fixed navbar and the sticky control strip when an Action List
 * click scrolls a section into view, so the heading does not come to rest
 * underneath them. The tab sections are targets in their own right - an action
 * whose answer is the whole tab jumps to #tab-<name> rather than to a heading
 * inside it - so they need the same clearance. */
.section-heading,
.temu-upload,
.analytics-content > section[id^="tab-"],
/* The ranked issue list on Data Quality is a jump target but not a heading:
 * four of the seven checks have no table of their own and land here. */
#quality-issues {
  scroll-margin-top: 150px;
}

/* Where an Action List click landed. Brief, because it is a pointer rather than
 * a state - the reader needs to find the section, not be reminded of it. */
@keyframes temu-jump-flash {
  from { background: rgba(79, 70, 229, 0.14); }
  to { background: transparent; }
}

.temu-jumped {
  animation: temu-jump-flash 1.6s ease-out;
  border-radius: 6px;
}

@media (prefers-reduced-motion: reduce) {
  .temu-jumped { animation: none; }
}

/* ---------------------------------------------------- Temu SKU matching --- */
/* Matching a listing to a catalogue product, on the Import tab.
   Everything interactive sits on white, like .temu-upload above it: the page
   background is a purple gradient, and the shared .btn-outline is var(--accent) on
   transparent, which disappears against it. */

.temu-skumatch {
  background: white;
  border-radius: 12px;
  border: 1px solid var(--border);
  padding: 16px;
  margin-bottom: 16px;
}

.temu-skumatch-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.temu-skumatch-controls #sku-search { flex: 1 1 16rem; min-width: 12rem; }
.temu-skumatch-controls .btn { margin-left: auto; white-space: nowrap; }
.temu-skumatch-count { color: var(--text-faint); font-size: 12px; }

/* The wrapper caps height at 640px, which is right for a report but wrong for
   a worklist you are scrolling through one row at a time. */
.temu-skumatch .analytics-table-wrapper { max-height: 70vh; }

.temu-input {
  padding: 8px 10px;
  border: 1px solid #d7dbe0;
  border-radius: 6px;
  font: inherit;
  font-size: 13px;
  background: #fff;
  color: var(--text);
}
.temu-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

/* .temu-muted and .btn-sm already exist above - redefining them here would
   silently restyle every other use on the page. */
.temu-error { color: #963226; margin-top: 0.6rem; font-size: 0.9rem; }

.temu-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(17, 24, 39, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 1000;
}
.temu-modal {
  background: #fff;
  color: var(--text);
  border-radius: 10px;
  padding: 1.5rem;
  width: min(34rem, 100%);
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
}
.temu-modal h3 { margin: 0 0 0.25rem; }

.temu-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 1rem 0 0.5rem;
}
.temu-field > span { font-weight: 600; font-size: 0.9rem; }

/* Bounded so a broad search cannot push the buttons off the screen. */
.temu-picker-results { max-height: 13rem; overflow-y: auto; }
.temu-picker-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.6rem;
  border: 0;
  border-bottom: 1px solid #eef0f2;
  background: none;
  font: inherit;
  cursor: pointer;
}
.temu-picker-row:hover,
.temu-picker-row:focus-visible { background: #f3f0ff; }

.temu-modal-actions {
  display: flex;
  gap: 0.6rem;
  justify-content: flex-end;
  margin-top: 1.25rem;
}
.temu-modal-actions .btn:nth-child(2) { margin-right: auto; }

/* Two counts instead of a decimal. "How much of a case is this" is not a
   question anyone can answer off a packet; the two that make it up are. */
.temu-ratio {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}
.temu-ratio label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 8rem;
}
.temu-ratio label em {
  font-style: normal;
  font-size: 11px;
  color: var(--text-faint);
}
.temu-ratio-op {
  padding-bottom: 20px;
  color: var(--text-faint);
  font-size: 15px;
}
.temu-ratio-out {
  padding: 8px 12px 8px 0;
  font-weight: 600;
  font-size: 15px;
  min-width: 4rem;
}
.temu-linkbtn {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--accent-strong);
  text-decoration: underline;
  cursor: pointer;
}

/* The profit and loss statement.
 *
 * Deliberately not an .analytics-table: this is read down a column of money
 * rather than scanned across rows, so the amounts are right-aligned on a fixed
 * column and the subtotals carry rules above them the way a statement does. */
.temu-pnl-wrap {
  background: white;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 4px;
  margin-bottom: 16px;
  overflow-x: auto;
}

.temu-pnl {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.temu-pnl td {
  padding: 9px 16px;
  vertical-align: top;
}

.temu-pnl .pnl-amount {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  width: 1%;
  font-weight: 500;
}

.temu-pnl .pnl-note {
  font-size: 12px;
  color: var(--text-faint);
  line-height: 1.45;
  margin-top: 2px;
}

.temu-pnl tr.pnl-subtotal td {
  border-top: 1px solid #dee2e6;
  font-weight: 700;
  color: var(--text);
}

.temu-pnl tr.pnl-final td {
  border-top: 2px solid #adb5bd;
  border-bottom: 2px solid #adb5bd;
  font-size: 15px;
}

.temu-pnl tr.pnl-memo td {
  border-top: 1px dashed #dee2e6;
  color: var(--text-muted);
}

.temu-pnl tr.pnl-missing .pnl-amount {
  color: var(--text-faint);
  font-weight: 500;
}

/* Section headings inside the P&L statement. Income, costs and the delivery
 * breakout are different questions, and running them together as one column of
 * numbers makes the reader do the grouping. */
.temu-pnl tr.pnl-header td {
  padding-top: 20px;
  padding-bottom: 4px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--accent-strong);
}

.temu-pnl tr.pnl-header:first-child td {
  padding-top: 6px;
}

/* --- Post to Sage ------------------------------------------------------- */
/* ---------------------------------------------------------------------------
 * The three steps.
 *
 * Post to Sage is the one screen in the app that writes to the live accounts,
 * and it has a real order to it: get the files, look at what would be created,
 * then say yes. Everywhere else on this page you can read the tabs in any
 * order; here you cannot, so the page says which of the three you are on.
 *
 * Reporting only - see setSageStep() for why none of it is clickable.
 * ------------------------------------------------------------------------ */
.sage-steps {
  display: flex;
  align-items: center;
  gap: 0;
  list-style: none;
  margin: 0 0 14px;
  padding: 12px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.sage-step {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

/* The rule between two steps takes all the room left over, so three steps
   spread across whatever width the column happens to be. */
.sage-step:not(:last-child)::after {
  content: "";
  flex: 1 1 auto;
  min-width: 24px;
  height: 1px;
  background: var(--border-strong);
  margin: 0 16px;
}

.sage-step:not(:last-child) {
  flex: 1 1 auto;
}

.sage-step-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-faint);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Both glyphs are in the markup and CSS picks one, so changing step never
   rewrites text a screen reader may be sitting on. */
.sage-step-dot i {
  display: none;
  font-size: 11px;
}

.sage-step-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-faint);
  white-space: nowrap;
}

.sage-step.is-current .sage-step-dot {
  background: var(--accent);
  border-color: var(--accent);
  color: #ffffff;
}

.sage-step.is-current .sage-step-name {
  color: var(--text);
  font-weight: 600;
}

.sage-step.is-done .sage-step-dot {
  background: var(--accent-soft);
  border-color: var(--accent-border);
  color: var(--accent-strong);
}

.sage-step.is-done .sage-step-dot b {
  display: none;
}

.sage-step.is-done .sage-step-dot i {
  display: inline;
}

.sage-step.is-done .sage-step-name {
  color: var(--accent-strong);
}

.sage-step.is-done::after {
  background: var(--accent-border);
}

@media (max-width: 640px) {
  /* Below this the three labels cannot share a line without truncating, and a
     step called "Confirm &" is worse than no label. The numbers carry it. */
  .sage-steps {
    padding: 12px 14px;
  }

  .sage-step-name {
    display: none;
  }

  .sage-step.is-current .sage-step-name {
    display: inline;
  }

  .sage-step:not(:last-child)::after {
    margin: 0 10px;
  }
}


/* Which of the two this is, in the order you do them. The heading says what
   the file is; this says when. */
.sage-upload-step {
  display: inline-block;
  margin-bottom: 6px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-faint);
}

/* The visible target. The card around it is the one that actually listens for
   a drop - a file let go an inch outside the rectangle should still land - so
   this is a button first and a dropzone second, and it says both. */
.sage-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  width: 100%;
  padding: 13px 16px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface-sunken);
  color: var(--text);
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}

.sage-dropzone i {
  font-size: 15px;
  color: var(--text-faint);
  margin-bottom: 3px;
  transition: color 0.15s ease;
}

.sage-dropzone-main {
  font-size: 13px;
  font-weight: 600;
}

.sage-dropzone-sub {
  font-size: 12px;
  color: var(--text-faint);
}

.sage-dropzone:hover,
.sage-upload.dragging .sage-dropzone {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.sage-dropzone:hover i,
.sage-upload.dragging .sage-dropzone i {
  color: var(--accent-strong);
}

.sage-dropzone:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* A card holding a file says so at its edge, so the pair can be read at a
   glance without parsing two filenames. */
.sage-upload.is-loaded {
  border-style: solid;
  border-color: var(--accent-border);
}

.sage-file-name {
  display: block;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 0.74rem;
  color: var(--text);
  overflow-wrap: anywhere;
}

.sage-file-meta {
  display: block;
  margin-top: 3px;
  font-weight: 600;
  color: var(--ok);
}

.sage-file-meta i {
  margin-right: 4px;
}

/* One step, one action: the button that moves you on is the full width of the
   column rather than a chip floating beside a paragraph. */
.sage-continue {
  width: 100%;
  justify-content: center;
  padding: 11px 16px;
  font-size: 14px;
  font-weight: 600;
}

.sage-continue:disabled {
  background: var(--surface-hover);
  border-color: var(--border-strong);
  color: var(--text-faint);
  cursor: not-allowed;
  box-shadow: none;
}

/* Problems only, and it holds no space until there is one - it is the last
   thing above the run panel, so an empty reserved line here pushes the run
   itself further down the page for nothing. */
.sage-status-line {
  margin: 10px 0 0;
  font-size: 0.85rem;
  color: var(--danger);
}

.sage-status-line:not(:has(#sage-status:not(:empty))) {
  display: none;
}

/* The history is reference, not a step - collapsed until asked for. */
.sage-collapse > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  list-style: none;
}

.sage-collapse > summary::-webkit-details-marker {
  display: none;
}

/* The chevron is drawn here rather than in the markup so it can rotate with
   the open state without any script. */
.sage-collapse > summary::before {
  content: "\f054";
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  font-size: 11px;
  color: var(--text-faint);
  transition: transform 0.15s ease;
}

.sage-collapse[open] > summary::before {
  transform: rotate(90deg);
}

.sage-collapse-count {
  margin-left: auto;
  padding: 1px 9px;
  border-radius: 999px;
  background: var(--surface-hover);
  color: var(--text-muted);
  font-size: 0.72rem;
  font-weight: 700;
}

.sage-collapse[open] > summary {
  margin-bottom: 12px;
}

/* Two upload slots side by side, because the two reports do different jobs and
   pairing them in one dropzone is how the wrong file gets sent. */
.sage-uploads {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}

/* The two slots are one control, so they hold the same height even when one
   carries more explanation than the other - two boxes of different heights
   read as two unrelated things. The state chip is pushed to the bottom edge
   so both filenames land on the same line. */
.sage-upload {
  display: flex;
  flex-direction: column;
}

/* Sat on `margin-top: auto` so the two filenames lined up at the bottom of
   the pair. The taller card sets the height either way, so all that bought
   was a band of empty card under the shorter one's dropzone. */
.sage-upload .sage-upload-state {
  padding-top: 10px;
}

.sage-upload {
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.sage-upload.dragging {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.sage-upload h3 {
  margin: 0 0 5px;
  font-size: 0.95rem;
  color: var(--text);
}

.sage-upload p {
  margin: 0 0 10px;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text-muted);
}

.sage-upload-state {
  display: block;
  margin-top: 10px;
  font-size: 0.82rem;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

/* The loaded state used to be a tinted chip, back when it was the only sign a
   file had arrived. The card now carries that itself - a solid green edge -
   so this drops to plain text: filename, then the size behind a tick. Two
   green boxes inside one green-edged card was three signals for one fact.

   Wraps rather than truncates: a successful upload writes a second line here
   ("also imported: N new, M updated") and an ellipsis would eat the half that
   says what the file did. A Temu filename is 50 characters of hex with
   nothing to break on, hence `anywhere` on .sage-file-name. */
.sage-upload-state.ok {
  line-height: 1.5;
}

.sage-upload-state.ok .sage-upload-sub {
  display: block;
  margin-top: 4px;
  color: var(--text-muted);
}

.sage-upload-state.bad {
  color: var(--danger);
  font-weight: 600;
}

.sage-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

.sage-status {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.sage-run-status {
  display: inline-block;
  margin-left: 10px;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  vertical-align: middle;
}

.sage-run-status.running { background: #fff3cd; color: #7a5c00; }
.sage-run-status.done    { background: #d8f3e3; color: #1e7f4f; }
.sage-run-status.failed  { background: #fbdcd8; color: #b02a1c; }

/* The script's own output, kept verbatim. It is the same text a person would
   read in a terminal, and paraphrasing it on the way to the page is how the
   page and the books start telling different stories. */
.sage-log {
  margin: 16px 0 0;
  padding: 14px 16px;
  background: #1e1e28;
  color: #e6e6ef;
  border-radius: 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.76rem;
  line-height: 1.55;
  max-height: 420px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Both the poll and the history open this, and the navbar is fixed - without
   a scroll margin `scrollIntoView` parks the panel's heading underneath it. */
#sage-run {
  scroll-margin-top: calc(var(--navbar-h) + 12px);
}

/* A panel that grows with what is in it.
   Deliberately not .chart-card, which is 240px tall by design because it holds
   a canvas - putting a table of twenty invoices in one clips it to a blank
   band, which is exactly what happened the first time. */
.sage-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 18px 20px;
  margin-top: 18px;
}

.sage-panel > h3 {
  margin: 0 0 6px;
  font-size: 0.95rem;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 8px;
}

/* .section-note is the muted grey used on the canvas; this is the same idea
   inside a panel, kept separate so the two can drift if a panel ever gets a
   tinted background. */
.sage-note {
  color: var(--text-muted);
  font-size: 0.82rem;
  line-height: 1.55;
  margin: 8px 0 0;
}

/* The review screen, between "what would this do" and "do it". */
.sage-section-head {
  margin: 22px 0 10px;
  font-size: 0.95rem;
}

.sage-section-head span {
  margin-left: 8px;
  padding: 1px 9px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-strong);
  font-size: 0.72rem;
  font-weight: 700;
}

.sage-review input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; }

.sage-review input[type="date"] {
  padding: 4px 6px;
  border: 1px solid #d6d9e0;
  border-radius: 5px;
  font-size: 0.82rem;
  font-family: inherit;
}

/* A row nobody is going to post should read as switched off, not as an error. */
.sage-review tr:has(.sage-pick:not(:checked)) { opacity: 0.42; }
.sage-review tr:has(.sage-pick:not(:checked)) input[type="date"] { pointer-events: none; }

.sage-confirm {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid #ececf2;
}

#sage-selected {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-right: auto;
}

.sage-held strong { color: #b8860b; }

.sage-pending {
  border-left: 3px solid #f0c36d;
  padding-left: 12px;
}

/* Money and counts line up on their last digit, which is the only way a column
   of figures can be scanned. There is no global .num rule - the analytics
   tables set alignment per column - so the review screen states its own. */
.sage-review td.num,
.sage-review th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* The one column that is prose. Everything else is fixed width, so this is
   where the wrapping should happen rather than forcing the table wider. */
.sage-review td.sage-detail {
  white-space: normal;
  min-width: 260px;
  color: var(--text-muted);
}

/* What Sage refused. Amber rather than red: the run did most of its job, and
   these come back on the next one. */
.sage-failed {
  margin: 14px 0 20px;
  padding: 16px 18px;
  background: #fffaf0;
  border: 1px solid #f2dfae;
  border-left: 4px solid #e0a53a;
  border-radius: 10px;
}

.sage-failed h4 {
  margin: 0 0 6px;
  font-size: 0.95rem;
  color: #7a5c00;
  display: flex;
  align-items: center;
  gap: 8px;
}

.sage-failed .sage-confirm { border-top-color: #f2dfae; }

.sage-run-status.partial { background: #fff3cd; color: #7a5c00; }

/* --- a run in progress ---------------------------------------------------- */
/* The first version was a spinner and an empty black box, which told a person
   nothing except that something might be happening. The script narrates its own
   work; the page may as well say the same thing. */
.sage-live h3 { gap: 10px; }

.sage-spinner {
  width: 15px;
  height: 15px;
  border: 2px solid #d9d6f5;
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: sage-spin 0.8s linear infinite;
  flex: none;
}

@keyframes sage-spin { to { transform: rotate(360deg); } }

.sage-bar {
  height: 8px;
  background: #eceaf6;
  border-radius: 999px;
  overflow: hidden;
  margin: 12px 0 6px;
}

.sage-bar > span {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
  transition: width 0.4s ease;
}

/* Reading Sage is one request per invoice and has no count to report, so the
   bar says "moving" rather than pretending to know how far along it is. */
.sage-bar.indeterminate > span {
  width: 34%;
  animation: sage-slide 1.3s ease-in-out infinite;
}

@keyframes sage-slide {
  0%   { margin-left: -34%; }
  100% { margin-left: 100%; }
}

.sage-live-count {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 600;
  color: #4b3fbb;
}

.sage-live-detail { font-variant-numeric: tabular-nums; }

/* The raw output stays available but folded away. It is the thing to reach for
   when something looks wrong, not the thing to read while waiting. */
.sage-details { margin-top: 14px; }

.sage-details > summary {
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--accent-strong);
  user-select: none;
}

.sage-details > summary::marker { color: #b9b3e6; }
.sage-details .sage-log { margin-top: 10px; }

@media (prefers-reduced-motion: reduce) {
  .sage-spinner { animation: none; border-top-color: #d9d6f5; }
  .sage-bar.indeterminate > span { animation: none; width: 100%; opacity: 0.5; }
}

/* The second thing an upload did, said quietly under the first. */
.sage-upload-sub {
  display: inline-block;
  margin-top: 3px;
  font-weight: 400;
  color: var(--text-muted);
  font-size: 0.78rem;
}

/* Every row in the history opens the run it describes. */
.sage-run-row { cursor: pointer; }
.sage-run-row:hover { background: #f4f2ff; }
.sage-run-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.sage-run-open {
  color: #b9b3e6;
  text-align: right;
  width: 1%;
}

.sage-run-row:hover .sage-run-open { color: var(--accent-strong); }
