/* Polypep — peptide tracker */
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap');

/* ═══════════════════════════════════════════════════════════════
   THEME TOKENS  ·  two themes ship: Dark (:root, default) + Sport
   (html[data-theme="sport"] — a flat athletic light). Accent hue is
   driven by --accent-rgb / --lime / --on-accent so accent literals
   (rgba(var(--accent-rgb),α)) recolor per accent. Nine accents per
   theme (see the Design System page for the full matrix).
   ═══════════════════════════════════════════════════════════════ */
:root {
  --bg: #0a0b0a;
  --bg-1: #131413;
  --bg-2: #1a1c1a;
  --line: rgba(255,255,255,0.08);
  --line-2: rgba(255,255,255,0.14);
  --text: #f5f7f4;
  --text-2: rgba(245,247,244,0.62);
  --text-3: rgba(245,247,244,0.38);

  /* accent (lime by default) */
  --lime: #d4fb3c;
  --lime-dim: #a8c930;
  --lime-soft: rgba(var(--accent-rgb),0.14);
  --accent-rgb: 212,251,60;
  --on-accent: #0a0b0a;
  --accent-glow: rgba(var(--accent-rgb),0.4);
  /* accent used as TEXT/glyph (legible tone); = accent in dark */
  --accent-text: var(--lime);
  /* Accent text on an accent TINT rather than on the plain card surface. The
     tint lifts the backdrop toward the accent hue, so a tone that clears 4.5:1
     on the card can fail on the chip. Only failing accents override it. */
  --accent-text-on-tint: var(--accent-text);
  /* data-color-as-ink darkening: on white we cap LIGHTNESS in OKLCH (hue +
     chroma preserved). 1 = vivid / uncapped (dark theme). */
  --data-keep: 100%;
  --data-ink: #0a0b0a;
  --data-lcap: 1;
  /* Same cap, stricter, for data colors painted as TEXT. At the graphics cap a
     pale hue stays pale — #8ee7ff capped at 0.8 is #74cde4, ~1.8:1 on a white
     card — so text needs its own cap to clear 4.5:1. 1 = uncapped (dark). */
  --data-lcap-text: 1;
  /* Between the two: big dose readouts (30–46px) keep the vivid slider hue but
     only need 3:1. 1 = uncapped (dark). */
  --data-lcap-dose: 1;

  --danger: #ff6b5a;
  --danger-rgb: 255,107,90;
  /* ink drawn ON a --danger fill; fixed, never follows the accent */
  --danger-ink: #1a0808;
  --warn: #ffb547;
  --warn-rgb: 255,181,71;
  /* Warn as TEXT or a text-sized glyph on a neutral surface — same fill/text
     split as --lime / --accent-text. Identical to --warn in dark. */
  --warn-text: var(--warn);
  /* Side-effect severity on neutral surfaces. Moderate and severe share the
     warning/danger roles; mild owns the remaining semantic green. */
  --severity-mild: #8fd98a;
  --severity-mild-rgb: 143,217,138;
  --severity-mild-tint: rgba(var(--severity-mild-rgb),0.14);
  --severity-mild-border: rgba(var(--severity-mild-rgb),0.34);
  --severity-moderate: var(--warn-text);
  --severity-moderate-tint: rgba(var(--warn-rgb),0.14);
  --severity-moderate-border: rgba(var(--warn-rgb),0.34);
  --severity-severe: var(--danger);
  --severity-severe-tint: rgba(var(--danger-rgb),0.14);
  --severity-severe-border: rgba(var(--danger-rgb),0.34);
  /* Streak flame — one fixed bright-orange ramp, identical in BOTH themes
     (Sport does not override these). Heroes, count numerals, completed days,
     full heatmap cells, and progress dots read these. */
  --streak-1: #ffc166;
  --streak-2: #ff8b4c;
  --streak-3: #d63a1f;
  --streak-rgb: 255,139,76;
  /* Streak text and outline glyphs on neutral surfaces deepen on Sport. */
  --streak-ink: #ffc166;
  --streak-fill-ink: #16120a;
  --corr-pos: var(--on-accent);
  --corr-neg: #fff;
  /* decorative glow intensity multiplier; white theme dials it down */
  --glow-scale: 1;
  --vial-shadow: rgba(0,0,0,0.4);
  --vial-cap: linear-gradient(to bottom, #3a3e35, #1e1f1a);
  --vial-neck: linear-gradient(to bottom, #1a1c18, #252824);
  --float-shadow: 0 10px 30px rgba(0,0,0,0.4);
  /* modal/popup backdrop scrim — dark by default, light on the Sport theme */
  --scrim: rgba(0,0,0,0.55);

  /* elevation overlay scale — light-on-dark films.
     White theme overrides these to dark-on-white so every migrated
     rgba(255,255,255,α) fill/border inverts in one place. */
  --w02: rgba(255,255,255,0.02);
  --w03: rgba(255,255,255,0.03);
  --w035: rgba(255,255,255,0.035);
  --w04: rgba(255,255,255,0.04);
  --w05: rgba(255,255,255,0.05);
  --w06: rgba(255,255,255,0.06);
  --w07: rgba(255,255,255,0.07);
  --w08: rgba(255,255,255,0.08);
  --w09: rgba(255,255,255,0.09);
  --w10: rgba(255,255,255,0.10);
  --w12: rgba(255,255,255,0.12);
  --w14: rgba(255,255,255,0.14);
  --w15: rgba(255,255,255,0.15);
  --w18: rgba(255,255,255,0.18);

  /* glass */
  --glass-bg: rgba(255,255,255,0.06);
  --glass-border: rgba(255,255,255,0.12);
  --glass-shadow: inset 1px 1px 0 rgba(255,255,255,0.08), inset -1px -1px 0 rgba(255,255,255,0.03), 0 8px 24px rgba(0,0,0,0.3);
  --glass-strong-bg: rgba(255,255,255,0.1);
  --glass-strong-border: rgba(255,255,255,0.18);
  --glass-strong-shadow: inset 1.5px 1.5px 0 rgba(255,255,255,0.15), inset -1px -1px 0 rgba(255,255,255,0.05), 0 12px 32px rgba(0,0,0,0.35);

  /* misc chrome */
  --card-shadow: none;
  --avatar-bg: radial-gradient(circle at 50% 35%, var(--w10), var(--bg-1) 72%);
  --avatar-ink: var(--accent-text);
  --ring-track: rgba(255,255,255,0.06);
  --home-indicator: rgba(255,255,255,0.4);
  --titlebar-bg: rgba(14,14,12,0.7);
  --chrome-bg: rgba(14,14,12,0.6);
  --dock-bg: rgba(20,22,18,0.72);
  --inset: rgba(0,0,0,0.25);
  --inset-strong: rgba(0,0,0,0.4);
  --web-frame: #1a1a1a;
  --web-tabstrip: #2a2a2a;
  --web-surface: #1a1a1a;
  --web-inset: #111;
  --body-bg:
    radial-gradient(1200px 600px at 20% 0%, rgba(var(--accent-rgb),0.04), transparent 60%),
    radial-gradient(900px 500px at 100% 100%, rgba(var(--accent-rgb),0.03), transparent 60%),
    #0a0a08;
}

/* ─── Dark accent treatments (explore) ─── */
/* Lime (:root) stays the default. Bright fills, dark ink — same pattern. */
html:not([data-theme="sport"])[data-accent="blue"] {
  --lime: #5b8dff; --lime-dim: #3e6fe0;
  --accent-rgb: 91,141,255; --on-accent: #06102a;
}
html:not([data-theme="sport"])[data-accent="volt"] {
  --lime: #ffd60a; --lime-dim: #d9b400;
  --accent-rgb: 255,214,10; --on-accent: #1a1400;
}
html:not([data-theme="sport"])[data-accent="kelly"] {
  --lime: #30d158; --lime-dim: #23a844;
  --accent-rgb: 48,209,88; --on-accent: #04230f;
}
html:not([data-theme="sport"])[data-accent="orange"] {
  --lime: #ff9f1a; --lime-dim: #e08200;
  --accent-rgb: 255,159,26; --on-accent: #201200;
}
html:not([data-theme="sport"])[data-accent="magenta"] {
  --lime: #ff5ad1; --lime-dim: #e03bb2;
  --accent-rgb: 255,90,209; --on-accent: #2a0620;
}
html:not([data-theme="sport"])[data-accent="cyan"] {
  --lime: #3ee0dc; --lime-dim: #22bdb9;
  --accent-rgb: 62,224,220; --on-accent: #032120;
}
html:not([data-theme="sport"])[data-accent="violet"] {
  --lime: #b18cff; --lime-dim: #9166ea;
  --accent-rgb: 177,140,255; --on-accent: #170a2e;
}
/* Mono — white accent, dark ink on fills (dark twin of white/ink). */
html:not([data-theme="sport"])[data-accent="mono"] {
  --lime: #f5f7f4; --lime-dim: #c9cdc6;
  --accent-rgb: 245,247,244; --on-accent: #0a0b0a;
  --accent-glow: rgba(245,247,244,0.22);
}

/* ═══════════════ SPORT THEME — flat athletic light (Strava/NRC school) ═══════════════ */
html[data-theme="sport"] {
  /* Neutral gray canvas, flat pure-white cards, hairline dividers,
     near-black ink, accent used full-strength but without glow. */
  --bg: #f4f4f6;
  --bg-1: #ffffff;
  --bg-2: #ededf0;
  --scrim: rgba(255,255,255,0.55);
  --line: rgba(17,17,19,0.09);
  --line-2: rgba(17,17,19,0.16);
  --text: #121214;
  --text-2: rgba(18,18,20,0.60);
  --text-3: rgba(18,18,20,0.44);
  --danger: #c93012;
  --danger-rgb: 201,48,18;
  --danger-ink: #ffffff;
  /* Orange so the glyph reads as a warning, not as "expired" — it clears the
     3:1 graphics floor everywhere, but only 4.13:1 as text on the grey canvas,
     so warn-coloured words and small glyphs take the darker tier below. */
  --warn: #c2560a;
  --warn-rgb: 194,86,10;
  --warn-text: #96660a;
  --severity-mild: #397a36;
  --severity-mild-rgb: 57,122,54;
  /* Eight-percent self-tints keep all three labels at 4.5:1 or better on a
     white Sport card; the former 12–14% tints did not. */
  --severity-mild-tint: rgba(var(--severity-mild-rgb),0.08);
  --severity-mild-border: rgba(var(--severity-mild-rgb),0.24);
  --severity-moderate-tint: rgba(var(--warn-rgb),0.08);
  --severity-moderate-border: rgba(var(--warn-rgb),0.24);
  --severity-severe-tint: rgba(var(--danger-rgb),0.08);
  --severity-severe-border: rgba(var(--danger-rgb),0.24);
  /* Deep orange so on-surface streak labels and glyphs keep contrast. */
  --streak-ink: #c2410c;
  --corr-pos: #121214;
  --corr-neg: #8a1d0e;
  --glow-scale: 0.15;
  /* Vial chrome softens and flips to film-based neutrals on the light canvas. */
  --vial-shadow: rgba(17,17,19,0.16);
  --vial-cap: linear-gradient(to bottom, rgba(17,17,19,0.30), rgba(17,17,19,0.14));
  --vial-neck: linear-gradient(to bottom, rgba(17,17,19,0.16), rgba(17,17,19,0.10));
  --float-shadow: 0 8px 20px rgba(17,17,19,0.14);

  --w02: rgba(17,17,19,0.025);
  --w03: #ffffff;     /* dominant card fill → flat white */
  --w035: #ffffff;
  --w04: rgba(17,17,19,0.04);
  --w05: rgba(17,17,19,0.05);
  --w06: rgba(17,17,19,0.06);
  --w07: rgba(17,17,19,0.065);
  --w08: rgba(17,17,19,0.08);
  --w09: rgba(17,17,19,0.09);
  --w10: rgba(17,17,19,0.10);
  --w12: rgba(17,17,19,0.11);
  --w14: rgba(17,17,19,0.13);
  --w15: rgba(17,17,19,0.13);
  --w18: rgba(17,17,19,0.15);

  /* chrome is near-solid white — no frosted-glass look */
  --glass-bg: rgba(255,255,255,0.92);
  --glass-border: rgba(17,17,19,0.08);
  --glass-shadow: 0 1px 0 rgba(17,17,19,0.05);
  --glass-strong-bg: rgba(255,255,255,0.97);
  --glass-strong-border: rgba(17,17,19,0.09);
  --glass-strong-shadow: 0 1px 2px rgba(17,17,19,0.05), 0 10px 28px rgba(17,17,19,0.10);

  --card-shadow: 0 1px 2px rgba(17,17,19,0.05);
  --avatar-bg: radial-gradient(circle at 50% 35%, var(--w10), var(--bg-1) 72%);
  --avatar-ink: var(--accent-text);
  --ring-track: rgba(17,17,19,0.08);
  --home-indicator: rgba(17,17,19,0.30);
  --titlebar-bg: rgba(255,255,255,0.92);
  --chrome-bg: rgba(255,255,255,0.88);
  --dock-bg: rgba(255,255,255,0.96);
  --inset: rgba(17,17,19,0.05);
  --inset-strong: rgba(17,17,19,0.07);
  --web-frame: #e3e4e7;
  --web-tabstrip: #e3e4e7;
  --web-surface: #ffffff;
  --web-inset: #f1f1f4;
  --body-bg: #e9eaed;

  /* default accent = green — same safety net as white */
  --lime: #c2e82e; --lime-dim: #9dbd1d;
  --accent-rgb: 194,232,46; --on-accent: #16240a;
  --lime-soft: rgba(194,232,46,0.2); --accent-glow: rgba(194,232,46,0.4);
  --accent-text: #4f7c00;
  --data-keep: 58%; --data-ink: #131316; --data-lcap: 0.8;
  /* Graphics only need ~3:1, text needs 4.5:1. 0.53 clears it for every hue on
     BOTH a white card and a chip tinted 8–16% with its own hue (worst 4.51:1). */
  --data-lcap-text: 0.53;
  /* Dose readouts intentionally match their slider exactly — same cap as the
     graphics ink (--data-lcap), so the number IS the slider colour. */
  --data-lcap-dose: 0.8;
}

/* Sport voice: crisper radii, heavier display type, zero glow */
html[data-theme="sport"] .card { border-radius: 16px; }
html[data-theme="sport"] .h-display { font-weight: 800; letter-spacing: -0.04em; }
html[data-theme="sport"] .tab.active .tab-bg { box-shadow: none; }
html[data-theme="sport"] .btn-lime:hover { box-shadow: 0 2px 10px rgba(var(--accent-rgb),0.35); }
html[data-theme="sport"] .ambient-glow { opacity: 0.12; }

/* ─── Light accent treatments (Sport theme) ─── */
/* Green stays the left/primary accent. */
html[data-theme="sport"][data-accent="green"] {
  --lime: #c2e82e; --lime-dim: #9dbd1d;
  --accent-rgb: 194,232,46; --on-accent: #16240a;
  --lime-soft: rgba(194,232,46,0.2); --accent-glow: rgba(194,232,46,0.4);
  --accent-text: #4f7c00;
}
html[data-theme="sport"][data-accent="blue"] {
  --lime: #2f6fed; --lime-dim: #1e5bd6;
  --accent-rgb: 47,111,237; --on-accent: #ffffff;
  --lime-soft: rgba(47,111,237,0.12); --accent-glow: rgba(47,111,237,0.24);
  --accent-text: #1a54c4;
}
/* Volt — NRC-style vivid yellow, black ink on fills. */
html[data-theme="sport"][data-accent="volt"] {
  --lime: #f2d21e; --lime-dim: #d9b400;
  --accent-rgb: 242,210,30; --on-accent: #1a1400;
  --lime-soft: rgba(242,210,30,0.2); --accent-glow: rgba(242,210,30,0.4);
  --accent-text: #f2d21e;
  /* Only the on-tint tone moves: #f2d21e reads on the card but measured 1.14:1
     on its own accent tint. Same hue at L~0.50 gives 4.68:1. */
  --accent-text-on-tint: #7c5d00;
}
/* Kelly — vivid sprint green, dark ink on fills. */
html[data-theme="sport"][data-accent="kelly"] {
  --lime: #24c95a; --lime-dim: #17a648;
  --accent-rgb: 36,201,90; --on-accent: #05230f;
  --lime-soft: rgba(36,201,90,0.14); --accent-glow: rgba(36,201,90,0.3);
  --accent-text: #0d7a33;
}
html[data-theme="sport"][data-accent="orange"] {
  --lime: #f2820a; --lime-dim: #d66d00;
  --accent-rgb: 242,130,10; --on-accent: #201200;
  --lime-soft: rgba(242,130,10,0.14); --accent-glow: rgba(242,130,10,0.3);
  --accent-text: #ad5a00;
}
html[data-theme="sport"][data-accent="magenta"] {
  --lime: #e0389f; --lime-dim: #c2217f;
  --accent-rgb: 224,56,159; --on-accent: #ffffff;
  --lime-soft: rgba(224,56,159,0.12); --accent-glow: rgba(224,56,159,0.26);
  --accent-text: #b81f7e;
}
html[data-theme="sport"][data-accent="cyan"] {
  --lime: #0fb5b0; --lime-dim: #0a938f;
  --accent-rgb: 15,181,176; --on-accent: #032120;
  --lime-soft: rgba(15,181,176,0.13); --accent-glow: rgba(15,181,176,0.28);
  --accent-text: #007d7a;
}
html[data-theme="sport"][data-accent="violet"] {
  --lime: #7a4fe0; --lime-dim: #6238c4;
  --accent-rgb: 122,79,224; --on-accent: #ffffff;
  --lime-soft: rgba(122,79,224,0.12); --accent-glow: rgba(122,79,224,0.26);
  --accent-text: #6538c9;
}
/* Ink — monochrome black accent, white ink on fills. */
html[data-theme="sport"][data-accent="ink"] {
  --lime: #17181c; --lime-dim: #000000;
  --accent-rgb: 23,24,28; --on-accent: #ffffff;
  --lime-soft: rgba(23,24,28,0.08); --accent-glow: rgba(23,24,28,0.18);
  --accent-text: #17181c;
}

* { box-sizing: border-box; -webkit-font-smoothing: antialiased; }

body {
  margin: 0;
  /* Interface face — matches the shipped app (src/theme/variables.css
     --pp-font-sans). Manrope is the default; Tweaks can swap it live. */
  font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', system-ui, sans-serif;
  color: var(--text);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  background: var(--body-bg);
}

.mono { font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace; }

/* ═════════ App surface ═════════ */
.app {
  position: absolute;
  inset: 0;
  background: var(--bg);
  overflow: hidden;
  border-radius: 48px;
  color: var(--text);
  display: flex;
  flex-direction: column;
}

.app-scroll {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
  padding-bottom: 110px;
}
.app-scroll::-webkit-scrollbar { display: none; }

.today-notifications-list { scrollbar-width: none; }
.today-notifications-list::-webkit-scrollbar { display: none; }

/* ═════════ Liquid glass building blocks ═════════ */
.glass {
  background: var(--glass-bg);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  border: 0.5px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
}

.glass-strong {
  background: var(--glass-strong-bg);
  backdrop-filter: blur(30px) saturate(200%);
  -webkit-backdrop-filter: blur(30px) saturate(200%);
  border: 0.5px solid var(--glass-strong-border);
  box-shadow: var(--glass-strong-shadow);
}

.card {
  background: var(--bg-1);
  border: 0.5px solid var(--line);
  border-radius: 24px;
  box-shadow: var(--card-shadow);
}

/* ═════════ Typography ═════════ */
.eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 500;
}

.h-display {
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
}

.h-title {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.h-section {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* ═════════ Tab bar (floating glass) ═════════ */
.tabbar {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 26px;
  height: 66px;
  border-radius: 999px;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 0 14px;
}

.tab {
  flex: 1;
  height: 54px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.2s;
  color: var(--text-2);
  position: relative;
}

.tab.active {
  color: var(--on-accent);
}
.tab.active .tab-bg {
  position: absolute;
  inset: 8px;
  background: var(--lime);
  border-radius: 999px;
  box-shadow: 0 0 24px var(--accent-glow);
}
.tab-icon { position: relative; z-index: 1; }

/* ═════════ Buttons ═════════ */
.btn-lime {
  background: var(--lime);
  color: var(--on-accent);
  border: none;
  border-radius: 999px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.1s, box-shadow 0.2s;
  box-shadow: 0 0 0 rgba(0,0,0,0);
}
.btn-lime:hover { box-shadow: 0 8px 24px var(--accent-glow); }
.btn-lime:active { transform: scale(0.98); }

.btn-ghost {
  background: transparent;
  border: 0.5px solid var(--line-2);
  color: var(--text);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s;
}
.btn-ghost:hover { background: var(--w04); }

/* ═════════ Micro animations ═════════ */
@keyframes pulseLime {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb),0.35); }
  50% { box-shadow: 0 0 0 10px rgba(var(--accent-rgb),0); }
}
.pulse-lime { animation: pulseLime 2.2s ease-out infinite; }

