/* ═══════════════════════════════════════════════════════════════════════════
   Sales dashboard v2 — styles.css (the "looks" drawer).
   RELOCATED 1:1 from dashboard.html's <style> block (the 2026-07 file split,
   see SPLIT-HANDOFF.md) — same rules, same order, no redesign.
   ONE deliberate difference from v1: this page loads the SHARED shell
   (/Shared Data/shell.css + shell.js), so the embedded shell-twin rules that
   shell.css provides identically (sidebar, admin/group drop-downs, footer,
   collapse toggle, header tip-card) are NOT repeated here. Load order in
   dashboard.html is shell.css FIRST, then this file — so the page-specific
   rules below (top bar layout, table skin, KPI sizes) win ties and the page
   keeps the exact live Sales look.
   ═══════════════════════════════════════════════════════════════════════════ */
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f6fa; color: #2d3436; }

  /* ── Sidebar ── */
  .sidebar {
    position: fixed; top: 0; left: 0; width: 150px; height: 100vh;
    background: #1a1f2e; color: #fff; display: flex; flex-direction: column; z-index: 100;
  }
  .sidebar .logo { padding: 14px 10px; border-bottom: 1px solid #2d3450; display: flex; align-items: center; gap: 8px; }
  .sidebar .logo svg { width: 28px; height: 28px; flex-shrink: 0; }
  .sidebar .logo span { font-size: 16px; font-weight: 800; font-style: italic; letter-spacing: 1.5px; color: #e8eaed; }
  .sidebar nav { flex: 1; padding: 12px 0; }
  .sidebar nav a {
    display: flex; align-items: center; gap: 10px; padding: 11px 18px; color: #8892a4;
    text-decoration: none; font-size: 13px; font-weight: 500; transition: all .15s;
  }
  .sidebar nav a:hover { background: #252b3d; color: #fff; }
  .sidebar nav a.active { background: #252b3d; color: #ff9900; border-left: 3px solid #ff9900; }
  .sidebar nav a .icon { width: 18px; text-align: center; font-size: 15px; }
  .sidebar .sidebar-footer { padding: 14px 14px; border-top: 1px solid #2d3450; font-size: 11px; color: #555e70; }

  /* ── Main ── */
  .main { margin-left: 150px; }

  /* ── Top bar ── */
  .topbar {
    background: #232f3e; color: #fff; padding: 14px 28px; display: flex;
    align-items: center; justify-content: space-between; position: sticky; top: 0; z-index: 50;
  }
  .topbar h1 { font-size: 18px; font-weight: 600; letter-spacing: .3px; }
  .topbar .subtitle { font-size: 12px; color: #a0aec0; margin-top: 2px; }

  /* ── Custom range ── */
  /* The look moved into Shared Data/shell.css on 2026-08-20 so Account Health
     could use the same from/to pair (RULEBOOK Rule 6 — reuse first, and a
     component used by two pages belongs in the shell). Nothing page-local left.
     Sales' own date boxes stay a touch larger than the shell default: */
  .custom-range input[type="date"] { padding: 6px 10px; font-size: 13px; }

  /* ── Filter section ── */
  .filters-bar { display: flex; align-items: flex-start; gap: 16px; padding: 14px 28px; background: #fff; border-radius: 10px; margin: 0 28px var(--cg-row, 14px); box-shadow: 0 1px 3px rgba(0,0,0,.06); flex-wrap: wrap; }
  .filter-group { display: flex; flex-direction: column; gap: 6px; }
  .filter-group > label { font-size: 11px; font-weight: 600; color: #636e72; text-transform: uppercase; letter-spacing: .5px; }
  .filter-chips { display: flex; flex-wrap: wrap; gap: 6px; }
  .filter-chip {
    padding: 4px 12px; border: 1px solid #cbd5e0; border-radius: 16px; font-size: 12px;
    cursor: pointer; user-select: none; transition: all .15s; background: #fff;
  }
  .filter-chip:hover { border-color: #ff9900; }
  .filter-chip.active { background: #ff9900; color: #fff; border-color: #ff9900; }

  /* ── Dropdown filters ── */
  .dropdown-filter-wrap { position: relative; }
  .dropdown-filter-btn {
    padding: 4px 14px; border: 1px solid #cbd5e0; border-radius: 16px; font-size: 12px;
    cursor: pointer; background: #fff; display: flex; align-items: center; gap: 6px;
  }
  .dropdown-filter-btn:hover { border-color: #ff9900; }
  .dropdown-panel {
    display: none; position: absolute; top: 100%; left: 0; margin-top: 4px;
    background: #fff; border: 1px solid #e2e8f0; border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0,0,0,.1); padding: 8px 0; z-index: 200;
    max-height: 320px; overflow-y: auto; min-width: 220px;
  }
  .dropdown-panel.open { display: block; }
  .dropdown-panel .dd-header { display: flex; justify-content: space-between; padding: 4px 12px 8px; border-bottom: 1px solid #edf2f7; }
  .dropdown-panel .dd-header a { font-size: 11px; color: #ff9900; cursor: pointer; text-decoration: none; }
  .dropdown-panel .dd-header a:hover { text-decoration: underline; }
  .dropdown-panel label {
    display: flex; align-items: center; gap: 8px; padding: 5px 12px; font-size: 12px; cursor: pointer;
  }
  .dropdown-panel label:hover { background: #f7fafc; }
  .dropdown-panel input[type="checkbox"] { accent-color: #ff9900; }
  .count-badge { background: #ff9900; color: #fff; border-radius: 10px; padding: 0 7px; font-size: 11px; font-weight: 700; }

  /* ── KPI cards ── */
  /* PAGE RHYTHM (owner 2026-08-05): the four vertical gaps between the topbar,
     the summary cards, the Charts card, the filters bar and the table are ALL
     exactly --cg-row (14px) — they used to be 36 / 22 / 22 / 16. Change the
     variable, not the individual paddings, or they drift apart again. */
  .kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 16px; padding: var(--cg-row, 14px) 28px; }
  .kpi { background: #fff; border-radius: 10px; padding: 18px 20px; box-shadow: 0 1px 3px rgba(0,0,0,.06); }
  .kpi .label { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; color: #4a5568; margin-bottom: 6px; }
  .kpi .value { font-size: 28px; font-weight: 700; }
  .kpi .change { font-size: 14px; font-weight: 600; margin-top: 6px; }
  .kpi .change.up { color: #00b894; }
  .kpi .change.down { color: #d63031; }
  /* The card's bottom line — the comparison ("+48% vs last year") and the card's
     own link share ONE row (owner 2026-08-18). The Gross Profit card used to
     put its "P&L ▾" on a row of its own, and because the summary cards are a
     grid, that one extra row made all seven boxes taller. Baseline-aligned so
     the small link sits on the comparison's line rather than its box. */
  .kpi-foot { display: flex; align-items: baseline; gap: 0 10px; flex-wrap: wrap; margin-top: 6px; }
  .kpi-foot .change { margin-top: 0; }
  /* on the slim one-line tiles (cg-kpis-slim, 2026-09-07) the comparison and
     the P&L link ride the same line as the figure — no gap of their own */
  html[data-shell="v2"] .kpis.cg-kpis-slim .kpi-foot { margin: 0; gap: 0 8px; min-width: 0; }
  html[data-shell="v2"] .kpis.cg-kpis-slim .kpi { min-width: 0; }

  /* ── Charts grid ── */
  .charts-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; padding: 0 28px 22px; }
  .chart-card { background: #fff; border-radius: 10px; box-shadow: 0 1px 3px rgba(0,0,0,.06); padding: 20px; }
  .chart-card h3 { font-size: 16px; font-weight: 600; margin-bottom: 14px; color: #2d3436; }
  .chart-card canvas { width: 100% !important; }
  .pie-card { display: flex; flex-direction: column; }
  .pie-card canvas { max-height: none; }   /* the wrapper's height rules (490 / 218, or the grip) */
  /* Right chart column: the Revenue pie on top, the Gross Profit pie below it */
  .pie-col { display: flex; flex-direction: column; gap: 20px; }
  .pie-col .chart-card { flex: 1; }
  /* the charts' height box (house grip under it). The canvases are resized to
     fit it (charts.js syncChartsHeight); `auto` is the last resort for a box
     dragged below the charts' floors, where scrolling beats hiding a pie. */
  #chartsHost { overflow: auto; }

  /* ── Revenue chart custom grouped legend ── */
  .rev-legend { display: flex; flex-wrap: wrap; gap: 28px; justify-content: center; margin-top: 12px; font-size: 11px; color: #2d3436; }
  .rev-legend-group { display: flex; flex-direction: column; gap: 4px; min-width: 150px; }
  .rev-legend-master { font-weight: 700; text-transform: uppercase; letter-spacing: .4px; font-size: 11px; display: flex; align-items: center; gap: 6px; cursor: pointer; padding-bottom: 4px; border-bottom: 1px solid #edf0f2; }
  /* TWO COLUMNS OF FOUR per period (owner 2026-08-23) — one stack of 8 made the
     card tall and left the chart squeezed. Four fixed ROWS with the items
     flowing into columns: 8 metrics → 4 + 4, and a period showing fewer (the
     Rating / BSR / Reviews lines only exist when ONE model is picked) simply
     fills one column — it never turns into a two-tall stub. */
  .rev-legend-items { display: grid; grid-auto-flow: column; grid-template-rows: repeat(4, auto);
                      justify-content: start; column-gap: 20px; row-gap: 3px; padding-left: 6px; }
  .rev-legend-item { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; }
  .rev-legend-item input, .rev-legend-master input { cursor: pointer; margin: 0; }
  .rev-legend-swatch { width: 22px; height: 10px; display: inline-block; border-radius: 2px; flex-shrink: 0; }
  .rev-legend-item.hidden-ds { opacity: .4; text-decoration: line-through; }

  /* ── Table ── */
  .table-wrap { padding: 0 28px 28px; }
  /* Scroll pane so the header row (and the frozen first columns) stay put as a
     spreadsheet-style grid. This table freezes the left columns + scrolls sideways,
     so it needs to be its own scroll area (can't page-scroll like the PPC table).
     max-height keeps the frozen header just below the sticky topbar. */
  /* The CARD does not scroll — its title bar (and the Download Excel button)
     must stay put. #tblPane inside it is the scroll pane; the shell sizes that
     to 10 rows including the header (RULEBOOK Rule 6). */
  .table-card { background: #fff; border-radius: 10px; box-shadow: 0 1px 3px rgba(0,0,0,.06); position: relative; }
  #tblPane { overflow: auto; max-height: calc(100vh - 180px); position: relative; }
  /* The real height comes from the shell: 10 rows, header included
     (RULEBOOK Rule 6). The value above is only what shows for the
     instant before shell.js measures the rows. */
  .table-card h2 { font-size: 17px; font-weight: 600; padding: 16px 20px; border-bottom: 1px solid #edf2f7; }
  /* The always-reachable horizontal scrollbar is a SHELL component now
     (.cg-xbar in Shared Data/shell.js) — every dashboard gets it. */
  table { border-collapse: collapse; font-size: 13px; table-layout: fixed; }
  /* HEADER ROW — shorter, and a HARD two-line cap (owner 2026-08-05): the sort
     arrow and info button are taken out of the text flow so they can never push
     a label onto a third line. */
  thead th {
    text-align: center; padding: 5px 15px 5px 7px; background: #4a5568; color: #edf2f7;
    font-weight: 600; font-size: 11.5px; text-transform: uppercase; letter-spacing: .4px;
    white-space: normal; vertical-align: middle; line-height: 1.2;
    overflow: hidden; text-overflow: ellipsis; height: 38px;
  }
  thead th .sort-arrow { position: absolute; right: 4px; bottom: 3px; font-size: 8px; line-height: 1; opacity: .75; }
  thead th .col-note-btn { position: absolute; right: 3px; top: 3px; }
  thead th.text-right { text-align: center; }
  thead th[title] { cursor: help; }
  thead th.sortable { cursor: pointer; user-select: none; }
  thead th.sortable:hover { color: #ff9900; }
  thead th .th-label { display: inline; }
  thead th .sort-arrow { font-size: 9px; margin-left: 2px; opacity: 0.5; color: #cbd5e0; white-space: nowrap; }

  /* ── Column info notes ── */
  .col-note-btn {
    display: inline-block; margin-left: 2px; width: 12px; height: 12px; line-height: 12px;
    font-size: 8px; font-weight: 700; text-align: center; vertical-align: middle;
    background: rgba(255,255,255,0.2); color: #cbd5e0; border-radius: 50%; cursor: pointer;
    font-style: italic; user-select: none; white-space: nowrap;
  }
  .col-note-btn:hover { background: #ff9900; color: #fff; }
  .col-note-popup {
    display: none; position: fixed; background: #232f3e; color: #e8eaed;
    font-size: 12px; font-weight: 400; padding: 8px 12px; border-radius: 6px;
    white-space: normal; max-width: 260px; z-index: 1001; line-height: 1.5;
    text-transform: none; letter-spacing: 0; box-shadow: 0 4px 12px rgba(0,0,0,.3);
    pointer-events: none;
  }
  .col-note-popup.show { display: block; }
  thead th.sort-active .sort-arrow { opacity: 1; color: #ff9900; }
  tbody td { padding: 7px 8px; border-top: 1px solid #edf2f7; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  tbody tr:hover { background: #fffaf0; }
  tbody tr.total-row { background: #4a5568; color: #fff; font-weight: 700; border-top: 3px solid #ff9900; font-size: 15px; }
  tbody tr.total-row td { padding: 10px 8px; }
  tbody tr.total-row .text-green { color: #55efc4; }
  tbody tr.total-row .text-red { color: #fab1a0; }

  /* ── PPC stock flag ──
     The red mark beside a model that can't cover its own selling rate: pause
     its PPC. Click opens the shared explanation card (shell.js). */
  .ppc-stock-flag {
    display: inline-block; margin-left: 6px; padding: 1px 5px; border-radius: 5px;
    background: #dc2626; color: #fff; font-size: 9.5px; font-weight: 700;
    letter-spacing: .04em; line-height: 1.5; cursor: pointer; vertical-align: 1px;
    user-select: none; white-space: nowrap;
  }
  /* RED = pause it · GREEN = restock landed, put it back on (shows for 3 days) */
  .ppc-stock-flag.ppc-pause { background: #dc2626; }
  .ppc-stock-flag.ppc-pause:hover { background: #b91c1c; }
  .ppc-stock-flag.ppc-resume { background: #12894f; }
  .ppc-stock-flag.ppc-resume:hover { background: #0f7040; }

  /* ── SKU styles ── */
  .sku-cell { cursor: pointer; max-width: 120px; }
  .sku-preview { display: inline; }
  .sku-more { color: #636e72; font-style: italic; font-size: 12px; }
  .sku-tooltip {
    display: none; position: fixed; background: #232f3e; color: #fff; padding: 8px 12px;
    border-radius: 6px; font-size: 12px; z-index: 1000; white-space: pre-line; line-height: 1.6;
    box-shadow: 0 4px 12px rgba(0,0,0,.2); max-width: 240px; pointer-events: none;
  }
  .sku-cell.tip-open .sku-tooltip { display: block; }
  .sku-cell { cursor: pointer; }
  .sku-expand-icon { display: inline-block; width: 14px; font-size: 9px; color: #ff9900; transition: transform .15s; margin-right: 3px; }
  .sku-expand-icon.open { transform: rotate(90deg); }
  .sku-clickable:hover { background: #fff8e1; }
  tr.sku-subrow { background: #f7fafc; }
  tr.sku-subrow td { padding: 5px 8px; font-size: 12px; color: #555; border-top: 1px dashed #e2e8f0; }
  tr.sku-subrow td:first-child { padding-left: 28px; }
  tr.sku-subrow .sku-label { font-family: 'SF Mono', 'Consolas', monospace; font-size: 12px; color: #636e72; }
  /* Child-model sub-rows under a parent — slightly darker so they stand apart from SKU sub-rows */
  tr.child-subrow { background: #eef3f8; }
  tr.child-subrow td { padding: 6px 8px; font-size: 12.5px; color: #2d3436; }
  tr.child-subrow .child-model-label { font-weight: 600; color: #2d3436; }
  /* SKU sub-rows nested under a child-model / ASIN sub-row get an extra indent on the SKU cell (now col 7) */
  tr.sku-subrow.nested-sku td:nth-child(7) { padding-left: 24px; }
  /* ASIN breakdown rows (between model and SKU) — indent the ASIN cell (col 6) */
  tr.sku-subrow.asin-subrow td:nth-child(6) { padding-left: 20px; }

  .marketplace-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
  .badge-us { background: #dfe6e9; color: #2d3436; }
  .badge-ca { background: #ffeaa7; color: #6c5ce7; }
  .text-right { text-align: center; }
  .text-green { color: #00b894; }
  .text-red { color: #d63031; }
  /* The ACOS palette moved to Shared Data/shell.css on 2026-08-12 — ONE set of
     colours for this page and the PPC dashboard. Only the numbers are still
     per-page (⚙ ACOS colours). Don't re-declare the hexes here. */
  /* Unit Price chips — SAME shape and weight as the ACOS chips above (owner
     2026-08-09: "there are several coloured cell figures, none of them like
     that, use the same method"). Green = a deal is running, orange = a deal is
     approved and starts later, red = full price with no strike-through. */
  .deal-live  { background: #d5f5e3; color: #0b6b3a; padding: 2px 6px; border-radius: 4px; font-weight: 600; }
  .deal-soon  { background: #ffe0b2; color: #e65100; padding: 2px 6px; border-radius: 4px; font-weight: 600; }
  /* The listing's own warning, on its OWN channel so it survives underneath a
     deal chip instead of being outranked by it: a red rule under the price
     means no strike-through price is showing. inline-block + the padding keep
     the line clear of the digits without changing the row height. */
  .no-strike  { display: inline-block; border-bottom: 2px solid #d63031; padding: 0 3px 1px; border-radius: 3px 3px 0 0; }
  .deal-live.no-strike, .deal-soon.no-strike { padding: 2px 6px 1px; }

  /* ── Column visibility ── */
  #colToggleStyles {} /* placeholder – rules injected by JS */

  /* ── Frozen left columns (checkbox, picture) ── */
  /* (The tick column's own padding moved to shell.css on 2026-08-27 — PPC had
     the identical bug, and the House Page Standard says a table fix belongs in
     the shell so every page gets it. Nothing to declare here any more.) */
  #dataTable th:nth-child(1), #dataTable tbody tr:not(.cg-arch-head) td:nth-child(1) { position: sticky; left: 0; }
  #dataTable th:nth-child(2), #dataTable td:nth-child(2) { position: sticky; left: 28px; }
  /* The stacking number is the BODY cells' only — a header cell's belongs to
     the shell (--cg-th-z, just below), and a number written here would win
     against it and flatten the frozen corners back under the sliding ones. */
  #dataTable tbody td:nth-child(1), #dataTable tbody td:nth-child(2) { z-index: 12; }
  /* The two frozen corner header cells stick both left AND top (z-index above the
     frozen column and the frozen header row). */
  #dataTable thead th:nth-child(1), #dataTable thead th:nth-child(2) { --cg-th-z: 21; top: 0; }
  /* :not(.cg-arch-head) — the archived block's heading row spans the whole table
     as ONE cell, which is also cell nth-child(1); without the exclusion this
     frozen-column white (an ID selector, so it outranks the shell) painted over
     the heading's own background and the block lost its divider. RULEBOOK
     Rule 6 §5a's frozen-column trap, one row lower down. */
  #dataTable tbody tr:not(.cg-arch-head) td:nth-child(1), #dataTable tbody tr:not(.cg-arch-head) td:nth-child(2) { background: #fff; }
  #dataTable tbody tr:not(.cg-arch-head):hover td:nth-child(1), #dataTable tbody tr:not(.cg-arch-head):hover td:nth-child(2) { background: #fffaf0; }
  #dataTable tbody tr.total-row td:nth-child(1), #dataTable tbody tr.total-row td:nth-child(2) { background: #4a5568; }
  #dataTable tbody tr.sku-subrow td:nth-child(1), #dataTable tbody tr.sku-subrow td:nth-child(2) { background: #f8f9fa; }

  /* ── Resizable columns ── */
  /* Non-corner header cells freeze on top (position:sticky) as the pane scrolls;
     sticky also provides the positioning context the resize handles need. */
  thead th:not(:nth-child(1)):not(:nth-child(2)) { position: sticky; top: 0; z-index: 11; }
  .col-resize-handle {
    position: absolute; right: 0; top: 0; bottom: 0; width: 5px;
    cursor: col-resize; user-select: none; z-index: 10;
    border-right: 2px solid rgba(255,255,255,0.45);
  }
  .col-resize-handle:hover, .col-resize-handle.active { background: #ff9900; border-right-color: #ff9900; }
  /* The drag guide line (commit-on-release column resize) */
  .col-resize-guide { position: fixed; top: 0; bottom: 0; width: 0; border-left: 2px solid #ff9900; z-index: 1200; pointer-events: none; }

  /* ── Hover cards (inventory breakdown + ACOS family) — shared card look ── */
  .inv-hover {
    position: relative; cursor: default; text-decoration: underline dotted #636e72;
  }
  .acos-hover {
    position: relative; cursor: pointer;
  }
  .inv-hover { cursor: pointer; }
  .inv-hover .inv-tip, .acos-hover .acos-tip {
    display: none; position: fixed;
    background: #232f3e; color: #e8eaed; font-size: 11px; padding: 7px 11px;
    border-radius: 6px; white-space: nowrap; z-index: 1000; line-height: 1.6;
    pointer-events: none; text-align: left; font-weight: 400;
    box-shadow: 0 4px 14px rgba(0,0,0,0.28);
  }
  /* Tips open on CLICK, not hover (user decision 2026-07-16) — JS toggles .tip-open */
  .inv-hover.tip-open .inv-tip, .acos-hover.tip-open .acos-tip { display: block; }
  /* Unchecked rows are dimmed with opacity, which creates a stacking context
     that would trap the open tip UNDER the sticky header — lift it while open. */
  tbody tr:has(.tip-open) { opacity: 1 !important; }
  .inv-tip .tip-head, .acos-tip .tip-head { display: block; color: #9aa7b2; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; margin-bottom: 2px; }
  .inv-tip .tip-row, .acos-tip .tip-row { display: flex; justify-content: space-between; gap: 18px; }
  .inv-tip .tip-row .l, .acos-tip .tip-row .l { color: #b8c4cf; }
  .inv-tip .tip-row.strong, .acos-tip .tip-row.strong { font-weight: 700; }
  .inv-tip .tip-row.strong .l, .acos-tip .tip-row.strong .l { color: #e8eaed; }
  /* PPC figures shown as a history-based estimate (live/early single-day view).
     A soft red cell TINT + italic marks them as "not final yet" — this reads as
     estimated on every cell WITHOUT fighting the ACOS colour-pills (which carry
     their own bg/text colour) or profit's green/red, so nothing goes red-on-red. */
  /* Estimated PPC figures: italic only — the red tint was removed 2026-07-17
     by user decision (it flagged the 1-2 day estimate window too loudly). */
  /* PROVISIONAL PPC — today, and yesterday before the ~3 AM re-sync. The figure
     is REAL (downloaded every 15 minutes) but not final: it under-counts
     Sponsored Brands until the overnight PPC pull lands.
     Owner 2026-08-21: the mark is ITALIC everywhere, and the red wash sits on
     the ACOS COLUMN ONLY. Washing every PPC-derived cell (and the KPI cards)
     turned half the page pink and read as an alarm, for a number that is real.
     One column carries the message. */
  .est-val { font-style: italic; }
  #dataTable td.est-acos {
    background: #fdf0f0;
    box-shadow: inset 0 0 0 1px #f6d9d9;
  }
  #dataTable tr.total-row td.est-acos { background: #fbe6e6; }
  /* While a period is loading, the KPI cards sit blank + dimmed and fill in
     together with the table (no $0/red flash, no stale lagging numbers). */
  .kpis.loading .kpi { opacity: .45; transition: opacity .15s; }
  /* covers a chart's canvas while its period reloads (stale-data rule) */
  .chart-loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #636e72; font-size: 13px; background: #fff; }
  /* ▲/▼ next to a Rating/BSR value (today vs yesterday) — line-height 1 keeps
     the row height unchanged, color set inline (green up / red down) */
  .rating-trend { font-size: 13px; line-height: 1; margin-left: 3px; vertical-align: -1px; }
  /* A narrow Rating/BSR column must never swallow the ▲/▼ into the cell's
     "…" ellipsis — cells holding a trend arrow show their content in full. */
  tbody td:has(.rating-trend) { overflow: visible; text-overflow: clip; }
  /* BSR #1 = our own best-seller badge (user request 2026-07-17) */
  .bsr-one { background: #ff9900; color: #fff; padding: 1px 7px; border-radius: 10px; font-weight: 700; }

  /* ── Header click-cards: the shared .sv2-tipcard element + .head-tip host
     styling come from /Shared Data/shell.css on this page (v1 carries an
     embedded copy; v2 loads the shared shell instead). ── */


  /* ── Footer ── */
  body { padding-bottom: 10px; }

  @media (max-width: 900px) {
    .charts-grid { grid-template-columns: 1fr; }
    .sidebar { width: 60px; } .sidebar .logo span { display: none; } .sidebar .logo { padding: 12px 10px; justify-content: center; }
    .sidebar nav a span:not(.icon) { display: none; }
    .main { margin-left: 60px; }

  }

  /* ═══ App shell v2 (design_handoff_shell) — the LOCKED design ═══════════════
     data-shell="v2" is hardcoded on <html> (shell.js also stamps it — the
     hardcoded copy avoids any pre-script flash). The generic shell rules live
     in /Shared Data/shell.css (loaded BEFORE this file); below are only the
     SALES-SPECIFIC parts of the design: page/table/KPI/filter skin plus the
     top-bar layout this page had live. Where a rule here ties with shell.css,
     this file loads later so the live Sales look wins. */
  html[data-shell="v2"] body {
    background: #f6f7f9;
    /* whole-page typography per the handoff — falls back to the previous
       system stack if Google Fonts is unreachable */
    font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    /* v1 shows the base body text color (its embedded shell block never set one);
       shell.css would flip it to #1a1d23 — keep the LIVE look (SPLIT-HANDOFF) */
    color: #2d3436;
  }
  /* ── table header row ──
     The COLOURS (background, label, underline, the `i` chip) are NOT here any
     more: they come from the house table colour tokens in Shared Data/shell.css
     (--cg-th-*) — the light blue is the app-wide default now, RULEBOOK Rule 6
     §5a. Only the Sales-specific TYPE size stays a page choice. */
  html[data-shell="v2"] thead th { font-size: 10.5px; letter-spacing: 0.04em; }
  html[data-shell="v2"] thead th .sort-arrow { color: #98a1b0; }
  html[data-shell="v2"] thead th.sortable:hover { color: #2563eb; }
  html[data-shell="v2"] thead th.sort-active { color: #2563eb; }
  html[data-shell="v2"] thead th.sort-active .sort-arrow { color: #2563eb; }
  html[data-shell="v2"] .col-resize-handle { border-right-color: #c9d2de; }
  html[data-shell="v2"] .col-resize-handle:hover, html[data-shell="v2"] .col-resize-handle.active { background: #2563eb; border-right-color: #2563eb; }
  /* ── cards, KPI row and table typography per the handoff (chart/pie data untouched) ── */
  html[data-shell="v2"] .kpi, html[data-shell="v2"] .chart-card,
  html[data-shell="v2"] .table-card, html[data-shell="v2"] .filters-bar { border: 1px solid #e6e8ec; border-radius: 12px; box-shadow: none; }
  html[data-shell="v2"] .kpi { padding: 15px 16px; }
  html[data-shell="v2"] .kpi .label { font-size: 12px; font-weight: 500; text-transform: none; letter-spacing: 0; color: #667085; }
  html[data-shell="v2"] .kpi .value { font-size: 25px; font-weight: 600; font-family: 'IBM Plex Mono', monospace; letter-spacing: -0.03em; }
  html[data-shell="v2"] .kpi .change { font-size: 12px; }
  html[data-shell="v2"] .kpi .change.up, html[data-shell="v2"] .text-green { color: #12894f; }
  html[data-shell="v2"] .kpi .change.down, html[data-shell="v2"] .text-red { color: #dc2626; }
  html[data-shell="v2"] .chart-card h3 { font-size: 14px; color: #1a1d23; }
  html[data-shell="v2"] .table-card h2 { font-size: 14px; border-bottom: 1px solid #eef0f3; }
  /* numeric table cells: mono + tabular figures */
  html[data-shell="v2"] tbody td.text-right { font-family: 'IBM Plex Mono', monospace; font-variant-numeric: tabular-nums; font-size: 12.5px; }
  /* totals row + row hover follow the light look. The totals COLOURS (including
     the two frozen cells) are the shell's --cg-total-* tokens — they match the
     header row. Only the Sales type size stays here. */
  html[data-shell="v2"] tbody tr.total-row { font-size: 13px; }
  html[data-shell="v2"] tbody tr.total-row .text-green { color: #12894f; }
  html[data-shell="v2"] tbody tr.total-row .text-red { color: #dc2626; }
  html[data-shell="v2"] tbody tr:hover { background: #f7f9fc; }
  html[data-shell="v2"] #dataTable tbody tr:not(.cg-arch-head):hover td:nth-child(1), html[data-shell="v2"] #dataTable tbody tr:not(.cg-arch-head):hover td:nth-child(2) { background: #f7f9fc; }
  /* filter controls follow the blue accent (the orange pills were the old brand) */
  html[data-shell="v2"] .filter-chip { border-radius: 9px; }
  html[data-shell="v2"] .filter-chip:hover { border-color: #2563eb; }
  html[data-shell="v2"] .filter-chip.active { background: #2563eb; border-color: #2563eb; color: #fff; }
  html[data-shell="v2"] .dropdown-filter-btn { border-radius: 9px; }
  html[data-shell="v2"] .dropdown-filter-btn:hover { border-color: #2563eb; }
  html[data-shell="v2"] .count-badge { background: #2563eb; }
  /* Notices — same design as /Shared Data/shell.css (keep the two in sync) */
  html[data-shell="v2"] .app-notice { border-radius: 11px; border: 1px solid transparent; font-size: 12.5px; line-height: 1.5; padding: 12px 14px; margin: 14px 28px 0; }
  html[data-shell="v2"] .app-notice.warn { background: #fffbeb; border-color: #fce6a8; color: #7c5b13; }
  html[data-shell="v2"] .app-notice.warn strong, html[data-shell="v2"] .app-notice.warn b { color: #8a5a00; }
  html[data-shell="v2"] .app-notice.info { background: #eff6ff; border-color: #bfdbfe; color: #1e40af; }
  html[data-shell="v2"] .app-notice.danger { background: #fef2f2; border-color: #fecaca; color: #b42318; }
  /* Low-priority notes: collapsed to small pills by default; click to expand */
  /* The chips row must cost NOTHING when every chip is hidden: its own top
     margin used to push the summary cards down by 14px on an empty row, which
     is what made the first gap taller than the rest. The spacing now lives on
     the chips, so a hidden chip (display:none) contributes nothing. */
  html[data-shell="v2"] #lowPriorityNotices { margin: 0 28px; display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; }
  html[data-shell="v2"] #lowPriorityNotices > * { margin-top: var(--cg-row, 14px); }
  html[data-shell="v2"] #lowPriorityNotices .app-notice { margin: var(--cg-row, 14px) 0 0; padding: 4px 12px; border-radius: 999px; font-size: 11.5px; line-height: 1.4; cursor: pointer; }
  html[data-shell="v2"] #lowPriorityNotices .app-notice.open { border-radius: 11px; padding: 10px 14px; font-size: 12.5px; }
  html[data-shell="v2"] #lowPriorityNotices .notice-full { display: none; }
  html[data-shell="v2"] #lowPriorityNotices .open .notice-full { display: inline; }
  html[data-shell="v2"] #lowPriorityNotices .open .notice-more { display: none; }
  html[data-shell="v2"] #lowPriorityNotices .notice-more { color: #b8860b; font-weight: 700; }
  html[data-shell="v2"] #excelBtn { background: #f2fbf5 !important; color: #12894f !important; border: 1px solid #cfe6d8 !important; border-radius: 9px !important; }
  html[data-shell="v2"] #excelBtn:hover { background: #e7f7ee !important; }
  /* (sidebar, admin + group drop-downs, footer, avatar — /Shared Data/shell.css) */
  html[data-shell="v2"] .sv2-toggle { display: inline-block; margin-top: 9px; font-size: 10.5px; color: #98a1b0; text-decoration: none; }
  html[data-shell="v2"] .sv2-toggle:hover { color: #2563eb; }
  /* ── top bar ── */
  html[data-shell="v2"] .topbar { background: #fff; color: #1a1d23; border-bottom: 1px solid #e6e8ec; height: 60px; padding: 0 24px; display: flex; align-items: center; justify-content: flex-start; gap: 10px; }
  html[data-shell="v2"] .topbar > div:first-child { display: contents; }
  html[data-shell="v2"] .topbar h1 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; color: #1a1d23; }
  /* (the "Amazon · SP-API" crumb, the "Live" dot and the Refresh button were
     removed from the header 2026-08-09 — their rules went with them) */
  /* The rate is a footnote under the title, not a box on the right (owner
     2026-08-12). `.topbar > div:first-child { display: contents }` above would
     flatten the title block and strand it, so that is undone here. */
  html[data-shell="v2"] .topbar > div:first-child { display: block; }
  html[data-shell="v2"] .topbar .subtitle { margin: 2px 0 0; font-size: 11.5px; color: #7b8494; font-family: 'IBM Plex Mono', monospace; padding: 0; background: none; text-align: left; }
  html[data-shell="v2"] .topbar .subtitle.is-blank { display: none; }
  html[data-shell="v2"] .topbar-pills { display: flex; align-items: center; gap: 10px; margin-left: auto; }
  /* (collapsible-sidebar geometry + .sv2-sbtoggle — /Shared Data/shell.css) */
  /* ── v2 narrow-screen collapse: only the SALES-SPECIFIC hides; the sidebar
     icon-rail rules come from shell.css ── */
  @media (max-width: 900px) {
    html[data-shell="v2"] .sv2-toggle { display: none !important; }
    html[data-shell="v2"] .topbar .subtitle { display: none; }
  }

  /* ── Frozen-column separators (2026-08-04): the table's collapsed borders do
     NOT travel with position:sticky cells, so the frozen columns' lines
     vanished the moment the table scrolled right. Inset shadows are painted by
     the cell itself and scroll with it — right edge + row line. ── */
  /* (the archived block's heading row is ONE full-width cell — it is not a
     frozen column, so it takes neither the sticky nor these edge lines) */
  #dataTable th:nth-child(1), #dataTable tbody tr:not(.cg-arch-head) td:nth-child(1),
  #dataTable th:nth-child(2), #dataTable td:nth-child(2) { box-shadow: inset -1px 0 0 #dfe4ea, inset 0 -1px 0 #edf2f7; }

  /* Summary-card + collapsed-row density is the HOUSE standard now — see
     Shared Data/shell.css (RULEBOOK Rule 6, page rhythm). */

  /* ── The Gross Profit card's P&L panel (pnl.js, 2026-08-06) ──
     Same panel look as the Daily Expenses panel next door: a white card
     dropping out of its summary card, drawn only once it is opened. */
  .pnl-panel {
    position: absolute; top: 100%; left: 0; z-index: 1500; margin-top: 4px;
    background: #fff; border: 1px solid #d7dbe2; border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,.18); padding: 12px 14px;
    width: 380px; max-width: 92vw; text-align: left; cursor: default;
    font-size: 12px; color: #2d3436;
  }
  .pnl-panel .pnl-head { font-weight: 700; font-size: 13px; }
  .pnl-panel .pnl-sub { color: #8895a3; font-size: 11px; margin-bottom: 8px; }
  /* table-layout / white-space / the row line are reset on purpose: the page's
     own data-table skin (`table`, `tbody td` above) would otherwise clip these
     labels and draw a line under every row. */
  .pnl-table { border-collapse: collapse; width: 100%; table-layout: auto; font-size: 12px; }
  .pnl-table td { padding: 3px 0; vertical-align: middle; border-top: none;
    white-space: normal; overflow: visible; text-overflow: clip; }
  .pnl-table td:nth-child(2) { text-align: right; font-family: 'IBM Plex Mono', monospace; white-space: nowrap; padding-left: 10px; }
  .pnl-table td:nth-child(3) { text-align: right; color: #8895a3; width: 52px; white-space: nowrap; padding-left: 8px; }
  .pnl-table tr.pnl-rev td { font-weight: 700; border-bottom: 1px solid #eceff3; padding-bottom: 5px; }
  .pnl-table tr.pnl-total td { font-weight: 700; font-size: 13px; border-top: 1px solid #cbd5e0; padding-top: 6px; }
  .pnl-table tr.pnl-total td.text-green { color: #12894f; }
  .pnl-table tr.pnl-total td.text-red { color: #dc2626; }
  .pnl-panel .pnl-note { margin-top: 9px; padding-top: 8px; border-top: 1px solid #eceff3; color: #8895a3; font-size: 10.5px; line-height: 1.55; }
  .pnl-panel .pnl-gap { height: 6px; }


  background: #faf5ff;
  color: #6b21a8;
  border-left: 2px solid #d8b4fe;
  border-right: 2px solid #d8b4fe;
}
