/* Detromotive Ops — design system.
   A clean, modern dashboard look: soft layered surfaces, a subtle brand glow,
   premium stat tiles, and calm data tables. Colours follow a validated status
   palette (good / warning / serious / critical) so money ages read correctly.
   Plain CSS, no framework; every class the templates use is defined here. */

:root {
  /* Brand + ink */
  --brand: #2563EB;
  --brand-600: #1D4ED8;
  --brand-50: #EEF3FF;
  --accent: #2563EB;              /* legacy alias kept for existing markup */
  --ink: #0F172A;
  --ink-2: #475569;
  --text: #0F172A;               /* legacy alias */
  --text-muted: #64748B;
  --muted: #94A3B8;

  /* Surfaces */
  --surface: #FFFFFF;
  --page: #F3F6FC;
  --bg: #F3F6FC;                 /* legacy alias */
  --border: rgba(15, 23, 42, 0.08);
  --border-2: rgba(15, 23, 42, 0.055);

  /* Status (money-age) palette — validated */
  --good: #16A34A;
  --warning: #F59E0B;
  --serious: #EA7A3B;
  --critical: #DC2626;
  --critical-deep: #991B1B;
  --healthy: #16A34A;            /* legacy aliases */
  --caution: #F59E0B;
  --severe: #DC2626;
  --destructive: #DC2626;

  /* Elevation + shape */
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, .05);
  --shadow: 0 1px 3px rgba(15, 23, 42, .06), 0 10px 30px -14px rgba(15, 23, 42, .18);
  --radius: 16px;
  --radius-sm: 12px;

  /* Spacing scale (multiples of 4) */
  --sp-xs: 4px;
  --sp-sm: 8px;
  --sp-md: 16px;
  --sp-lg: 24px;
  --sp-xl: 32px;
  --sp-2xl: 48px;
  --sp-3xl: 64px;

  --wrap-max: 1400px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background:
    radial-gradient(1100px 520px at 100% -8%, #E4ECFF 0%, rgba(228, 236, 255, 0) 60%),
    radial-gradient(900px 500px at -10% 0%, #EAF3FF 0%, rgba(234, 243, 255, 0) 55%),
    var(--page);
  background-attachment: fixed;
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand); text-decoration: none; }

/* --- Header ------------------------------------------------------------- */
/* App chrome (brand bar + primary nav) sticks to the top as one unit so the
   nav stays reachable while scrolling any page. */
