/* ============================================================================
   Warrantyfy — Design System
   ----------------------------------------------------------------------------
   One stylesheet, no framework, no build step. Loads in a single request so
   first paint stays fast on a phone over mobile data.

   Status colours are fixed by the reference workflow and are not decorative:
     in warranty  -> green, light text
     near expiry  -> amber, DARK text (amber on white fails contrast)
     expired      -> red, light text, and the whole row is flagged
   Status is never carried by colour alone; every badge also carries a label
   and a shape, so it still reads for a colour-blind user and in print.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   1. Tokens
   ------------------------------------------------------------------------- */
:root {
  color-scheme: light dark;

  /* Brand — deep indigo reads as records and trust rather than retail. */
  --brand-50:  #eef2ff;
  --brand-100: #e0e7ff;
  --brand-200: #c7d2fe;
  --brand-300: #a5b4fc;
  --brand-400: #818cf8;
  --brand-500: #6366f1;
  --brand-600: #4f46e5;
  --brand-700: #4338ca;
  --brand-800: #3730a3;
  --brand-900: #312e81;
  --brand-950: #1e1b4b;

  /* Status */
  --ok-bg:   #16a34a;  --ok-fg:   #ffffff;  --ok-soft:   #dcfce7;  --ok-text:   #14532d;
  --warn-bg: #f59e0b;  --warn-fg: #1f1300;  --warn-soft: #fef3c7;  --warn-text: #78350f;
  --bad-bg:  #dc2626;  --bad-fg:  #ffffff;  --bad-soft:  #fee2e2;  --bad-text:  #7f1d1d;
  --mute-bg: #64748b;  --mute-fg: #ffffff;  --mute-soft: #f1f5f9;  --mute-text: #334155;

  /* Neutrals */
  --n-0:  #ffffff; --n-25: #fcfcfd; --n-50: #f8fafc; --n-100:#f1f5f9;
  --n-200:#e2e8f0; --n-300:#cbd5e1; --n-400:#94a3b8; --n-500:#64748b;
  --n-600:#475569; --n-700:#334155; --n-800:#1e293b; --n-900:#0f172a;
  --n-950:#020617;

  /* Semantic surfaces — redefined wholesale for dark mode. */
  --bg:         var(--n-50);
  --bg-elev:    var(--n-0);
  --bg-sunken:  var(--n-100);
  --bg-hover:   var(--n-100);
  --text:       var(--n-900);
  --text-soft:  var(--n-600);
  --text-faint: var(--n-500);
  --border:     var(--n-200);
  --border-strong: var(--n-300);
  --accent:     var(--brand-600);
  --accent-text:#ffffff;
  --accent-soft:var(--brand-50);
  --accent-ring:color-mix(in srgb, var(--brand-600) 35%, transparent);

  --radius-xs: 6px;  --radius-sm: 9px;  --radius: 14px;
  --radius-lg: 20px; --radius-xl: 28px; --radius-full: 999px;

  --shadow-xs: 0 1px 2px rgba(15,23,42,.06);
  --shadow-sm: 0 1px 3px rgba(15,23,42,.08), 0 1px 2px rgba(15,23,42,.04);
  --shadow:    0 4px 12px rgba(15,23,42,.07), 0 1px 3px rgba(15,23,42,.05);
  --shadow-lg: 0 12px 32px rgba(15,23,42,.10), 0 4px 8px rgba(15,23,42,.05);
  --shadow-xl: 0 24px 56px rgba(15,23,42,.14), 0 8px 16px rgba(15,23,42,.06);

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
          'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
  --font-num: 'Inter', ui-monospace, 'SF Mono', Menlo, monospace;

  --step--1: clamp(.78rem, .76rem + .1vw, .83rem);
  --step-0:  clamp(.94rem, .92rem + .12vw, 1rem);
  --step-1:  clamp(1.1rem, 1.05rem + .25vw, 1.2rem);
  --step-2:  clamp(1.3rem, 1.2rem + .5vw, 1.55rem);
  --step-3:  clamp(1.6rem, 1.4rem + 1vw, 2.1rem);
  --step-4:  clamp(2rem, 1.6rem + 2vw, 3rem);
  --step-5:  clamp(2.4rem, 1.8rem + 3.2vw, 3.9rem);

  --gutter: clamp(1rem, 4vw, 2rem);
  --maxw: 1240px;
  --maxw-prose: 44rem;

  --ease: cubic-bezier(.4, 0, .2, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* Dark mode. Applied when the OS asks for it, unless the user has explicitly
   chosen light; and always when the user has explicitly chosen dark. The
   reference review called a bright light theme fatiguing, so dark is a
   first-class theme here rather than an inverted afterthought. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:         #0b1020;
    --bg-elev:    #121a2e;
    --bg-sunken:  #080d19;
    --bg-hover:   #1a2440;
    --text:       #eef2f9;
    --text-soft:  #a9b6cd;
    --text-faint: #7c8aa3;
    --border:     #22304d;
    --border-strong: #324465;
    --accent:     var(--brand-400);
    --accent-text:#0b1020;
    --accent-soft:rgba(129,140,248,.14);
    --ok-soft:   rgba(22,163,74,.18);  --ok-text:   #86efac;
    --warn-soft: rgba(245,158,11,.18); --warn-text: #fcd34d;
    --bad-soft:  rgba(220,38,38,.18);  --bad-text:  #fca5a5;
    --mute-soft: rgba(100,116,139,.16);--mute-text: #cbd5e1;
    --shadow-xs: 0 1px 2px rgba(0,0,0,.4);
    --shadow-sm: 0 1px 3px rgba(0,0,0,.45);
    --shadow:    0 4px 14px rgba(0,0,0,.5);
    --shadow-lg: 0 14px 36px rgba(0,0,0,.55);
    --shadow-xl: 0 26px 60px rgba(0,0,0,.6);
  }
}
:root[data-theme="dark"] {
  --bg:#0b1020; --bg-elev:#121a2e; --bg-sunken:#080d19; --bg-hover:#1a2440;
  --text:#eef2f9; --text-soft:#a9b6cd; --text-faint:#7c8aa3;
  --border:#22304d; --border-strong:#324465;
  --accent:var(--brand-400); --accent-text:#0b1020; --accent-soft:rgba(129,140,248,.14);
  --ok-soft:rgba(22,163,74,.18);  --ok-text:#86efac;
  --warn-soft:rgba(245,158,11,.18); --warn-text:#fcd34d;
  --bad-soft:rgba(220,38,38,.18);  --bad-text:#fca5a5;
  --mute-soft:rgba(100,116,139,.16); --mute-text:#cbd5e1;
  --shadow-xs:0 1px 2px rgba(0,0,0,.4);
  --shadow-sm:0 1px 3px rgba(0,0,0,.45);
  --shadow:0 4px 14px rgba(0,0,0,.5);
  --shadow-lg:0 14px 36px rgba(0,0,0,.55);
  --shadow-xl:0 26px 60px rgba(0,0,0,.6);
}

/* ---------------------------------------------------------------------------
   2. Reset
   ------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5.5rem;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  font-family: var(--font);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  overflow-x: hidden;
}

img, svg, video, canvas { display: block; max-width: 100%; height: auto; }
svg { flex-shrink: 0; }

/* Inline icons carry no intrinsic size, so without this they stretch to fill
   whatever box they land in. `.ic` is added to every generated icon; any more
   specific rule below (.btn svg, .empty-art svg …) still wins. */
.ic { width: 1.15em; height: 1.15em; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: none; padding: 0; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }
ul, ol { padding-left: 1.25rem; }
table { border-collapse: collapse; width: 100%; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}
:where(button, a, input, select, textarea):focus:not(:focus-visible) { outline: none; }

