/* ══════════════════════════════════════════════════════════════════════════
   DropCode — "Warm Vault" design system
   ------------------------------------------------------------------------
   A friendly physical object: a warm paper counter with a chunky metal
   locker on it. Big shapes, real shadows, one loud accent (tangerine), one
   deep anchor (indigo), lots of breathing room.

   RULES (AGENT.md §6):
   - Every colour, radius, shadow, duration and easing is a token in :root.
     Nothing in this file uses a raw colour outside the token blocks.
   - Light is the default (warm paper is the differentiator). Dark is a
     header toggle that sets [data-theme="dark"]; a first visit with no
     stored choice picks up prefers-color-scheme via the media block below.
   - 16px is the floor for anything a finger or a keyboard touches.

   Motion helpers (the JS in §7) live in assets/motion.js — this file only
   carries the CSS transitions/keyframes those helpers and the components
   rely on.
   ══════════════════════════════════════════════════════════════════════════ */

/* ─── Tokens ─────────────────────────────────────────────────────────────── */

:root {
  /* surfaces — warm, paper-like, not grey */
  --dc-paper:      #FBF6EE;
  --dc-card:       #FFFFFF;
  --dc-sunken:     #F2EADD;
  --dc-line:       #E4D8C7;

  /* ink */
  --dc-ink:        #1A1720;
  --dc-ink-2:      #4A4453;
  --dc-ink-3:      #857C90;

  /* one loud accent + one deep anchor */
  --dc-accent:     #FF5A1F;
  --dc-accent-ink: #C93A05;
  --dc-deep:       #241B57;
  --dc-deep-edge:  #17103A;   /* darker indigo for the key-cap bottom edge */

  /* text that sits ON a filled accent / deep surface — kept as tokens so
     the dark theme can flip them to dark ink where the lighter dark-mode
     accent would fail contrast against white. */
  --dc-on-accent:  #FFFFFF;
  --dc-on-deep:    #FFFFFF;

  /* semantic */
  --dc-ok:         #0E9F6E;
  --dc-warn:       #B45309;
  --dc-danger:     #C0362C;

  /* radii — chunky, consistent */
  --dc-r-sm:   10px;
  --dc-r-md:   18px;
  --dc-r-lg:   28px;
  --dc-r-pill: 999px;

  /* elevation — warm shadows, never pure black */
  --dc-e1: 0 1px 2px rgba(36,27,87,.06), 0 2px 8px rgba(36,27,87,.05);
  --dc-e2: 0 4px 12px rgba(36,27,87,.08), 0 12px 28px rgba(36,27,87,.08);
  --dc-e3: 0 12px 24px rgba(36,27,87,.10), 0 32px 64px rgba(36,27,87,.12);
  --dc-press: inset 0 2px 0 rgba(255,255,255,.6), 0 3px 0 var(--dc-deep);

  /* type */
  --dc-font: "Plus Jakarta Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
  --dc-mono: "Space Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  --dc-h1:    clamp(2.2rem, 7vw, 4.2rem);
  --dc-h2:    clamp(1.55rem, 4.4vw, 2.5rem);
  --dc-h3:    clamp(1.2rem, 3vw, 1.5rem);
  --dc-body:  clamp(1rem, 2.4vw, 1.075rem);
  --dc-meta:  0.9rem;               /* never below 14px */

  /* motion (§7.1) */
  --dc-t-fast: 140ms;
  --dc-t-base: 260ms;
  --dc-t-slow: 520ms;
  --dc-ease:   cubic-bezier(.22, 1, .36, 1);       /* out-expo-ish */
  --dc-spring: cubic-bezier(.34, 1.56, .64, 1);    /* overshoot */

  /* accent tints (derived from --dc-accent, kept as tokens so components
     never hand-mix a colour) */
  --dc-accent-wash:  rgba(255, 90, 31, .08);
  --dc-accent-line:  rgba(255, 90, 31, .35);
  --dc-deep-wash:    rgba(36, 27, 87, .06);

  /* a subtle paper grain — static feTurbulence, kept under 4% opacity */
  --dc-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");

  color-scheme: light;
}

