/* Everkind — design system
   Palette: deep teal (brand/primary), warm coral (accent/CTA), soft cream background.
   Deliberately no web-font import — system font stack only, so pages never wait on
   (or break because of) a third-party font CDN. */

:root {
  --teal-900: #0b3b36;
  --teal-700: #0f5f56;
  --teal-600: #0f766e;
  --teal-500: #14958a;
  --teal-100: #e3f4f1;
  --coral-600: #e85d4a;
  --coral-500: #f4714f;
  --coral-100: #fde9e2;
  --cream: #fbf8f3;
  --paper: #ffffff;
  --ink-900: #1f2430;
  --ink-600: #545c6b;
  --ink-400: #8b93a1;
  --line: #e7e2d8;
  --danger: #c0392b;
  --success: #1e8e5a;
  --radius: 14px;
  --radius-sm: 8px;
  --shadow: 0 1px 2px rgba(20, 20, 20, 0.04), 0 8px 24px rgba(20, 20, 20, 0.06);
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--cream);
  color: var(--ink-900);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }

.container {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 20px;
}

/* ---------- Header ---------- */

.site-header {
  background: var(--teal-900);
  color: #fff;
  position: sticky;
  top: 0;
  z-index: 20;
}

.site-header .bar {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 16px 20px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  color: #fff;
}

.brand-mark {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: linear-gradient(135deg, var(--coral-500), var(--coral-600));
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 800;
  font-size: 1rem;
}

.site-nav {
  display: flex;
  gap: 18px;
  margin-left: auto;
  align-items: center;
  font-size: 0.95rem;
}

.site-nav a {
  opacity: 0.88;
  padding: 8px 4px;
}
.site-nav a:hover { opacity: 1; }

.cart-pill {
  background: rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  padding: 8px 14px;
  font-weight: 600;
  display: inline-flex;
  gap: 6px;
  align-items: center;
}
.cart-pill:hover { background: rgba(255, 255, 255, 0.2); }

.search-form {
  flex: 1;
  max-width: 420px;
}
.search-form input {
  width: 100%;
  border: none;
  border-radius: 999px;
  padding: 9px 16px;
  font-size: 0.92rem;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
}
.search-form input::placeholder { color: rgba(255, 255, 255, 0.65); }
.search-form input:focus {
  outline: 2px solid var(--coral-500);
  background: #fff;
  color: var(--ink-900);
}

/* ---------- Hero ---------- */

.hero {
  background: linear-gradient(160deg, var(--teal-700), var(--teal-900) 70%);
  color: #fff;
  padding: 56px 20px 44px;
  text-align: center;
}
.hero h1 { font-size: 2.3rem; margin: 0 0 8px; letter-spacing: -0.02em; }
.hero p { margin: 0; opacity: 0.85; font-size: 1.05rem; }

.category-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 22px;
}
.chip {
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.2);
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 0.88rem;
  color: #fff;
}
.chip.active, .chip:hover { background: var(--coral-500); border-color: var(--coral-500); }

/* ---------- Layout sections ---------- */

.section { padding: 36px 20px; }
.section h2 { font-size: 1.35rem; margin: 0 0 18px; letter-spacing: -0.01em; }

/* ---------- Category sidebar (shown once a category is active) ---------- */
/* Clicking a top-level category chip replaces the flat browse view with a
   two-column layout: this sidebar (its subcategories, each with a
   hover-triggered flyout of its own sub-subcategories) plus the filtered
   product grid — see src/views/pages/home.ts / src/routes/storefront.ts. */

.shop-layout { display: flex; align-items: flex-start; gap: 32px; }
.shop-main { flex: 1; min-width: 0; }

.category-sidebar {
  width: 220px;
  flex-shrink: 0;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  /* Deliberately NOT position: sticky. Chromium (and other engines) treat
     a sticky ancestor as its own compositing layer, and content that
     overflows it via position: absolute (the sub-subcategory flyout) can
     end up painted BEHIND later, non-positioned siblings (the product
     grid) despite a higher z-index — verified directly with
     document.elementFromPoint(). Static keeps the flyout reliably on top;
     the "sidebar follows you while scrolling" behavior wasn't part of
     what was asked for, so it's not worth the trade-off. */
  position: static;
}
.sidebar-heading { font-weight: 700; font-size: 0.95rem; margin-bottom: 8px; padding: 0 10px; }
.sidebar-list { list-style: none; margin: 4px 0 0; padding: 0; }
.sidebar-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  color: var(--ink-600);
}
.sidebar-link:hover, .sidebar-link.active { background: var(--teal-100); color: var(--teal-700); font-weight: 600; }
.sidebar-caret { color: var(--ink-400); font-size: 0.85rem; }

