/* styles.css — "Vital" design system for Nurse CNE */

:root {
  /* light theme — bone & jade */
  --bg:        oklch(0.985 0.004 90);
  --bg-2:      oklch(0.965 0.005 90);
  --surface:   #ffffff;
  --surface-2: oklch(0.975 0.004 90);
  --border:    oklch(0.91 0.005 90);
  --border-strong: oklch(0.85 0.006 90);
  --fg:        oklch(0.20 0.015 70);
  --fg-2:      oklch(0.45 0.012 70);
  --fg-3:      oklch(0.62 0.010 70);
  --primary:        oklch(0.42 0.06 175);
  --primary-ink:    #ffffff;
  --primary-soft:   oklch(0.92 0.025 175);
  --primary-soft-2: oklch(0.97 0.012 175);
  --accent:        oklch(0.68 0.10 50);
  --accent-soft:   oklch(0.94 0.04 50);
  --success: oklch(0.62 0.10 150);
  --warning: oklch(0.78 0.13 80);
  --danger:  oklch(0.58 0.16 25);

  --shadow-sm: 0 1px 2px rgba(20, 20, 14, 0.04);
  --shadow:    0 2px 6px rgba(20, 20, 14, 0.05), 0 1px 2px rgba(20, 20, 14, 0.04);
  --shadow-lg: 0 14px 32px -10px rgba(20, 20, 14, 0.18), 0 6px 14px -6px rgba(20, 20, 14, 0.10);

  --radius-sm: 8px;
  --radius:    14px;
  --radius-lg: 20px;
  --radius-xl: 28px;

  --font-sans:  'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-serif: 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:  'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --pad: 18px;       /* density-controlled */
  --gap: 14px;
}

[data-theme='dark'] {
  --bg:        oklch(0.16 0.01 70);
  --bg-2:      oklch(0.20 0.012 70);
  --surface:   oklch(0.22 0.012 70);
  --surface-2: oklch(0.25 0.012 70);
  --border:    oklch(0.30 0.008 70);
  --border-strong: oklch(0.40 0.008 70);
  --fg:        oklch(0.96 0.004 90);
  --fg-2:      oklch(0.72 0.008 70);
  --fg-3:      oklch(0.55 0.008 70);
  --primary:        oklch(0.72 0.08 175);
  --primary-ink:    oklch(0.18 0.02 175);
  --primary-soft:   oklch(0.30 0.04 175);
  --primary-soft-2: oklch(0.24 0.02 175);
  --accent:        oklch(0.78 0.10 50);
  --accent-soft:   oklch(0.30 0.05 50);
  --shadow:    0 2px 6px rgba(0,0,0, 0.3), 0 1px 2px rgba(0,0,0, 0.2);
  --shadow-lg: 0 14px 32px -10px rgba(0,0,0, 0.5);
}

[data-theme='ocean'] {
  --primary:        oklch(0.45 0.09 240);
  --primary-soft:   oklch(0.93 0.03 240);
  --primary-soft-2: oklch(0.97 0.015 240);
  --accent:        oklch(0.68 0.11 30);
  --accent-soft:   oklch(0.94 0.04 30);
}

[data-theme='dusk'] {
  --primary:        oklch(0.45 0.09 320);
  --primary-soft:   oklch(0.94 0.03 320);
  --primary-soft-2: oklch(0.97 0.015 320);
  --accent:        oklch(0.72 0.10 70);
  --accent-soft:   oklch(0.94 0.04 70);
}

[data-density='compact'] { --pad: 14px; --gap: 10px; }
[data-density='comfy']   { --pad: 22px; --gap: 18px; }