.appchrome {
  position: sticky;
  top: 0;
  z-index: 50;
}
.topbar {
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
  padding: 12px clamp(16px, 4vw, 28px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
}

/* --- Primary top navigation (app-wide, base.html) ----------------------- */
.mainnav {
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
}
.mainnav-inner {
  max-width: var(--wrap-max);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 7px clamp(12px, 4vw, 28px);
  overflow-x: auto;
  scrollbar-width: none;               /* Firefox: hide the strip's scrollbar */
  -webkit-overflow-scrolling: touch;   /* momentum scroll on iOS */
  scroll-snap-type: x proximity;
}
.mainnav-inner::-webkit-scrollbar { display: none; }
.mnav {
  flex: none;
  scroll-snap-align: start;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 13px;
  border-radius: 10px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1;
  color: var(--text-muted);
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.mnav-ic { font-size: 15px; line-height: 1; }
.mnav:hover { background: var(--brand-50); color: var(--brand); }
.mnav.is-active {
  background: var(--brand-50);
  color: var(--brand-600);
  border-color: rgba(37, 99, 235, .16);
  font-weight: 700;
}
.mnav:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.mnav-sep {
  flex: none;
  width: 1px;
  align-self: stretch;
  margin: 4px 6px;
  background: var(--border);
}
@media (prefers-reduced-motion: reduce) {
  .mnav { transition: none; }
  .mainnav-inner { scroll-behavior: auto; }
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
}
/* Header monogram lockup (B-16) -- white container (the real Detromotive
   monogram PNG has its own baked-in white background, per UI-SPEC Component
   1) replacing the old blue-gradient "D" placeholder. Class name kept
   (.brand-mark) -- only background/box-shadow swapped, an <img> child added
   in base.html.
   TODO(B-17): the monogram PNG has a hard-baked white background with no
   alpha channel, so it will show a visible white square if this header ever
   goes dark. Dark mode is a separate backlog phase (not attempted here); if
   it happens, swap this PNG for a transparent/SVG version
   (app/static/img/detromotive-logo.pdf is the vector source). */
.brand-mark {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: #FFFFFF;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  flex: none;
}
.brand-mark img {
  width: 26px;
  height: 26px;
  object-fit: contain;
  display: block;
}
.header-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
}

/* --- Layout ------------------------------------------------------------- */
.wrap {
  max-width: var(--wrap-max);
  margin: 0 auto;
  padding: clamp(16px, 3vw, 28px);
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 22px;
  box-shadow: var(--shadow);
  min-width: 0; /* flex/grid child: allow shrink so wide inner tables scroll instead of widening the page */
}
.kpi-row { min-width: 0; }

/* --- Type --------------------------------------------------------------- */
.label {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: .05em;
  margin: 0 0 var(--sp-xs) 0;
}
.heading {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1.25;
  margin: 0;
  color: var(--ink);
}
.display {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.1;
  color: var(--ink);
}
.microcopy {
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.45;
  margin: var(--sp-sm) 0 0 0;
}

/* --- Status pills ------------------------------------------------------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  color: #fff;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
}
.pill-green { background: var(--good); }
.pill-amber { background: var(--warning); }
.pill-red   { background: var(--critical); }
/* Calm/neutral flag for values sourced from a fallback estimate, not a real
   number (D-07) -- reuses the existing --muted token, never a red/warning color. */
.pill-neutral { background: var(--muted); }
/* Soft badge variant with a leading dot (connection status) */
.pill-green::before, .pill-red::before {
  content: "";
  width: 7px; height: 7px; border-radius: 50%;
  background: rgba(255, 255, 255, .9);
}

/* --- Meters / bars ------------------------------------------------------ */
.bar {
  height: 10px;
  border-radius: 999px;
  background: #EDF1F7;
  overflow: hidden;
  margin-top: var(--sp-sm);
}
.bar > i {
  display: block;
  height: 100%;
  border-radius: 999px;
  transition: width .3s ease;
}
.usage-green { background: var(--good); }
.usage-amber { background: var(--warning); }
.usage-red   { background: var(--critical); }

/* --- Buttons / links ---------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  padding: 10px 18px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  transition: transform .08s ease, box-shadow .12s ease, filter .12s ease;
}
.btn:hover { box-shadow: var(--shadow-sm); }
.btn-accent {
  background: linear-gradient(180deg, #3B82F6, #2563EB);
  border: none;
  color: #fff;
  box-shadow: 0 3px 10px rgba(37, 99, 235, .32);
}
.btn-accent:hover { filter: brightness(1.05); transform: translateY(-1px); }
.btn-destructive { background: var(--destructive); border-color: var(--destructive); color: #fff; }

.link-btn {
  background: none;
  border: none;
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 600;
  min-height: 40px;
  padding: 8px 12px;
  border-radius: 8px;
  cursor: pointer;
}
.link-btn:hover { background: #F1F5FB; color: var(--ink); }

.nav-link {
  color: var(--ink-2);
  font-weight: 600;
  font-size: 14px;
  min-height: 40px;
  padding: 8px 12px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
}
.nav-link:hover { background: var(--brand-50); color: var(--brand); }

/* --- Action cards (report links on Home) -------------------------------- */
.action {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font-weight: 700;
  font-size: 15px;
  box-shadow: var(--shadow-sm);
  transition: transform .1s ease, box-shadow .12s ease, border-color .12s ease;
}
.action + .action { margin-top: 10px; }
.action:hover { transform: translateY(-1px); box-shadow: var(--shadow); border-color: #C7D6FF; }
.action-ic {
  width: 40px; height: 40px; border-radius: 11px;
  background: var(--brand-50);
  display: flex; align-items: center; justify-content: center;
  font-size: 20px; flex: none;
}
.action-body { display: flex; flex-direction: column; gap: 1px; }
.action-sub { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.action-arrow { margin-left: auto; color: var(--muted); font-size: 18px; }

/* --- KPI / stat tiles --------------------------------------------------- */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}
.kpi {
  position: relative;
  min-width: 0; /* let grid tracks shrink below content min-width (no row overflow on mobile) */
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px 18px;
  box-shadow: var(--shadow);
  overflow: hidden;
}
.kpi-v { overflow: hidden; text-overflow: ellipsis; }
.kpi::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--kpi-accent, var(--brand));
}
.kpi-icon {
  width: 34px; height: 34px; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 17px; margin-bottom: 10px;
  background: var(--kpi-tint, var(--brand-50));
}
.kpi-v {
  font-size: 26px; font-weight: 800; letter-spacing: -.02em;
  line-height: 1.1; color: var(--ink);
}
.kpi-l { color: var(--ink-2); font-size: 12px; font-weight: 600; margin-top: 3px; }
.kpi--money   { --kpi-accent: var(--brand);    --kpi-tint: #EAF0FF; }
.kpi--danger  { --kpi-accent: var(--critical); --kpi-tint: #FDECEC; }
.kpi--good    { --kpi-accent: var(--good);     --kpi-tint: #E7F6EC; }
.kpi--neutral { --kpi-accent: #64748B;         --kpi-tint: #EEF2F7; }

/* --- Tab bar (bank tabs D-02; "By customer / By cousin" toggle) --------- */
/* One visual pattern learned once, reused for the reconciliation bank tabs
   (Plan 04) and this "By customer / By cousin" toggle. Server-rendered as
   plain links with aria-selected set from the current query param — no
   client-side JS framework needed, same approach as the rest of the app. */
.tab-bar {
  display: flex;
  gap: var(--sp-xs);
  padding: 4px;
  background: #EEF1F6;
  border-radius: var(--radius-sm);
  width: fit-content;
  margin: var(--sp-md) 0;
}
.tab-bar .tab {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 8px 16px;
  border-radius: 8px;
  border: none;
  background: none;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
}
.tab-bar .tab[aria-selected="true"] {
  background: var(--surface);
  color: var(--brand);
  box-shadow: var(--shadow-sm);
}

/* --- Interest-cost callout (B-01) --------------------------------------- */
/* Warm amber, not error-red: draws the eye to money leaking without reading
   as an alarm/broken state (owner's calm-status rule). */
.callout {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  background: #FFF7ED;
  border: 1px solid #FED7AA;
  border-left: 4px solid #EA7A3B;
  border-radius: 16px;
  padding: 18px 22px;
  box-shadow: var(--shadow);
  min-width: 0;
}
.callout-ic { font-size: 26px; line-height: 1; }
.callout-body { min-width: 0; }
.callout-lead { font-size: 13px; font-weight: 700; color: #9A3412; letter-spacing: .01em; }
.callout-v { font-size: 30px; font-weight: 800; color: #7C2D12; letter-spacing: -.02em; line-height: 1.15; margin-top: 2px; }
.callout-sub { font-size: 12.5px; color: #B45309; margin-top: 4px; font-weight: 500; }

/* --- "Money caught" headline callout (D-04.2, Plan 04) ------------------ */
/* Structurally identical to .callout above (same callout-ic/callout-body/
   callout-lead/callout-v/callout-sub inner structure) -- green instead of
   amber, so the "Paid but not in Zoho" headline reads as good news (money
   the owner can go collect), not a cost warning. */
.callout-good {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  background: #E7F6EC;
  border: 1px solid #B7E4C7;
  border-left: 4px solid var(--good);
  border-radius: 16px;
  padding: 18px 22px;
  box-shadow: var(--shadow);
  min-width: 0;
}
.callout-good .callout-lead { font-size: 13px; font-weight: 700; color: #14532D; letter-spacing: .01em; }
.callout-good .callout-v { font-size: 30px; font-weight: 800; color: #14532D; letter-spacing: -.02em; line-height: 1.15; margin-top: 2px; }
.callout-good .callout-sub { font-size: 12.5px; color: #166534; margin-top: 4px; font-weight: 500; }

/* --- Report tables ------------------------------------------------------ */
/* Wide financial tables scroll horizontally WITHIN their card on narrow
   screens instead of forcing the whole page to overflow sideways (which
   clipped key columns like the overdue-day pill on phones). Desktop is
   unaffected — the card is always wider than the min-width. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 0 -2px;
}
table.rpt {
  width: 100%;
  min-width: 520px;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13.5px;
}
table.rpt thead th {
  text-align: left;
  padding: 10px 12px;
  color: var(--muted);
  font-weight: 700;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: .05em;
  border-bottom: 1px solid var(--border);
  background: #FBFCFE;
}
table.rpt tbody td {
  padding: 12px;
  border-bottom: 1px solid var(--border-2);
  color: var(--ink);
}
table.rpt tbody tr:last-child td { border-bottom: none; }
table.rpt td.r, table.rpt th.r { text-align: right; font-variant-numeric: tabular-nums; }
table.rpt tbody td:first-child { font-weight: 600; }
table.rpt tbody tr:hover { background: #F6F9FF; }
table.rpt tbody tr.is-hidden-row { display: none; }
table.rpt .buyer-share { color: var(--muted); font-size: 11.5px; margin-left: 8px; font-weight: 500; }

/* "Who buys it" concentration line (Phase 02.6/B-23) -- amber/serious ⚠ when
   one buyer dominates, calm-green when spread across many; NEVER alarm-red
   (that stays reserved for the Stop verdict badge elsewhere on the page). */
.conc-line {
  border: 1px solid var(--border-2); border-left: 3px solid var(--serious);
  border-radius: 10px; background: color-mix(in srgb, var(--warning) 9%, transparent);
  padding: 11px 13px; font-size: 13.5px; line-height: 1.5; margin-bottom: 14px;
}
.conc-line.conc-low { border-left-color: var(--good); background: color-mix(in srgb, var(--good) 8%, transparent); }
.conc-line b { color: var(--ink); }

.show-all-btn {
  margin-top: 12px; width: 100%; border: 1px solid var(--border); background: var(--surface);
  color: var(--brand); font: inherit; font-weight: 600; font-size: 13.5px; padding: 9px 14px;
  border-radius: 10px; cursor: pointer;
}
.show-all-btn:hover, .show-all-btn:focus-visible { border-color: var(--brand); outline: none; }

/* --- Login -------------------------------------------------------------- */
.login-card {
  max-width: 380px;
  margin: clamp(32px, 8vh, 80px) auto 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
}
.login-form { display: flex; flex-direction: column; gap: var(--sp-sm); }
.login-form label {
  display: flex; flex-direction: column; gap: var(--sp-xs);
  font-size: 13px; font-weight: 600; color: var(--ink-2);
}
.login-form input {
  min-height: 46px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  font-size: 16px;
  background: #fff;
}
.login-form input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, .15);
}
.error { color: var(--destructive); font-size: 13px; font-weight: 600; }

/* --- Peek list ---------------------------------------------------------- */
.peek-list { list-style: none; margin: var(--sp-sm) 0 0 0; padding: 0; display: flex; flex-direction: column; }
.peek-list li { padding: 10px 0; border-top: 1px solid var(--border-2); display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.peek-list li:first-child { border-top: none; }
.peek-name { font-weight: 600; color: var(--ink); }
.peek-amount { margin-left: auto; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.peek-detail { flex-basis: 100%; font-size: 0.82rem; color: var(--text-muted); }

/* --- Home two-column layout + "What's new" panel ------------------------ */
.home-grid { display: grid; gap: var(--sp-md); grid-template-columns: 1fr; margin-top: var(--sp-md); }
@media (min-width: 900px) {
  /* 2.4fr/1fr (D-15 Variant B) -- a page-specific ratio, not used elsewhere,
     safe to change in place; was minmax(0,2fr) minmax(0,1fr). */
  .home-grid { grid-template-columns: minmax(0, 2.4fr) minmax(0, 1fr); align-items: start; }
  .home-aside { position: sticky; top: 76px; }
}
.home-main { display: flex; flex-direction: column; gap: var(--sp-md); }
.home-main > .card { margin: 0; }

.wn-entry { padding: 12px 0; border-bottom: 1px solid var(--border-2); }
.wn-entry:last-child { border-bottom: 0; padding-bottom: 0; }
.wn-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-sm); }
.wn-ver {
  font-weight: 800; font-size: 11px; color: var(--brand);
  background: var(--brand-50); border-radius: 999px; padding: 2px 9px; letter-spacing: .01em;
}
.wn-date { color: var(--muted); font-size: 11px; white-space: nowrap; }
.wn-title { font-weight: 700; font-size: 13px; margin-top: 5px; color: var(--ink); }
.wn-bullets { margin: 6px 0 0; padding-left: 18px; }
.wn-bullets li { font-size: 12px; color: var(--text-muted); margin-bottom: 3px; line-height: 1.45; }

/* --- Phase 02.3 -- Item-360 Variant A components (D-15/D-16) ------------ */
/* Ported verbatim from .planning/sketches/themes/default.css so the shipped
   app matches the owner-approved mockup pixel-for-pixel. Every rule below
   references :root custom properties, never a literal hex, except where a
   token is being defined for the first time (trend-good, matching the
   D-16 forward-compat note). */

/* Soft, low-key chip for tags / SKU / related items -- the template already
   used class="chip"/"chip-link" (plan 02.3-06 placeholder) with no CSS
   backing it; added here (Rule 2) so the SKU chip, brand chip-link, and the
   3 score-explainability chips all render styled, not as bare inline text. */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: 999px;
  background: #F1F5FB; border: 1px solid var(--border-2);
  color: var(--ink-2); font-size: 12.5px; font-weight: 600;
  white-space: nowrap;
}
.chip-sku { background: #EEF2F7; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.chip-link { background: var(--brand-50); color: var(--brand); border-color: rgba(37, 99, 235, .14); }

/* Item title row (name + SKU chip + brand chip-link) -- added alongside
   .chip (Rule 2) for the same reason: no CSS backed this class yet. */
.item-title { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.item-title h1 { font-size: 24px; font-weight: 800; letter-spacing: -.02em; margin: 0; color: var(--ink); }

/* Section titling inside a card (all-caps eyebrow) */
.sec-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 0 0 12px 0; }

/* Health score ring -- --pct/--ring set per-instance (score*10 / tier color:
   good/warning/serious, never critical). ring-cap's text color is bound to
   the SAME --ring custom property (not a hardcoded var(--good) as in the
   sketch, which only ever demoed the "Healthy" state) so a Watch/OK item's
   caption correctly follows its own tier instead of always reading green. */
.ring {
  --pct: 80; --ring: var(--good);
  width: 128px; height: 128px; border-radius: 50%; flex: none;
  background:
    radial-gradient(closest-side, #fff 76%, transparent 77% 100%),
    conic-gradient(var(--ring) calc(var(--pct) * 1%), #E9EEF5 0);
  display: grid; place-items: center; position: relative;
}
.ring-inner { text-align: center; line-height: 1; }
.ring-score { font-size: 34px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
.ring-score span { font-size: 17px; font-weight: 700; color: var(--muted); }
.ring-cap { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ring); margin-top: 3px; }

/* --- Four-gauge decision panel (Plan 02.4-06, C-2/D-03..D-08) ----------- */
/* .gauge reuses the .card visual weight at a smaller scale; --gc is set
   ONCE per instance by a band-colour class below and referenced by every
   visual piece inside (ring override, big value colour, trend colour,
   verdict pill) -- a gauge's colour is set in exactly one place. */
.gauge-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 840px) { .gauge-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.gauge {
  position: relative; min-width: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 18px 16px 16px; box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; align-items: center; text-align: center;
}
.gauge-label { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 700; margin: 0 0 14px 0; }
.gauge-cap { font-size: 12px; color: var(--text-muted); margin-top: 10px; }

/* Band -> semantic token, ONE custom property per instance (--gc), same
   semantic-tone naming already used elsewhere (.kpi--warning/.kpi--serious
   above). Red (--critical) and orange (--serious) are always separate
   classes -- never folded onto each other (D-04/D-12 two-band rule); the
   too_little/weak/slowing -> gauge-critical and too_much -> gauge-serious
   mapping lives in item360_detail.html's per-gauge band dicts, which bind
   to these token classes. */
.gauge-good     { --gc: var(--good); }
.gauge-warning  { --gc: var(--warning); }
.gauge-serious  { --gc: var(--serious); }
.gauge-critical { --gc: var(--critical); }

/* Gauge 1 -- reuses the existing .ring component, bound to --gc instead of
   a hardcoded tier colour, sized down for the 4-up grid. */
.gauge .ring { --ring: var(--gc); width: 100px; height: 100px; }
.gauge .ring-score { font-size: 24px; }

/* Gauge 2 -- big value + a static tri-colour reference meter (purely
   decorative context, never re-deriving the months figure -- that is
   rendered verbatim from d.gauges.cover.label). */
.gauge-bigval { font-size: 21px; font-weight: 800; letter-spacing: -.02em; color: var(--gc); margin-top: 4px; }
.gauge-meter {
  width: 100%; max-width: 150px; height: 10px; border-radius: 999px; margin-top: 12px; overflow: hidden;
  background: linear-gradient(90deg, var(--critical) 0 18%, var(--good) 18% 62%, var(--serious) 62% 100%);
}
.gauge-meter i { display: block; height: 100%; }

/* Gauge 3 -- trend arrow + label, coloured by --gc. */
.gauge-trend { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: 15px; color: var(--gc); margin-top: 8px; }
.gauge-arrow { font-size: 17px; }

/* Gauge 3 (Phase 02.6/B-22) -- the two window counts side by side ("last 3
   mo" / "prev 3 mo") + the delta line underneath, reusing the mockup's
   .cmp/.n/.delta shapes but bound to the SAME semantic tokens every other
   gauge piece uses (no new one-off colours). */
.gauge-cmp { display: flex; justify-content: center; gap: 8px; margin-top: 10px; font-variant-numeric: tabular-nums; }
.gauge-cmp-n {
  background: var(--surface); border: 1px solid var(--border-2); border-radius: 8px;
  padding: 6px 9px; min-width: 58px;
}
.gauge-cmp-n b { display: block; font-size: 15px; font-weight: 800; color: var(--ink); }
.gauge-cmp-n span { font-size: 9.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.gauge-delta { margin-top: 8px; font-weight: 700; font-size: 13px; }
.gauge-delta.up { color: var(--good); }
.gauge-delta.down { color: var(--critical); }
.gauge-delta.flat { color: var(--ink-2); }

/* Gauge 4 -- verdict pill, solid --gc fill (mirrors the existing .pill
   solid-fill pattern above). */
.gauge-verdict {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 15px; font-weight: 800; letter-spacing: -.01em;
  padding: 10px 16px; border-radius: 10px; margin-top: 6px;
  background: var(--gc); color: #fff;
}
.gauge-verdict-ic { font-size: 14px; }

/* Verdict advice (Phase 02.6/B-22) -- the educative why/action block under
   the four-gauge grid, replacing the old generic "mixed signals..." caption. */
.verdict-advice { margin-top: 4px; font-size: 14px; line-height: 1.5; }
.verdict-advice .va-why { color: var(--ink-2); }
.verdict-advice .va-do { display: block; margin-top: 8px; font-weight: 700; color: var(--ink); }
.verdict-advice .va-do em { color: var(--brand); font-style: normal; }

/* --- ⓘ info affordance (D-09/D-10, C-3) --------------------------------- */
/* Tap-friendly (a real <button>, not hover-only) -- one macro / one CSS
   pattern reused for every gauge and every data figure. */
.info-wrap { position: relative; display: inline-flex; vertical-align: middle; }
.info-trigger {
  width: 20px; height: 20px; min-height: 0; min-width: 0;
  border-radius: 50%; border: 1px solid var(--border); background: var(--surface);
  color: var(--muted); font-size: 13px; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; padding: 0;
}
.info-trigger:hover, .info-trigger:focus-visible { color: var(--brand); border-color: var(--brand); outline: none; }
.info-pop {
  display: none; position: absolute; top: 26px; right: 0; z-index: 6;
  width: 240px; max-width: 72vw;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow); padding: 12px 14px;
  text-align: left; font-size: 12.5px; line-height: 1.5; color: var(--text-muted);
  font-weight: 500; text-transform: none; letter-spacing: normal;
}
.info-pop.is-open { display: block; }
/* A gauge card's ⓘ is pinned to its own top-right corner (the approved
   mockup's look-and-feel); everywhere else (kpi/softstat/section captions)
   it flows inline next to the figure's own text. */
.gauge > .info-wrap { position: absolute; top: 12px; right: 12px; }

/* Verdict block (hero headline + sub-line beside the ring) */
.verdict-lead { font-size: 20px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); line-height: 1.3; }
.verdict-sub { font-size: 13px; color: var(--text-muted); margin-top: 6px; }

/* Sitting & holding -- 3 soft-stat tiles, 14px gap (D-16 waiver: matches
   every other tile grid in the app, not 16px) */
.softstat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.softstat {
  background: #FBFCFE; border: 1px solid var(--border-2); border-radius: 12px; padding: 14px 16px;
}
.softstat .ss-ic { font-size: 18px; }
.softstat .ss-v { font-size: 22px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); margin-top: 6px; font-variant-numeric: tabular-nums; }
.softstat .ss-l { font-size: 12px; color: var(--text-muted); margin-top: 3px; font-weight: 500; }

/* Where it's stocked -- warehouse mini cards, 14px gap (D-16 waiver) */
.wh-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.wh {
  border: 1px solid var(--border); border-radius: 12px; padding: 16px; background: #fff;
  display: flex; align-items: center; gap: 14px;
}
.wh-ic { width: 40px; height: 40px; border-radius: 11px; background: var(--brand-50); display: grid; place-items: center; font-size: 20px; flex: none; }
.wh-name { font-size: 13px; font-weight: 700; color: var(--ink); }
.wh-qty { font-size: 22px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); font-variant-numeric: tabular-nums; }
.wh-sit { font-size: 12px; color: var(--text-muted); }
.nudge {
  margin-top: 12px; display: flex; align-items: center; gap: 10px;
  background: var(--brand-50); border: 1px solid rgba(37, 99, 235, .14);
  border-radius: 12px; padding: 12px 14px; font-size: 13px; color: var(--brand-600); font-weight: 600;
}

/* Autocomplete search shell (D-14, first client-JS component) */
.search-wrap { position: relative; max-width: 560px; }
.search-input {
  width: 100%; min-height: 48px; padding: 0 16px 0 44px;
  border: 1px solid var(--border); border-radius: 12px;
  font-size: 16px; background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' fill='none' stroke='%2394A3B8' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='8' cy='8' r='6'/%3E%3Cpath d='M13 13l4 4'/%3E%3C/svg%3E") no-repeat 14px center;
  outline: none;
}
.search-input:focus { box-shadow: 0 0 0 3px rgba(37, 99, 235, .12); }
.search-menu {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px);
  background: #fff; border: 1px solid var(--border);
  border-radius: 12px; box-shadow: var(--shadow); z-index: 5;
  /* Scroll through a long result list instead of hard-capping at what fits
     on screen (owner: "there are more, I must be able to scroll"). */
  max-height: 360px; overflow-y: auto; overflow-x: hidden;
}
.search-opt {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; font-size: 14.5px; font-weight: 600; color: var(--ink);
  border-top: 1px solid var(--border-2); cursor: pointer;
}
.search-opt:first-child { border-top: none; }
.search-opt[aria-selected="true"] { background: var(--brand-50); color: var(--brand-600); }
.search-opt .opt-ic { color: var(--muted); font-size: 14px; }
.search-opt .opt-sub { margin-left: auto; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.search-hint { margin-top: 8px; font-size: 12px; color: var(--muted); font-weight: 500; }
/* Brand suggestion rows sort first (D-09) and read visually distinct from
   item rows (Rule 2 -- Component 8's "visually distinct" requirement). */
.search-opt--brand { font-weight: 700; }
.search-opt--brand .opt-ic { color: var(--brand); }
/* Non-interactive, muted "no matches" row -- no hover/selected state. */
.search-opt--empty { color: var(--muted); font-weight: 500; cursor: default; }
.search-opt--empty:hover { background: none; }
/* Item rows coloured by stock status (D-01, C-1) -- a colour-coded DOT (the
   owner-approved mockup look) reinforced by a matching subtle left-border.
   Brand rows (.search-opt--brand) never carry a stock-status class (added by
   app.js's renderRows for row.type === "item" only). Red (--critical, zero
   stock) and orange (--serious, minus stock) stay visually distinct per the
   two-band requirement, matching the gauge palette above.
   NOTE: the dot is a styled element, never a coloured emoji -- CSS `color`
   does not tint emoji glyphs. */
.opt-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: var(--muted);
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 12%, transparent);
}
.search-opt.stock-in    { border-left: 3px solid var(--good); }
.search-opt.stock-in    .opt-dot { background: var(--good); color: var(--good); }
.search-opt.stock-out   { border-left: 3px solid var(--critical); }
.search-opt.stock-out   .opt-dot { background: var(--critical); color: var(--critical); }
.search-opt.stock-neg   { border-left: 3px solid var(--serious); }
.search-opt.stock-neg   .opt-dot { background: var(--serious); color: var(--serious); }

/* Two-column generic grid (brand-rollup / who-buys-it companions) */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-md); align-items: start; }

/* Sparkline caption */
.spark-cap { font-size: 12px; color: var(--text-muted); margin-top: 8px; font-weight: 500; }

/* Cost-easing trend chip (green) -- reuses the exact .callout-good hex
   values (D-16 forward-compat note); .trend-amber (rising cost) already
   exists as a plain inline style pattern elsewhere and is not duplicated
   here since no template in this plan renders a rising-cost chip yet. */
.trend-good {
  display: inline-flex; align-items: center; gap: 7px;
  background: #E7F6EC; border: 1px solid #B7E4C7; color: #14532D;
  border-radius: 999px; padding: 5px 12px; font-size: 12.5px; font-weight: 700;
}

/* 5-column money-tile modifier (on hand / unit cost / landed / retail /
   margin) -- a distinct class from the base 4-column .kpi-row used
   elsewhere (e.g. /stock); the existing mobile @media rule below still
   collapses both to 2 columns since it is declared after this block. */
.kpi-row--five { grid-template-columns: repeat(5, minmax(0, 1fr)); }

/* Two extra .kpi tile accent modifiers -- the base set (kpi--money/good/
   danger/neutral) had no warning/serious tone; the Home kpi-hero strip
   (below) needs both (overdue/late-payment = warning, dead-stock = serious,
   never critical, D-16 "never alarming red"). */
.kpi--warning { --kpi-accent: var(--warning); --kpi-tint: #FEF3E2; }
.kpi--serious { --kpi-accent: var(--serious); --kpi-tint: #FCE9DD; }

/* --- Phase 02.3 -- Home Variant B (D-15) components --------------------- */
/* Ported verbatim from .planning/sketches/themes/default.css so the shipped
   Home dashboard matches the owner-approved Variant-B mockup pixel-for-pixel
   (same D-16 forward-compat rule: every new selector below references a
   :root custom property, never a literal hex, except where a token is being
   defined for the first time). */

/* Generic three-column grid (Needs-attention att-cards, Recent-activity
   3-list row) and a vertical flex stack (main column / right rail). */
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-md); align-items: start; }
.stack { display: flex; flex-direction: column; gap: var(--sp-md); }

/* Six-tile KPI hero strip (full width, above the 2-column area); collapses
   to 3 columns at the same <=1100px breakpoint as the sketch (D-16 waiver:
   14px gap, matching every other tile grid in the app, not 16px). */
.kpi-hero { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 14px; min-width: 0; }
@media (max-width: 1100px) { .kpi-hero { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* Prominent "Needs your attention today" cards -- bold accent-barred, 3 per
   row inside .grid-3. --acc is set per-instance (good/warning/serious,
   NEVER --critical -- D-16). */
.att-card {
  position: relative; overflow: hidden; min-width: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  padding: 16px 18px; box-shadow: var(--shadow-sm);
}
.att-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--acc, var(--brand)); }
.att-card .ac-lead { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.att-card .ac-v { font-size: 22px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); margin-top: 6px; font-variant-numeric: tabular-nums; }
.att-card .ac-sub { font-size: 12.5px; color: var(--text-muted); margin-top: 5px; }

/* Reports as a 2x2 icon-tile grid (replaces Home's old stacked .action
   rows -- .action itself stays valid app-wide, just no longer used here). */
.tile-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.tile {
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
  border: 1px solid var(--border); border-radius: 12px; padding: 15px 16px;
  background: var(--surface); box-shadow: var(--shadow-sm);
  transition: transform .1s ease, box-shadow .12s ease, border-color .12s ease;
}
.tile:hover { transform: translateY(-1px); box-shadow: var(--shadow); border-color: #C7D6FF; }
.tile-ic { width: 40px; height: 40px; border-radius: 11px; background: var(--brand-50); display: grid; place-items: center; font-size: 20px; }
.tile-name { font-weight: 700; font-size: 14.5px; color: var(--ink); }
.tile-sub { font-size: 12px; color: var(--text-muted); }

/* Small inline "healthy sync" dot, used inside the kpi-hero's sync-status
   tile value (Zoho sync · N min ago). */
.sync-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--good); display: inline-block; box-shadow: 0 0 0 3px rgba(22, 163, 74, .15); }

/* --- Phase 02.5 -- Leaderboard (D-02..D-06) -----------------------------
   Owner-approved calm/premium look, ported from the signed-off mockup
   (.planning/phases/02.5-team-usage-leaderboard-presence-gamified-activity-
   scoring-adoption/02.5-APPROVED-MOCKUP.html). Namespaced .lb-* throughout
   so nothing collides with the app's existing .row/.bar/.label/.dot etc.
   Every colour here is an existing token EXCEPT --flame (a new, independent
   "streak flame" tone -- deliberately its own custom property, never
   var(--critical)/var(--serious), per D-06's no-alarm-colour rule). */
:root {
  --flame: #EA7A3B;
}
@media (prefers-color-scheme: dark) {
  :root { --flame: #F08A4B; }
}

.lb-label {
  font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); margin: 22px 0 8px;
}
.lb-label:first-child { margin-top: 0; }
.lb-reset { font-weight: 600; text-transform: none; color: var(--text-muted); font-size: 11.5px; letter-spacing: 0; }

.lb-board { margin-top: 4px; }
.lb-row {
  display: grid; grid-template-columns: 26px 34px 1fr auto; align-items: center;
  gap: 12px; padding: 12px 0; border-top: 1px solid var(--border-2);
}
.lb-row:first-child { border-top: 0; }
.lb-rank { color: var(--muted); font-weight: 700; font-variant-numeric: tabular-nums; text-align: center; }
.lb-row--lead .lb-rank { color: var(--brand); }

.lb-av {
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  font-weight: 700; font-size: 13px; color: #fff; flex: none;
}
.lb-av--0 { background: linear-gradient(135deg, var(--brand), var(--brand-600)); }
.lb-av--1 { background: linear-gradient(135deg, var(--good), #34C77B); }
.lb-av--2 { background: linear-gradient(135deg, #7C3AED, #9F67F0); }

.lb-who { min-width: 0; }
.lb-name { font-weight: 600; color: var(--ink); }
.lb-streak { font-size: 13px; color: var(--flame); font-weight: 600; margin-top: 2px; }
.lb-streak--none { color: var(--muted); font-weight: 500; }

.lb-score { text-align: right; }
.lb-pts { font-weight: 700; font-variant-numeric: tabular-nums; font-size: 16.5px; color: var(--ink); }
.lb-pts small { font-weight: 600; color: var(--text-muted); font-size: 11.5px; margin-left: 2px; }

.lb-progress {
  grid-column: 3 / 5; height: 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--brand) 12%, transparent);
  overflow: hidden; margin-top: 4px;
}
.lb-progress > i {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--brand), var(--brand-600));
}

.lb-board--alltime .lb-row { grid-template-columns: 26px 34px 1fr auto; }

/* Owner who's-online view */
.lb-presence { display: flex; align-items: center; gap: 11px; padding: 12px 0; border-top: 1px solid var(--border-2); }
.lb-presence:first-child { border-top: 0; }
.lb-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.lb-dot--online { background: var(--good); box-shadow: 0 0 0 4px color-mix(in srgb, var(--good) 18%, transparent); }
.lb-dot--recent { background: var(--warning); box-shadow: 0 0 0 4px color-mix(in srgb, var(--warning) 18%, transparent); }
.lb-dot--away { background: var(--muted); }
.lb-pname { font-weight: 600; color: var(--ink); }
.lb-pstate { color: var(--text-muted); font-size: 13px; margin-left: auto; }

.lb-person { display: flex; align-items: center; gap: 10px; margin-top: 20px; }
.lb-person .lb-av { width: 30px; height: 30px; font-size: 12px; }
.lb-person .lb-pn { font-weight: 700; color: var(--ink); }
.lb-person .lb-pn small { display: block; font-weight: 500; color: var(--text-muted); font-size: 12.5px; }

.lb-stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 12px; }
.lb-stat {
  background: color-mix(in srgb, var(--brand-50) 60%, transparent);
  border: 1px solid var(--border-2); border-radius: var(--radius-sm); padding: 12px;
}
.lb-stat b { display: block; font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink); }
.lb-stat span { font-size: 11.5px; color: var(--text-muted); }

