/* HearMark — shared design system
   Calm, audio-first, editorial. Bricolage Grotesque headings, Geist for the
   interface and the wordmark, Geist Mono for labels/numerals, Instrument Serif
   italic as a sparing editorial accent. Two themes: paper (light, default) and
   ink (dark, [data-theme="ink"]).

   Fonts are SELF-HOSTED (see assets/fonts/) so text renders instantly, offline,
   and under CSP — the native Capacitor shell runs from a local origin with no
   guaranteed network, where a CDN @import would FOIT or silently fall back to
   system fonts. Each family ships a `latin` + `latin-ext` woff2 subset.
*/

/* ---------- Self-hosted webfonts (SIL OFL 1.1 — see assets/fonts/LICENSES.txt) ---------- */
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/static/assets/fonts/Geist-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/static/assets/fonts/Geist-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("/static/assets/fonts/GeistMono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("/static/assets/fonts/GeistMono-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
  src: url("/static/assets/fonts/BricolageGrotesque-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
  src: url("/static/assets/fonts/BricolageGrotesque-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/assets/fonts/InstrumentSerif-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/assets/fonts/InstrumentSerif-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/static/assets/fonts/InstrumentSerif-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/static/assets/fonts/InstrumentSerif-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* ---------- Type families ---------- */
  --font-heading: "Bricolage Grotesque", "Geist", sans-serif; /* screen titles, section/card heads, modal/sheet titles */
  --sans: "Geist", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;  /* body, controls, content/episode titles, wordmark */
  --mono: "Geist Mono", "JetBrains Mono", ui-monospace, SFMono-Regular, monospace; /* eyebrows, labels, meta, numerals */
  --serif: "Instrument Serif", "Cormorant Garamond", Georgia, serif; /* sparing editorial italic accent only */

  /* ---------- Type scale (px) ---------- */
  --text-display: 48px;
  --text-h1: 36px;
  --text-h2: 28px;
  --text-h3: 20px;
  --text-body-lg: 16px;
  --text-body: 14px;
  --text-sm: 13px;
  --text-xs: 12px;
  --text-eyebrow: 10.5px;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  --leading-tight: 0.96;
  --leading-snug: 1.3;
  --leading-body: 1.55;

  --tracking-tight: -0.02em;
  --tracking-eyebrow: 0.14em;

  /* ---------- Colors — Paper (light, default) ---------- */
  --paper: oklch(0.985 0.004 80);
  --paper-2: oklch(0.965 0.006 75);
  --paper-3: oklch(0.94 0.008 70);
  --rule: oklch(0.86 0.008 70);
  --rule-soft: oklch(0.92 0.006 70);
  --ink: oklch(0.18 0.012 60);
  --ink-2: oklch(0.32 0.012 60);
  --ink-3: oklch(0.5 0.012 60);
  --ink-4: oklch(0.65 0.012 60);

  --amber: oklch(0.74 0.15 60);
  --amber-2: oklch(0.68 0.16 55);
  --amber-bg: oklch(0.94 0.04 75);

  --plum: oklch(0.5 0.09 300);
  --plum-2: oklch(0.4 0.09 295);
  --plum-bg: oklch(0.92 0.025 300);

  --ok: oklch(0.62 0.1 150);
  --ok-bg: oklch(0.93 0.04 150);
  --warn: oklch(0.7 0.14 70);
  --warn-bg: oklch(0.94 0.04 75);
  --err: oklch(0.55 0.18 25);
  --err-bg: oklch(0.94 0.04 25);

  /* ---------- Brand gradient — logo / app icon / hero art ONLY, never UI ---------- */
  --brand-blue: oklch(0.62 0.2 268);
  --brand-violet: oklch(0.58 0.22 310);
  --brand-ink: oklch(0.16 0.02 280);
  --brand-gradient: linear-gradient(150deg, var(--brand-blue), var(--brand-violet));

  /* ---------- Semantic aliases ---------- */
  --bg: var(--paper);
  --surface: var(--paper);
  --surface-raised: var(--paper-2);
  --surface-sunken: var(--paper-3);
  --border: var(--rule);
  --border-soft: var(--rule-soft);
  --text: var(--ink);
  --text-muted: var(--ink-3);
  --accent: var(--amber);
  --accent-strong: var(--amber-2);
  --on-accent: oklch(0.18 0.05 60); /* text on amber fills */

  /* ---------- Spacing (4px base) ---------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* ---------- Radii ---------- */
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-pill: 999px;

  /* ---------- Shadows — whisper-soft; the UI leans on hairline borders ---------- */
  --shadow-sm: 0 1px 0 oklch(0.85 0.008 70);
  --shadow: 0 1px 2px oklch(0.85 0.008 70 / 0.4), 0 4px 16px oklch(0.7 0.01 70 / 0.08);
  --shadow-lg: 0 2px 6px oklch(0.7 0.01 70 / 0.12), 0 18px 48px oklch(0.6 0.02 70 / 0.16);

  /* ---------- Tap-target floor (iOS/Android HIG) — enforce on native controls ---------- */
  --tap-min: 44px;
}

[data-theme="ink"] {
  --paper: oklch(0.155 0.012 280);
  --paper-2: oklch(0.195 0.014 280);
  --paper-3: oklch(0.235 0.014 280);
  --rule: oklch(0.3 0.014 280);
  --rule-soft: oklch(0.24 0.012 280);
  --ink: oklch(0.96 0.006 80);
  --ink-2: oklch(0.82 0.008 80);
  --ink-3: oklch(0.62 0.01 80);
  --ink-4: oklch(0.48 0.012 80);

  --amber: oklch(0.78 0.15 65);
  --amber-2: oklch(0.72 0.17 60);
  --amber-bg: oklch(0.28 0.06 60);

  --plum: oklch(0.72 0.1 300);
  --plum-2: oklch(0.62 0.1 295);
  --plum-bg: oklch(0.28 0.06 300);

  --ok: oklch(0.78 0.12 150);
  --ok-bg: oklch(0.28 0.05 150);
  --warn: oklch(0.78 0.14 70);
  --warn-bg: oklch(0.28 0.06 70);
  --err: oklch(0.7 0.16 25);
  --err-bg: oklch(0.3 0.06 25);

  --shadow-sm: 0 1px 0 oklch(0.1 0.012 280);
  --shadow: 0 1px 2px oklch(0 0 0 / 0.5), 0 8px 24px oklch(0 0 0 / 0.4);
  --shadow-lg: 0 2px 8px oklch(0 0 0 / 0.5), 0 24px 60px oklch(0 0 0 / 0.55);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* Make the hidden attribute unconditional — it must win even over classes
   that set display (e.g. .hm-modal-overlay's flex). All show/hide toggling
   uses `el.hidden` / the hidden attribute; CSP (style-src 'self') bans a
   style="display:none" inline escape hatch. JS must never fight this
   with el.style.display — toggle .hidden instead. */
[hidden] { display: none !important; }
/* Controls take taps, not double-tap zoom: two quick taps on a control (the
   15s rewind) act twice instead of zooming the page. Pinch-zoom is untouched. */
a, button, input, select, textarea, label, summary, [role="button"] { touch-action: manipulation; }
body {
  font-family: var(--sans);
  font-feature-settings: "ss01", "cv11";
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---------- Utilities ---------- */
.hm-mono { font-family: var(--mono); font-feature-settings: "ss01"; }
.hm-serif { font-family: var(--serif); font-style: italic; font-weight: 400; }
.hm-tnum { font-variant-numeric: tabular-nums; }
.hm-rule { border: none; border-top: 1px solid var(--rule-soft); margin: 0; }
.hm-hairline { background: var(--rule-soft); height: 1px; width: 100%; }

.hm-eyebrow {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ---------- Headings — Bricolage Grotesque (functional screen/section titles) ---------- */
.hm-h1 {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.02;
  color: var(--ink);
  margin: 0;
}
.hm-h2 {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.05;
  color: var(--ink);
  margin: 0;
}
/* Functional heading utility — use for screen titles, card section heads,
   modal/sheet titles. */
.hm-heading {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.1;
  color: var(--ink);
}

/* ---------- Buttons ---------- */
.hm-btn {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.005em;
  padding: 9px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: background 0.12s ease, border-color 0.12s ease, opacity 0.12s ease;
  white-space: nowrap;
  text-decoration: none;
}
.hm-btn:hover:not(:disabled) { background: var(--paper-2); }
.hm-btn:disabled { opacity: 0.55; cursor: not-allowed; }
.hm-btn--primary {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.hm-btn--primary:hover:not(:disabled) { background: var(--ink-2); border-color: var(--ink-2); }
.hm-btn--amber {
  background: var(--amber);
  color: var(--on-accent);
  border-color: var(--amber);
  font-weight: 600;
}
.hm-btn--amber:hover:not(:disabled) { background: var(--amber-2); border-color: var(--amber-2); }
.hm-btn--ghost { border-color: transparent; background: transparent; }
.hm-btn--ghost:hover:not(:disabled) { background: var(--paper-2); }
.hm-btn--danger {
  border-color: var(--err);
  color: var(--err);
  background: transparent;
}
.hm-btn--danger:hover:not(:disabled) { background: var(--err-bg); }
.hm-btn--lg { padding: 13px 22px; font-size: 14px; }
.hm-btn--sm { padding: 6px 11px; font-size: 12px; }
.hm-btn--block { width: 100%; }

/* ---------- Badges ---------- */
.hm-badge {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 4px;
  background: var(--paper-3);
  color: var(--ink-3);
  border: 1px solid var(--rule-soft);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}
.hm-badge--amber { background: var(--amber-bg); color: var(--amber-2); border-color: transparent; }
.hm-badge--ok { background: var(--ok-bg); color: var(--ok); border-color: transparent; }
.hm-badge--plum { background: var(--plum-bg); color: var(--plum-2); border-color: transparent; }
.hm-badge--warn { background: var(--warn-bg); color: var(--warn); border-color: transparent; }
.hm-badge--err { background: var(--err-bg); color: var(--err); border-color: transparent; }

/* ---------- Chips (toggle filters) ----------
   ONE chip. The feed's All/Downloaded pills and the voice picker's filter chips are
   the same control and share this base. Two near-identical implementations
   (index.css) would drift: different padding and — worse — two different state
   conventions, `.is-active` vs `[aria-pressed="true"]`, so a contrast or theme fix would
   need applying twice and a screen reader would hear the state of only one of them.

   The convention is `aria-pressed`, because these ARE toggle buttons: the attribute is
   the state (announced by AT), and the style follows it. A chip styled by a class an
   assistive tech can't see is a chip that looks pressed and doesn't say so. */
.hm-chip {
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 500;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.hm-chip:hover { background: var(--paper); color: var(--ink); }
.hm-chip[aria-pressed="true"] {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

/* ---------- Inputs ---------- */
.hm-input,
input.hm-input,
textarea.hm-input,
select.hm-input {
  font-family: var(--sans);
  font-size: 14px;
  padding: 11px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--paper);
  color: var(--ink);
  outline: none;
  width: 100%;
  transition: border-color 0.12s ease;
}
.hm-input:focus { border-color: var(--ink-3); }
.hm-input::placeholder { color: var(--ink-4); }
textarea.hm-input { resize: vertical; min-height: 80px; }
/* Native shells only: bump inputs to 16px so iOS doesn't auto-zoom-on-focus
   (it zooms any focused control with font-size < 16px, which then pans the page
   horizontally — the "login scroll" bug). Web keeps 14px. */
html[data-hm-native] .hm-input { font-size: 16px; }

.hm-label {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  display: block;
  margin-bottom: 6px;
}

/* ---------- Wordmark — Geist bold, tight tracking (deliberately not the serif) ---------- */
.hm-wordmark-row {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}
.hm-wordmark-icon {
  display: block;
  border-radius: 22%;
}
.hm-wordmark {
  font-family: var(--sans);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--ink);
}
/* Size variants — icon = round(1.05 × font size). Classes, not
   per-instance inline width/font-size styles (CSP: style-src 'self' bans
   style="" attributes); the wordmark markup is written directly in each
   page's HTML with the matching variant class. */
.hm-wordmark-row--16 .hm-wordmark { font-size: 16px; }
.hm-wordmark-row--16 .hm-wordmark-icon { width: 17px; height: 17px; }
.hm-wordmark-row--18 .hm-wordmark { font-size: 18px; }
.hm-wordmark-row--18 .hm-wordmark-icon { width: 19px; height: 19px; }
.hm-wordmark-row--20 .hm-wordmark { font-size: 20px; }
.hm-wordmark-row--20 .hm-wordmark-icon { width: 21px; height: 21px; }
.hm-wordmark-row--22 .hm-wordmark { font-size: 22px; }
.hm-wordmark-row--22 .hm-wordmark-icon { width: 23px; height: 23px; }
/* On the dark auth-hero panes the wordmark reads in warm off-white. */
.hm-wordmark-row--light .hm-wordmark { color: oklch(0.96 0.006 80); }

/* ---------- Wave (animated) ---------- */
.hm-wave {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: 18px;
}
.hm-wave > i {
  display: block;
  width: 2px;
  background: var(--amber);
  border-radius: 1px;
  animation: hmwave 1.2s ease-in-out infinite;
}
.hm-wave > i:nth-child(1) { height: 30%; animation-delay: 0s; }
.hm-wave > i:nth-child(2) { height: 65%; animation-delay: 0.1s; }
.hm-wave > i:nth-child(3) { height: 100%; animation-delay: 0.2s; }
.hm-wave > i:nth-child(4) { height: 80%; animation-delay: 0.15s; }
.hm-wave > i:nth-child(5) { height: 50%; animation-delay: 0.05s; }
.hm-wave > i:nth-child(6) { height: 30%; animation-delay: 0.18s; }
.hm-wave--static > i { animation: none; }

@keyframes hmwave {
  0%, 100% { transform: scaleY(0.5); }
  50% { transform: scaleY(1); }
}

/* ---------- Static waveform (built by JS) ----------
   HM.buildWaveform() emits bars with data-h geometry;
   HM.hydrateWaveforms() applies it via CSSOM (inline style attributes are
   CSP-blocked, el.style writes are not). */
.hm-waveform {
  display: flex;
  align-items: center;
  gap: 2px;
}
.hm-waveform > span {
  display: block;
  width: 2px;
  background: var(--ink-4);
  border-radius: 1px;
  opacity: 0.55;
}
.hm-waveform > span.is-played {
  background: var(--amber);
  opacity: 1;
}

/* ---------- Icon glyphs (HM.icon / data-hm-icon) ---------- */
.hm-icon-svg {
  display: inline-block;
  flex-shrink: 0;
  vertical-align: middle;
}

/* ---------- Spinner ---------- */
.hm-spinner {
  display: inline-block;
  vertical-align: middle;
}
.hm-spinner-track { stroke: var(--rule); }
.hm-spinner-arc {
  stroke: var(--amber);
  stroke-dasharray: 10 30;
  transform-origin: center;
  animation: hmspin 1s linear infinite;
}
@keyframes hmspin { to { transform: rotate(360deg); } }

/* ---------- Don't animate an invisible tab ----------
   A backgrounded tab paints nothing, but its `infinite` animations keep
   ticking the style/animation machinery, and a throttled background tab does
   that work in periodic batches — a measurable CPU pulse in a tab the user
   isn't even looking at. HearMark holds several long-lived infinite animations
   (the generating-strip spinner + progress shimmer, feed-row status badges),
   and a job that never terminalises (#313) keeps them alive indefinitely.

   `data-hm-hidden` is stamped on <html> from the visibilitychange handler in
   hm.js. Pausing is the right verb, not stopping: state is preserved, so
   returning to the tab resumes mid-cycle with no visible jump. The universal
   selector is deliberate — it covers animations nobody remembers declaring,
   which is exactly the failure mode here. It only ever matches while hidden,
   so the extra style work costs one recalc per visibility change.
   Pinned by tests/browser/test_idle_cpu.py. */
html[data-hm-hidden] *,
html[data-hm-hidden] *::before,
html[data-hm-hidden] *::after {
  animation-play-state: paused !important;
}

/* ---------- Striped placeholder ---------- */
.hm-placeholder {
  background: repeating-linear-gradient(135deg, var(--paper-2), var(--paper-2) 6px, var(--paper-3) 6px, var(--paper-3) 12px);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ---------- Scrollbars ---------- */
.hm-scroll::-webkit-scrollbar { width: 8px; height: 8px; }
.hm-scroll::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 4px; }
.hm-scroll::-webkit-scrollbar-track { background: transparent; }

/* ---------- Cards ---------- */
.hm-card {
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius);
  background: var(--paper);
  padding: 16px 20px;
}

/* ---------- Theme toggle button (small) ---------- */
.hm-theme-toggle {
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  padding: 5px 8px;
  cursor: pointer;
  color: var(--ink-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.12s ease, color 0.12s ease;
}
.hm-theme-toggle:hover { border-color: var(--ink-3); color: var(--ink); }

/* ---------- Modal overlay ---------- */
.hm-modal-overlay {
  position: fixed;
  inset: 0;
  background: oklch(0.1 0.01 280 / 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 24px;
}
[data-theme="ink"] .hm-modal-overlay { background: oklch(0 0 0 / 0.6); }
.hm-modal {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: 28px 32px;
  max-width: 480px;
  width: 100%;
  max-height: calc(100vh - 48px);
  max-height: calc(100dvh - 48px);
  overflow-y: auto;
  box-shadow: var(--shadow);
}
.hm-modal h3 {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 24px;
  letter-spacing: -0.015em;
  margin: 0 0 12px;
  color: var(--ink);
}
.hm-modal p {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0 0 12px;
}
.hm-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}

/* ---------- Toast ---------- */
.hm-toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  max-width: 380px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 14px 18px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-2);
  box-shadow: var(--shadow);
  z-index: 1100;
  animation: hmtoast 0.18s ease-out;
}
.hm-toast strong { color: var(--ink); display: block; margin-bottom: 4px; font-weight: 600; }
.hm-toast-close {
  position: absolute;
  top: 8px;
  right: 10px;
  background: transparent;
  border: none;
  font-size: 18px;
  color: var(--ink-3);
  cursor: pointer;
  padding: 0;
  line-height: 1;
}
@keyframes hmtoast {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- Links ---------- */
.hm-link {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.hm-link:hover { color: var(--amber-2); }