.sidebar-item { position: relative; }

/* The sub-subcategory flyout — hidden by default, revealed on hover (or
   keyboard focus, so it isn't hover-only for accessibility) of its parent
   subcategory row. Positioned to open to the right of the sidebar. */
.sidebar-flyout {
  display: none;
  position: absolute;
  left: 100%;
  top: 0;
  /* A fixed width (not min-width/shrink-to-fit) so the box is never sized
     down by the auto-width algorithm some browsers apply differently to
     absolutely-positioned elements — this is what caused sub-subcategory
     names to render clipped instead of on one full line in practice. */
  width: 220px;
  max-width: 220px;
  overflow: visible;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  padding: 6px;
  margin: 0;
  list-style: none;
  z-index: 30;
}
.sidebar-item:hover .sidebar-flyout,
.sidebar-item:focus-within .sidebar-flyout {
  display: block;
}
.sidebar-flyout a {
  display: block;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  font-size: 0.87rem;
  color: var(--ink-600);
  /* Wrap instead of nowrap: with a fixed-width box (above), a long
     sub-subcategory name should wrap onto a second line rather than ever
     get clipped or spill out past the box's edge. */
  white-space: normal;
  line-height: 1.3;
}
.sidebar-flyout a:hover, .sidebar-flyout a.active { background: var(--teal-100); color: var(--teal-700); font-weight: 600; }

@media (max-width: 800px) {
  .shop-layout { flex-direction: column; }
  .category-sidebar { width: 100%; position: static; }
  .sidebar-flyout { position: static; box-shadow: none; border: none; padding-left: 14px; display: block; }
  .sidebar-item:hover .sidebar-flyout, .sidebar-item:focus-within .sidebar-flyout { display: block; }
}

/* ---------- Category carousels (home landing view) ---------- */
/* One horizontally-scrolling row per top-level category, with click-to-
   scroll arrows — the home page's default view when no category or search
   is active (see showCategoryRows in src/routes/storefront.ts). */

.category-carousel { margin-bottom: 36px; }
.category-carousel:last-child { margin-bottom: 0; }
.carousel-heading { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 14px; }
.carousel-heading h2 { margin: 0; }
.carousel-see-all { font-size: 0.85rem; font-weight: 600; color: var(--teal-700); }
.carousel-see-all:hover { text-decoration: underline; }

.carousel-wrap { position: relative; }
.carousel-track {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scroll-behavior: smooth;
  scroll-snap-type: x proximity;
  padding: 2px 2px 10px;
  -webkit-overflow-scrolling: touch;
}
.carousel-track::-webkit-scrollbar { height: 6px; }
.carousel-track::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
.carousel-track .card { min-width: 190px; max-width: 190px; scroll-snap-align: start; flex-shrink: 0; }

.carousel-arrow {
  position: absolute;
  top: 40%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--ink-900);
  cursor: pointer;
  z-index: 5;
}
.carousel-arrow:hover { background: var(--teal-100); }
.carousel-arrow-left { left: -14px; }
.carousel-arrow-right { right: -14px; }
@media (max-width: 700px) {
  /* Touch devices scroll the row natively — the overlaid arrow buttons
     mostly get in the way of a thumb swipe at this width. */
  .carousel-arrow { display: none; }
}

/* ---------- Back to top ---------- */

#back-to-top-btn {
  position: fixed;
  right: 22px;
  bottom: 22px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--teal-900);
  color: #fff;
  border: none;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--shadow);
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 50;
}
#back-to-top-btn.visible { opacity: 1; pointer-events: auto; transform: translateY(0); }
#back-to-top-btn:hover { background: var(--teal-700); }

/* ---------- Product grid/cards ---------- */

.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 18px;
}

.card {
  background: var(--paper);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
}
.card:hover { box-shadow: 0 4px 8px rgba(20,20,20,.06), 0 16px 32px rgba(20,20,20,.09); }