.lb-hist { display: flex; gap: 5px; margin-top: 14px; align-items: flex-end; height: 42px; }
.lb-hist i { flex: 1; background: color-mix(in srgb, var(--brand) 12%, transparent); border-radius: 4px 4px 2px 2px; min-height: 4px; }
.lb-hist i.lb-hist--today { background: linear-gradient(180deg, var(--brand), var(--brand-600)); }
.lb-hist-cap { font-size: 11.5px; color: var(--muted); margin-top: 6px; }

/* Fading milestone toast (light touch, D-04) -- a setTimeout show/hide
   (app.js renderMilestoneToast) + this CSS transition; NO @keyframes
   animation library, NO setInterval heartbeat. */
.lb-toast-wrap { position: fixed; left: 0; right: 0; bottom: 26px; display: flex; justify-content: center; pointer-events: none; z-index: 40; }
.lb-toast {
  background: var(--ink); color: var(--surface); padding: 12px 18px; border-radius: 999px;
  font-weight: 600; font-size: 14px; box-shadow: var(--shadow); display: flex; gap: 9px; align-items: center;
  opacity: 0; transform: translateY(12px) scale(.96);
  transition: opacity .3s ease, transform .3s ease;
}
.lb-toast--show { opacity: 1; transform: translateY(0) scale(1); }
@media (prefers-reduced-motion: reduce) {
  .lb-toast { transition-duration: .01ms; }
}

