/* ── CONARTIST — COMPONENTS ── */
  /* ── STOCK HEADER CONTROLS ── */
  .page-header-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
  }

  .stock-controls {
    display: flex;
    gap: 10px;
    margin-top: 14px;
    flex-wrap: wrap;
    align-items: center;
  }

  .search-input {
    flex: 1;
    min-width: 160px;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: 13px;
    background: var(--bg-card);
    color: var(--text-primary);
    outline: none;
    transition: border-color 0.15s;
  }
  .search-input:focus { border-color: var(--accent); }

  .filter-select {
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: 13px;
    background: var(--bg-card);
    color: var(--text-primary);
    outline: none;
    cursor: pointer;
    transition: border-color 0.15s;
  }
  .filter-select:focus { border-color: var(--accent); }

  .toggle-label {
    font-size: 13px;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    white-space: nowrap;
  }

  /* ── BUTTONS ── */
  .btn-primary {
    padding: 9px 18px;
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s;
    white-space: nowrap;
    flex-shrink: 0;
  }
  .btn-primary:hover { background: var(--accent-dark); }
  .btn-primary:active { transform: scale(0.97); }

  .btn-secondary {
    padding: 8px 16px;
    background: transparent;
    color: var(--text-secondary);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: 13px;
    cursor: pointer;
    transition: all 0.15s;
  }
  .btn-secondary:hover { background: var(--bg); color: var(--text-primary); }
  /* Active/toggled state — e.g. Archived button when archived-only view is on.
     Tints with the accent so the toggle reads at a glance. */
  .btn-secondary.active {
    background: var(--accent-light);
    color: var(--accent-dark);
    border-color: var(--accent);
  }

  /* ── DRAG HANDLE ──
     The ⋮⋮ grip used for manual-sort drag on product rows, series/collection/category
     headers, and settings channel rows. Faded by default so it doesn't shout in
     manual-sort mode; lights up when its row is hovered, or when hovered directly. */
  .drag-handle {
    opacity: 0.22;
    transition: opacity 0.12s ease, color 0.12s ease;
  }
  tr:hover .drag-handle,
  .drag-handle:hover {
    opacity: 1;
  }
  .drag-handle:hover { color: var(--accent) !important; }
  .drag-handle:active { cursor: grabbing !important; }

  .btn-danger {
    padding: 8px 16px;
    background: transparent;
    color: var(--danger);
    border: 1px solid var(--danger-border);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: 13px;
    cursor: pointer;
    transition: all 0.15s;
  }
  .btn-danger:hover { background: var(--danger-bg); }

  /* ── PRODUCT TABLE ── */
  .product-table-wrap {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
  }

  .product-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    /* Fixed layout so column widths come from <colgroup> only — keeps the columns from
       shifting around when the user collapses/expands sections (auto layout would
       re-measure based on whichever rows are currently visible). */
    table-layout: fixed;
  }
  .product-table td { word-wrap: break-word; }

  .product-table th {
    padding: 11px 16px;
    text-align: left;
    font-size: 11px;
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
    /* nowrap + fixed column widths = header text painting over the neighbour column
       when a channel-scoped header injects a long channel name. Clip instead. */
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .product-table td {
    padding: 13px 16px;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
    color: var(--text-primary);
  }

  .product-table tr:last-child td { border-bottom: none; }
  /* Category column reads as a tag/badge — centring it inside the cell keeps the column
     visually compact and lines up the badges down the page. */
  .product-table th.col-sku,
  .product-table td.col-sku { text-align: center; }
  .product-table td.col-sku > div { align-items: center; }
  .product-table tbody tr { transition: background 0.1s; }
  .product-table tbody tr:hover { background: var(--bg); }
  .product-table tbody tr.archived-row { opacity: 0.45; }

  /* Tree-view connector: a single accent-light rail on product rows only, sitting
     under the category chevron column so the eye traces from category → its products. */
  .product-table tbody tr:not(.series-header):not(.collection-header):not(.category-subheader) > td:first-child {
    position: relative;
  }
  .product-table tbody tr:not(.series-header):not(.collection-header):not(.category-subheader) > td:first-child::before {
    content: '';
    position: absolute;
    left: 74px; top: 0; bottom: 0; width: 3px;
    background: var(--accent-light);
    pointer-events: none;
  }

  /* ── NARROW-WIDTH OVERLAP FIX (Stock table) ── */
  /* Between 640 and 1024px (iPad portrait + split-view + small laptops) the fixed-width
     6-column layout overruns its container: actions get clipped, variant-group + by-channel
     columns squash text into 1-char wraps, padding eats the price column. Drop the two
     least-essential columns at this range AND shrink cell padding so the remaining columns
     have breathing room. Below 640 the existing phone rules already kick in. */
  @media (min-width: 641px) and (max-width: 1024px) {
    .col-sku,
    .col-stock-detail,
    .product-table th.col-sku,
    .product-table th.col-stock-detail { display: none; }
    /* table-layout:fixed reserves the <col> widths even when every cell in the column
       is hidden — zero them so the freed 230px actually goes to the name column
       (otherwise names get starved and overlap the Price column at ~700–1024px). */
    .product-table col.cg-vg,
    .product-table col.cg-bychan { width: 0 !important; }
    .product-table { font-size: 12px; }
    .product-table th,
    .product-table td { padding: 9px 10px; }
    .product-table tbody tr:not(.series-header):not(.collection-header):not(.category-subheader) > td:first-child::before {
      left: 56px; /* match the tighter row padding so the rail stays under the chevron */
    }
    /* Page-header controls — let them wrap instead of overlapping their siblings. */
    .stock-sticky-controls .stock-controls { flex-wrap: wrap; row-gap: 6px; }
  }

  /* ── 641–900px (iPad split-view / narrow laptop side panel) ────────────
     At ~800px the regular tablet layout still applies most rules, but a handful of
     containers + text blocks get visibly crowded. This block fixes the actually-broken
     bits without rewriting the layout. */
  @media (min-width: 641px) and (max-width: 900px) {
    /* Page title shrinks so the right-side button cluster has room to live on the
       same row. Subtitle drops a line so it can wrap below the title if needed. */
    .page-title { font-size: 22px; }
    .page-subtitle { font-size: 12px; }
    .page-header { padding: 18px 16px 12px; }
    .screen-body { padding: 18px; }

    /* Top header row: title block | actions block — let the actions wrap to the next
       line instead of mashing into the title. */
    .page-header-top { flex-wrap: wrap; row-gap: 10px; }
    .page-header-top > div:last-child { flex-wrap: wrap; }

    /* Stat-row cards (Stock, Reports): cap to 2 columns so each card has breathing
       room. Default was auto-fit minmax(140px,1fr) which packs 4–5 across at ~800px. */
    .stat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .stat-card { padding: 12px 14px; }
    .stat-value { font-size: 20px; }

    /* Form modals: two-column form grid stays, but tighten gaps so labels + inputs
       don't crash into each other at narrow modal widths. */
    .form-grid { gap: 10px; }

    /* Tighten the stock product-table name cell so the emoji/thumb + checkbox + drag
       handle + name don't crowd the variant badges. */
    .product-table .product-name { font-size: 13px; }
    .product-name-cell { gap: 6px; }
  }

  /* ── Series grid (top level of grid view) ── */
  .series-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 14px;
  }
  .series-card {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    overflow: hidden;
    cursor: pointer;
    transition: box-shadow 0.15s, transform 0.15s;
    display: flex;
    flex-direction: column;
  }
  .series-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
  .series-card-info { padding: 14px 16px; display: flex; flex-direction: column; gap: 4px; }
  .series-card-title {
    font-family: var(--font-display); font-size: 16px; font-weight: 600;
    color: var(--text-primary); line-height: 1.2;
  }
  .series-card-count { font-size: 11px; color: var(--text-muted); }
  /* Expanded series card spans the full row of the series grid and embeds a nested
     collection grid in its body. */
  .series-card.expanded {
    grid-column: 1 / -1;
    cursor: default;
  }
  .series-card.expanded:hover { transform: none; }
  .series-card-head {
    display: flex; align-items: center; gap: 10px;
    padding: 14px 18px;
    background: var(--accent-light);
    border-bottom: 1px solid var(--border);
    cursor: pointer;
  }
  .series-card-body { padding: 14px; background: var(--bg); }

  /* ── Collection grid (nested inside an expanded series card, or at top in legacy) ── */
  .collection-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 12px;
  }
  .collection-card {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    overflow: hidden;
    cursor: pointer;
    transition: box-shadow 0.15s, transform 0.15s;
    display: flex;
    flex-direction: column;
  }
  .collection-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
  .collection-card-info {
    padding: 10px 12px 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .collection-card-title {
    font-family: var(--font-display);
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }
  .collection-card-count { font-size: 11px; color: var(--text-muted); }
  .collection-card-chips { display: flex; flex-wrap: wrap; gap: 4px; }
  /* Expanded card: spans the entire grid row and renders its product table inside. */
  .collection-card.expanded {
    grid-column: 1 / -1;
    cursor: default;
    background: var(--bg-card);
  }
  .collection-card.expanded:hover { transform: none; }
  .collection-card-head {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    background: var(--accent-light);
    border-bottom: 1px solid var(--border);
    cursor: pointer;
  }
  .collection-card-body { padding: 0; }
  .collection-card-body .product-table-wrap { border: none; border-radius: 0; box-shadow: none; }

  .product-name-cell { display: flex; align-items: center; gap: 10px; min-width: 0; }
  /* The name+sku block must be allowed to shrink below its content width, or long
     names refuse to wrap and paint over the Price column on narrow iPads (flex items
     default to min-width:auto). */
  .product-name-cell > div { min-width: 0; }
  /* Product name uses the same bold-black weight as the Price and By-Channel columns
     so the row reads with consistent visual weight across columns. */
  .product-name { font-weight: 600; color: var(--text-primary); font-size: 13px; overflow-wrap: anywhere; }
  .product-sku { font-size: 11px; color: var(--text-muted); margin-top: 1px; overflow-wrap: anywhere; }

  .category-badge {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 20px;
    font-size: 11px;
    font-weight: 500;
    background: var(--accent-light);
    color: var(--accent-dark);
  }

  .stock-cell { display: flex; flex-direction: column; gap: 3px; }
  .stock-channel-row {
    display: flex; align-items: center; gap: 6px;
    font-size: 12px; font-weight: 600; color: var(--text-primary);
  }


  /* Sticky search + action rows — they stay glued to the top of the scroll area so the
     user always has search, filters, and "+ Add Product" within reach. */
  .stock-sticky-controls {
    position: sticky; top: 0; z-index: 30;
    background: var(--bg); padding-bottom: 8px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border);
  }

  /* Sticky thead — used only by the Bulk Edit modal's .data-table, which has a real
     scroll container (modal-body) so sticky works cleanly. The main Stock-page
     .product-table doesn't get sticky thead — the page-header controls already stick,
     and the series / collection / category rows act as section markers when scrolling. */
  .data-table thead th {
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--bg);
  }
  .stock-action-row {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    margin-top: 8px;
  }
  .stock-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
  .stock-dot.shopify { background: #2D6A30; }
  .stock-dot.etsy { background: #C8431A; }
  .stock-dot.conventions { background: var(--accent); }
  .stock-dot.other { background: #4A47A3; }

  .stock-total { font-weight: 600; font-size: 14px; }
  .stock-total.low { color: var(--danger); }
  .stock-total.ok { color: var(--text-primary); }

  .low-badge {
    display: inline-block;
    padding: 2px 7px;
    border-radius: 20px;
    font-size: 10px;
    font-weight: 600;
    background: var(--danger-bg);
    color: var(--danger);
    border: 1px solid var(--danger-border);
    text-transform: uppercase;
    letter-spacing: 0.3px;
  }

  .action-btns { display: flex; gap: 6px; }
  .icon-btn {
    width: 32px; height: 32px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: transparent;
    cursor: pointer;
    font-size: 14px;
    display: flex; align-items: center; justify-content: center;
    transition: all 0.15s;
    color: var(--text-secondary);
  }
  .icon-btn:hover { background: var(--accent-light); border-color: var(--accent); color: var(--accent-dark); }
  .icon-btn.danger:hover { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger); }

  /* Info-tip — small (i) icon at the right end of a form label. Hovering surfaces helper
     text via a JS-positioned tooltip (see shared/tooltip.js) so it can detect viewport
     edges and flip / clamp to stay on-screen. The icon itself just carries the data-tip
     attribute and matching styling. */
  .info-tip {
    display: inline-flex;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 10px;
    font-weight: 600;
    font-style: italic;
    font-family: 'Times New Roman', Georgia, serif;
    align-items: center;
    justify-content: center;
    cursor: help;
    flex-shrink: 0;
    line-height: 1;
    user-select: none;
    /* Section titles around the icon use text-transform:uppercase + letter-spacing —
       reset both so the "i" inside the bubble stays normal-cased. */
    text-transform: none;
    letter-spacing: 0;
  }
  .info-tip:hover { background: var(--accent-light); border-color: var(--accent); color: var(--accent-dark); }

  /* Form labels with an info-tip use this layout — title on the left, icon on the right
     so the icon visually aligns with the input's right edge below. */
  .form-label.has-info { display: flex; align-items: center; justify-content: space-between; gap: 8px; }

  /* ── EXPENSES SECTION (Reports tab) ──
     Two stacked blocks — Active subscriptions (per-channel rows) and One-off ledger.
     Sits below the existing Sales charts as its own area so it doesn't compete for
     visual weight when the user is reading revenue. */
  .reports-expenses-section { margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--border); }
  .exp-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; gap: 12px; flex-wrap: wrap; }
  .exp-title { font-family: var(--font-display); font-size: 22px; font-weight: 500; color: var(--text-primary); }
  .exp-add-btn { font-size: 13px; padding: 8px 16px; }

  /* Three-card rollup row — fixed costs / one-offs / total this month. */
  .exp-rollup { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-bottom: 18px; }
  .exp-rollup-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px 16px; }
  .exp-rollup-card--total { background: var(--accent-light); border-color: var(--accent); }
  .exp-rollup-label { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
  .exp-rollup-val { font-family: var(--font-display); font-size: 22px; font-weight: 500; color: var(--accent); }
  .exp-rollup-card--total .exp-rollup-val { color: var(--accent-dark); }
  .exp-rollup-sub { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

  /* Block titles. */
  .exp-block { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 16px 20px; margin-bottom: 14px; box-shadow: var(--shadow-sm); }
  .exp-block-title { font-size: 13px; font-weight: 600; color: var(--text-primary); margin-bottom: 12px; display: flex; align-items: center; gap: 8px; }

  /* Active subscriptions: one row per channel, with pills for each recurring entry. */
  .exp-sub-row { display: grid; grid-template-columns: minmax(140px, 1fr) minmax(0, 2fr) auto; gap: 14px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--border); }
  .exp-sub-row:last-child { border-bottom: none; }
  .exp-sub-row--empty .exp-sub-channel { color: var(--text-muted); }
  .exp-sub-row--orphan { background: #FFFBEB; border-radius: var(--radius-sm); padding: 8px 10px; margin-top: 4px; }
  .exp-sub-channel { font-size: 13px; font-weight: 500; color: var(--text-primary); }
  .exp-sub-list { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
  .exp-sub-pill { font-family: var(--font-body); font-size: 12px; font-weight: 500; padding: 4px 10px; border-radius: 14px; border: 1px solid var(--border); background: var(--bg); color: var(--text-secondary); cursor: pointer; transition: all 0.12s; }
  .exp-sub-pill:hover { border-color: var(--accent); color: var(--accent); }
  .exp-sub-add { font-family: var(--font-body); font-size: 11px; font-weight: 500; padding: 3px 9px; border-radius: 14px; border: 1px dashed var(--border); background: transparent; color: var(--text-muted); cursor: pointer; transition: all 0.12s; }
  .exp-sub-add:hover { border-color: var(--accent); color: var(--accent); border-style: solid; }
  .exp-sub-total { font-family: var(--font-display); font-size: 14px; font-weight: 500; color: var(--accent); white-space: nowrap; text-align: right; }
  .exp-sub-total small { font-size: 10px; color: var(--text-muted); margin-left: 1px; }

  /* One-off ledger: 6-col grid (date, category, link, note, amount, status). */
  .exp-table-head, .exp-row {
    display: grid;
    grid-template-columns: 90px 110px minmax(120px, 1fr) minmax(120px, 2fr) 100px 90px;
    gap: 12px;
    align-items: center;
    padding: 8px 4px;
    font-size: 12px;
  }
  .exp-table-head { color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 10px; border-bottom: 1px solid var(--border); padding-bottom: 6px; }
  .exp-row { border-bottom: 1px solid var(--border); cursor: pointer; transition: background 0.12s; }
  .exp-row:hover { background: var(--bg); }
  .exp-row:last-child { border-bottom: none; }
  .exp-row-date { color: var(--text-muted); font-size: 11px; }
  .exp-row-cat { font-size: 11px; padding: 2px 8px; background: var(--accent-light); color: var(--accent-dark); border-radius: 10px; text-transform: capitalize; justify-self: start; display: inline-flex; align-items: center; gap: 5px; }
  /* Tiny "con" pill on convention-sourced rows so they read as imported, not native. */
  .exp-row-source { font-size: 9px; font-weight: 700; letter-spacing: 0.5px; padding: 1px 5px; border-radius: 4px; background: rgba(255,255,255,0.7); color: var(--text-muted); text-transform: uppercase; }

  /* ── PACK LIST CHECKBOX TREE ──
     Two-level tree: Category (collapsible) → Collection → Product. Each level shows a
     tri-state checkbox so the user can tick/untick whole groups at once. */
  .pack-cat-block { margin-bottom: 8px; }
  .pack-cat-head {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px; background: var(--accent-light);
    border-radius: var(--radius-sm); cursor: pointer; user-select: none;
  }
  .pack-cat-head:hover { background: color-mix(in oklab, var(--accent-light) 80%, var(--accent) 10%); }
  .pack-cat-chevron { font-size: 10px; color: var(--accent-dark); width: 10px; flex-shrink: 0; }
  .pack-cat-name { font-size: 13px; font-weight: 600; color: var(--accent-dark); flex: 1; }
  .pack-cat-count { font-size: 11px; color: var(--accent-dark); opacity: 0.7; }
  .pack-cat-body { padding: 4px 0 0 14px; }

  .pack-col-block { margin: 6px 0; }
  .pack-col-head {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 10px; background: var(--bg-card);
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    cursor: pointer; user-select: none; font-size: 12px; font-weight: 500;
  }
  .pack-col-head:hover { border-color: var(--accent); }
  .pack-col-name { flex: 1; color: var(--text-primary); }
  .pack-col-count { font-size: 10px; color: var(--text-muted); }
  .pack-prod-list { padding: 4px 0 4px 14px; display: flex; flex-direction: column; gap: 2px; }

  .pack-prod-row {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 8px; border-radius: var(--radius-sm);
    cursor: pointer; font-size: 12px;
  }
  .pack-prod-row:hover { background: var(--bg); }
  .pack-prod-row input { cursor: pointer; flex-shrink: 0; }
  .pack-prod-emoji { font-size: 16px; width: 22px; text-align: center; flex-shrink: 0; }
  .pack-prod-img { width: 22px; height: 22px; border-radius: 4px; object-fit: cover; flex-shrink: 0; }
  .pack-prod-name { flex: 1; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .pack-prod-sku { font-family: monospace; font-size: 10px; color: var(--text-muted); }

  /* Tri-state checkbox icon. Some browsers don't render unicode "◪" cleanly; fall back
     to a simple letter style if needed. */
  .pack-tri { font-size: 14px; flex-shrink: 0; line-height: 1; cursor: pointer; }
  .pack-tri[data-tri="all"]  { color: var(--accent); }
  .pack-tri[data-tri="some"] { color: var(--accent); }
  .pack-tri[data-tri="none"] { color: var(--text-muted); }
  .exp-row-link { font-size: 11px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .exp-row-note { font-size: 12px; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .exp-row-amount { font-family: var(--font-display); font-weight: 500; color: var(--text-primary); text-align: right; }
  .exp-row-paid { font-size: 11px; text-align: right; }
  .exp-empty { font-size: 12px; color: var(--text-muted); padding: 14px 0; text-align: center; }

  /* Stack the table rows on narrow screens — a 6-column grid is unreadable below ~700px. */
  @media (max-width: 768px) {
    .exp-table-head { display: none; }
    .exp-row {
      grid-template-columns: 1fr auto;
      grid-template-areas:
        "date cat"
        "note amount"
        "link paid";
      gap: 4px 12px;
      padding: 10px 4px;
    }
    .exp-row-date { grid-area: date; }
    .exp-row-cat { grid-area: cat; justify-self: end; }
    .exp-row-link { grid-area: link; }
    .exp-row-note { grid-area: note; font-weight: 500; white-space: normal; }
    .exp-row-amount { grid-area: amount; }
    .exp-row-paid { grid-area: paid; text-align: left; }
    .exp-sub-row { grid-template-columns: 1fr; gap: 6px; }
    .exp-sub-total { text-align: left; }
  }

  /* ── APP TOOLTIP (info + error) ──
     Rendered into <body> by shared/tooltip.js, positioned absolutely. Two kinds:
     • info  — neutral, light card with subtle shadow.
     • error — themed red, matches form validation tone.
     `data-pos` is set to "above" or "below" so the arrow flips to point at the target. */
  .app-tooltip {
    position: fixed;
    z-index: 10001;
    padding: 8px 12px;
    border-radius: 8px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 500;
    line-height: 1.45;
    white-space: pre-wrap;
    box-shadow: 0 6px 20px rgba(0,0,0,0.18);
    pointer-events: none;
    /* Defensive resets — tooltip is rendered into <body> but a parent style cascade
       (e.g. text-transform from a section title) could still bleed in via inheritance. */
    text-transform: none;
    letter-spacing: 0;
    text-align: left;
    --arrow-x: 50%;
  }
  .app-tooltip::after {
    content: '';
    position: absolute;
    left: var(--arrow-x);
    width: 0; height: 0;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    transform: translateX(-50%);
  }
  .app-tooltip[data-pos="above"]::after { top: 100%; border-top: 6px solid var(--app-tooltip-bg, #FFFBEB); }
  .app-tooltip[data-pos="below"]::after { bottom: 100%; border-bottom: 6px solid var(--app-tooltip-bg, #FFFBEB); }

  /* Info variant — soft cream card, easy on the eyes for read-on-hover help text. */
  .app-tooltip--info {
    --app-tooltip-bg: #FFFBEB;
    background: var(--app-tooltip-bg);
    color: #44403C;
    border: 1px solid #FCD34D;
  }
  .app-tooltip--info[data-pos="above"]::after { border-top-color: #FCD34D; }
  .app-tooltip--info[data-pos="below"]::after { border-bottom-color: #FCD34D; }

  /* Error variant — uses the themed --error-color so users can change red to whatever
     reads well in their colour scheme. Default sits at a balanced rose. */
  .app-tooltip--error {
    --app-tooltip-bg: #FEF2F2;
    background: var(--app-tooltip-bg);
    color: var(--error-color, #B91C1C);
    border: 1px solid var(--error-color, #B91C1C);
    font-weight: 600;
  }
  .app-tooltip--error[data-pos="above"]::after { border-top-color: var(--error-color, #B91C1C); }
  .app-tooltip--error[data-pos="below"]::after { border-bottom-color: var(--error-color, #B91C1C); }

  /* Field with an active error gets a red ring without pushing surrounding layout. */
  .form-input.field-error,
  .form-select.field-error { border-color: var(--error-color, #B91C1C) !important; box-shadow: 0 0 0 2px color-mix(in oklab, var(--error-color, #B91C1C) 18%, transparent); }

  /* Compact view — toggled from the Stock toolbar. Hides product images / emoji and
     the SKU sub-line so each row is a single line of text. All other columns (name,
     variant group, price, total stock, by-channel, actions) stay visible. */
  .compact-view .product-thumb,
  .compact-view .product-emoji { display: none; }
  .compact-view .product-sku { display: none; }
  .compact-view .product-table th,
  .compact-view .product-table td { padding-top: 6px; padding-bottom: 6px; }
  .compact-view .icon-btn { width: 28px; height: 28px; font-size: 13px; }

  /* ── MODAL ── */
  .modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(28,25,23,0.5);
    z-index: 200;
    align-items: center;
    justify-content: center;
    /* Generous side padding on desktop so a near-edge click lands on the overlay
       safely instead of misfiring inside the modal — phones tighten this in pos.css. */
    padding: 40px 56px;
  }
  .modal-overlay.open { display: flex; }

  .modal {
    background: var(--bg-card);
    border-radius: var(--radius-lg);
    width: 100%;
    max-width: 560px;
    max-height: 90dvh;
    /* Flex column so .modal-body scrolls while header + footer stay pinned —
       no more scroll-to-the-bottom hunt for the Save button. */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: var(--shadow-md);
    animation: modalIn 0.2s ease;
  }

  @keyframes modalIn {
    from { opacity: 0; transform: translateY(12px) scale(0.98); }
    to { opacity: 1; transform: translateY(0) scale(1); }
  }

  .modal-header {
    padding: 20px 24px 16px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .modal-title {
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 500;
  }

  .modal-close {
    width: 32px; height: 32px;
    border: none; background: none;
    cursor: pointer; font-size: 18px;
    color: var(--text-muted);
    border-radius: var(--radius-sm);
    display: flex; align-items: center; justify-content: center;
    transition: all 0.15s;
  }
  .modal-close:hover { background: var(--bg); color: var(--text-primary); }

  .modal-header { flex-shrink: 0; padding-left: 64px; padding-right: 64px; }
  /* Generous horizontal padding (~two-finger margin) on desktop so form contents have
     breathing room and the modal feels deliberate. The phone media query in pos.css
     pulls this back to 0 / minimal padding for full-screen layout. */
  .modal-body { padding: 20px 64px; flex: 1 1 auto; overflow-y: auto; min-height: 0; }
  .modal-footer {
    padding: 16px 64px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    flex-shrink: 0;
    background: var(--bg-card);
  }

  /* ── FORM STYLES ── */
  .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
  .form-grid.full { grid-template-columns: 1fr; }
  .form-group { display: flex; flex-direction: column; gap: 5px; }
  .form-group.span2 { grid-column: span 2; }

  .form-label {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.4px;
  }

  .form-input, .form-select {
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: 14px;
    color: var(--text-primary);
    background: var(--bg-card);
    outline: none;
    transition: border-color 0.15s;
    width: 100%;
  }
  .form-input:focus, .form-select:focus { border-color: var(--accent); }

  .form-section-title {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    margin: 16px 0 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
  }

  .stock-inputs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

  /* Stock+Price per channel */
  .channel-sp-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--bg-card);
    margin-bottom: 8px;
  }
  .channel-sp-header {
    grid-column: span 2;
    padding: 7px 12px;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    font-size: 11px;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    display: flex;
    align-items: center;
    gap: 6px;
  }
  .channel-sp-cell {
    padding: 8px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .channel-sp-cell + .channel-sp-cell {
    border-left: 1px solid var(--border);
  }
  .channel-sp-label {
    font-size: 10px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.4px;
  }
  .channel-sp-input {
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: 13px;
    color: var(--text-primary);
    background: var(--bg-card);
    outline: none;
    width: 100%;
    transition: border-color 0.15s;
  }
  .channel-sp-input:focus { border-color: var(--accent); }
  .channel-sp-input.using-default {
    color: var(--text-muted);
    font-style: italic;
  }
  .channel-sp-default-hint {
    font-size: 10px;
    color: var(--text-muted);
    font-style: italic;
  }

  /* Price popover in stock table */
  .price-cell {
    position: relative;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
  }
  .price-cell-indicator {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--accent);
    opacity: 0.6;
    flex-shrink: 0;
  }
  /* Price popover is positioned into document.body by JS so it escapes table overflow
     and can flip above/below based on viewport space. The static popover in the table
     is read-only (its innerHTML is cloned into the floating layer on hover). */
  .price-popover {
    display: none;
    position: fixed;
    z-index: 9999;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    min-width: 200px;
    padding: 10px 0;
  }
  .price-popover-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 5px 14px;
    font-size: 12px;
    gap: 16px;
  }
  .price-popover-row:not(:last-child) { border-bottom: 1px solid var(--border); }
  .price-popover-channel { color: var(--text-secondary); }
  .price-popover-val { font-weight: 600; color: var(--text-primary); }
  .price-popover-default { color: var(--text-muted); font-style: italic; }

  /* ── RESTOCK MODAL ── */
  .restock-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

  /* ── IMAGE UPLOAD ── */
  .image-upload-area {
    border: 2px dashed var(--border-strong);
    border-radius: var(--radius-md);
    padding: 20px;
    text-align: center;
    cursor: pointer;
    transition: all 0.15s;
    background: var(--bg);
    position: relative;
    min-height: 100px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .image-upload-area:hover { border-color: var(--accent); background: var(--accent-light); }
  .image-upload-area.has-image { padding: 0; border-style: solid; border-color: var(--border); }
  .image-preview-wrap { display: flex; flex-direction: column; align-items: center; gap: 6px; }
  .image-upload-icon { font-size: 28px; opacity: 0.5; }
  .image-upload-text { font-size: 14px; font-weight: 500; color: var(--text-secondary); }
  .image-upload-hint { font-size: 11px; color: var(--text-muted); }
  .image-preview-img {
    width: 100%;
    max-height: 180px;
    object-fit: contain;
    border-radius: var(--radius-md);
    display: block;
  }

  /* ── PRODUCT THUMBNAIL in table ── */
  .product-thumb {
    width: 56px;
    height: 56px;
    border-radius: var(--radius-sm);
    object-fit: cover;
    border: 1px solid var(--border);
    flex-shrink: 0;
    cursor: zoom-in;
  }
  .product-thumb:hover { border-color: var(--accent); }
  /* Floating image preview — positioned by JS so it clamps to viewport */
  .thumb-preview-popup {
    position: fixed;
    z-index: 9999;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 12px 32px rgba(0,0,0,0.24);
    padding: 6px;
    pointer-events: none;
  }
  .thumb-preview-popup img {
    display: block;
    width: 220px;
    height: 220px;
    object-fit: contain;
    border-radius: 4px;
  }
  .product-emoji-fallback, .product-emoji {
    width: 56px;
    height: 56px;
    border-radius: var(--radius-sm);
    background: var(--accent-light);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    flex-shrink: 0;
    border: 1px solid var(--border);
  }

  /* ── EMPTY STATE ── */
  .empty-state {
    text-align: center;
    padding: 60px 20px;
    color: var(--text-muted);
  }
  .empty-state-icon { font-size: 36px; margin-bottom: 12px; opacity: 0.5; }
  .empty-state-text { font-size: 14px; font-weight: 300; }

  /* ── SETTINGS ── */
  .settings-section { margin-bottom: 32px; }
  .settings-section-title {
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 500;
    color: var(--text-primary);
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
  }
  .settings-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 20px;
    box-shadow: var(--shadow-sm);
  }
  .channel-add-row {
    display: flex;
    gap: 10px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    flex-wrap: wrap;
  }
  .channel-row-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
  }
  .channel-row-item:last-child { border-bottom: none; }
  .channel-row-emoji { font-size: 18px; width: 28px; text-align: center; }
  .channel-row-name { flex: 1; font-size: 14px; font-weight: 500; color: var(--text-primary); }
  .channel-row-badge {
    font-size: 10px;
    padding: 2px 8px;
    border-radius: 20px;
    background: var(--bg);
    color: var(--text-muted);
    border: 1px solid var(--border);
    text-transform: uppercase;
    letter-spacing: 0.4px;
  }
  .theme-swatches { display: flex; gap: 10px; flex-wrap: wrap; }
  .theme-swatch {
    width: 36px; height: 36px;
    border-radius: 50%;
    cursor: pointer;
    border: 3px solid transparent;
    transition: all 0.15s;
    position: relative;
  }
  .theme-swatch.active { border-color: var(--text-primary); transform: scale(1.1); }
  .theme-swatch:hover { transform: scale(1.1); }