.card-media {
  aspect-ratio: 1 / 1;
  background: var(--teal-100);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  position: relative;
}
.card-media img { width: 100%; height: 100%; object-fit: cover; }
.card-media .placeholder { color: var(--teal-500); font-size: 2rem; }

.badge {
  position: absolute;
  top: 10px;
  left: 10px;
  background: var(--coral-600);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.card-body { padding: 12px 14px 16px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.card-title { font-size: 0.95rem; font-weight: 600; line-height: 1.3; }
.card-meta { font-size: 0.8rem; color: var(--ink-400); }
.card-price { margin-top: auto; font-weight: 700; color: var(--teal-700); font-size: 1.05rem; }
.card-price .compare { color: var(--ink-400); font-weight: 500; text-decoration: line-through; font-size: 0.85rem; margin-left: 6px; }

/* ---------- Buttons & forms ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: 999px;
  padding: 11px 22px;
  font-weight: 600;
  font-size: 0.95rem;
  border: none;
  cursor: pointer;
  font-family: var(--font);
}
.btn-primary { background: var(--coral-600); color: #fff; }
.btn-primary:hover { background: var(--coral-500); }
.btn-secondary { background: var(--teal-100); color: var(--teal-700); }
.btn-secondary:hover { background: #d5ede8; }
.btn-outline { background: transparent; border: 1px solid var(--line); color: var(--ink-900); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-block { width: 100%; }
.btn-sm { padding: 7px 14px; font-size: 0.85rem; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.field { margin-bottom: 16px; }
.field label { display: block; font-size: 0.85rem; font-weight: 600; margin-bottom: 6px; color: var(--ink-600); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  font-size: 0.95rem;
  font-family: var(--font);
  background: #fff;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--teal-500);
  border-color: transparent;
}
.field-hint { font-size: 0.78rem; color: var(--ink-400); margin-top: 4px; }
.field-row { display: flex; gap: 14px; }
.field-row .field { flex: 1; }

/* A checkbox + inline label pair (e.g. the Payments/Shipping on-off
   switches on the Settings page) — overrides .field label's block layout
   and bold weight, since a toggle's label sits beside its checkbox, not
   above it like every other .field label. */
.toggle-field .toggle-label { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 0.92rem; color: var(--ink-900); margin-bottom: 0; }
.toggle-field .toggle-label input[type="checkbox"] { width: auto; }
.toggle-field .field-hint { margin-left: 26px; }

/* Auction buyer's-fee/tax calculator on the New/Edit product form — see
   auctionFeeScript() in adminProductForm.ts. */
.auction-fee-block { background: var(--teal-100); border-radius: var(--radius-sm); padding: 12px 14px; }
.auction-fee-block label { font-size: 0.88rem; font-weight: 600; color: var(--teal-900); }
.auction-fee-breakdown { margin-top: 10px; padding-top: 10px; border-top: 1px solid rgba(15, 95, 86, 0.15); }
.auction-fee-line { display: flex; justify-content: space-between; font-size: 0.85rem; color: var(--ink-600); padding: 3px 0; }
.auction-fee-line strong { font-variant-numeric: tabular-nums; color: var(--ink-900); }
.auction-fee-total { border-top: 1px dashed rgba(15, 95, 86, 0.25); margin-top: 4px; padding-top: 8px; font-size: 0.95rem; }
.auction-fee-total span { font-weight: 700; color: var(--teal-900); }
.auction-fee-total strong { font-size: 1.05rem; color: var(--teal-700); }

.alert { padding: 12px 16px; border-radius: var(--radius-sm); font-size: 0.9rem; margin-bottom: 16px; }
.alert-error { background: #fdecea; color: var(--danger); border: 1px solid #f6c6c0; }
.alert-success { background: #e9f7ef; color: var(--success); border: 1px solid #b9e5cc; }
.alert-warning { background: #fff6e0; color: #8a6100; border: 1px solid #f0dca0; }

/* ---------- Product detail ---------- */

.product-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; padding: 40px 20px; }
@media (max-width: 800px) { .product-detail { grid-template-columns: 1fr; gap: 24px; } }

.gallery-main { border-radius: var(--radius); overflow: hidden; background: var(--teal-100); aspect-ratio: 1/1; }
.gallery-main img { width: 100%; height: 100%; object-fit: cover; }
.gallery-thumbs { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.gallery-thumbs a { width: 64px; height: 64px; border-radius: 8px; overflow: hidden; border: 2px solid transparent; }
.gallery-thumbs a.active { border-color: var(--coral-500); }
.gallery-thumbs img { width: 100%; height: 100%; object-fit: cover; }

.pd-title { font-size: 1.7rem; margin: 0 0 6px; letter-spacing: -0.01em; }
.pd-sku { font-size: 0.8rem; color: var(--ink-400); margin: 0 0 8px; }
.pd-price { font-size: 1.6rem; font-weight: 700; color: var(--teal-700); margin: 10px 0; }
.pd-desc { color: var(--ink-600); white-space: pre-wrap; line-height: 1.6; }
.pd-desc-list { color: var(--ink-600); line-height: 1.5; list-style: disc; padding-left: 22px; margin: 0; }
.pd-desc-list li { margin-bottom: 10px; }
.pd-desc-list li:last-child { margin-bottom: 0; }
.pd-desc-list li strong { color: var(--ink-900); }
.pd-meta-row { display: flex; gap: 10px; margin: 14px 0; flex-wrap: wrap; }
.tag { background: var(--teal-100); color: var(--teal-700); padding: 5px 12px; border-radius: 999px; font-size: 0.8rem; font-weight: 600; }

/* ---------- Cart ---------- */

.cart-row { display: flex; gap: 14px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--line); }
.cart-row img { width: 72px; height: 72px; border-radius: 10px; object-fit: cover; background: var(--teal-100); }
.cart-row .grow { flex: 1; }
.cart-summary { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; }
.summary-line { display: flex; justify-content: space-between; padding: 6px 0; font-size: 0.95rem; }
.summary-line.total { font-weight: 700; font-size: 1.1rem; border-top: 1px solid var(--line); margin-top: 8px; padding-top: 12px; }
.qty-input { width: 56px; text-align: center; padding: 6px; border-radius: 8px; border: 1px solid var(--line); }

/* ---------- Cart holds (reservation countdown) ---------- */

.hold-explainer { color: var(--ink-400); font-size: 0.88rem; margin: -6px 0 16px; }
.hold-line { color: var(--teal-700) !important; font-weight: 600; margin-top: 2px; }
.hold-countdown { font-variant-numeric: tabular-nums; }

.hold-modal {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 20, 0.5);
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 1000;
}
.hold-modal.open { display: flex; }
.hold-modal-box {
  background: #fff;
  border-radius: var(--radius);
  padding: 24px;
  max-width: 420px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
}
.hold-modal-box h3 { margin: 0 0 10px; font-size: 1.1rem; }
.hold-modal-box p { color: var(--ink-600); font-size: 0.92rem; line-height: 1.5; margin: 0 0 16px; }

/* Generic modal overlay/box — same visual language as .hold-modal above,
   just under a name that isn't cart-specific, for reuse anywhere else a
   popup is needed (the admin "Mark As Sold" popup, the admin idle-timeout
   warning, etc.). */
.ek-modal {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 20, 0.5);
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 1000;
}
.ek-modal.open { display: flex; }
.ek-modal-box {
  background: #fff;
  border-radius: var(--radius);
  padding: 24px;
  max-width: 420px;
  width: 100%;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
}
.ek-modal-box h3 { margin: 0 0 10px; font-size: 1.1rem; }
.ek-modal-box p { color: var(--ink-600); font-size: 0.92rem; line-height: 1.5; margin: 0 0 16px; }

/* ---------- Local pickup only ---------- */

.pickup-banner { display: flex; flex-direction: column; gap: 4px; }
.pickup-banner strong { font-size: 1rem; }

/* ---------- Admin ---------- */

.admin-shell { display: flex; min-height: 100vh; }
.admin-sidebar { width: 220px; background: var(--teal-900); color: #fff; padding: 20px 0; flex-shrink: 0; }
.admin-sidebar .brand { padding: 0 20px 20px; }
.admin-sidebar a { display: block; padding: 10px 20px; opacity: 0.8; font-size: 0.92rem; }
.admin-sidebar a:hover, .admin-sidebar a.active { opacity: 1; background: rgba(255,255,255,0.08); }

/* Jumps straight to the live customer-facing storefront in a new tab —
   deliberately styled as a real button (not just another nav link) so it
   stands out as "go see what a customer sees" rather than blending into the
   admin section list below it. */
.admin-shop-btn {
  display: block;
  margin: 0 20px 16px;
  padding: 10px 14px !important;
  background: linear-gradient(135deg, var(--coral-500), var(--coral-600));
  color: #fff !important;
  text-align: center;
  border-radius: var(--radius-sm);
  font-weight: 700;
  opacity: 1 !important;
  width: auto;
}
.admin-shop-btn:hover { filter: brightness(1.08); }
/* max-width raised from 1100px — the Products table alone has 13+ columns
   (checkbox, thumbnail, name, SKU, status, price, cost, qty, purchased,
   sold, sold-for, profit, FB, actions) and was forcing a horizontal
   scroll on ordinary browser windows even after trimming columns.
   Everything else on admin pages (forms, cards, category names) already
   constrains its own width inline, so giving the shell more room just
   gives wide tables more room to breathe without stretching narrow
   content oddly. table.admin-table's own .table-scroll wrapper is still
   there as a fallback for anyone on a genuinely narrow window. */
.admin-main { flex: 1; padding: 28px 32px; max-width: 1600px; }
.admin-topline { display: flex; justify-content: space-between; align-items: center; margin-bottom: 22px; }
.admin-topline h1 { font-size: 1.5rem; margin: 0; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-bottom: 28px; }
.stat-card { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px; }
.stat-card .label { font-size: 0.8rem; color: var(--ink-400); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.stat-card .value { font-size: 1.7rem; font-weight: 700; margin-top: 4px; }

/* The Products table has grown to 13+ columns (checkboxes, thumbnail,
   name, SKU, status, price, cost, qty, purchased, sold, sold-for, profit,
   FB link, actions) — wide enough that on a normal browser window it
   overflows well past the visible area. Without this wrapper the table
   just bled off the right edge of the page with no visible scrollbar,
   which is why "Post to FB" (the last column) read as "missing" — it was
   there, just off-screen. overflow-x: auto here scopes the horizontal
   scroll to the table itself so the sidebar, filters, and action bar stay
   put while only the table's columns scroll. */
.table-scroll { overflow-x: auto; border-radius: var(--radius); }
.table-scroll table.admin-table { border-radius: 0; }
table.admin-table { width: 100%; border-collapse: collapse; background: var(--paper); border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); }
table.admin-table th, table.admin-table td { text-align: left; padding: 12px 14px; font-size: 0.9rem; border-bottom: 1px solid var(--line); }
table.admin-table th { background: var(--teal-100); color: var(--teal-700); font-weight: 700; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; }
table.admin-table tr:last-child td { border-bottom: none; }
table.admin-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.admin-table th.sortable a { color: inherit; text-decoration: none; }
table.admin-table th.sortable a:hover { text-decoration: underline; }

/* Collapse/expand toggle on the Categories tree (see the script at the
   bottom of adminCategories.ts). A plain triangle button, not a full .btn —
   it sits inline with the name input at every depth, so it needs to be
   compact and not compete visually with Save/Delete. Leaf rows (no
   children) get .cat-toggle-spacer instead, so the name input still lines
   up in the same column whether or not its row has a toggle. */
/* Given its own small button "box" (border + background) rather than a
   bare glyph — with the new per-depth level icon (📂/↳/·) sitting right
   next to it, a borderless triangle read as decoration, not a control. */
.cat-toggle {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  cursor: pointer;
  font-size: 0.75rem;
  color: var(--ink-600);
  padding: 0;
  line-height: 1;
}
.cat-toggle:hover { color: var(--ink-900); background: var(--teal-100); border-color: var(--teal-500); }
.cat-toggle-spacer { display: inline-block; width: 22px; flex-shrink: 0; }

/* Small key above the Categories table explaining the three row styles
   below — so the visual language (icon + shade + weight) is legible on
   first look, not something you have to reverse-engineer by trial and
   error. Also hosts the Collapse all/Expand all bulk-action buttons,
   pushed to the far right of the same row. */
.cat-legend { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; margin: 10px 0 16px; font-size: 0.85rem; color: var(--ink-600); }
.cat-legend-item { display: inline-flex; align-items: center; gap: 8px; }
.cat-legend-swatch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  border: 1px solid var(--line);
  font-size: 0.85rem;
}
.cat-bulk-actions { margin-left: auto; display: flex; gap: 8px; }

/* Category tree row hierarchy — each depth gets its own background tint,
   left accent bar, and name weight/size so which tier a row belongs to is
   obvious at a glance, without having to compare indentation carefully.
   Depth 0 (top-level category): boldest, tinted like the table header.
   Depth 1 (subcategory): plain background, medium weight, teal accent bar.
   Depth 2 (sub-subcategory): softest, smaller, muted accent bar. */
tr.cat-row-lvl0 { background: var(--teal-100); border-left: 4px solid var(--teal-600); }
tr.cat-row-lvl0 .cat-name-input { font-weight: 700; font-size: 0.98rem; color: var(--teal-900); }
tr.cat-row-lvl0 td { border-bottom: 1px solid var(--teal-100); }

tr.cat-row-lvl1 { background: var(--paper); border-left: 4px solid var(--teal-500); }
tr.cat-row-lvl1 .cat-name-input { font-weight: 600; font-size: 0.9rem; color: var(--ink-900); }

tr.cat-row-lvl2 { background: var(--cream); border-left: 4px solid var(--line); }
tr.cat-row-lvl2 .cat-name-input { font-weight: 400; font-size: 0.87rem; color: var(--ink-600); }

.cat-level-icon { flex-shrink: 0; font-size: 0.9rem; width: 18px; text-align: center; color: var(--ink-400); }
tr.cat-row-lvl0 .cat-level-icon { font-size: 1rem; }
tr.cat-row-lvl2 .cat-level-icon { color: var(--ink-400); font-weight: 700; }

/* The "Add a subcategory/sub-subcategory" prompt rows are deliberately
   styled to look like an action, not a data row — dashed top border,
   no left accent bar, muted "+" marker — so they're never mistaken for an
   actual existing category while scanning the tree. */
tr.cat-add-row { background: transparent; border-top: 1px dashed var(--line); }
tr.cat-add-row td { border-bottom: 1px solid var(--line); padding-top: 8px; padding-bottom: 8px; }
.cat-level-icon-add { color: var(--teal-600); font-weight: 700; }

/* Fixed-size product thumbnail in the admin Products table.
   TRUE ROOT CAUSE of thumbnails rendering as a near-invisible sliver
   (found by inspecting computed styles live, not guessing): the global
   `img { max-width: 100%; }` reset near the top of this file. This admin
   table has no `table-layout: fixed`, so the browser's auto column-sizing
   algorithm is free to squeeze this column down when the row's other
   columns (long product names, Cost, Purchased, Sold, two action buttons)
   need more room than the viewport has. Once that column shrank below
   72px, `max-width: 100%` capped the <img> to whatever sliver of width
   was left — one row measured at 6px wide by 72px tall, regardless of
   object-fit mode. Explicit width/height HTML attributes (kept below)
   still matter for a different reason (they reserve intrinsic size so a
   lazy-loaded image doesn't collapse before it scrolls into view), but
   they don't stop this specific collapse — only `max-width: none` here
   does, by taking the percentage constraint out of the picture entirely
   so the image (and therefore this column) can't be squeezed below 72px
   in the first place. */
table.admin-table td.thumb-cell { width: 84px; min-width: 84px; padding-right: 8px; }
table.admin-table td.thumb-cell img,
table.admin-table td.thumb-cell .thumb-placeholder {
  display: block;
  width: 72px;
  height: 72px;
  max-width: none;
  min-width: 72px;
  /* object-fit: contain — these are marketplace-sourced photos with wildly
     inconsistent aspect ratios, and cropping to fill a square (cover) cuts
     off real chunks of the product on a tall/narrow photo. Showing the
     whole photo letterboxed looks better than a lossy crop, and now that
     the max-width collapse above is fixed, "contain" no longer means
     "invisible" — it just means letterboxed within a correctly-sized 72x72
     box. */
  object-fit: contain;
  border-radius: 8px;
  border: 1px solid var(--line);
  /* A tinted background instead of plain white — most of these product
     photos are themselves shot on a white background, and a white photo on
     a white table row (with only a faint 1px border) was hard to even
     notice, especially a narrow/tall photo that's mostly white padding.
     The tint gives every photo visible contrast against its cell no matter
     what color the photo itself is. */
  background: var(--teal-100);
}

/* Small inline stat strip for the Products list's filtered-results report
   (count/sold/cost/profit for whatever's currently shown) — same visual
   language as .stat-card but compact enough to sit above a table. */
.mini-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 1.25rem; }
.mini-stat-card { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; }
.mini-stat-card .label { font-size: 0.72rem; color: var(--ink-400); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.mini-stat-card .value { font-size: 1.2rem; font-weight: 700; margin-top: 2px; }

/* Bulk-selection action bar above the Products table (Archive / Mark Sold /
   Return To Inventory / Duplicate / Bulk Edit) — buttons stay disabled
   (see the inline script in adminProducts.ts) until at least one row
   checkbox is checked, so it's always visible but inert rather than
   popping in/out of the layout as rows are (de)selected. */
.bulk-action-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; background: var(--cream); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 10px; }
.bulk-action-bar #bulkSelectedCount { font-size: 0.85rem; font-weight: 600; color: var(--ink-600); margin-right: 4px; }
.bulk-action-bar .btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* Status pills — bolder, more saturated colors than the original muted set
   (each pale enough to still pair with black text at a glance, but with a
   colored left bar for a quick scan down a long table without even reading
   the word). Each status gets its own hue rather than sharing teal with the
   brand color, so "Sold" doesn't visually blend into every other teal
   accent on the page the way it used to. */
.status-pill { padding: 3px 10px 3px 8px; border-radius: 999px; font-size: 0.75rem; font-weight: 700; text-transform: capitalize; border-left: 3px solid transparent; }
.status-active, .status-paid { background: #d3f4e0; color: #0a7a42; border-left-color: #0a7a42; }
.status-draft, .status-pending { background: #ffe6b8; color: #9a5b00; border-left-color: #9a5b00; }
.status-sold, .status-fulfilled { background: #dbe9ff; color: #1849c7; border-left-color: #1849c7; }
.status-archived, .status-cancelled { background: #ece5fb; color: #6633cc; border-left-color: #6633cc; }

.login-shell { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--teal-900); }
.login-card { background: #fff; border-radius: var(--radius); padding: 36px; width: 360px; box-shadow: var(--shadow); }
.login-card .brand { justify-content: center; color: var(--ink-900); margin-bottom: 20px; }

.image-drop { border: 2px dashed var(--line); border-radius: var(--radius); padding: 20px; text-align: center; color: var(--ink-400); font-size: 0.88rem; transition: border-color 0.15s, background 0.15s; }
.image-drop.dragover { border-color: var(--teal-700, #0a7a6c); background: var(--teal-100, #e3f4f1); color: var(--ink-600); }
.field-warning { color: #b3261e; font-size: 0.82rem; margin-top: 4px; }
.field-ok { color: #0a7a42; font-size: 0.82rem; margin-top: 4px; }
.thumb-strip { display: flex; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
/* object-fit: contain, not cover — see the matching comment on .thumb-cell
   in this file for why: a tight crop on inconsistently-framed marketplace
   photos was cutting off parts of the product.
   max-width: none — same latent bug as .thumb-cell (the global
   `img { max-width: 100% }` reset near the top of this file can cap an
   explicitly-sized <img> down to whatever room its container happens to
   have). This page normally has plenty of room for a 140px thumbnail, so
   it hasn't been reported broken, but the fix costs nothing and closes off
   the same failure mode here too.
   Tinted background, not plain white — same reasoning as .thumb-cell: a
   white-background product photo on a white page was nearly invisible. */
.thumb-strip img { width: 140px; height: 140px; max-width: none; object-fit: contain; border-radius: 8px; border: 1px solid var(--line); background: var(--teal-100); }

/* ---------- Footer ---------- */

.site-footer { background: #fff; border-top: 1px solid var(--line); padding: 28px 20px; margin-top: 40px; color: var(--ink-400); font-size: 0.85rem; text-align: center; }

/* ---------- Utility ---------- */
.empty-state { text-align: center; padding: 60px 20px; color: var(--ink-400); }
.mt-0 { margin-top: 0; }
.text-right { text-align: right; }
@media (max-width: 640px) {
  .site-header .bar { flex-wrap: wrap; }
  .search-form { order: 3; max-width: none; width: 100%; }
}