/* --- Responsive --------------------------------------------------------- */
@media (max-width: 720px) {
  .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hide-m { display: none; }
  .kpi-v { font-size: 22px; }
  .card { padding: 16px 16px; }
}

/* =========================================================================
   Item-360 v2.0 dense (02.8) — SCOPED, do not affect other screens
   ---------------------------------------------------------------------
   Ported from the owner-approved mockup (02.8-MOCKUP-approved.html) for the
   Plan 06 template rewrite. Every selector below is descendant-scoped under
   an `.i360` page wrapper so it can only ever match inside the Item-360
   detail page. Several class names intentionally reuse names that already
   exist app-wide (`.card`, `.kpi`, `.gauge`, `.ring`, `.chip`, `.wh`,
   `.stat`, `.nudge`, `.sec-title`) -- because every rule here is written as
   `.i360 <selector>` (two-class specificity), the dense i360 version always
   wins INSIDE the wrapper while the bare global rule is left byte-for-byte
   untouched for Home/leaderboard/reconciliation/every other screen.
   Colours/radii/shadows reuse the app's existing :root tokens (--brand,
   --good/--warning/--serious/--critical, --radius, --shadow, tabular-nums)
   -- see the UI-SPEC "REUSE the app's existing tokens" rule. The handful of
   status-tint backgrounds and the extra-small radius the mockup needs but
   the app doesn't yet define are added as new, clearly-prefixed local vars
   (`--i360-*`) scoped to `.i360` only -- not a second global palette. */