::selection { background: var(--brand-200); color: var(--brand-950); }
:root[data-theme="dark"] ::selection { background: var(--brand-700); color: #fff; }

h1, h2, h3, h4 { line-height: 1.18; font-weight: 700; letter-spacing: -.02em; text-wrap: balance; }
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }
p  { text-wrap: pretty; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--accent); color: var(--accent-text);
  padding: .7rem 1.1rem; border-radius: 0 0 var(--radius) 0; font-weight: 600;
}
.skip-link:focus { left: 0; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------------------------------
   3. Layout
   ------------------------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.wrap-narrow { max-width: 56rem; }
.prose-wrap { max-width: var(--maxw-prose); margin-inline: auto; padding-inline: var(--gutter); }

.section { padding-block: clamp(3rem, 7vw, 5.5rem); }
.section-sm { padding-block: clamp(2rem, 4vw, 3rem); }
.section-alt { background: var(--bg-elev); border-block: 1px solid var(--border); }

.stack > * + * { margin-top: var(--gap, 1rem); }
.row { display: flex; align-items: center; gap: var(--gap, .75rem); flex-wrap: wrap; }
.row-tight { gap: .4rem; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }
.center { text-align: center; }
.hide { display: none !important; }

.grid { display: grid; gap: clamp(1rem, 2.5vw, 1.5rem); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }

.eyebrow {
  font-size: var(--step--1); font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent);
}
.lede { font-size: var(--step-1); color: var(--text-soft); max-width: 46rem; }
.muted { color: var(--text-soft); }
.faint { color: var(--text-faint); font-size: var(--step--1); }
.num { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }

/* ---------------------------------------------------------------------------
   4. Header / nav
   ------------------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg-elev) 88%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}
.site-header .wrap { display: flex; align-items: center; gap: 1rem; min-height: 4rem; }

/* The wordmark is a link to home. A logo that does not go home is a small
   betrayal of a convention everyone relies on. */
.brand {
  display: inline-flex; align-items: center; gap: .6rem;
  font-weight: 800; font-size: 1.1rem; letter-spacing: -.03em;
  color: var(--text); text-decoration: none; flex-shrink: 0;
}
.brand:hover { color: var(--accent); }
.brand-mark {
  width: 2rem; height: 2rem; border-radius: 9px; flex-shrink: 0;
  background: linear-gradient(140deg, var(--brand-500), var(--brand-700));
  display: grid; place-items: center; color: #fff;
  box-shadow: 0 2px 8px color-mix(in srgb, var(--brand-600) 40%, transparent);
}
.brand-mark svg { width: 1.15rem; height: 1.15rem; }

.nav { display: flex; align-items: center; gap: .15rem; margin-left: auto; }
/* Scoped with :not(.btn) so the call-to-action button in the nav keeps its own
   colours. A bare `.nav a` rule outranks `.btn-primary` on specificity and
   would paint the button's label muted grey on an indigo fill. */
.nav a:not(.btn) {
  padding: .5rem .8rem; border-radius: var(--radius-sm);
  color: var(--text-soft); text-decoration: none;
  font-weight: 550; font-size: var(--step--1); white-space: nowrap;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.nav a:not(.btn):hover { background: var(--bg-hover); color: var(--text); }
.nav a:not(.btn)[aria-current="page"] { color: var(--accent); background: var(--accent-soft); }

.nav-toggle { display: none; }

@media (max-width: 900px) {
  .nav-toggle {
    display: grid; place-items: center; margin-left: auto;
    width: 2.5rem; height: 2.5rem; border-radius: var(--radius-sm);
    border: 1px solid var(--border); color: var(--text);
  }
  .nav-toggle:hover { background: var(--bg-hover); }
  .nav {
    position: absolute; inset-inline: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: .15rem;
    background: var(--bg-elev); border-bottom: 1px solid var(--border);
    padding: .6rem var(--gutter) 1rem; margin: 0;
    box-shadow: var(--shadow-lg);
    max-height: calc(100dvh - 4rem); overflow-y: auto;
  }
  .nav:not(.open) { display: none; }
  .nav a { padding: .75rem .8rem; font-size: var(--step-0); }
  .nav .btn { width: 100%; justify-content: center; margin-top: .4rem; }
}

/* ---------------------------------------------------------------------------
   5. Buttons
   ------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .65rem 1.15rem; border-radius: var(--radius-sm);
  font-weight: 600; font-size: var(--step--1); line-height: 1.2;
  border: 1px solid transparent; text-decoration: none; white-space: nowrap;
  transition: background .15s var(--ease), border-color .15s var(--ease),
              transform .1s var(--ease), box-shadow .15s var(--ease), color .15s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.btn:active { transform: translateY(1px); }
.btn svg { width: 1.05em; height: 1.05em; flex-shrink: 0; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; pointer-events: none; }

.btn-primary {
  background: var(--brand-600); color: #fff;
  box-shadow: 0 1px 2px rgba(15,23,42,.1), 0 2px 8px color-mix(in srgb, var(--brand-600) 28%, transparent);
}
.btn-primary:hover { background: var(--brand-700); }
:root[data-theme="dark"] .btn-primary { background: var(--brand-500); }
:root[data-theme="dark"] .btn-primary:hover { background: var(--brand-400); color: #0b1020; }

.btn-ghost { background: var(--bg-elev); color: var(--text); border-color: var(--border-strong); }
.btn-ghost:hover { background: var(--bg-hover); border-color: var(--accent); color: var(--accent); }

.btn-quiet { background: transparent; color: var(--text-soft); }
.btn-quiet:hover { background: var(--bg-hover); color: var(--text); }

.btn-danger { background: var(--bad-bg); color: var(--bad-fg); }
.btn-danger:hover { filter: brightness(1.08); }

.btn-lg { padding: .9rem 1.6rem; font-size: var(--step-0); border-radius: var(--radius); }
.btn-sm { padding: .4rem .7rem; font-size: var(--step--1); }
.btn-icon { padding: .45rem; width: 2.2rem; height: 2.2rem; }
.btn-block { width: 100%; }

/* ---------------------------------------------------------------------------
   6. Cards / panels
   ------------------------------------------------------------------------- */
.card {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius); padding: clamp(1.1rem, 2.5vw, 1.6rem);
}
.card-pad-lg { padding: clamp(1.5rem, 4vw, 2.5rem); }
.card-hover { transition: border-color .15s var(--ease), box-shadow .2s var(--ease), transform .2s var(--ease); }
.card-hover:hover { border-color: var(--border-strong); box-shadow: var(--shadow); transform: translateY(-2px); }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }
.card-title { font-size: var(--step-1); font-weight: 700; display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.card-title svg { width: 1.05em; height: 1.05em; color: var(--text-faint); }

.panel { background: var(--bg-sunken); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.1rem; }

.callout {
  border-left: 3px solid var(--accent);
  background: var(--accent-soft); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 1rem 1.1rem;
}
.callout-warn { border-left-color: var(--warn-bg); background: var(--warn-soft); }
.callout-warn strong { color: var(--warn-text); }
.callout-bad  { border-left-color: var(--bad-bg);  background: var(--bad-soft); }
.callout-bad strong { color: var(--bad-text); }
.callout-ok   { border-left-color: var(--ok-bg);   background: var(--ok-soft); }
.callout-ok strong { color: var(--ok-text); }
.callout p + p { margin-top: .5rem; }

/* ---------------------------------------------------------------------------
   7. Status badges — label + colour + shape, never colour alone
   ------------------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .22rem .6rem; border-radius: var(--radius-full);
  font-size: .74rem; font-weight: 700; letter-spacing: .02em;
  white-space: nowrap; border: 1px solid transparent;
}
.badge::before {
  content: ''; width: .5rem; height: .5rem; flex-shrink: 0; background: currentColor;
}
.badge-ok   { background: var(--ok-soft);   color: var(--ok-text);   border-color: color-mix(in srgb, var(--ok-bg) 30%, transparent); }
.badge-ok::before   { border-radius: 50%; }                      /* circle */
.badge-warn { background: var(--warn-soft); color: var(--warn-text); border-color: color-mix(in srgb, var(--warn-bg) 40%, transparent); }
.badge-warn::before { clip-path: polygon(50% 0, 100% 100%, 0 100%); } /* triangle */
.badge-bad  { background: var(--bad-soft);  color: var(--bad-text);  border-color: color-mix(in srgb, var(--bad-bg) 30%, transparent); }
.badge-bad::before  { clip-path: polygon(50% 0,100% 50%,50% 100%,0 50%); } /* diamond */
.badge-mute { background: var(--mute-soft); color: var(--mute-text); border-color: var(--border); }
.badge-mute::before { border-radius: 2px; }                      /* square */

.badge-solid-ok   { background: var(--ok-bg);   color: var(--ok-fg);   border-color: transparent; }
.badge-solid-warn { background: var(--warn-bg); color: var(--warn-fg); border-color: transparent; }
.badge-solid-bad  { background: var(--bad-bg);  color: var(--bad-fg);  border-color: transparent; }

.chip {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .2rem .55rem; border-radius: var(--radius-full);
  background: var(--bg-sunken); border: 1px solid var(--border);
  font-size: .74rem; font-weight: 550; color: var(--text-soft);
}
.chip-x { display: grid; place-items: center; width: 1rem; height: 1rem; border-radius: 50%; color: var(--text-faint); }
.chip-x svg { width: .7rem; height: .7rem; }
.chip svg { width: .8rem; height: .8rem; }
.chip-x:hover { background: var(--bad-soft); color: var(--bad-text); }

/* ---------------------------------------------------------------------------
   8. Stat tiles — the dashboard counters
   ------------------------------------------------------------------------- */
.stats { display: grid; gap: .85rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); }
.stat {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1rem 1.1rem;
  position: relative; overflow: hidden; text-align: left;
  display: flex; flex-direction: column; gap: .15rem;
  transition: border-color .15s var(--ease), transform .15s var(--ease);
}
button.stat { cursor: pointer; }
button.stat:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.stat[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.stat::after { content: ''; position: absolute; inset-inline-start: 0; inset-block: 0; width: 3px; background: var(--mute-bg); }
.stat-ok::after   { background: var(--ok-bg); }
.stat-warn::after { background: var(--warn-bg); }
.stat-bad::after  { background: var(--bad-bg); }
.stat-accent::after { background: var(--accent); }
.stat-label { font-size: .72rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-faint); }
.stat-value { font-family: var(--font-num); font-size: var(--step-3); font-weight: 800; line-height: 1.05; font-variant-numeric: tabular-nums; letter-spacing: -.03em; }
.stat-ok   .stat-value { color: var(--ok-text); }
.stat-warn .stat-value { color: var(--warn-text); }
.stat-bad  .stat-value { color: var(--bad-text); }
.stat-note { font-size: .74rem; color: var(--text-faint); }