/* Dark — applied on first visit via the OS setting (unless a light choice
   is already stored), and whenever the header toggle sets data-theme. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --dc-paper:  #141119;
    --dc-card:   #1D1926;
    --dc-sunken: #241F2E;
    --dc-line:   #332C42;
    --dc-ink:    #F6F1EA;
    --dc-ink-2:  #C6BDD1;
    --dc-ink-3:  #8F8599;
    --dc-accent:     #FF7A45;
    --dc-accent-ink: #FFB08A;
    --dc-deep:       #B9A6FF;
    --dc-deep-edge:  #7C68C9;
    --dc-on-accent:  #2A1206;   /* dark ink — the lighter dark accent fails on white */
    --dc-on-deep:    #17122B;   /* dark ink on the light-lavender tile face */
    --dc-e1: 0 1px 2px rgba(0,0,0,.4);
    --dc-e2: 0 6px 18px rgba(0,0,0,.45);
    --dc-e3: 0 18px 48px rgba(0,0,0,.55);
    --dc-press: inset 0 2px 0 rgba(255,255,255,.14), 0 3px 0 var(--dc-deep-edge);
    --dc-accent-wash: rgba(255, 122, 69, .12);
    --dc-accent-line: rgba(255, 122, 69, .40);
    --dc-deep-wash:   rgba(185, 166, 255, .10);
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --dc-paper:  #141119;
  --dc-card:   #1D1926;
  --dc-sunken: #241F2E;
  --dc-line:   #332C42;
  --dc-ink:    #F6F1EA;
  --dc-ink-2:  #C6BDD1;
  --dc-ink-3:  #8F8599;
  --dc-accent:     #FF7A45;
  --dc-accent-ink: #FFB08A;
  --dc-deep:       #B9A6FF;
  --dc-deep-edge:  #7C68C9;
  --dc-on-accent:  #2A1206;   /* dark ink — the lighter dark accent fails on white */
  --dc-on-deep:    #17122B;   /* dark ink on the light-lavender tile face */
  --dc-e1: 0 1px 2px rgba(0,0,0,.4);
  --dc-e2: 0 6px 18px rgba(0,0,0,.45);
  --dc-e3: 0 18px 48px rgba(0,0,0,.55);
  --dc-press: inset 0 2px 0 rgba(255,255,255,.14), 0 3px 0 var(--dc-deep-edge);
  --dc-accent-wash: rgba(255, 122, 69, .12);
  --dc-accent-line: rgba(255, 122, 69, .40);
  --dc-deep-wash:   rgba(185, 166, 255, .10);
  color-scheme: dark;
}

/* ─── Reset & base ───────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

/* The [hidden] attribute is our show/hide switch (toggled via el.hidden).
   A component class that sets `display` would otherwise out-specify the UA
   rule and leak a "hidden" element onto the page — force it. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--dc-paper);
  color: var(--dc-ink-2);
  font-family: var(--dc-font);
  font-size: var(--dc-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Grain overlay — kills the flat-CSS look. Static, so it stays even under
   reduced motion; capped well below 4% opacity. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--dc-grain);
  background-size: 140px 140px;
  opacity: .035;
  mix-blend-mode: multiply;
}
:root[data-theme="dark"] body::before,
:root:not([data-theme="light"]) body::before { mix-blend-mode: screen; opacity: .05; }

h1, h2, h3, h4 {
  font-family: var(--dc-font);
  color: var(--dc-ink);
  font-weight: 800;
  letter-spacing: -0.03em;
  margin: 0 0 .5em;
}
h1 { font-size: var(--dc-h1); line-height: 1.02; }
h2 { font-size: var(--dc-h2); line-height: 1.08; }
h3 { font-size: var(--dc-h3); line-height: 1.15; letter-spacing: -0.02em; }

p { margin: 0 0 1em; }
a { color: var(--dc-accent-ink); text-underline-offset: 2px; }

small, .dc-meta {
  font-size: var(--dc-meta);
  color: var(--dc-ink-3);
  line-height: 1.5;
}

img { max-width: 100%; height: auto; }

/* ─── Focus (§6.5) — visible everywhere, never removed without a swap ───── */