@keyframes shimmer {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

@keyframes screenIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
.screen { animation: screenIn 0.28s ease-out; }

@keyframes slideUp {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ═════════ Progress ring ═════════ */
.ring-track { stroke: var(--ring-track); }
.ring-fill { stroke: var(--lime); stroke-linecap: round; transition: stroke-dashoffset 0.6s ease; }

/* ═════════ Ambient lime glow ═════════ */
.ambient-glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  pointer-events: none;
  opacity: 0.5;
}

/* Canvas layout */
.canvas {
  display: flex;
  gap: 60px;
  padding: 60px 40px;
  align-items: flex-start;
  flex-wrap: wrap;
  justify-content: center;
}

.phone-wrap {
  position: relative;
  width: 402px;
  height: 874px;
  flex-shrink: 0;
}
.phone-label {
  position: absolute;
  top: -32px;
  left: 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* Header greeting */
.header-pad { padding: 62px 20px 0; }

/* Injection site dots */
.site-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid var(--bg);
  position: absolute;
  box-shadow: 0 0 0 1.5px var(--lime);
  background: var(--lime);
}
.site-dot.recent { background: var(--lime); }
.site-dot.old { background: rgba(var(--accent-rgb),0.25); box-shadow: 0 0 0 1px rgba(var(--accent-rgb),0.5); }

/* Vial */
.vial {
  width: 58px;
  height: 140px;
  border-radius: 14px 14px 20px 20px;
  position: relative;
  overflow: hidden;
  background: linear-gradient(to bottom, rgba(255,255,255,0.04), rgba(255,255,255,0.08));
  border: 0.5px solid rgba(255,255,255,0.15);
}
.vial-cap {
  position: absolute;
  top: 0; left: 8px; right: 8px;
  height: 18px;
  background: linear-gradient(to bottom, #2a2d28, #1a1c18);
  border-radius: 8px 8px 2px 2px;
  border-bottom: 0.5px solid rgba(255,255,255,0.12);
}
.vial-liquid {
  position: absolute;
  bottom: 0; left: 3px; right: 3px;
  background: linear-gradient(to top, var(--lime), rgba(var(--accent-rgb),0.6));
  border-radius: 0 0 16px 16px;
  box-shadow: inset 0 8px 20px rgba(255,255,255,0.15);
}
.vial-label {
  position: absolute;
  top: 40%; left: 3px; right: 3px;
  height: 32px;
  background: rgba(255,255,255,0.06);
  backdrop-filter: blur(10px);
  border-top: 0.5px solid rgba(255,255,255,0.15);
  border-bottom: 0.5px solid rgba(255,255,255,0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: rgba(255,255,255,0.9);
}

/* ═════════ Press (touch-down) states ═════════
   One contract for every tappable surface: a veil taken from the theme's overlay
   ramp (white on Dark, ink on Sport) plus a small scale-down. The veil is an
   ::after layer, so it never collides with the inline styles components carry.
     .press        base — veil + scale 0.97
     .press-fill   accent/filled controls — the veil darkens instead of lightening
     .press-deep   small circular controls — presses further (0.93)
     .press-flat   large surfaces (rows, cards, tabs) — veil only, no scale
     .is-pressed   forces the state on (documentation)
     .pp-press-on / body.pp-force-press  force every descendant pressed (testing)
   .btn-lime / .btn-ghost / .tab press without needing the class. */
:root { --press-veil: rgba(255,255,255,0.11); --press-veil-fill: rgba(0,0,0,0.16); }
html[data-theme="sport"] { --press-veil: rgba(17,17,19,0.08); --press-veil-fill: rgba(0,0,0,0.13); }
.press, .btn-lime, .btn-ghost { position: relative; }
.press, .btn-lime, .btn-ghost, .tab, .tab-fab { --press-scale: 0.97; -webkit-tap-highlight-color: transparent; }
.press, .btn-lime, .btn-ghost, .tab-fab { transition: transform 0.13s cubic-bezier(0.2,0.7,0.3,1), box-shadow 0.18s ease, background 0.15s ease; }
.press::after, .btn-lime::after, .btn-ghost::after, .tab::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: var(--press-veil); opacity: 0; pointer-events: none; z-index: 3;
  transition: opacity 0.12s ease;
}
.press-fill::after, .btn-lime::after { background: var(--press-veil-fill); }
.tab::after { inset: 8px; }
.press-deep { --press-scale: 0.93; }
.press-card { --press-scale: 0.98; }
.press-flat { --press-scale: 1; }
.press:active, .btn-lime:active, .btn-ghost:active, .tab:active { transform: scale(var(--press-scale)); }
.press:active::after, .btn-lime:active::after, .btn-ghost:active::after, .tab:active::after { opacity: 1; }
.press:disabled:active, .btn-lime:disabled:active { transform: none; }
.tab-fab { transform: translateY(-2px); }
.tab-fab:active { transform: translateY(-2px) scale(var(--press-scale)); }
/* forced (docs + testing) */
.is-pressed::after { opacity: 1; }
.is-pressed { transform: scale(var(--press-scale, 0.97)); }
:where(.pp-press-on, body.pp-force-press) :is(.press, .btn-lime, .btn-ghost, .tab)::after { opacity: 1; }
:where(.pp-press-on, body.pp-force-press) :is(.press, .btn-lime, .btn-ghost) { transform: scale(var(--press-scale)); }
:where(.pp-press-on, body.pp-force-press) :is(.press, .btn-lime):disabled { transform: none; }
:where(.pp-press-on, body.pp-force-press) :is(.press, .btn-lime, .btn-ghost):disabled::after, .is-pressed:disabled::after { opacity: 0; }
.tab-fab.is-pressed, :where(.pp-press-on, body.pp-force-press) .tab-fab { transform: translateY(-2px) scale(var(--press-scale)); }

/* Default link colors (users may add links via the editor) */
a { color: var(--lime-dim); text-decoration: none; }
a:hover { color: var(--lime); }
html[data-theme="sport"] a { color: var(--accent-text); }
html[data-theme="sport"] a:hover { color: var(--text); }