/* ─────────────────── base ─────────────────── */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.app {
  width: 100%;
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* ─────────────────── Page stack (tab ↔ detail overlay) ───────────────────
 * The tab screens (Home/Discover/Record/Profile) stay mounted whether or
 * not a course detail is open — the detail layer is positioned over the
 * top of them. Keeping the tab in the DOM is what preserves the user's
 * scroll position on back navigation without any save/restore logic.
 * ──────────────────────────────────────────────────────────────────── */
.page-stack {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.page-layer {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.page-layer--tab {
  flex: 1;
}
.page-layer--tab.is-hidden {
  /* Hide visually without unmounting — scrollTop on inner .scroll
   * elements is preserved while the detail layer sits on top. */
  visibility: hidden;
  pointer-events: none;
}
.page-layer--detail {
  position: absolute;
  inset: 0;
  background: var(--bg);
  z-index: 5;
  animation: page-slide-in 220ms cubic-bezier(0.2, 0.7, 0.1, 1);
}
@keyframes page-slide-in {
  from { transform: translateX(6px); opacity: 0; }
  to   { transform: translateX(0);   opacity: 1; }
}

.scroll {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.scroll::-webkit-scrollbar { display: none; }

/* ─────────────────── typography ─────────────────── */
.serif { font-family: var(--font-serif); font-weight: 500; letter-spacing: -0.012em; }
.mono  { font-family: var(--font-mono);  letter-spacing: -0.01em; }
.eyebrow {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--fg-3);
  font-weight: 500;
}
.h-greet { font-size: 13px; color: var(--fg-2); font-weight: 400; }
.h-screen {
  font-family: var(--font-serif);
  font-size: 32px;
  line-height: 1.08;
  letter-spacing: -0.018em;
  font-weight: 500;
  color: var(--fg);
}
.h-section {
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.012em;
  color: var(--fg);
  line-height: 1.15;
}
.h-row {
  font-size: 15px;
  font-weight: 500;
  color: var(--fg);
  line-height: 1.3;
  text-wrap: pretty;
}
.muted   { color: var(--fg-2); }
.muted-2 { color: var(--fg-3); }

/* ─────────────────── status bar shim ─────────────────── */
.bar { padding: 0 20px; }

/* ─────────────────── top header ─────────────────── */
.top {
  padding: 56px 20px 8px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}
.top.compact { padding-top: 56px; padding-bottom: 4px; }

.icon-btn {
  width: 38px; height: 38px;
  border-radius: 12px;
  border: 0.5px solid var(--border);
  background: var(--surface);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--fg);
  cursor: pointer;
  transition: transform .12s ease, background .12s ease;
}
.icon-btn:hover { background: var(--surface-2); }
.icon-btn:active { transform: scale(0.96); }
.icon-btn .dot {
  position: absolute; top: 8px; right: 8px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  border: 1.5px solid var(--surface);
}

.avatar {
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--primary-soft);
  color: var(--primary);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-sans);
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.01em;
  border: 0.5px solid var(--border);
}

/* ─────────────────── chips ─────────────────── */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  background: var(--surface-2);
  color: var(--fg-2);
  border: 0.5px solid var(--border);
  white-space: nowrap;
}
.chip.solid {
  background: var(--primary);
  color: var(--primary-ink);
  border-color: transparent;
}
.chip.ghost { background: transparent; }
.chip.lg { padding: 6px 12px; font-size: 12px; }

.filter-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 500;
  background: var(--surface);
  color: var(--fg-2);
  border: 0.5px solid var(--border);
  cursor: pointer;
  white-space: nowrap;
  transition: all .12s;
}
.filter-chip:hover { color: var(--fg); }
.filter-chip.on {
  background: var(--fg);
  color: var(--bg);
  border-color: var(--fg);
}

/* ─────────────────── cards ─────────────────── */
.card {
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: var(--radius);
  padding: var(--pad);
}

.card.flush { padding: 0; overflow: hidden; }

.card-row {
  display: flex; gap: 14px; align-items: stretch;
  padding: 14px var(--pad);
  border-bottom: 0.5px solid var(--border);
  cursor: pointer;
  transition: background .12s;
}
.card-row:last-child { border-bottom: 0; }
.card-row:hover { background: var(--surface-2); }

/* ─────────────────── buttons ─────────────────── */
.btn {
  appearance: none;
  border: 0;
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  padding: 13px 18px;
  border-radius: 12px;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  transition: transform .12s, background .12s, opacity .12s;
}
.btn:active { transform: scale(0.985); }

.btn-primary {
  background: var(--primary);
  color: var(--primary-ink);
}
.btn-primary:hover { opacity: 0.92; }

.btn-ghost {
  background: var(--surface);
  color: var(--fg);
  border: 0.5px solid var(--border);
}
.btn-ghost:hover { background: var(--surface-2); }

.btn-fill {
  display: flex;
  width: 100%;
}

/* ─────────────────── tab bar ─────────────────── */
.tab-bar {
  position: relative;
  height: 86px;
  flex-shrink: 0;
  background: color-mix(in oklch, var(--surface) 75%, transparent);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border-top: 0.5px solid var(--border);
  display: flex;
  align-items: flex-start;
  padding: 8px 6px 0;
}
.tab {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  padding-top: 6px;
  gap: 3px;
  cursor: pointer;
  color: var(--fg-3);
  background: transparent;
  border: 0;
  font-family: inherit;
  transition: color .12s;
}
.tab span {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.tab.on { color: var(--primary); }
.tab.fab {
  flex: 0 0 64px;
}
.tab .fab-circle {
  width: 50px; height: 50px;
  border-radius: 50%;
  background: var(--fg);
  color: var(--bg);
  display: flex; align-items: center; justify-content: center;
  margin-top: -10px;
  box-shadow: var(--shadow-lg);
}

/* ─────────────────── progress ─────────────────── */
.progress-bar {
  height: 6px;
  background: var(--bg-2);
  border-radius: 999px;
  overflow: hidden;
}
.progress-bar > div {
  height: 100%;
  background: var(--primary);
  border-radius: 999px;
  transition: width .4s ease;
}

/* ─────────────────── divider ─────────────────── */
.hr { height: 0.5px; background: var(--border); margin: 0; border: 0; }

/* ─────────────────── topic tint utilities ─────────────────── */
.topic-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
}
.topic-pill::before {
  content: '';
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
}