/* Today strip: day name, date, month */
.today-strip { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.today-day   { font-size: var(--step-1); font-weight: 700; }
.today-date  { font-family: var(--font-num); font-size: var(--step-2); font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
.today-month { font-size: var(--step-1); font-weight: 600; color: var(--text-soft); }

/* ---------------------------------------------------------------------------
   9. Forms
   ------------------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: .35rem; min-width: 0; }
.field > label, .field-label {
  font-size: var(--step--1); font-weight: 650; color: var(--text);
  display: flex; align-items: center; gap: .35rem;
}
.req { color: var(--bad-bg); font-weight: 700; }
.field-hint { font-size: .76rem; color: var(--text-faint); line-height: 1.45; }
.field-error { font-size: .78rem; color: var(--bad-text); font-weight: 600; display: flex; align-items: center; gap: .3rem; }
.field-error:empty { display: none; }

.input, .select, .textarea {
  width: 100%; padding: .6rem .75rem;
  background: var(--bg-elev); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  font-size: var(--step-0); line-height: 1.4;
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
  min-width: 0;
}
.input::placeholder, .textarea::placeholder { color: var(--text-faint); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--text-faint); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
.input[aria-invalid="true"], .select[aria-invalid="true"] {
  border-color: var(--bad-bg); box-shadow: 0 0 0 3px color-mix(in srgb, var(--bad-bg) 20%, transparent);
}
.textarea { resize: vertical; min-height: 5.5rem; }

.select {
  appearance: none; padding-right: 2.2rem; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .65rem center; background-size: 1.05rem;
}
:root[data-theme="dark"] .select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a9b6cd' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

/* Keep native date pickers legible in dark mode. */
:root[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(.8); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(.8); }
}

.input-group { display: flex; gap: .4rem; align-items: stretch; }
.input-group .input { flex: 1 1 auto; }
.input-prefix {
  display: grid; place-items: center; padding-inline: .7rem;
  background: var(--bg-sunken); border: 1px solid var(--border-strong);
  border-right: none; border-radius: var(--radius-sm) 0 0 var(--radius-sm);
  color: var(--text-soft); font-weight: 650; font-size: var(--step--1);
}
.input-prefix + .input { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }

.check { display: flex; align-items: flex-start; gap: .55rem; cursor: pointer; font-size: var(--step--1); line-height: 1.45; }
.check input[type="checkbox"], .check input[type="radio"] {
  width: 1.05rem; height: 1.05rem; margin-top: .15rem; flex-shrink: 0;
  accent-color: var(--brand-600); cursor: pointer;
}
.switch-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .7rem 0; border-bottom: 1px solid var(--border); }
.switch-row:last-child { border-bottom: none; }
.switch-row-text { min-width: 0; }
.switch-row-text strong { display: block; font-size: var(--step--1); font-weight: 650; }