.i360 {
  /* New, i360-only tokens (not a palette redefinition -- these are tints
     derived from the existing --good/--warning/--serious/--critical status
     colours, matching the mockup's :root exactly, plus one extra-small
     radius the app didn't previously need). */
  --i360-radius-xs: 9px;
  --i360-good-bg: #E9F7EF;
  --i360-warning-bg: #FEF4E4;
  --i360-serious-bg: #FDEEE3;
  --i360-critical-bg: #FBEAEA;

  max-width: 1180px;
  margin: 0 auto;
  padding: 18px clamp(12px, 3vw, 26px) 60px;
  font-variant-numeric: tabular-nums;
}

/* ---- sticky mini header ---- */
.i360 .ministicky {
  position: sticky; top: 8px; z-index: 40; margin-bottom: 14px;
  display: flex; align-items: center; gap: 12px; padding: 10px 14px;
  background: rgba(255, 255, 255, .86); border: 1px solid var(--border); border-radius: var(--radius-sm);
  box-shadow: var(--shadow); backdrop-filter: saturate(180%) blur(12px);
}
.i360 .ministicky .ms-name { font-weight: 700; letter-spacing: -.01em; font-size: 15px; color: var(--ink); }
.i360 .ministicky .ms-brand { color: var(--text-muted); font-size: 12.5px; font-weight: 600; }
.i360 .ministicky .ms-verdict { margin-left: auto; }