/* ─────────────────── points wallet hero ─────────────────── */
.wallet {
  position: relative;
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px;
  overflow: hidden;
}
.wallet::after {
  content: '';
  position: absolute;
  right: -40px; top: -40px;
  width: 160px; height: 160px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, var(--primary-soft) 0%, transparent 70%);
  pointer-events: none;
}
.wallet-num {
  font-family: var(--font-serif);
  font-size: 56px;
  line-height: 0.95;
  letter-spacing: -0.028em;
  color: var(--fg);
  font-weight: 500;
  font-feature-settings: 'tnum';
  font-variant-numeric: tabular-nums;
}
.wallet-num .of {
  font-size: 28px;
  color: var(--fg-3);
  margin-left: 6px;
}

/* ─────────────────── timeline ─────────────────── */
.timeline {
  position: relative;
  padding-left: 22px;
}
.timeline::before {
  content: '';
  position: absolute;
  left: 6px; top: 6px; bottom: 6px;
  width: 1px;
  background: var(--border);
}
.tl-item {
  position: relative;
  padding: 0 0 18px 0;
}
.tl-item::before {
  content: '';
  position: absolute;
  left: -22px; top: 6px;
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--border-strong);
}
.tl-item.done::before {
  background: var(--primary);
  border-color: var(--primary);
}
.tl-item.up::before {
  background: var(--accent);
  border-color: var(--accent);
}

/* ─────────────────── bottom sheet (modal) ─────────────────── */
.sheet-backdrop {
  position: absolute; inset: 0;
  background: rgba(20, 20, 14, 0.36);
  z-index: 100;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  animation: fadeIn .2s;
}
.sheet {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  background: var(--bg);
  border-top-left-radius: 28px;
  border-top-right-radius: 28px;
  box-shadow: 0 -10px 40px rgba(0,0,0,0.18);
  z-index: 101;
  max-height: 90%;
  display: flex; flex-direction: column;
  animation: slideUp .28s cubic-bezier(.18,.7,.2,1);
  overflow: hidden;
}
.sheet-handle {
  width: 38px; height: 5px; border-radius: 3px;
  background: var(--border-strong);
  margin: 8px auto 0;
  flex-shrink: 0;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }

/* ─────────────────── form fields ─────────────────── */
.field {
  display: flex; flex-direction: column; gap: 6px;
}
.field-label {
  font-size: 12px;
  color: var(--fg-2);
  font-weight: 500;
}
.field-input {
  appearance: none;
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: 12px;
  padding: 13px 14px;
  font-family: inherit;
  font-size: 15px;
  color: var(--fg);
  outline: none;
  transition: border-color .12s, background .12s;
}
.field-input:focus {
  border-color: var(--primary);
  background: var(--surface);
}
.field-input::placeholder { color: var(--fg-3); }

.search-bar {
  position: relative;
  display: flex; align-items: center;
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: 12px;
  padding: 0 12px;
  height: 42px;
}
.search-bar input {
  appearance: none;
  border: 0;
  background: transparent;
  flex: 1;
  outline: none;
  font-family: inherit;
  font-size: 14px;
  color: var(--fg);
  margin-left: 8px;
}
.search-bar input::placeholder { color: var(--fg-3); }

/* ─────────────────── Pills row (no-scroll-bar) ─────────────────── */
.scroll-x {
  display: flex; gap: 10px;
  overflow-x: auto;
  -ms-overflow-style: none;
  scrollbar-width: none;
  padding: 4px 20px 8px;
  margin: 0 -20px;
  scroll-padding: 20px;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.scroll-x::-webkit-scrollbar { display: none; }

/* ─────────────────── Course card (large list) ─────────────────── */
.course-card {
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  cursor: pointer;
  display: flex; flex-direction: column; gap: 10px;
  transition: transform .15s ease, border-color .12s;
}
.course-card:hover { border-color: var(--border-strong); }
.course-card:active { transform: scale(0.99); }

/* Expired courses dim slightly so they read as historical without disappearing. */
.course-card.is-ended {
  opacity: 0.72;
  background: var(--surface-2);
}
.course-card.is-ended h4 { color: var(--fg-2); }

.course-card .row {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}
.course-card h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.003em;
  color: var(--fg);
  text-wrap: pretty;
}
.course-card .meta {
  font-size: 12.5px;
  color: var(--fg-2);
}
.course-card .pts {
  font-family: var(--font-serif);
  font-size: 26px;
  font-weight: 500;
  line-height: 1;
  color: var(--fg);
  letter-spacing: -0.022em;
  font-variant-numeric: tabular-nums;
}
.course-card .pts-label {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin-top: 2px;
}