/* Segmented control — also the view switcher */
.segmented { display: inline-flex; background: var(--bg-sunken); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 2px; gap: 2px; }
.segmented button {
  padding: .35rem .7rem; border-radius: calc(var(--radius-sm) - 3px);
  font-size: var(--step--1); font-weight: 600; color: var(--text-soft);
  display: inline-flex; align-items: center; gap: .35rem;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.segmented button:hover { color: var(--text); }
.segmented button[aria-pressed="true"] { background: var(--bg-elev); color: var(--accent); box-shadow: var(--shadow-xs); }
.segmented svg { width: 1rem; height: 1rem; }

/* Preset pills: one tap instead of month-to-year arithmetic */
.presets { display: flex; flex-wrap: wrap; gap: .35rem; }
.preset {
  padding: .3rem .65rem; border-radius: var(--radius-full);
  border: 1px solid var(--border-strong); background: var(--bg-elev);
  font-size: .76rem; font-weight: 600; color: var(--text-soft);
}
.preset:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.preset[aria-pressed="true"] { background: var(--accent); color: var(--accent-text); border-color: var(--accent); }

/* Search box with live result count */
.search-box { position: relative; flex: 1 1 16rem; min-width: 0; }
.search-box .input { padding-left: 2.4rem; padding-right: 2.2rem; }
.search-icon { position: absolute; left: .75rem; top: 50%; transform: translateY(-50%); width: 1.05rem; height: 1.05rem; color: var(--text-faint); pointer-events: none; }
.search-clear { position: absolute; right: .5rem; top: 50%; transform: translateY(-50%); display: grid; place-items: center; width: 1.5rem; height: 1.5rem; border-radius: 50%; color: var(--text-faint); }
.search-clear:hover { background: var(--bg-hover); color: var(--text); }

/* Drop zone for receipts */
.dropzone {
  border: 2px dashed var(--border-strong); border-radius: var(--radius);
  padding: clamp(1.2rem, 4vw, 2rem); text-align: center;
  background: var(--bg-sunken); cursor: pointer;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.dropzone:hover, .dropzone.drag { border-color: var(--accent); background: var(--accent-soft); }
.dropzone svg { width: 2rem; height: 2rem; color: var(--text-faint); margin-inline: auto; margin-bottom: .5rem; }
.dropzone.drag svg { color: var(--accent); }

.doc-list { display: flex; flex-direction: column; gap: .4rem; }
.doc-row {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .7rem; background: var(--bg-sunken);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.doc-row svg { width: 1.1rem; height: 1.1rem; color: var(--text-faint); flex-shrink: 0; }
.doc-name { font-size: var(--step--1); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------------------------------------------------------------------
   10. Wizard
   ------------------------------------------------------------------------- */
.steps { display: flex; gap: .3rem; overflow-x: auto; padding-bottom: .4rem; scrollbar-width: none; }
.steps::-webkit-scrollbar { display: none; }
.step {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .45rem .75rem; border-radius: var(--radius-full);
  font-size: var(--step--1); font-weight: 600; color: var(--text-faint);
  background: var(--bg-sunken); border: 1px solid var(--border);
  white-space: nowrap; flex-shrink: 0;
}
.step-n {
  display: grid; place-items: center; width: 1.3rem; height: 1.3rem;
  border-radius: 50%; background: var(--border); color: var(--text-soft);
  font-size: .7rem; font-weight: 800; flex-shrink: 0;
}
.step[aria-current="step"] { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.step[aria-current="step"] .step-n { background: var(--accent); color: var(--accent-text); }
.step.done { color: var(--ok-text); border-color: color-mix(in srgb, var(--ok-bg) 35%, transparent); background: var(--ok-soft); }
.step.done .step-n { background: var(--ok-bg); color: #fff; }

.wizard-pane { display: none; }
.wizard-pane.active { display: block; animation: paneIn .25s var(--ease-out); }
@keyframes paneIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.summary-grid { display: grid; gap: .1rem; }
.summary-row { display: grid; grid-template-columns: minmax(8rem, 12rem) 1fr; gap: .75rem; padding: .55rem 0; border-bottom: 1px solid var(--border); font-size: var(--step--1); }
.summary-row:last-child { border-bottom: none; }
.summary-row dt { color: var(--text-faint); font-weight: 600; }
.summary-row dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
@media (max-width: 560px) { .summary-row { grid-template-columns: 1fr; gap: .1rem; } }

/* ---------------------------------------------------------------------------
   11. Product views — grid / list / table
   ------------------------------------------------------------------------- */
.pv-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); }

.pcard {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column;
  transition: border-color .15s var(--ease), box-shadow .2s var(--ease), transform .2s var(--ease);
  position: relative;
}
.pcard:hover { border-color: var(--border-strong); box-shadow: var(--shadow); transform: translateY(-2px); }
.pcard-bar { height: 4px; background: var(--mute-bg); }
.pcard.is-active  .pcard-bar { background: var(--ok-bg); }
.pcard.is-soon    .pcard-bar { background: var(--warn-bg); }
.pcard.is-expired .pcard-bar { background: var(--bad-bg); }

/* An expired record is flagged across its full width so it cannot be
   skimmed past — the one state that costs real money to miss. */
.pcard.is-expired { background: var(--bad-soft); border-color: color-mix(in srgb, var(--bad-bg) 35%, transparent); }
.pcard.is-soon    { background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn-bg) 35%, transparent); }

.pcard-body { padding: .9rem 1rem 1rem; display: flex; flex-direction: column; gap: .5rem; flex: 1; }
.pcard-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.pcard-name { font-size: var(--step-0); font-weight: 700; line-height: 1.3; overflow-wrap: anywhere; }
.pcard-brand { font-size: .76rem; color: var(--text-soft); font-weight: 550; }
.pcard-meta { display: grid; gap: .3rem; font-size: .78rem; margin-top: auto; }
.pcard-meta-row { display: flex; justify-content: space-between; gap: .5rem; }
.pcard-meta-row dt { color: var(--text-faint); }
.pcard-meta-row dd { margin: 0; font-weight: 650; font-variant-numeric: tabular-nums; }
.pcard-count { font-weight: 750; font-size: var(--step--1); }
.pcard.is-active  .pcard-count { color: var(--ok-text); }
.pcard.is-soon    .pcard-count { color: var(--warn-text); }
.pcard.is-expired .pcard-count { color: var(--bad-text); }
.pcard-foot { display: flex; align-items: center; gap: .3rem; padding-top: .55rem; border-top: 1px solid var(--border); margin-top: .2rem; }
.pcard-tags { display: flex; flex-wrap: wrap; gap: .25rem; }

/* Life bar */
.lifebar { height: 5px; border-radius: 3px; background: var(--bg-sunken); overflow: hidden; border: 1px solid var(--border); }
.lifebar span { display: block; height: 100%; background: var(--ok-bg); transition: width .3s var(--ease); }
.is-soon .lifebar span { background: var(--warn-bg); }
.is-expired .lifebar span { background: var(--bad-bg); }

/* Claim-readiness dot */
.ready-dot { display: inline-flex; align-items: center; gap: .3rem; font-size: .72rem; font-weight: 650; }
.ready-dot i { width: .5rem; height: .5rem; border-radius: 50%; display: block; }
.ready-strong i { background: var(--ok-bg); }  .ready-strong { color: var(--ok-text); }
.ready-fair   i { background: var(--warn-bg); } .ready-fair   { color: var(--warn-text); }
.ready-weak   i { background: var(--bad-bg); }  .ready-weak   { color: var(--bad-text); }

/* List view */
.pv-list { display: flex; flex-direction: column; gap: .5rem; }
.prow {
  display: grid; align-items: center; gap: .85rem;
  grid-template-columns: 4px 1fr auto auto;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: .7rem .9rem .7rem 0; overflow: hidden;
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.prow:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.prow-flag { width: 4px; align-self: stretch; background: var(--mute-bg); }
.prow.is-active  .prow-flag { background: var(--ok-bg); }
.prow.is-soon    .prow-flag { background: var(--warn-bg); }
.prow.is-expired .prow-flag { background: var(--bad-bg); }
.prow.is-expired { background: var(--bad-soft); border-color: color-mix(in srgb, var(--bad-bg) 30%, transparent); }
.prow.is-soon    { background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn-bg) 30%, transparent); }
.prow-main { min-width: 0; }
.prow-name { font-weight: 700; font-size: var(--step-0); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prow-sub { font-size: .76rem; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prow-dates { text-align: right; font-size: .78rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.prow-actions { display: flex; gap: .2rem; }
@media (max-width: 760px) {
  .prow { grid-template-columns: 4px 1fr auto; }
  .prow-dates { grid-column: 2 / -1; text-align: left; display: flex; gap: .75rem; flex-wrap: wrap; }
}

/* Table view */
.pv-table-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-elev); }
.pv-table { min-width: 60rem; font-size: var(--step--1); }
.pv-table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--bg-sunken); text-align: left;
  padding: .65rem .8rem; font-weight: 700; font-size: .74rem;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint);
  border-bottom: 1px solid var(--border); white-space: nowrap;
}
.pv-table thead th button { display: inline-flex; align-items: center; gap: .3rem; font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; }
.pv-table thead th button:hover { color: var(--accent); }
.pv-table tbody td { padding: .6rem .8rem; border-bottom: 1px solid var(--border); vertical-align: middle; }
.pv-table tbody tr:last-child td { border-bottom: none; }
.pv-table tbody tr:hover { background: var(--bg-hover); }
.pv-table .num { font-variant-numeric: tabular-nums; }
.pv-table .t-name { font-weight: 650; }

/* The expired row, flagged across its full width. */
.pv-table tbody tr.is-expired { background: var(--bad-soft); }
.pv-table tbody tr.is-expired td { color: var(--bad-text); }
.pv-table tbody tr.is-expired .t-name { color: var(--bad-text); font-weight: 750; }
.pv-table tbody tr.is-expired:hover { background: color-mix(in srgb, var(--bad-bg) 22%, var(--bg-elev)); }
.pv-table tbody tr.is-soon { background: var(--warn-soft); }
.pv-table tbody tr.is-soon td { color: var(--warn-text); }
.pv-table tbody tr.is-soon:hover { background: color-mix(in srgb, var(--warn-bg) 22%, var(--bg-elev)); }

/* ---------------------------------------------------------------------------
   12. Empty states
   ------------------------------------------------------------------------- */
.empty { text-align: center; padding: clamp(2rem, 7vw, 4rem) 1rem; max-width: 30rem; margin-inline: auto; }
.empty-art { width: 3.5rem; height: 3.5rem; margin-inline: auto; margin-bottom: 1rem; color: var(--text-faint); opacity: .7; }
.empty-art svg { width: 100%; height: 100%; }
.empty h3 { font-size: var(--step-1); margin-bottom: .4rem; }
.empty p { color: var(--text-soft); font-size: var(--step--1); margin-bottom: 1.2rem; }

/* ---------------------------------------------------------------------------
   13. Modal / drawer
   ------------------------------------------------------------------------- */