:where(a, button, input, textarea, select, [tabindex], summary):focus-visible {
  outline: 3px solid var(--dc-accent);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ─── Layout helpers ─────────────────────────────────────────────────────── */

.dc-wrap {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1060px;
  margin-inline: auto;
  padding-inline: clamp(16px, 4vw, 28px);
}
.dc-stack > * + * { margin-top: var(--dc-stack-gap, 1rem); }
.dc-center { text-align: center; }

/* ─── Chip / eyebrow ─────────────────────────────────────────────────────── */

.dc-chip {
  display: inline-flex;
  align-items: center;
  gap: .5ch;
  padding: 7px 14px;
  border-radius: var(--dc-r-pill);
  background: var(--dc-card);
  border: 1px solid var(--dc-line);
  box-shadow: var(--dc-e1);
  font-size: var(--dc-meta);
  font-weight: 700;
  color: var(--dc-ink-2);
  letter-spacing: .01em;
}
.dc-chip--accent { color: var(--dc-accent-ink); border-color: var(--dc-accent-line); background: var(--dc-accent-wash); }

/* ─── Buttons — chunky press (§6.3.3) ────────────────────────────────────── */

.dc-btn {
  --_edge: var(--dc-deep-edge);
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6ch;
  min-height: 52px;
  padding: 14px 26px;
  border: 0;
  border-radius: var(--dc-r-md);
  font-family: var(--dc-font);
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1;
  cursor: pointer;
  text-decoration: none;
  color: var(--dc-on-deep);
  background: var(--dc-deep);
  box-shadow: 0 3px 0 var(--_edge), var(--dc-e1);
  transform: translateY(0);
  transition:
    transform var(--dc-t-fast) var(--dc-ease),
    box-shadow var(--dc-t-fast) var(--dc-ease),
    background-color var(--dc-t-fast) var(--dc-ease),
    filter var(--dc-t-fast) var(--dc-ease);
}
.dc-btn:hover { filter: brightness(1.04); }
.dc-btn:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 var(--_edge), var(--dc-e1);
}
.dc-btn[disabled], .dc-btn[aria-disabled="true"] {
  opacity: .55;
  cursor: not-allowed;
  filter: none;
  transform: none;
  box-shadow: 0 3px 0 var(--_edge);
}
.dc-btn--block { width: 100%; }
.dc-btn--lg { min-height: 60px; padding: 18px 32px; font-size: 1.075rem; }

.dc-btn--primary {
  --_edge: var(--dc-accent-ink);
  background: var(--dc-accent);
  color: var(--dc-on-accent);
}
.dc-btn--secondary {
  background: var(--dc-card);
  color: var(--dc-ink);
  --_edge: var(--dc-line);
  box-shadow: 0 3px 0 var(--dc-line), var(--dc-e1);
}
.dc-btn--ghost {
  background: transparent;
  color: var(--dc-ink-2);
  box-shadow: none;
  min-height: 44px;
  padding: 10px 16px;
}
.dc-btn--ghost:active { transform: none; box-shadow: none; background: var(--dc-deep-wash); }

/* ripple layer (motion.js draws a radial-gradient here) */
.dc-btn { position: relative; overflow: hidden; }
.dc-btn > * { position: relative; z-index: 1; }

/* ─── Card + ticket (§6.3.2) ─────────────────────────────────────────────── */

.dc-card {
  position: relative;
  background: var(--dc-card);
  border: 1px solid var(--dc-line);
  border-radius: var(--dc-r-lg);
  box-shadow: var(--dc-e2);
  padding: clamp(20px, 5vw, 40px);
}
.dc-card--pad-lg { padding: clamp(28px, 6vw, 56px); }

/* Punched-hole ticket — two notches on the sides via radial-gradient masks.
   Used for the success card only. */