/* ─────────────────── small course card (horizontal scroll) ─────────────────── */
.mini-card {
  flex: 0 0 232px;
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: var(--radius);
  padding: 13px 14px 12px;
  display: flex; flex-direction: column; gap: 10px;
  cursor: pointer;
  min-height: 158px;
  transition: border-color .12s ease, transform .15s ease;
  scroll-snap-align: start;
}
.mini-card:hover { border-color: var(--border-strong); }
.mini-card:active { transform: scale(0.99); }
.mini-card .mc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}
.mini-card .mc-date {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-3);
  white-space: nowrap;
  flex-shrink: 0;
}
.mini-card h5 {
  margin: 0;
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.005em;
  color: var(--fg);
  text-wrap: pretty;
  /* clamp to 2 lines so long English titles don't stretch the row */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
  overflow-wrap: anywhere;
}
.mini-card .mc-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 10px;
  margin-top: auto;
  padding-top: 10px;
  border-top: 0.5px solid var(--border);
}
.mini-card .mc-provider {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--fg-2);
  font-size: 11.5px;
  min-width: 0;
}
.mini-card .mc-provider-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.mini-card .mc-pts {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  flex-shrink: 0;
}
.mini-card .mc-pts-num {
  font-size: 20px;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.mini-card .mc-pts-label {
  font-size: 9.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
}

/* ─────────────────── Detail screen ─────────────────── */
.detail-hero {
  padding: 0 20px 14px;
}
.detail-facts {
  margin: 0 20px;
  border: 0.5px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.fact-row {
  display: grid;
  grid-template-columns: 96px 1fr;
  align-items: start;
  padding: 12px 16px;
  border-bottom: 0.5px solid var(--border);
  font-size: 13.5px;
}
.fact-row:last-child { border-bottom: 0; }
.fact-row .k {
  color: var(--fg-3);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  padding-top: 3px;
}
.fact-row .v {
  color: var(--fg);
  font-weight: 500;
  text-wrap: pretty;
}

/* ─────────────────── Stick CTA ─────────────────── */
.cta-bar {
  position: absolute;
  left: 0; right: 0; bottom: 86px;
  padding: 12px 20px 14px;
  background: color-mix(in oklch, var(--bg) 70%, transparent);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border-top: 0.5px solid var(--border);
  display: flex; gap: 10px;
  z-index: 30;
}
.cta-bar.detail { bottom: 0; }

/* ─────────────────── ring (segmented progress) ─────────────────── */
.ring-num {
  font-family: var(--font-sans);
  font-size: 38px;
  font-weight: 500;
  line-height: 1;
  color: var(--fg);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum', 'cv11';
}

/* ─────────────────── empty + states ─────────────────── */
.dot-status { width: 6px; height: 6px; border-radius: 50%; display: inline-block; }

/* ─────────────────── animation utility ─────────────────── */
/* Subtle entrance — translates rather than fades so screenshot tools
   (and reduced-motion users) still see content at frame 0. */
.fade-in {
  animation: vital-slide-in .25s cubic-bezier(.2,.7,.2,1);
}
@keyframes vital-slide-in {
  from { transform: translateY(6px); }
  to   { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .fade-in { animation: none; }
}

/* ─────────────────── Vital brand lockup ─────────────────── */
.vital-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.vital-brand-v {
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
}
.vital-brand-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-soft);
  color: var(--primary);
  border-radius: 11px;
  flex-shrink: 0;
}
.vital-brand-text { min-width: 0; }
.vital-brand-name {
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.018em;
  line-height: 1;
  color: var(--fg);
}
.vital-brand-v .vital-brand-name { font-size: 24px; }
.vital-brand-tag {
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin-top: 3px;
}
.vital-brand-v .vital-brand-tag { font-size: 9.5px; letter-spacing: 0.20em; }

/* ─────────────────── Vital splash (loading) ─────────────────── */
.vital-splash {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  color: var(--fg);
  gap: 14px;
  z-index: 300;
}
.vital-splash-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 96px;
  height: 96px;
  color: var(--primary);
  position: relative;
}
/* The ring breathes (a soft scale + opacity pulse) */
.vs-ring {
  transform-origin: center;
  transform-box: fill-box;
  animation: vs-breathe 2.4s ease-in-out infinite;
}
/* The heartbeat path is always visible at low opacity (so the screenshot /
   first frame always has shape). A second copy on top sweeps a bright pulse
   across via a CSS mask, giving the "alive" feel. */
.vs-pulse-bg {
  opacity: 0.25;
}
.vs-pulse {
  -webkit-mask: linear-gradient(90deg, transparent 0%, #000 40%, #000 60%, transparent 100%);
          mask: linear-gradient(90deg, transparent 0%, #000 40%, #000 60%, transparent 100%);
  -webkit-mask-size: 60% 100%;
          mask-size: 60% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  animation: vs-sweep 2.4s ease-in-out infinite;
}
@keyframes vs-breathe {
  0%, 100% { opacity: 0.6; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.04); }
}
@keyframes vs-sweep {
  0%   { -webkit-mask-position: -60% 0; mask-position: -60% 0; }
  100% { -webkit-mask-position: 160% 0; mask-position: 160% 0; }
}
.vital-splash-name {
  font-size: 26px;
  letter-spacing: -0.022em;
  font-weight: 500;
  margin-top: 8px;
  color: var(--fg);
}
.vital-splash-label {
  font-size: 9.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--fg-3);
}
@media (prefers-reduced-motion: reduce) {
  .vs-ring  { animation: none; opacity: 1; }
  .vs-pulse { animation: none; -webkit-mask: none; mask: none; }
}