dialog.modal {
  border: none; padding: 0; background: transparent; max-width: none; max-height: none;
  width: 100%; height: 100%; inset: 0;
}
dialog.modal::backdrop { background: rgba(2, 6, 23, .6); backdrop-filter: blur(3px); }
.modal-inner {
  background: var(--bg-elev); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  width: min(100%, 44rem); max-height: min(92dvh, 52rem);
  margin: auto; display: flex; flex-direction: column;
  box-shadow: var(--shadow-xl); overflow: hidden;
  animation: modalIn .22s var(--ease-out);
}
.modal-wide .modal-inner { width: min(100%, 60rem); }
@keyframes modalIn { from { opacity: 0; transform: translateY(12px) scale(.985); } to { opacity: 1; transform: none; } }
dialog.modal { display: flex; align-items: center; justify-content: center; padding: clamp(.5rem, 3vw, 2rem); }
dialog.modal:not([open]) { display: none; }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem 1.25rem; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.modal-head h2 { font-size: var(--step-1); }
.modal-body { padding: 1.25rem; overflow-y: auto; flex: 1; }
.modal-foot { display: flex; align-items: center; justify-content: space-between; gap: .75rem; padding: 1rem 1.25rem; border-top: 1px solid var(--border); background: var(--bg-sunken); flex-shrink: 0; flex-wrap: wrap; }
.modal-close { display: grid; place-items: center; width: 2.1rem; height: 2.1rem; border-radius: var(--radius-sm); color: var(--text-soft); flex-shrink: 0; }
.modal-close:hover { background: var(--bg-hover); color: var(--text); }
@media (max-width: 560px) {
  .modal-inner { width: 100%; max-height: 100dvh; border-radius: 0; border: none; }
  dialog.modal { padding: 0; }
  .modal-foot { flex-direction: column-reverse; align-items: stretch; }
  .modal-foot .btn { width: 100%; justify-content: center; }
  .modal-foot > div { display: flex; gap: .5rem; }
  .modal-foot > div .btn { flex: 1; }
}

/* ---------------------------------------------------------------------------
   14. Toasts
   ------------------------------------------------------------------------- */
.toasts { position: fixed; z-index: 200; bottom: 1rem; right: 1rem; display: flex; flex-direction: column-reverse; gap: .5rem; max-width: min(24rem, calc(100vw - 2rem)); pointer-events: none; }
.toast {
  display: flex; align-items: flex-start; gap: .6rem;
  background: var(--n-900); color: #fff;
  border-radius: var(--radius-sm); padding: .7rem .9rem;
  font-size: var(--step--1); font-weight: 550; line-height: 1.4;
  box-shadow: var(--shadow-lg); pointer-events: auto;
  animation: toastIn .25s var(--ease-out);
}
:root[data-theme="dark"] .toast { background: #253354; border: 1px solid var(--border-strong); }
.toast svg { width: 1.1rem; height: 1.1rem; flex-shrink: 0; margin-top: .05rem; }
.toast-ok  svg { color: #4ade80; }
.toast-bad svg { color: #f87171; }
.toast-warn svg { color: #fbbf24; }
.toast.out { animation: toastOut .2s var(--ease) forwards; }
@keyframes toastIn  { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateX(16px); } }
@media (max-width: 560px) { .toasts { left: 1rem; right: 1rem; bottom: 1rem; max-width: none; } }

/* ---------------------------------------------------------------------------
   15. Calendar
   ------------------------------------------------------------------------- */
.cal-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap; }
.cal-title { font-size: var(--step-2); font-weight: 750; }
.cal-dows { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-bottom: 4px; }
.cal-dow { text-align: center; font-size: .68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-faint); padding: .3rem 0; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-cell {
  position: relative; min-height: 5.2rem; padding: .35rem .4rem;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius-xs); display: flex; flex-direction: column; gap: .2rem;
  text-align: left; overflow: hidden;
}
.cal-cell.out { background: var(--bg-sunken); opacity: .55; }
.cal-cell.today { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.cal-cell.has:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.cal-cell.has { cursor: pointer; }
.cal-daynum { font-family: var(--font-num); font-size: .78rem; font-weight: 700; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.cal-cell.today .cal-daynum { color: var(--accent); }
.cal-ev {
  font-size: .66rem; font-weight: 650; padding: .1rem .3rem;
  border-radius: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: var(--ok-bg); color: var(--ok-fg);
}
.cal-ev.soon    { background: var(--warn-bg); color: var(--warn-fg); }
.cal-ev.expired { background: var(--bad-bg);  color: var(--bad-fg); }
.cal-more { font-size: .64rem; font-weight: 700; color: var(--text-faint); }
@media (max-width: 720px) {
  .cal-cell { min-height: 3.4rem; padding: .25rem .25rem; }
  .cal-ev { font-size: 0; padding: 0; height: 5px; border-radius: 3px; }
  .cal-more { display: none; }
}

/* ---------------------------------------------------------------------------
   16. Landing page
   ------------------------------------------------------------------------- */
.hero { position: relative; padding-block: clamp(3rem, 8vw, 6rem); overflow: hidden; }
.hero::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(70rem 36rem at 82% -8%, color-mix(in srgb, var(--brand-500) 16%, transparent), transparent 62%),
    radial-gradient(52rem 30rem at 6% 8%, color-mix(in srgb, var(--brand-700) 11%, transparent), transparent 58%);
}
.hero-grid { display: grid; gap: clamp(2rem, 5vw, 3.5rem); align-items: center; grid-template-columns: 1fr; }
@media (min-width: 1000px) { .hero-grid { grid-template-columns: 1.05fr .95fr; } }
.hero h1 { font-size: var(--step-5); letter-spacing: -.035em; }
.hero .lede { font-size: clamp(1.02rem, .98rem + .4vw, 1.2rem); margin-top: 1rem; }
.hero-cta { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: 1.6rem; }
.hero-trust { display: flex; flex-wrap: wrap; gap: .4rem 1.1rem; margin-top: 1.4rem; font-size: .8rem; color: var(--text-soft); }
.hero-trust span { display: inline-flex; align-items: center; gap: .35rem; }
.hero-trust svg { width: .95rem; height: .95rem; color: var(--ok-bg); flex-shrink: 0; }

/* Device mock */
.mock { background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); overflow: hidden; }
.mock-bar { display: flex; align-items: center; gap: .4rem; padding: .6rem .8rem; background: var(--bg-sunken); border-bottom: 1px solid var(--border); }
.mock-dot { width: .6rem; height: .6rem; border-radius: 50%; background: var(--border-strong); }
.mock-url { margin-left: .5rem; font-size: .68rem; color: var(--text-faint); font-family: var(--font-num); }
.mock-body { padding: .9rem; display: grid; gap: .7rem; }
.mock-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; }
.mock-stat { background: var(--bg-sunken); border: 1px solid var(--border); border-radius: var(--radius-xs); padding: .45rem .5rem; }
.mock-stat b { display: block; font-family: var(--font-num); font-size: 1.15rem; font-weight: 800; line-height: 1.1; }
.mock-stat small { font-size: .56rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint); }
.mock-rows { display: grid; gap: .35rem; }
.mock-row { display: grid; grid-template-columns: 3px 1fr auto; gap: .5rem; align-items: center; background: var(--bg-sunken); border: 1px solid var(--border); border-radius: var(--radius-xs); padding: .4rem .5rem .4rem 0; overflow: hidden; }
.mock-row > i { width: 3px; align-self: stretch; }
.mock-row b { font-size: .72rem; font-weight: 700; display: block; }
.mock-row small { font-size: .6rem; color: var(--text-faint); }
.mock-pill { font-size: .56rem; font-weight: 800; padding: .1rem .35rem; border-radius: 999px; white-space: nowrap; }
.m-ok   { background: var(--ok-soft);   color: var(--ok-text); }
.m-warn { background: var(--warn-soft); color: var(--warn-text); }
.m-bad  { background: var(--bad-soft);  color: var(--bad-text); }

/* Hero scan demo: the receipt, and what was read off it */
.scan-demo {
  display: grid; gap: .8rem; align-items: stretch;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
}
@media (max-width: 520px) { .scan-demo { grid-template-columns: 1fr; } }