.dc-card--ticket {
  --_notch: 18px;
  -webkit-mask:
    radial-gradient(var(--_notch) at 0 50%, transparent 98%, #000) left / 51% 100% no-repeat,
    radial-gradient(var(--_notch) at 100% 50%, transparent 98%, #000) right / 51% 100% no-repeat;
          mask:
    radial-gradient(var(--_notch) at 0 50%, transparent 98%, #000) left / 51% 100% no-repeat,
    radial-gradient(var(--_notch) at 100% 50%, transparent 98%, #000) right / 51% 100% no-repeat;
}

/* ─── Code tiles — key-cap look (§6.3.1) ─────────────────────────────────── */

.dc-code {
  display: flex;
  justify-content: center;
  gap: clamp(8px, 2.5vw, 16px);
  perspective: 600px;                 /* for tileFlip in motion.js */
}
.dc-tile {
  --_rot: -1.5deg;
  display: grid;
  place-items: center;
  width:  clamp(48px, 15vw, 84px);
  height: clamp(60px, 19vw, 104px);
  border-radius: var(--dc-r-md);
  background: var(--dc-deep);
  color: var(--dc-on-deep);
  font-family: var(--dc-mono);
  font-size: clamp(1.9rem, 7vw, 3.4rem);
  font-weight: 700;
  letter-spacing: .04em;
  box-shadow: 0 4px 0 var(--dc-deep-edge), var(--dc-e2);
  transform: rotate(var(--_rot));
  transform-style: preserve-3d;
  transition: box-shadow var(--dc-t-base) var(--dc-ease), transform var(--dc-t-base) var(--dc-spring);
  user-select: all;
}
.dc-tile:nth-child(even) { --_rot: 1.5deg; }

/* tangerine glow behind the code on success */
.dc-code--won .dc-tile {
  box-shadow:
    0 4px 0 var(--dc-deep-edge),
    0 0 0 3px var(--dc-accent-line),
    0 10px 30px var(--dc-accent-wash),
    var(--dc-e2);
}
.dc-tile--pop { transform: rotate(var(--_rot)) scale(1.06); }

/* ─── 4-char entry inputs (receive) ─────────────────────────────────────── */

.dc-code-inputs {
  display: flex;
  justify-content: center;
  gap: clamp(8px, 3vw, 14px);
}
.dc-code-inputs input {
  width:  clamp(52px, 16vw, 68px);
  height: clamp(60px, 18vw, 80px);
  padding: 0;
  border: 2px solid var(--dc-line);
  border-radius: var(--dc-r-md);
  background: var(--dc-card);
  color: var(--dc-ink);
  font-family: var(--dc-mono);
  font-size: clamp(1.6rem, 6vw, 2.2rem);   /* well above the 16px iOS-zoom floor */
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
  box-shadow: var(--dc-e1);
  transition: border-color var(--dc-t-fast) var(--dc-ease), box-shadow var(--dc-t-fast) var(--dc-ease);
}
.dc-code-inputs input:focus {
  border-color: var(--dc-accent);
  box-shadow: 0 0 0 4px var(--dc-accent-wash);
  outline: none;                            /* replaced by the ring above */
}
.dc-code-inputs input:not(:placeholder-shown) { border-color: var(--dc-deep); }

/* wrong-code: amber, not red (§5.4) */
.dc-code-inputs--wrong input {
  border-color: var(--dc-warn);
  box-shadow: 0 0 0 4px rgba(180, 83, 9, .14);
}

/* ─── Text field / textarea ─────────────────────────────────────────────── */

.dc-field { display: block; }
.dc-label {
  display: block;
  margin-bottom: 8px;
  font-size: var(--dc-meta);
  font-weight: 700;
  color: var(--dc-ink-2);
}
.dc-input, .dc-textarea {
  width: 100%;
  padding: 14px 16px;
  border: 2px solid var(--dc-line);
  border-radius: var(--dc-r-md);
  background: var(--dc-card);
  color: var(--dc-ink);
  font-family: var(--dc-font);
  font-size: 1rem;                          /* 16px — no iOS zoom */
  line-height: 1.5;
  transition: border-color var(--dc-t-fast) var(--dc-ease), box-shadow var(--dc-t-fast) var(--dc-ease);
}
.dc-textarea {
  min-height: 140px;
  resize: vertical;
  font-family: var(--dc-mono);
  font-size: 1rem;
}
.dc-input:focus, .dc-textarea:focus {
  border-color: var(--dc-accent);
  box-shadow: 0 0 0 4px var(--dc-accent-wash);
  outline: none;
}
.dc-counter { font-size: var(--dc-meta); color: var(--dc-ink-3); text-align: right; }
.dc-counter--near { color: var(--dc-danger); font-weight: 700; }

/* ─── Drop zone (§5.2) ──────────────────────────────────────────────────── */

.dc-dropzone {
  position: relative;
  display: grid;
  place-items: center;
  gap: 10px;
  padding: clamp(28px, 8vw, 52px) 20px;
  border: 2px dashed var(--dc-line);
  border-radius: var(--dc-r-lg);
  background: var(--dc-sunken);
  text-align: center;
  color: var(--dc-ink-3);
  cursor: pointer;
  transition:
    border-color var(--dc-t-base) var(--dc-ease),
    background-color var(--dc-t-base) var(--dc-ease),
    transform var(--dc-t-base) var(--dc-spring);
}
.dc-dropzone__icon {
  font-size: 2.2rem;
  transition: transform var(--dc-t-base) var(--dc-spring);
}
.dc-dropzone__hint { font-size: var(--dc-meta); }
.dc-dropzone.is-hot {
  border-color: var(--dc-accent);
  border-style: solid;
  background: var(--dc-accent-wash);
  color: var(--dc-accent-ink);
}
.dc-dropzone.is-hot .dc-dropzone__icon { transform: scale(1.08); }

/* file card (photo/file preview) */
.dc-filecard {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--dc-line);
  border-radius: var(--dc-r-md);
  background: var(--dc-card);
  box-shadow: var(--dc-e1);
}
.dc-filecard__thumb {
  flex: 0 0 auto;
  width: 56px; height: 56px;
  display: grid; place-items: center;
  border-radius: var(--dc-r-sm);
  background: var(--dc-deep-wash);
  color: var(--dc-deep);
  font-weight: 800;
  overflow: hidden;
}
.dc-filecard__thumb img { width: 100%; height: 100%; object-fit: cover; }
.dc-filecard__name { font-weight: 700; color: var(--dc-ink); word-break: break-word; }
.dc-filecard__meta { font-size: var(--dc-meta); color: var(--dc-ink-3); }
.dc-ext-chip {
  display: inline-block;
  padding: 2px 8px;
  border-radius: var(--dc-r-pill);
  background: var(--dc-deep-wash);
  color: var(--dc-deep);
  font-size: .72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .06em;
}

/* ─── Segmented control (§5.2) ──────────────────────────────────────────── */

.dc-segment {
  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 2px;
  padding: 5px;
  border-radius: var(--dc-r-pill);
  background: var(--dc-sunken);
  border: 1px solid var(--dc-line);
}
.dc-segment__pill {
  position: absolute;
  top: 5px; left: 5px;
  height: calc(100% - 10px);
  border-radius: var(--dc-r-pill);
  background: var(--dc-card);
  box-shadow: var(--dc-e1);
  transition: transform var(--dc-t-base) var(--dc-spring), width var(--dc-t-base) var(--dc-ease);
  z-index: 0;
}
.dc-segment button {
  position: relative;
  z-index: 1;
  appearance: none;
  border: 0;
  background: transparent;
  padding: 12px 10px;
  min-height: 44px;
  border-radius: var(--dc-r-pill);
  font-family: var(--dc-font);
  font-size: .95rem;
  font-weight: 700;
  color: var(--dc-ink-3);
  cursor: pointer;
  transition: color var(--dc-t-fast) var(--dc-ease);
}
.dc-segment button[aria-selected="true"] { color: var(--dc-ink); }

/* ─── Pills (TTL selector) ──────────────────────────────────────────────── */

.dc-pills { display: flex; gap: 8px; flex-wrap: wrap; }
.dc-pill {
  appearance: none;
  padding: 10px 18px;
  min-height: 44px;
  border: 2px solid var(--dc-line);
  border-radius: var(--dc-r-pill);
  background: var(--dc-card);
  color: var(--dc-ink-2);
  font-family: var(--dc-font);
  font-size: .95rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color var(--dc-t-fast) var(--dc-ease), background-color var(--dc-t-fast) var(--dc-ease), color var(--dc-t-fast) var(--dc-ease);
}
.dc-pill[aria-pressed="true"] {
  border-color: var(--dc-accent);
  background: var(--dc-accent-wash);
  color: var(--dc-accent-ink);
}

/* ─── Switch (burn after read) ──────────────────────────────────────────── */

.dc-switch {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  font-size: var(--dc-meta);
  font-weight: 700;
  color: var(--dc-ink-2);
}
.dc-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.dc-switch__track {
  flex: 0 0 auto;
  width: 52px; height: 30px;
  border-radius: var(--dc-r-pill);
  background: var(--dc-sunken);
  border: 1px solid var(--dc-line);
  position: relative;
  transition: background-color var(--dc-t-fast) var(--dc-ease), border-color var(--dc-t-fast) var(--dc-ease);
}
.dc-switch__track::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--dc-card);
  box-shadow: var(--dc-e1);
  transition: transform var(--dc-t-fast) var(--dc-spring);
}
.dc-switch input:checked + .dc-switch__track { background: var(--dc-accent); border-color: var(--dc-accent-ink); }
.dc-switch input:checked + .dc-switch__track::after { transform: translateX(22px); }
.dc-switch input:focus-visible + .dc-switch__track { outline: 3px solid var(--dc-accent); outline-offset: 3px; }

/* ─── Disclosure (Options) ──────────────────────────────────────────────── */

.dc-disclosure { border: 1px solid var(--dc-line); border-radius: var(--dc-r-md); background: var(--dc-card); }
.dc-disclosure > summary {
  list-style: none;
  padding: 14px 16px;
  font-weight: 700;
  color: var(--dc-ink);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.dc-disclosure > summary::-webkit-details-marker { display: none; }
.dc-disclosure > summary::after { content: "▾"; color: var(--dc-ink-3); transition: transform var(--dc-t-fast) var(--dc-ease); }
.dc-disclosure[open] > summary::after { transform: rotate(180deg); }
.dc-disclosure__body { padding: 4px 16px 18px; }

/* ─── Stat tile (§5.1) ──────────────────────────────────────────────────── */

.dc-stats { display: grid; gap: 12px; grid-template-columns: repeat(3, 1fr); }
.dc-stat {
  padding: 18px 16px;
  border-radius: var(--dc-r-md);
  background: var(--dc-card);
  border: 1px solid var(--dc-line);
  box-shadow: var(--dc-e1);
  text-align: center;
}
.dc-stat__num {
  font-family: var(--dc-mono);
  font-size: clamp(1.5rem, 5vw, 2.1rem);
  font-weight: 700;
  color: var(--dc-ink);
  font-variant-numeric: tabular-nums;   /* no width jitter during countUp */
}
.dc-stat__label { font-size: var(--dc-meta); color: var(--dc-ink-3); margin-top: 2px; }
@media (max-width: 520px) {
  .dc-stats { grid-template-columns: 1fr; }
}

/* ─── Progress: thin depleting bar + ring ───────────────────────────────── */

.dc-progress {
  height: 6px;
  border-radius: var(--dc-r-pill);
  background: var(--dc-sunken);
  overflow: hidden;
}
.dc-progress__fill {
  height: 100%;
  border-radius: inherit;
  background: var(--dc-accent);
  transform-origin: left;
  transition: transform var(--dc-t-slow) linear;
}
.dc-progress--warn .dc-progress__fill { background: var(--dc-warn); }

.dc-ring { display: inline-grid; place-items: center; }
.dc-ring circle { fill: none; stroke-width: 6; }
.dc-ring__track { stroke: var(--dc-sunken); }
.dc-ring__value {
  stroke: var(--dc-accent);
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
  transition: stroke-dashoffset var(--dc-t-base) var(--dc-ease);
}

/* ─── Skeleton (§7.2.12) ────────────────────────────────────────────────── */

.dc-skeleton {
  --_base: var(--dc-sunken);
  border-radius: var(--dc-r-sm);
  background:
    linear-gradient(90deg, transparent, var(--dc-accent-wash), transparent) 0 0 / 40% 100% no-repeat,
    var(--_base);
  animation: dc-shimmer 1.4s linear infinite;
}
@keyframes dc-shimmer {
  from { background-position: -60% 0, 0 0; }
  to   { background-position: 160% 0, 0 0; }
}

/* ─── Toast (§7.2.13) ──────────────────────────────────────────────────── */

.dc-toasts {
  position: fixed;
  z-index: 60;
  inset-inline: 0;
  bottom: max(16px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}
@media (min-width: 720px) {
  .dc-toasts { inset-inline: auto 20px; bottom: auto; top: 20px; align-items: flex-end; }
}
.dc-toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(92vw, 380px);
  padding: 12px 16px;
  border-radius: var(--dc-r-md);
  background: var(--dc-ink);
  color: var(--dc-paper);
  font-size: .95rem;
  font-weight: 600;
  box-shadow: var(--dc-e3);
}
.dc-toast--ok   { background: var(--dc-ok); color: #fff; }
.dc-toast--warn { background: var(--dc-warn); color: #fff; }
.dc-toast--err  { background: var(--dc-danger); color: #fff; }

/* ─── QR frame ─────────────────────────────────────────────────────────── */

.dc-qr {
  display: inline-block;
  padding: 12px;
  border-radius: var(--dc-r-md);
  background: #fff;                     /* a QR must stay dark-on-white to scan */
  border: 1px solid var(--dc-line);
  box-shadow: var(--dc-e1);
  line-height: 0;
}
.dc-qr img, .dc-qr canvas { width: clamp(120px, 34vw, 168px); height: auto; image-rendering: pixelated; }

/* ─── Safety banner (§5.5) ─────────────────────────────────────────────── */

.dc-banner {
  display: flex;
  gap: 10px;
  padding: 14px 16px;
  border-radius: var(--dc-r-md);
  background: var(--dc-accent-wash);
  border: 1px solid var(--dc-accent-line);
  color: var(--dc-accent-ink);
  font-size: var(--dc-meta);
  font-weight: 600;
  line-height: 1.5;
}

/* ─── Hand-drawn arrow (§6.3.5) ────────────────────────────────────────── */

.dc-arrow { color: var(--dc-ink-3); width: 64px; height: auto; }
.dc-arrow path { fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; }

/* ─── Recent-drops strip (§5.3) ────────────────────────────────────────── */

.dc-recent { display: flex; gap: 8px; flex-wrap: wrap; }
.dc-recent__item {
  font-family: var(--dc-mono);
  font-weight: 700;
  font-size: .95rem;
  padding: 8px 12px;
  border-radius: var(--dc-r-sm);
  background: var(--dc-sunken);
  border: 1px solid var(--dc-line);
  color: var(--dc-ink-2);
  cursor: pointer;
}

/* ─── Ambient drift shapes (§7.2.15) — CSS-only, GPU-cheap ──────────────── */

.dc-ambient { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.dc-ambient span {
  position: absolute;
  width: 46vmax; height: 46vmax;
  border-radius: 50%;
  filter: blur(60px);
  opacity: .04;
  background: var(--dc-accent);
  animation: dc-drift 34s var(--dc-ease) infinite alternate;
}
.dc-ambient span:nth-child(2) { background: var(--dc-deep); opacity: .05; animation-duration: 46s; left: 60%; top: 30%; }
.dc-ambient span:nth-child(3) { background: var(--dc-accent); opacity: .03; animation-duration: 40s; left: 20%; top: 55%; }
@keyframes dc-drift {
  from { transform: translate3d(-6%, -4%, 0) scale(1); }
  to   { transform: translate3d(8%, 6%, 0) scale(1.15); }
}

/* ─── Reduced motion (§7.6) ────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .dc-ambient { display: none; }
}

/* ─── Print ────────────────────────────────────────────────────────────── */

@media print {
  body::before, .dc-ambient, .dc-toasts { display: none; }
  .dc-card { box-shadow: none; border-color: #000; }
}