/* ─────────────────── Guest sign-in card (Profile, Home, Record) ─────── */
.guest-card {
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 26px 22px;
  position: relative;
  overflow: hidden;
}
.guest-card::after {
  content: '';
  position: absolute;
  right: -80px; top: -80px;
  width: 240px; height: 240px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, var(--primary-soft) 0%, transparent 70%);
  pointer-events: none;
  z-index: 0;
}
.guest-card > * { position: relative; z-index: 1; }
.guest-card .gc-eyebrow {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--primary);
  font-weight: 500;
  margin-bottom: 12px;
}
.guest-card .gc-title {
  font-family: var(--font-serif);
  font-size: 26px;
  font-weight: 500;
  line-height: 1.12;
  letter-spacing: -0.022em;
  color: var(--fg);
  margin: 0 0 8px;
  text-wrap: balance;
}
.guest-card .gc-sub {
  font-size: 14px;
  line-height: 1.5;
  color: var(--fg-2);
  margin: 0 0 18px;
  text-wrap: pretty;
}
.guest-card .gc-cta {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* Guest-mode Record / locked screen */
.guest-lock {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 28px;
  text-align: center;
  gap: 14px;
}
.guest-lock-icon {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--primary-soft);
  color: var(--primary);
  display: flex; align-items: center; justify-content: center;
}
.guest-lock-title {
  font-family: var(--font-serif);
  font-size: 24px;
  font-weight: 500;
  letter-spacing: -0.022em;
  margin: 0;
  text-wrap: balance;
}
.guest-lock-sub {
  color: var(--fg-2);
  font-size: 14px;
  max-width: 360px;
  text-wrap: pretty;
  margin: 0;
}

/* SideNav Sign-in CTA (replaces user card for guests) */
.sn-signin-btn {
  appearance: none;
  cursor: pointer;
  background: var(--primary);
  color: var(--primary-ink);
  border: 0;
  border-radius: 999px;
  padding: 0;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font: 500 13px var(--font-sans);
  margin: 0 auto;
  transition: opacity 120ms, transform 120ms;
}
.sn-signin-btn:hover { opacity: 0.92; }
@media (min-width: 1024px) {
  .sn-signin-btn {
    width: 100%;
    height: auto;
    padding: 11px 14px;
    border-radius: 12px;
    margin: 0;
  }
}

/* Auth overlay: full-screen modal carrying AuthRouter */
.auth-overlay {
  position: fixed;
  inset: 0;
  background: color-mix(in oklch, var(--bg) 96%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  z-index: 400;
  display: flex;
  align-items: stretch;
  justify-content: center;
  animation: vital-fade-in .18s ease both;
}
@keyframes vital-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.auth-overlay > .auth-shell { background: transparent; }
.auth-overlay-close {
  position: fixed;
  top: 18px; right: 18px;
  width: 38px; height: 38px;
  border-radius: 12px;
  border: 0.5px solid var(--border);
  background: var(--surface);
  color: var(--fg);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  z-index: 410;
  transition: background 120ms;
}
.auth-overlay-close:hover { background: var(--surface-2); }
@media (min-width: 768px) {
  .auth-overlay { padding: 28px; }
  .auth-overlay > .auth-shell {
    align-self: center;
    width: 100%;
    max-width: 480px;
    background: var(--surface);
    border: 0.5px solid var(--border);
    border-radius: 22px;
    box-shadow: var(--shadow-lg);
    height: auto;
    max-height: calc(100vh - 56px);
  }
  .auth-overlay > .auth-shell .auth-top    { padding-top: 30px; }
  .auth-overlay > .auth-shell .auth-body   { padding-top: 28px; }
}

/* lang toggle */
.lang-toggle {
  display: inline-flex;
  background: var(--bg-2);
  border-radius: 999px;
  padding: 3px;
  font-size: 11px;
  font-weight: 500;
  border: 0.5px solid var(--border);
}
.lang-toggle button {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 4px 10px;
  border-radius: 999px;
  color: var(--fg-3);
  cursor: pointer;
  font-family: inherit;
}
.lang-toggle button.on {
  background: var(--surface);
  color: var(--fg);
  box-shadow: var(--shadow-sm);
}

/* ─────────────────── Detail floating topbar + menu + toast ─────────────────── */
.detail-topbar {
  position: absolute;
  top: 0; left: 0; right: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  z-index: 20;
  transition: background 200ms ease, backdrop-filter 200ms ease, border-bottom-color 200ms ease, padding 200ms ease;
  background: transparent;
  border-bottom: 0.5px solid transparent;
  pointer-events: none;
}
.detail-topbar > * { pointer-events: auto; }
.detail-topbar .icon-btn {
  background: rgba(255, 255, 255, 0.78);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-color: transparent;
  flex-shrink: 0;
}
.detail-topbar.is-scrolled {
  background: color-mix(in oklch, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  border-bottom-color: var(--border);
  padding-top: 10px;
  padding-bottom: 10px;
}
.detail-topbar-title {
  flex: 1;
  min-width: 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--fg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
  opacity: 0;
  transition: opacity 200ms ease;
  pointer-events: none;
}
.detail-topbar.is-scrolled .detail-topbar-title { opacity: 1; }
[data-theme='dark'] .detail-topbar .icon-btn { background: rgba(40, 40, 36, 0.6); }

.detail-menu-wrap { position: relative; flex-shrink: 0; }
.detail-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 220px;
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow-lg);
  padding: 6px;
  z-index: 30;
  animation: vital-menu-in 140ms cubic-bezier(.18, .7, .2, 1) both;
}
@keyframes vital-menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.detail-menu-item {
  appearance: none;
  background: transparent;
  border: 0;
  font: inherit;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 9px;
  color: var(--fg);
  font-size: 13.5px;
  text-align: left;
  cursor: pointer;
  transition: background 100ms;
}
.detail-menu-item:hover { background: var(--surface-2); }
.detail-menu-item.danger { color: var(--danger); }
.detail-menu-divider {
  height: 0.5px;
  background: var(--border);
  margin: 6px 4px;
}