.scan-demo-paper {
  position: relative; overflow: hidden;
  background: #f7f5f0; color: #1a1a1a;
  border-radius: var(--radius); padding: .9rem .8rem;
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; gap: .18rem;
  font-family: var(--font-num); font-size: .56rem; line-height: 1.5;
  /* Torn-receipt edge along the bottom. */
  -webkit-mask-image: radial-gradient(circle at 6px 100%, transparent 0 4px, #000 4.5px);
  mask-image: radial-gradient(circle at 6px 100%, transparent 0 4px, #000 4.5px);
  -webkit-mask-size: 12px 100%; mask-size: 12px 100%;
  -webkit-mask-repeat: repeat-x; mask-repeat: repeat-x;
}
.scan-demo-paper b { font-size: .68rem; font-weight: 800; }
.scan-demo-paper span { color: #3b3b3b; }
.scan-demo-paper hr { border: none; border-top: 1px dashed #b9b4a8; margin: .3rem 0; width: 100%; }

/* A pass of light down the bill, to read as "being scanned". */
.scan-demo-beam {
  position: absolute; left: 0; right: 0; height: 36%;
  background: linear-gradient(180deg,
    transparent, color-mix(in srgb, var(--brand-500) 42%, transparent), transparent);
  animation: scanBeam 3.4s var(--ease-out) infinite;
  pointer-events: none;
}
@keyframes scanBeam {
  0%, 12%   { transform: translateY(-110%); opacity: 0; }
  20%       { opacity: 1; }
  80%       { opacity: 1; }
  88%, 100% { transform: translateY(300%); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .scan-demo-beam { display: none; } }

.scan-demo-out {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius); padding: .85rem .9rem;
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; gap: .35rem;
}
.scan-demo-head {
  display: flex; align-items: center; gap: .35rem;
  font-size: .76rem; font-weight: 800; color: var(--ok-text);
  padding-bottom: .4rem; border-bottom: 1px solid var(--border);
}
.scan-demo-row {
  display: grid; grid-template-columns: 1fr auto; gap: .1rem .5rem;
  align-items: center; padding: .18rem 0;
}
.scan-demo-row small {
  grid-column: 1 / -1; font-size: .58rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--text-faint);
}
.scan-demo-row b { font-size: .78rem; font-weight: 700; overflow-wrap: anywhere; }
.scan-demo-foot {
  margin-top: .3rem; padding-top: .5rem; border-top: 1px solid var(--border);
  font-size: .68rem; color: var(--text-soft);
}
.scan-demo-foot b { color: var(--text); }

/* Feature cards */
.feat { display: flex; flex-direction: column; gap: .6rem; }
.feat-icon { display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: var(--radius-sm); background: var(--accent-soft); color: var(--accent); flex-shrink: 0; }
.feat-icon svg { width: 1.3rem; height: 1.3rem; }
.feat h3 { font-size: var(--step-1); }
.feat p { font-size: var(--step--1); color: var(--text-soft); }

/* Compare table */
.cmp-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); }
.cmp { min-width: 36rem; font-size: var(--step--1); background: var(--bg-elev); }
.cmp th, .cmp td { padding: .8rem 1rem; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.cmp thead th { background: var(--bg-sunken); font-size: .74rem; letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint); font-weight: 700; }
.cmp tbody tr:last-child td { border-bottom: none; }
.cmp .c-us { background: var(--accent-soft); font-weight: 600; }
.cmp thead .c-us { background: color-mix(in srgb, var(--accent) 18%, var(--bg-sunken)); color: var(--accent); }
.cmp td svg { width: 1rem; height: 1rem; vertical-align: -2px; margin-right: .3rem; }
.ic-yes { color: var(--ok-bg); }
.ic-no  { color: var(--bad-bg); }

/* Steps */
.flow { display: grid; gap: 1.2rem; counter-reset: flow; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
.flow-step { position: relative; padding-top: 2.6rem; }
.flow-step::before {
  counter-increment: flow; content: counter(flow);
  position: absolute; top: 0; left: 0;
  display: grid; place-items: center; width: 2rem; height: 2rem;
  border-radius: 50%; background: var(--accent); color: var(--accent-text);
  font-family: var(--font-num); font-weight: 800; font-size: .9rem;
}
.flow-step h3 { font-size: var(--step-0); margin-bottom: .3rem; }
.flow-step p { font-size: var(--step--1); color: var(--text-soft); }

/* FAQ */
.faq { display: grid; gap: .5rem; }
.faq details { background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.faq details[open] { border-color: var(--border-strong); }
.faq summary {
  padding: .9rem 1.1rem; cursor: pointer; font-weight: 650; font-size: var(--step-0);
  list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ''; width: .6rem; height: .6rem; flex-shrink: 0;
  border-right: 2px solid var(--text-faint); border-bottom: 2px solid var(--text-faint);
  transform: rotate(45deg); transition: transform .2s var(--ease);
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq summary:hover { background: var(--bg-hover); }
.faq-body { padding: 0 1.1rem 1.1rem; color: var(--text-soft); font-size: var(--step--1); }
.faq-body p + p { margin-top: .6rem; }

/* CTA band */
.cta-band {
  background: linear-gradient(135deg, var(--brand-700), var(--brand-900));
  color: #fff; border-radius: var(--radius-lg); padding: clamp(1.8rem, 5vw, 3rem); text-align: center;
}
.cta-band h2 { font-size: var(--step-3); }
.cta-band p { color: var(--brand-100); max-width: 38rem; margin: .7rem auto 1.5rem; }
.cta-band .btn-primary { background: #fff; color: var(--brand-800); }
.cta-band .btn-primary:hover { background: var(--brand-50); }
.cta-band .btn-ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.4); }
.cta-band .btn-ghost:hover { background: rgba(255,255,255,.12); color: #fff; border-color: #fff; }

/* ---------------------------------------------------------------------------
   17. Editorial / guides
   ------------------------------------------------------------------------- */
.prose { font-size: 1.025rem; line-height: 1.72; }
.prose > * + * { margin-top: 1.1rem; }
.prose h2 { font-size: var(--step-2); margin-top: 2.4rem; padding-top: .3rem; }
.prose h3 { font-size: var(--step-1); margin-top: 1.8rem; }
.prose h2 + p, .prose h3 + p { margin-top: .6rem; }
.prose ul, .prose ol { padding-left: 1.4rem; }
.prose li + li { margin-top: .45rem; }
.prose strong { font-weight: 700; color: var(--text); }
.prose blockquote {
  border-left: 3px solid var(--accent); padding: .3rem 0 .3rem 1.1rem;
  color: var(--text-soft); font-style: italic;
}
.prose code {
  background: var(--bg-sunken); border: 1px solid var(--border);
  padding: .1rem .35rem; border-radius: var(--radius-xs);
  font-family: var(--font-num); font-size: .88em; overflow-wrap: anywhere;
}
.prose table { font-size: var(--step--1); display: block; overflow-x: auto; }
.prose :is(th, td) { padding: .6rem .8rem; border: 1px solid var(--border); text-align: left; vertical-align: top; }
.prose th { background: var(--bg-sunken); font-weight: 700; white-space: nowrap; }
.prose hr { border: none; border-top: 1px solid var(--border); margin-block: 2rem; }
.prose figure { margin: 0; }
.prose figcaption { font-size: .8rem; color: var(--text-faint); margin-top: .4rem; }

.article-head { padding-block: clamp(2rem, 5vw, 3.2rem) 1.5rem; }
.article-meta { display: flex; flex-wrap: wrap; gap: .4rem .9rem; font-size: .8rem; color: var(--text-faint); margin-top: .9rem; }
.article-meta span { display: inline-flex; align-items: center; gap: .3rem; }

.breadcrumb { display: flex; flex-wrap: wrap; gap: .3rem; font-size: .78rem; color: var(--text-faint); margin-bottom: .9rem; list-style: none; padding: 0; }
.breadcrumb li { display: flex; align-items: center; gap: .3rem; }
.breadcrumb li + li::before { content: '/'; color: var(--border-strong); }
.breadcrumb a { color: var(--text-soft); text-decoration: none; }
.breadcrumb a:hover { color: var(--accent); text-decoration: underline; }

.toc { background: var(--bg-sunken); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.2rem; }
.toc h2 { font-size: var(--step--1) !important; text-transform: uppercase; letter-spacing: .07em; color: var(--text-faint); margin: 0 0 .6rem !important; }
.toc ol { margin: 0; padding-left: 1.2rem; font-size: var(--step--1); }
.toc li + li { margin-top: .3rem; }
.toc a { color: var(--text-soft); text-decoration: none; }
.toc a:hover { color: var(--accent); text-decoration: underline; }

.guide-card { display: flex; flex-direction: column; gap: .5rem; background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.2rem; text-decoration: none; color: inherit; height: 100%; transition: border-color .15s var(--ease), box-shadow .2s var(--ease), transform .2s var(--ease); }
.guide-card:hover { border-color: var(--accent); box-shadow: var(--shadow); transform: translateY(-2px); }
.guide-card h3 { font-size: var(--step-0); line-height: 1.35; }
.guide-card p { font-size: .82rem; color: var(--text-soft); flex: 1; }
.guide-card .faint { margin-top: auto; }
.guide-kicker { font-size: .68rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--accent); }

/* ---------------------------------------------------------------------------
   18. Ads
   ---------------------------------------------------------------------------
   Reserved height prevents the layout shift that hurts both the reader and
   the page's own ranking. Ad units never sit immediately beside a primary
   action, so a mis-tap cannot be mistaken for interest.
   ------------------------------------------------------------------------- */
.ad-slot { margin-block: clamp(1.5rem, 4vw, 2.5rem); text-align: center; }
.ad-slot > .ad-label { display: block; font-size: .62rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--text-faint); margin-bottom: .4rem; }
.ad-slot ins, .ad-ph { display: block; width: 100%; }
.ad-ph {
  min-height: 100px; border: 1px dashed var(--border-strong); border-radius: var(--radius-sm);
  background: var(--bg-sunken); display: grid; place-items: center;
  color: var(--text-faint); font-size: .72rem; font-weight: 600; letter-spacing: .04em;
}
.ad-slot[data-size="leaderboard"] .ad-ph { min-height: 90px; }
.ad-slot[data-size="rect"] .ad-ph { min-height: 250px; max-width: 336px; margin-inline: auto; }
.ad-slot[data-size="sidebar"] .ad-ph { min-height: 600px; }
@media print { .ad-slot { display: none !important; } }

/* ---------------------------------------------------------------------------
   18b. Receipt scanner
   ------------------------------------------------------------------------- */
.scan-stage { display: flex; flex-direction: column; gap: .9rem; }

/* The viewfinder keeps a portrait aspect because receipts are tall. */
.scan-view {
  position: relative; width: 100%; aspect-ratio: 3 / 4; max-height: 56vh;
  background: #000; border-radius: var(--radius); overflow: hidden;
  display: grid; place-items: center;
}
.scan-view video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Corner marks rather than a full frame: they guide without hiding the bill. */
.scan-guide { position: absolute; inset: 8% 10%; pointer-events: none; }
.scan-guide i {
  position: absolute; width: 1.6rem; height: 1.6rem;
  border: 3px solid rgba(255,255,255,.9); border-radius: 3px;
}
.scan-guide i:nth-child(1) { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.scan-guide i:nth-child(2) { top: 0; right: 0; border-left: 0; border-bottom: 0; }
.scan-guide i:nth-child(3) { bottom: 0; left: 0; border-right: 0; border-top: 0; }
.scan-guide i:nth-child(4) { bottom: 0; right: 0; border-left: 0; border-top: 0; }
.scan-hint {
  position: absolute; left: 0; right: 0; bottom: .6rem; text-align: center;
  color: #fff; font-size: .74rem; font-weight: 600;
  text-shadow: 0 1px 4px rgba(0,0,0,.8); padding-inline: 1rem;
}

.scan-controls { display: flex; align-items: center; justify-content: center; gap: 1rem; }
.scan-shutter {
  width: 4rem; height: 4rem; border-radius: 50%;
  background: var(--brand-600); border: 4px solid var(--bg-elev);
  box-shadow: 0 0 0 3px var(--brand-600), var(--shadow);
  display: grid; place-items: center; color: #fff; flex-shrink: 0;
  transition: transform .1s var(--ease);
}
.scan-shutter:hover { background: var(--brand-700); }
.scan-shutter:active { transform: scale(.94); }
.scan-shutter:disabled { opacity: .4; pointer-events: none; }
.scan-shutter svg { width: 1.5rem; height: 1.5rem; }
.scan-torch[aria-pressed="true"] { background: var(--warn-bg); color: var(--warn-fg); border-color: var(--warn-bg); }

.scan-progress {
  height: 8px; border-radius: 999px; background: var(--bg-sunken);
  border: 1px solid var(--border); overflow: hidden;
}
.scan-progress span {
  display: block; height: 100%; width: 10%;
  background: linear-gradient(90deg, var(--brand-500), var(--brand-700));
  transition: width .3s var(--ease);
}

.scan-field {
  padding: .7rem 0; border-bottom: 1px solid var(--border);
}
.scan-field:last-child { border-bottom: none; }
.scan-field.is-empty { opacity: .62; }
.scan-field .check { align-items: flex-start; }
.scan-src {
  display: block; margin-top: .3rem; font-size: .7rem; color: var(--text-faint);
  font-family: var(--font-num); overflow-wrap: anywhere; line-height: 1.4;
}
.scan-raw {
  white-space: pre-wrap; font-family: var(--font-num); font-size: .72rem;
  line-height: 1.5; color: var(--text-soft); background: var(--bg-sunken);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: .7rem .8rem; max-height: 16rem; overflow: auto; overflow-wrap: anywhere;
}

/* The scan button sits above the first field, where someone reaching for the
   camera will look before they start typing. */
.scan-cta {
  display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
  padding: .9rem 1rem; border-radius: var(--radius);
  background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}
.scan-cta-text { flex: 1 1 14rem; min-width: 0; }
.scan-cta-text strong { display: block; font-size: var(--step--1); }
.scan-cta-text span { font-size: .78rem; color: var(--text-soft); }

/* ---------------------------------------------------------------------------
   19. Report page
   ------------------------------------------------------------------------- */
.price-tag { display: flex; align-items: baseline; gap: .4rem; }
.price-amt { font-family: var(--font-num); font-size: var(--step-4); font-weight: 800; letter-spacing: -.03em; }
.price-note { font-size: var(--step--1); color: var(--text-soft); }

/* Pricing comparison table ------------------------------------------------ */
/* Three columns do not fit a phone, so below 640px each row becomes its own
   block: the feature name on one line, then the two values labelled from the
   data-label attributes in the markup. No duplicated content, no horizontal
   scroll, and the header row is hidden rather than repeated. */
/* .table sets min-width: 44rem and is defined LATER in this file, so a bare
   .compare-table selector loses the tie and the comparison table kept a 704px
   min-width inside its scroll wrapper - stacking correctly on a phone and then
   scrolling sideways anyway. Two classes outrank one, regardless of order. */
.table.compare-table { min-width: 0; }
.compare-table th[scope="row"] { font-weight: 600; color: var(--text); }
.compare-table thead th:not(:first-child),
.compare-table tbody td { text-align: center; }
.compare-table td.yes { color: var(--ok-text); font-weight: 700; }
.compare-table td.no  { color: var(--text-faint); }

/* The paid column is the one being compared against, so give it a tint. */
.compare-table thead th:last-child,
.compare-table tbody td:last-child { background: var(--brand-50); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .compare-table thead th:last-child,
  :root:not([data-theme="light"]) .compare-table tbody td:last-child {
    background: color-mix(in srgb, var(--accent) 12%, transparent);
  }
}
:root[data-theme="dark"] .compare-table thead th:last-child,
:root[data-theme="dark"] .compare-table tbody td:last-child {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

@media (max-width: 640px) {
  .compare-table, .compare-table tbody, .compare-table tr, .compare-table td,
  .compare-table th { display: block; }
  .compare-table thead { display: none; }

  .compare-table tr {
    padding: .75rem 0;
    border-bottom: 1px solid var(--border);
  }
  .compare-table tr:last-child { border-bottom: none; }

  .compare-table th[scope="row"] { padding: 0 .9rem .35rem; }

  .compare-table tbody td {
    text-align: left;
    padding: .15rem .9rem;
    border: none;
    background: none !important;
    font-size: var(--step--1);
  }
  .compare-table tbody td::before {
    content: attr(data-label) ": ";
    color: var(--text-soft);
    font-weight: 600;
  }
}

/* Footer social row ------------------------------------------------------- */
/* Hidden entirely when no profile URLs are configured - the markup is not
   emitted at all, so there is no empty row to style around. */
.foot-social {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem 1.1rem;
  padding-top: 1.25rem;
  margin-top: 1.25rem;
  border-top: 1px solid var(--border);
  font-size: var(--step--1);
}

.foot-social a { font-weight: 600; }

/* Generic data table, used by the admin panel ----------------------------- */
/* The product views have .pv-table, but that is pinned to a 60rem min-width
   for its own column set. This is the same look without that assumption, so a
   five-column table does not get a horizontal scrollbar it does not need. */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-elev);
}

.table { min-width: 44rem; font-size: var(--step--1); }

.table thead th {
  text-align: left;
  padding: .6rem .8rem;
  font-weight: 700;
  color: var(--text-soft);
  background: var(--bg-sunk, var(--bg));
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.table tbody td {
  padding: .6rem .8rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover td { background: var(--bg-sunk, transparent); }

/* Key/value list, used on the account page -------------------------------- */
/* Two columns on anything wider than a phone, stacked below that, because a
   label and a long email address side by side at 320px just overflows. */
.kv {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .45rem 1.25rem;
  margin: 0;
  font-size: var(--step--1);
}
.kv dt { color: var(--text-soft); font-weight: 600; }
.kv dd { margin: 0; overflow-wrap: anywhere; }

@media (max-width: 420px) {
  .kv { grid-template-columns: 1fr; gap: .15rem; }
  .kv dd { margin-bottom: .5rem; }
}

/* Pricing plans ---------------------------------------------------------- */
/* Two cards that must read as a pair. They sit in .grid-2, which collapses to
   one column below ~20rem of available width, so they stack on a phone with no
   extra rules. align-items:stretch keeps both the same height when the feature
   lists differ in length, and the flex column pushes each button to the bottom
   so the two CTAs line up with each other. */
.plans { align-items: stretch; }

.plan {
  display: flex;
  flex-direction: column;
  position: relative;
}

/* The feature list absorbs the height difference between the two cards, so the
   buttons land level even though the blurbs above them differ in length.
   This only holds while the small note BELOW each button is the same number of
   lines in both cards - anything under the button sits outside the part that
   stretches. Keep those two notes to one line each, or the buttons drift apart
   by exactly one line height. */
.plan .tick-list { flex: 1 1 auto; }

.plan-name {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin-bottom: .35rem;
}

/* The paid card is marked, not shouted. A heavier border and a lift is enough
   to say "this is the other option" without implying the free plan is the
   lesser one — which, for this product, it is not. */
.plan-featured {
  border-color: var(--border-strong);
  box-shadow: var(--shadow);
}

.plan-flag {
  position: absolute;
  top: 0;
  right: clamp(1.5rem, 4vw, 2.5rem);
  transform: translateY(-50%);
}
.tick-list { list-style: none; padding: 0; display: grid; gap: .55rem; }
.tick-list li { display: flex; align-items: flex-start; gap: .55rem; font-size: var(--step--1); }
.tick-list svg { width: 1.05rem; height: 1.05rem; color: var(--ok-bg); flex-shrink: 0; margin-top: .15rem; }
.locked { position: relative; }
.locked-veil {
  position: absolute; inset: 0; display: grid; place-items: center; padding: 1rem;
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(5px); border-radius: var(--radius); text-align: center; z-index: 3;
}

/* Printable report */
.report-sheet { background: #fff; color: #0f172a; border-radius: var(--radius); padding: clamp(1.2rem, 4vw, 2.4rem); border: 1px solid var(--border); }
.report-sheet * { color: inherit; }
.report-sheet h1 { font-size: 1.6rem; }
.report-sheet h2 { font-size: 1.1rem; margin-top: 1.6rem; padding-bottom: .3rem; border-bottom: 2px solid #0f172a; }
.report-sheet table { font-size: .78rem; margin-top: .6rem; }
.report-sheet :is(th, td) { border: 1px solid #cbd5e1; padding: .35rem .5rem; text-align: left; }
.report-sheet th { background: #f1f5f9; font-weight: 700; }
.report-sheet .r-bad  { background: #fee2e2; }
.report-sheet .r-warn { background: #fef3c7; }
.report-sheet .r-head { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; align-items: flex-start; border-bottom: 3px solid #0f172a; padding-bottom: .8rem; }

@media print {
  .site-header, .site-footer, .no-print, .toasts { display: none !important; }
  body { background: #fff; color: #000; }
  .report-sheet { border: none; border-radius: 0; padding: 0; }
  .card { border: 1px solid #ccc; box-shadow: none; }
  a[href^="http"]::after { content: ' (' attr(href) ')'; font-size: .7em; color: #555; }
  @page { margin: 14mm; }
}

/* ---------------------------------------------------------------------------
   20. Footer
   ------------------------------------------------------------------------- */
.site-footer { background: var(--bg-elev); border-top: 1px solid var(--border); padding-block: clamp(2.2rem, 5vw, 3.2rem) 1.5rem; margin-top: clamp(2.5rem, 6vw, 4.5rem); }
.foot-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); }
.foot-brand { max-width: 22rem; }
.foot-brand p { font-size: .82rem; color: var(--text-soft); margin-top: .7rem; }
.foot-col h3 { font-size: .7rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint); margin-bottom: .7rem; }
.foot-col ul { list-style: none; padding: 0; display: grid; gap: .45rem; }
.foot-col a { font-size: .84rem; color: var(--text-soft); text-decoration: none; }
.foot-col a:hover { color: var(--accent); text-decoration: underline; }
.foot-bottom { margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--border); display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; font-size: .78rem; color: var(--text-faint); }

/* ---------------------------------------------------------------------------
   21. Utilities
   ------------------------------------------------------------------------- */
.mt-0{margin-top:0}.mt-1{margin-top:.5rem}.mt-2{margin-top:1rem}.mt-3{margin-top:1.5rem}.mt-4{margin-top:2rem}.mt-6{margin-top:3rem}
.mb-1{margin-bottom:.5rem}.mb-2{margin-bottom:1rem}.mb-3{margin-bottom:1.5rem}.mb-4{margin-bottom:2rem}
.gap-1{gap:.5rem}.gap-2{gap:1rem}.gap-3{gap:1.5rem}
.w-full{width:100%}.ml-auto{margin-left:auto}.flex-col{flex-direction:column}
.items-start{align-items:flex-start}.items-end{align-items:flex-end}
.justify-end{justify-content:flex-end}.justify-center{justify-content:center}
.text-sm{font-size:var(--step--1)}.text-xs{font-size:.74rem}
.fw-600{font-weight:600}.fw-700{font-weight:700}
.nowrap{white-space:nowrap}.break{overflow-wrap:anywhere}
.t-ok{color:var(--ok-text)}.t-warn{color:var(--warn-text)}.t-bad{color:var(--bad-text)}.t-accent{color:var(--accent)}
@media (max-width:640px){.hide-sm{display:none!important}}
@media (min-width:641px){.show-sm{display:none!important}}

.spinner {
  width: 1.1rem; height: 1.1rem; border-radius: 50%;
  border: 2px solid var(--border-strong); border-top-color: var(--accent);
  animation: spin .7s linear infinite; flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Distribution bar used on the dashboard */
.distbar { display: flex; height: 10px; border-radius: 999px; overflow: hidden; background: var(--bg-sunken); border: 1px solid var(--border); }
.distbar i { display: block; height: 100%; }
.distbar .d-ok { background: var(--ok-bg); }
.distbar .d-warn { background: var(--warn-bg); }
.distbar .d-bad { background: var(--bad-bg); }
.distbar .d-mute { background: var(--mute-bg); }
.dist-key { display: flex; flex-wrap: wrap; gap: .3rem .9rem; margin-top: .55rem; font-size: .74rem; color: var(--text-soft); }
.dist-key span { display: inline-flex; align-items: center; gap: .3rem; }
.dist-key i { width: .55rem; height: .55rem; border-radius: 2px; display: block; }