/* ---- verdict pill ---- */
.i360 .vpill { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; font-size: 12.5px; padding: 6px 12px; border-radius: 999px; letter-spacing: .01em; }
.i360 .vpill .vic { width: 16px; height: 16px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 10px; font-weight: 800; }
.i360 .is-good { background: var(--i360-good-bg); color: #0f7a37; } .i360 .is-good .vic { background: var(--good); }
.i360 .is-warn { background: var(--i360-warning-bg); color: #9a6207; } .i360 .is-warn .vic { background: var(--warning); }
.i360 .is-crit { background: var(--i360-critical-bg); color: #a41d1d; } .i360 .is-crit .vic { background: var(--critical); }
.i360 .is-serious { background: var(--i360-serious-bg); color: #a3521f; } .i360 .is-serious .vic { background: var(--serious); }

/* ---- header bar ---- */
.i360 .headbar {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 16px 18px; margin-bottom: 14px;
}
.i360 .hb-top { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; }
.i360 .hb-name { font-size: 22px; font-weight: 750; letter-spacing: -.02em; margin: 0; text-wrap: balance; line-height: 1.15; color: var(--ink); }
.i360 .hb-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }
/* .chip already exists app-wide (SKU/brand chips) -- this dense variant is
   scoped so it only applies on this page; the global .chip is untouched. */
.i360 .chip { font-size: 11.5px; font-weight: 600; padding: 4px 9px; border-radius: 999px; border: 1px solid var(--border); color: var(--ink-2); background: #F8FAFF; display: inline-flex; align-items: center; gap: 5px; }
.i360 .chip b { color: var(--ink); font-weight: 700; }
.i360 .chip.brandchip { color: var(--brand-600); border-color: rgba(37, 99, 235, .25); background: var(--brand-50); }
.i360 .chip .clabel { color: var(--muted); font-weight: 600; }
.i360 .hb-verdict { margin-left: auto; text-align: right; max-width: 340px; }
.i360 .hb-verdict .headline { font-size: 14.5px; font-weight: 650; line-height: 1.4; letter-spacing: -.01em; color: var(--ink); }
.i360 .hb-verdict .headline .lead { display: block; font-weight: 750; }

/* ---- safety alerts strip ---- */
.i360 .alerts { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.i360 .alert { display: flex; align-items: flex-start; gap: 10px; padding: 11px 14px; border-radius: var(--radius-sm); border: 1px solid; font-size: 13px; font-weight: 550; }
.i360 .alert .aic { font-size: 15px; line-height: 1.2; }
.i360 .alert.crit { background: var(--i360-critical-bg); border-color: rgba(220, 38, 38, .28); color: #8f1a1a; }
.i360 .alert.warn { background: var(--i360-warning-bg); border-color: rgba(245, 158, 11, .3); color: #8a5a08; }
.i360 .alert.serious { background: var(--i360-serious-bg); border-color: rgba(234, 122, 59, .32); color: #8a441a; }
.i360 .alert.ok { background: var(--i360-good-bg); border-color: rgba(22, 163, 74, .25); color: #0f7a37; }
.i360 .alert b { font-weight: 750; }

/* ---- dense 12-col grid ---- */
.i360 .grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 14px; }
/* .card already exists app-wide -- this dense variant (14px padding vs the
   global 20px/22px) is scoped under .i360 so only this page gets it. */
.i360 .card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-sm); padding: 14px 15px; min-width: 0; }
.i360 .col-4 { grid-column: span 4; } .i360 .col-5 { grid-column: span 5; } .i360 .col-6 { grid-column: span 6; }
.i360 .col-7 { grid-column: span 7; } .i360 .col-8 { grid-column: span 8; } .i360 .col-12 { grid-column: span 12; }
/* .sec-title already exists app-wide -- reused visual language, scoped copy
   here only differs in the optional trailing .rank chip (Real-sales rank). */
.i360 .sec-title { font-size: 11.5px; font-weight: 750; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); margin: 0 0 11px; display: flex; align-items: center; gap: 8px; }
.i360 .sec-title .rank { margin-left: auto; text-transform: none; letter-spacing: 0; font-size: 11.5px; color: var(--brand-600); background: var(--brand-50); padding: 3px 8px; border-radius: 999px; font-weight: 700; }
/* Positioning helper for the app's existing .info-wrap ⓘ affordance (reused
   as-is per UI-SPEC, not redefined here) pinned to a gauge card's corner. */
.i360 .gauge .ginfo { position: absolute; top: 9px; right: 9px; }

/* ---- four-gauge decision panel (denser) ---- */
.i360 .gauges { display: grid; grid-template-columns: repeat(4, 1fr); gap: 11px; }
/* .gauge already exists app-wide -- this denser card is scoped under .i360. */
.i360 .gauge { border: 1px solid var(--border-2); border-radius: var(--radius-sm); padding: 12px 11px; text-align: center; position: relative; background: #FCFDFF; }
.i360 .gauge .glabel { font-size: 11px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; margin: 0 0 9px; padding: 0 18px; }
/* .ring already exists app-wide (128px health-score ring) -- this smaller
   74px gauge ring is scoped under .i360 so the global ring is untouched. */
.i360 .ring { width: 74px; height: 74px; border-radius: 50%; margin: 0 auto 8px; display: grid; place-items: center; position: relative; background: conic-gradient(var(--ring-c, var(--brand)) calc(var(--pct, 0) * 1%), #EAEEF6 0); }
.i360 .ring::before { content: ""; position: absolute; width: 56px; height: 56px; border-radius: 50%; background: #fff; box-shadow: var(--shadow-sm); }
.i360 .ring b { position: relative; font-size: 18px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
.i360 .ring b span { font-size: 11px; font-weight: 600; color: var(--muted); }
.i360 .gbig { font-size: 20px; font-weight: 800; letter-spacing: -.02em; margin: 6px 0 4px; color: var(--ink); }
.i360 .gmeter { height: 7px; border-radius: 5px; background: #EAEEF6; overflow: hidden; margin: 8px 2px 6px; }
.i360 .gmeter i { display: block; height: 100%; border-radius: 5px; background: var(--gm-c, var(--brand)); width: var(--gm-w, 0%); }
.i360 .gtrend { font-size: 16px; font-weight: 800; letter-spacing: -.01em; margin: 4px 0; display: flex; align-items: center; justify-content: center; gap: 6px; }
.i360 .gtrend .arw { font-size: 19px; }
.i360 .gcmp { display: flex; justify-content: center; gap: 12px; margin: 6px 0 3px; }
.i360 .gcmp div { font-size: 11px; color: var(--text-muted); }
.i360 .gcmp b { display: block; font-size: 15px; color: var(--ink); font-weight: 750; }
.i360 .gdelta { font-size: 12px; font-weight: 700; margin-top: 2px; }
.i360 .gcap { font-size: 10.5px; color: var(--muted); margin: 6px 0 0; line-height: 1.35; }
.i360 .gverdict { font-size: 15px; font-weight: 800; letter-spacing: -.01em; margin: 14px 0 6px; display: flex; align-items: center; justify-content: center; gap: 7px; }
.i360 .gverdict .vic { width: 20px; height: 20px; font-size: 12px; }
.i360 .g-good { color: var(--good); } .i360 .g-warn { color: var(--warning); } .i360 .g-serious { color: var(--serious); } .i360 .g-crit { color: var(--critical); }
.i360 .g-good .glabel { color: #4b9c68; }
.i360 .va { margin-top: 11px; padding: 11px 13px; background: #F7F9FD; border: 1px solid var(--border-2); border-radius: var(--radius-sm); font-size: 13px; line-height: 1.5; }
.i360 .va .why { font-weight: 600; color: var(--ink-2); } .i360 .va .do { color: var(--brand-600); font-weight: 700; }

/* ---- kpi tiles (the money) ---- */
.i360 .kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
/* .kpi already exists app-wide (26px display figure, coloured left bar) --
   this denser tile is scoped under .i360 so the global .kpi is untouched. */
.i360 .kpi { border: 1px solid var(--border-2); border-radius: var(--radius-sm); padding: 11px 12px; background: #FCFDFF; position: relative; }
.i360 .kpi .kl { font-size: 11px; color: var(--text-muted); font-weight: 600; margin: 0 0 4px; display: flex; align-items: center; gap: 5px; }
.i360 .kpi .kv { font-size: 18px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
.i360 .kpi .kv small { font-size: 11px; font-weight: 600; color: var(--muted); }
.i360 .kpi .ktrend { font-size: 11px; font-weight: 700; margin-top: 3px; }
.i360 .kpi.big .kv { font-size: 22px; }
.i360 .kpi.hero { background: linear-gradient(180deg, #F4F8FF, #FCFDFF); border-color: rgba(37, 99, 235, .16); }
.i360 .pos { color: var(--good); } .i360 .neg { color: var(--critical); } .i360 .flat { color: var(--text-muted); }
.i360 .spark { display: block; width: 100%; height: 26px; margin-top: 5px; }

/* ---- real sales bar chart (replaces the old fake sparkline) ---- */
.i360 .saleschart { width: 100%; height: 118px; display: block; }
.i360 .chart-legend { display: flex; gap: 14px; font-size: 11px; color: var(--text-muted); margin-top: 8px; flex-wrap: wrap; }
.i360 .chart-legend span { display: inline-flex; align-items: center; gap: 6px; }
.i360 .chart-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.i360 .miniseason { display: flex; gap: 16px; margin-top: 9px; font-size: 12px; flex-wrap: wrap; color: var(--ink-2); }
.i360 .miniseason b { font-weight: 750; color: var(--ink); }

/* ---- pricing health rows ---- */
.i360 .prow { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px dashed var(--border-2); font-size: 13px; }
.i360 .prow:last-child { border-bottom: 0; }
.i360 .prow .pl { color: var(--text-muted); font-weight: 600; }
.i360 .prow .pv { font-weight: 750; color: var(--ink); }
.i360 .leakbar { height: 8px; border-radius: 5px; background: #EAEEF6; overflow: hidden; margin-top: 9px; }
.i360 .leakbar i { display: block; height: 100%; background: var(--serious); border-radius: 5px; }

/* ---- stock & where it sits ---- */
.i360 .stockrow { display: flex; gap: 10px; flex-wrap: wrap; }
.i360 .stat { flex: 1; min-width: 96px; border: 1px solid var(--border-2); border-radius: var(--radius-sm); padding: 10px 11px; background: #FCFDFF; }
.i360 .stat .sl { font-size: 10.5px; color: var(--text-muted); font-weight: 600; margin-bottom: 3px; }
.i360 .stat .sv { font-size: 16px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
.i360 .whsplit { display: flex; gap: 8px; margin-top: 11px; flex-wrap: wrap; }
/* .wh already exists app-wide (warehouse mini card) -- this denser per-city
   split card is scoped under .i360 so the global .wh is untouched. */
.i360 .wh { flex: 1; min-width: 92px; display: flex; align-items: center; gap: 9px; border: 1px solid var(--border-2); border-radius: var(--radius-sm); padding: 9px 10px; background: #fff; }
.i360 .wh .whic { font-size: 16px; }
.i360 .wh .whname { font-size: 11px; color: var(--text-muted); font-weight: 600; }
.i360 .wh .whqty { font-size: 15px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); }
/* .nudge already exists app-wide (brand-tinted callout) -- the reorder/
   oversold nudge here is amber-serious, scoped under .i360. */
.i360 .nudge { margin-top: 10px; font-size: 12px; color: var(--serious); font-weight: 650; background: var(--i360-serious-bg); border: 1px solid rgba(234, 122, 59, .25); padding: 8px 11px; border-radius: var(--radius-sm); }

/* ---- efficiency row ---- */
.i360 .efrow { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }

/* ---- who buys it ---- */
.i360 .conc { font-size: 12.5px; line-height: 1.5; padding: 10px 12px; border-radius: var(--radius-sm); margin-bottom: 10px; }
.i360 .conc.low { background: var(--i360-good-bg); color: #0f7a37; }
.i360 .conc.high { background: var(--i360-warning-bg); color: #8a5a08; }
.i360 table.buyers { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.i360 table.buyers th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; padding: 5px 4px; border-bottom: 1px solid var(--border-2); }
.i360 table.buyers td { padding: 7px 4px; border-bottom: 1px solid var(--border-2); color: var(--ink); }
.i360 table.buyers td.r { text-align: right; font-weight: 750; }
.i360 .bshare { display: block; font-size: 10.5px; color: var(--muted); font-weight: 600; }

/* ---- activity timeline ---- */
.i360 .timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.i360 .timeline::before { content: ""; position: absolute; left: 8px; top: 4px; bottom: 4px; width: 2px; background: var(--border); }
.i360 .timeline li { position: relative; padding: 0 0 12px 26px; font-size: 12.5px; }
.i360 .timeline li:last-child { padding-bottom: 0; }
.i360 .timeline .tdot { position: absolute; left: 2px; top: 2px; width: 14px; height: 14px; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 0 0 1px var(--border); }
.i360 .t-buy { background: var(--brand); } .i360 .t-sell { background: var(--good); } .i360 .t-price { background: var(--warning); } .i360 .t-restock { background: var(--serious); }
.i360 .timeline .tw { color: var(--ink); font-weight: 650; }
.i360 .timeline .tsub { color: var(--text-muted); }
.i360 .timeline .tdate { color: var(--muted); font-size: 11px; }

/* ---- salesperson placeholder ---- */
.i360 .placeholder { border: 1.5px dashed var(--border); border-radius: var(--radius-sm); padding: 16px; text-align: center; background: #FBFCFE; }
.i360 .placeholder .pic { font-size: 22px; opacity: .7; }
.i360 .placeholder .pt { font-weight: 700; font-size: 13px; margin: 6px 0 3px; color: var(--ink); }
.i360 .placeholder .ps { font-size: 12px; color: var(--text-muted); line-height: 1.5; }

/* ---- 820px responsive collapse (mirrors the approved mockup) ---- */
@media (max-width: 820px) {
  .i360 .grid > .card { grid-column: span 12 !important; }
  .i360 .gauges { grid-template-columns: repeat(2, 1fr); }
  .i360 .kpis { grid-template-columns: repeat(2, 1fr); }
  .i360 .hb-verdict { margin-left: 0; text-align: left; max-width: none; }
}