/* Inline toast (used by Copy link confirmation) */
.vital-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: color-mix(in oklch, var(--fg) 88%, transparent);
  color: var(--bg);
  font-size: 13px;
  padding: 10px 16px;
  border-radius: 999px;
  box-shadow: var(--shadow-lg);
  z-index: 500;
  animation: vital-toast-in 220ms cubic-bezier(.18, .7, .2, 1) both;
}
@keyframes vital-toast-in {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ─────────────────── Register dialog (two-step) ─────────────────── */
.register-dialog-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 14, 0.36);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  z-index: 450;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  animation: vital-fade-in .18s ease both;
}
.register-dialog {
  position: relative;
  background: var(--bg);
  width: 100%;
  max-width: 520px;
  border-radius: 22px;
  padding: 28px 22px 22px;
  box-shadow: var(--shadow-lg);
  animation: rd-pop .22s cubic-bezier(.18, .7, .2, 1) both;
}
@keyframes rd-pop {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}
@media (min-width: 768px) {
  .register-dialog-backdrop { padding: 28px; }
}
.register-dialog-close {
  position: absolute;
  top: 14px; right: 14px;
  width: 32px; height: 32px;
  border-radius: 10px;
}
.register-dialog-eyebrow {
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--primary);
  font-weight: 500;
  margin-bottom: 8px;
}
.register-dialog-title {
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.018em;
  color: var(--fg);
  margin: 0 36px 6px 0;
  text-wrap: balance;
  line-height: 1.2;
}
.register-dialog-sub {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--fg-2);
  margin: 0;
  text-wrap: pretty;
}

.register-dialog-card {
  appearance: none;
  width: 100%;
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: 14px;
  padding: 14px;
  display: flex;
  align-items: center;
  gap: 14px;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: border-color 120ms, background 120ms, transform 120ms;
}
.register-dialog-card:hover:not(:disabled) {
  border-color: var(--border-strong);
  background: var(--surface-2);
}
.register-dialog-card:active:not(:disabled) { transform: scale(0.995); }
.rd-card-icon {
  width: 40px; height: 40px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.rd-card-body { flex: 1; min-width: 0; }
.rd-card-title {
  font-size: 14.5px;
  font-weight: 500;
  color: var(--fg);
  margin-bottom: 2px;
}
.rd-card-sub {
  font-size: 12.5px;
  color: var(--fg-2);
  line-height: 1.4;
}

.register-dialog-url {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  padding: 10px 14px;
  background: var(--surface-2);
  border: 0.5px solid var(--border);
  border-radius: 10px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--fg-2);
  word-break: break-all;
  overflow: hidden;
}
.register-dialog-url > span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}
.register-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 18px;
}
.register-dialog-kbd {
  font-family: var(--font-mono);
  font-size: 10.5px;
  background: rgba(255,255,255,0.18);
  color: inherit;
  padding: 2px 6px;
  border-radius: 5px;
  margin-left: 4px;
}

/* ─────────────────── Course detail — speakers + fees ─────────────────── */
.speaker-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: 12px;
}
.speaker-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--primary-soft);
  color: var(--primary);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: -0.02em;
  flex-shrink: 0;
}
.fee-line {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  font-weight: 400;
  color: var(--fg-2);
  gap: 14px;
}
.fee-line .mono { font-size: 12px; color: var(--fg); font-variant-numeric: tabular-nums; }

/* ─────────────────── Change log / change history ─────────────────── */
.changelog {
  margin-top: 6px;
  border: 0.5px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.changelog[open] { background: var(--surface); }
.changelog-summary {
  appearance: none;
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  font-size: 13px;
  color: var(--fg-2);
  font-weight: 500;
  user-select: none;
  transition: background 120ms;
}
.changelog-summary::-webkit-details-marker { display: none; }
.changelog-summary:hover { background: var(--surface-2); }
.changelog-summary-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.changelog-summary-meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--fg-3);
}
.changelog-count {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--fg-2);
  min-width: 22px;
  text-align: center;
}
.changelog[open] .changelog-summary svg:last-child {
  transform: rotate(180deg);
}
.changelog-summary svg:last-child {
  transition: transform 180ms ease;
}
.changelog-list {
  list-style: none;
  margin: 0;
  padding: 4px 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 0;
  border-top: 0.5px solid var(--border);
}
.changelog-item {
  position: relative;
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: 12px;
  padding: 14px 0 14px 0;
}
.changelog-item + .changelog-item {
  border-top: 0.5px solid var(--border);
}
/* Vertical timeline line through the bullets */
.changelog-item::before {
  content: '';
  position: absolute;
  left: 8px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--border);
}
.changelog-item:first-child::before { top: 22px; }
.changelog-item:last-child::before  { bottom: calc(100% - 22px); }
.changelog-bullet {
  position: relative;
  z-index: 1;
  margin-top: 7px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--surface);
  border: 1.5px solid var(--border-strong);
  align-self: start;
  justify-self: center;
}
.changelog-item:first-child .changelog-bullet {
  background: var(--primary);
  border-color: var(--primary);
}
.changelog-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.changelog-date {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.changelog-changes {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.changelog-change {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.changelog-field {
  font-size: 13px;
  font-weight: 500;
  color: var(--fg);
  letter-spacing: -0.003em;
}
.changelog-diff {
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: var(--surface-2);
  border: 0.5px solid var(--border);
  border-radius: 10px;
  padding: 8px 10px;
}
.changelog-diff-row {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: 10px;
  align-items: start;
  font-size: 12.5px;
  line-height: 1.45;
}
.changelog-diff-tag {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  padding: 2px 0;
  text-align: left;
  color: var(--fg-3);
  white-space: nowrap;
}
.changelog-diff-tag.was { color: var(--fg-3); }
.changelog-diff-tag.now { color: var(--primary); }
.changelog-diff-old {
  color: var(--fg-3);
  text-decoration: line-through;
  text-decoration-color: var(--border-strong);
  word-break: break-word;
  overflow-wrap: anywhere;
}
.changelog-diff-new {
  color: var(--fg);
  word-break: break-word;
  overflow-wrap: anywhere;
}


/* ═══════════════════════════════════════════════════════════════════════
   MOTION-KIT support styles
   Drop-in CSS for motion-kit.jsx. All values are derived from existing
   tokens; no new colors are introduced.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Stagger entrance (consumed by <Stagger>) ─────────────────────────── */
@keyframes vital-stagger-in {
  from { opacity: 0; transform: translateY(var(--vital-stagger-dist, 8px)); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Skeleton shimmer (consumed by <Skeleton>) ────────────────────────── */
.vital-skel {
  position: relative;
  overflow: hidden;
  background: var(--bg-2);
  isolation: isolate;
}
.vital-skel::before {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in oklch, var(--surface) 60%, transparent) 50%,
    transparent 100%
  );
  animation: vital-skel-shimmer 1.6s ease-in-out infinite;
}
@keyframes vital-skel-shimmer {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

/* ── Spinner (consumed by <Spinner> / <LoadingButton>) ────────────────── */
.vital-spinner {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1.6px solid color-mix(in oklch, currentColor 22%, transparent);
  border-top-color: currentColor;
  animation: vital-spin .7s linear infinite;
  vertical-align: -2px;
}
@keyframes vital-spin { to { transform: rotate(360deg); } }

/* ── Sheet exit (paired with the new 'is-closing' class in <Sheet>) ───── */
.sheet.is-closing         { animation: vital-slide-down .24s cubic-bezier(.4,0,.2,1) both; }
.sheet-backdrop.is-closing{ animation: vital-fade-out   .22s ease both; }
@keyframes vital-slide-down {
  from { transform: translateY(0);    opacity: 1; }
  to   { transform: translateY(100%); opacity: 0; }
}
@keyframes vital-fade-out { from { opacity: 1; } to { opacity: 0; } }

/* On tablet+ the sheet becomes a centered modal — exit needs its own
   keyframe because the base transform is translate(-50%, -50%). */
@media (min-width: 768px) {
  .sheet.is-closing {
    animation: vital-modal-out .22s cubic-bezier(.4,0,.2,1) both;
  }
  @keyframes vital-modal-out {
    from { transform: translate(-50%, -50%) scale(1);    opacity: 1; }
    to   { transform: translate(-50%, -50%) scale(0.96); opacity: 0; }
  }
}

/* ── Toast exit ───────────────────────────────────────────────────────── */
.vital-toast.is-out { animation: vital-toast-out .22s ease both; }
@keyframes vital-toast-out {
  from { opacity: 1; transform: translate(-50%, 0); }
  to   { opacity: 0; transform: translate(-50%, 8px); }
}
.vital-toast.is-danger  { background: color-mix(in oklch, var(--danger) 90%, transparent); }
.vital-toast.is-success { background: color-mix(in oklch, var(--success) 90%, transparent); }

/* ── Auth overlay exit ────────────────────────────────────────────────── */
.auth-overlay[data-anim-state="exit"] { animation: vital-fade-out .18s ease both; }

/* ── Safe-area handling (iOS notch + bottom indicator) ───────────────── */
/* The mobile bottom tab bar pads itself so its hit targets sit above the
   iOS home indicator. Equivalent of Tailwind's pb-safe. */
.tab-bar {
  padding-bottom: max(0px, env(safe-area-inset-bottom));
  height: calc(86px + env(safe-area-inset-bottom));
}
/* Sticky CTA bars (course detail "Register" / "Enrol" buttons) */
.cta-bar {
  padding-bottom: max(14px, calc(14px + env(safe-area-inset-bottom)));
}
/* Screen header should clear the iOS status bar / notch */
@supports (padding-top: env(safe-area-inset-top)) {
  .top { padding-top: max(56px, calc(env(safe-area-inset-top) + 18px)); }
}

/* ── Z-index stacking hygiene ─────────────────────────────────────────── */
/* These root scrollers each get their own stacking context so blurred
   backdrops and absolute children inside one screen can never bleed
   onto another (the original cause of "menu hides behind hero" bugs). */
.app, .scroll, .detail-shell, .sheet, .auth-overlay,
.register-dialog-backdrop, .detail-menu-wrap {
  isolation: isolate;
}

/* ── Spring-y tap on existing chrome (works alongside motion-kit) ─────── */
.btn {
  transition: transform .14s cubic-bezier(.5, .8, .35, 1.4),
              background .14s ease, opacity .14s ease, box-shadow .18s ease;
}
.btn:active:not([disabled]):not([aria-busy="true"]) { transform: scale(0.96); }
.btn[disabled],
.btn[aria-busy="true"] { cursor: not-allowed; }
.btn[aria-busy="true"] { opacity: .88; }

.icon-btn {
  transition: transform .14s cubic-bezier(.5,.8,.35,1.4),
              background .12s ease, color .12s ease;
}
.icon-btn:active { transform: scale(0.92); }

.filter-chip {
  transition: transform .14s cubic-bezier(.5,.8,.35,1.4),
              background .14s ease, color .14s ease, border-color .14s ease;
}
.filter-chip:active { transform: scale(0.96); }

/* Cards already have :hover/:active rules; layer a spring curve on top
   so the existing 'transform: scale(.99)' rule feels deliberate. */
.course-card,
.mini-card {
  transition: transform .18s cubic-bezier(.18,.7,.2,1),
              border-color .14s ease,
              box-shadow .2s ease,
              background .14s ease;
}
.course-card:hover,
.mini-card:hover { transform: translateY(-1px); box-shadow: var(--shadow); }

/* ── Focus-visible ring (keyboard a11y) ──────────────────────────────── */
*:focus { outline: none; }
*:focus-visible {
  outline: 2px solid color-mix(in oklch, var(--primary) 80%, transparent);
  outline-offset: 2px;
  border-radius: 8px;
}
/* Keep card focus rings flush with their border radius */
.card:focus-visible,
.course-card:focus-visible,
.mini-card:focus-visible,
.sheet:focus-visible { outline-offset: 3px; border-radius: var(--radius); }

/* ── Text-overflow defenses (utility classes) ─────────────────────────── */
.clamp-1 { display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; word-break: break-word; }
.clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; word-break: break-word; }
.clamp-3 { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; word-break: break-word; }
.truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The course-card heading is the single most overflow-prone element.
   Clamp it to 2 lines so long bilingual titles never explode the row. */
.course-card h4 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}

/* ── Empty state ──────────────────────────────────────────────────────── */
.vital-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 48px 24px;
  text-align: center;
  color: var(--fg-2);
}
.vital-empty .vital-empty-icon {
  width: 48px; height: 48px;
  border-radius: 50%;
  background: var(--primary-soft-2);
  color: var(--primary);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 4px;
}
.vital-empty .vital-empty-title {
  font-family: var(--font-serif);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.012em;
  color: var(--fg);
}
.vital-empty .vital-empty-sub {
  font-size: 13px;
  line-height: 1.5;
  max-width: 320px;
  text-wrap: pretty;
}

/* ── Reduced-motion master switch (last layer wins) ──────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .vital-skel::before { opacity: 0.35; animation: none !important; }
}
