/* Font is now loaded via a <link> in index.html's <head> instead of
   @import here — see the comment there. An @import at the top of this
   file would force the browser to fully fetch this stylesheet before it
   even discovers the font needs fetching too, turning one round trip
   into two in sequence; the <link> lets both happen in parallel. */

/* ============================================================
   Theme system — three switchable themes, same structure used
   across the MindFit365 suite (Solar Mint / Dark / Neuro).
   ============================================================ */

:root, [data-theme="light"] {
  color-scheme: light;
  --bg-base: #F0EDFF;
  --bg-surface: #FFFFFF;
  --text-main: #1A0A3C;
  --text-muted: #6B57A0;
  --primary: #7C3AED;
  --secondary: #059669;
  --accent: #D97706;
  /* Deliberately declared only once here (not per-theme): every other
     theme block below inherits this unchanged, same as any other
     variable it doesn't redefine. It's an "attention" amber rather than
     any theme's brand color on purpose — the pulsing ring on
     .test-banner-hot is meant to read as "look now" independent of
     whatever hue that theme's panels happen to be, and amber reads
     clearly against every one of this app's page backgrounds, light or
     dark, unlike a plain white ring (see the comment on .test-banner). */
  --pulse-ring: rgba(251,191,36,0.55);
  --danger: #DC2626;
  --border-color: #DDD6FE;
  --shadow: 0 8px 32px -4px rgba(124,58,237,0.12), 0 0 0 1px rgba(124,58,237,0.08);
  --radius-lg: 20px;
  --radius-md: 14px;
  --panel-bg: var(--bg-surface);
  --chrome-bg: color-mix(in srgb, var(--bg-surface) 88%, transparent);
  --progress-fill: linear-gradient(90deg, #7C3AED, #059669);
  --progress-bg: rgba(124,58,237,0.1);
  --card-back-grad: linear-gradient(135deg, #6D28D9 0%, #7C3AED 50%, #8B5CF6 100%);
  --card-back-text: #FFFFFF;
  --card-back-glow: 0 2px 16px rgba(109,40,217,0.45);
  /* "Your vocabulary" (.progress-hero) gets its OWN palette here, rather
     than reusing --card-back-grad like every other theme does below —
     light mode is the one case where the flashcard-back violet and
     --primary-panel-grad's violet are close enough in hue that stacking
     Home's test banner, practice panel, and this stat card all in the
     same violet family read as three copies of the same block. Unlike
     the other themes (which stay full-bleed/colorful but just go darker
     and more muted — see the dark theme's version below), light mode's
     page background is itself light, so a dark card here would be
     introducing a treatment nothing else on Home uses, not matching
     one. The distinct-but-still-light option is a plain neutral card —
     same idea as .week-chart-card / .due-chip just below it on Home —
     so the hierarchy reads as "two bold color CTAs, then a quiet stat
     card", the same relationship the other themes have, just without
     ever going dark to get there. */
  --progress-hero-grad: var(--bg-surface);
  --progress-hero-text: var(--text-main);
  --progress-hero-glow: 0 0 0 rgba(0,0,0,0);
  --progress-hero-border: var(--border-color);
  --grid-line: rgba(255,255,255,0.15);
  --primary-btn-grad: linear-gradient(135deg, #7C3AED, #A78BFA);
  --primary-btn-glow: 0 0 16px rgba(167,139,250,0.35);
  --primary-panel-grad: linear-gradient(135deg, #5B21B6, #7C3AED);
  --good-grad: linear-gradient(135deg, #059669, #34D399);
  --good-glow: 0 0 16px rgba(52,211,153,0.35);
  --retry-grad: linear-gradient(135deg, #DC2626, #F87171);
  --retry-glow: 0 0 16px rgba(248,113,113,0.35);
  --hard-grad: linear-gradient(135deg, #D97706, #FBBF24);
  --hard-glow: 0 0 16px rgba(251,191,36,0.35);
  --easy-grad: linear-gradient(135deg, #2563EB, #60A5FA);
  --easy-glow: 0 0 16px rgba(96,165,250,0.35);
  --due-grad: linear-gradient(135deg, #F59E0B, #EF4444);
  --due-glow: 0 0 14px rgba(239,68,68,0.4);
  --test-grad: linear-gradient(135deg, #2563EB, #7C3AED);
  --test-glow: 0 0 14px rgba(37,99,235,0.4);
}



* { box-sizing: border-box; }

html {
  height: 100%;
  overscroll-behavior-y: contain; /* prevent the browser's pull-to-refresh gesture from firing inside what should feel like a self-contained app */
  -webkit-tap-highlight-color: transparent; /* remove the default gray flash-on-tap — our own :active states provide feedback instead */
}

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  background: var(--bg-base);
  color: var(--text-main);
  font-family: 'Inter', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.4s ease, color 0.4s ease;
  -webkit-user-select: none;
  user-select: none; /* UI chrome shouldn't be selectable text, like a native app's controls aren't */
}
html { height: 100%; }
body { min-height: 100vh; }

/* ...but actual text content people might want to copy (a word, an
   example sentence, a quiz question) and anything editable stays
   selectable — the rule above is about buttons/labels/nav, not content. */
.word, .example, .quiz-word, input, textarea {
  -webkit-user-select: text;
  user-select: text;
}

button, .btn, a, select, .bottom-nav button, .control-btn {
  touch-action: manipulation; /* skip the ~300ms double-tap-zoom delay browsers add by default on tappable elements */
}

h1, h2, h3 { font-family: 'Inter', sans-serif; font-weight: 900; letter-spacing: -0.01em; margin: 0; }
button { font-family: inherit; }
a { color: var(--primary); text-decoration: none; font-weight: 600; }
a:hover, a:focus { text-decoration: underline; } /* keep the affordance for pointer users; touch users get the color/weight cue instead */

/* Frosted-glass chrome everywhere, not just Neuro — the header, tab bar
   and round icon buttons now use a translucent --chrome-bg (see theme
   blocks above), so blur them all so content scrolling underneath
   reads as "behind glass" rather than "abruptly clipped", matching the
   native iOS/Android tab-bar feel on a phone. */
.app-header,
.bottom-nav,
.control-btn,
.brand-pill {
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
}

/* ---------- Shell / header ---------- */

.app-shell {
  max-width: 640px;
  margin: 0 auto;
  padding: 84px 20px calc(84px + env(safe-area-inset-bottom, 0px));
  position: relative;
}

/* First-paint placeholder for #home-content — see the comment on it in
   index.html. Deliberately simple/self-contained (no --custom-properties
   dependent on JS having picked a theme yet, no layout that would jump
   once real content replaces it) since its whole job is to show up the
   instant this stylesheet loads, however slow the connection is. */
.boot-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 60px 20px;
  color: var(--text-muted, #6b57a0);
  font-size: 0.92rem;
  font-weight: 600;
}
.boot-spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2.5px solid color-mix(in srgb, var(--primary, #7C3AED) 25%, transparent);
  border-top-color: var(--primary, #7C3AED);
  animation: bootSpin 0.8s linear infinite;
}
@keyframes bootSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .boot-spinner { animation: none; }
}

.app-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  max-width: 640px;
  margin: 0 auto;
  padding: 15px 20px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  z-index: 5;
}

.control-btn {
  background: var(--chrome-bg);
  border: 1px solid var(--border-color);
  border-radius: 50%;
  width: 46px;
  height: 46px;
  flex: none;
  font-size: 1.3rem;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: var(--shadow);
  text-decoration: none;
  color: var(--text-main);
  transition: transform 0.2s cubic-bezier(0.4,0,0.2,1), background-color 0.2s;
}
.control-btn:hover { transform: translateY(-2px); }
.control-btn:active { transform: scale(0.95); }
.control-btn svg { width: 20px; height: 20px; }

.brand-pill {
  flex: 1;
  min-width: 0;
  background: var(--chrome-bg);
  border: 1px solid var(--border-color);
  padding: 8px 18px;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.brand-pill .mark {
  font-weight: 900;
  font-size: 1rem;
  letter-spacing: 0.2px;
  color: var(--text-main);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.brand-pill .mark .hl { color: var(--primary); }

.badge-group {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
}

/* Both pills set their own `display` for their visible state, which
   (being an author rule) would otherwise outrank the browser's default
   `[hidden]{display:none}` regardless of selector specificity — so
   toggling the `hidden` attribute from app.js would silently do
   nothing without this explicit override. */
.due-pill[hidden], .test-pill[hidden] { display: none; }

.due-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: inherit;
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: #fff;
  background: var(--due-grad);
  box-shadow: var(--due-glow);
  border: none;
  padding: 5px 11px;
  border-radius: 999px;
  white-space: nowrap;
  flex: none;
  cursor: pointer;
  animation: duePillPulse 1.8s ease-in-out infinite;
}
.due-pill:hover, .due-pill:focus-visible { filter: brightness(1.08); }
.due-pill:active { transform: scale(0.97); }
.due-pill.is-clear {
  color: var(--text-muted);
  background: color-mix(in srgb, var(--secondary) 16%, transparent);
  box-shadow: none;
  animation: none;
}
.due-pill-icon, .test-pill-icon { font-size: 0.85em; }

@keyframes duePillPulse {
  0%, 100% { box-shadow: var(--due-glow); }
  50% { box-shadow: 0 0 4px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .due-pill { animation: none; }
}

/* "Time to test" header pill — sits next to the due-pill in
   badge-group and only appears when a test is actually worth
   taking (see testReadiness() in app.js): the studied pool has
   words one answer from Mastered, it's the user's first eligible
   test, or it's been a while since the last one. It stays calm
   (a steady glow, no pulsing) rather than urgent like due-pill,
   since testing is an invitation, not something decaying — the
   "-hot" variant (a word is one answer from Mastered right now)
   gets a gentle pulse instead, because that one IS time-limited
   in spirit: the nudge is most exciting right when it's true. */
.test-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: inherit;
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: #fff;
  background: var(--test-grad);
  box-shadow: var(--test-glow);
  border: none;
  padding: 5px 11px;
  border-radius: 999px;
  white-space: nowrap;
  flex: none;
  cursor: pointer;
}
.test-pill:hover, .test-pill:focus-visible { filter: brightness(1.1); }
.test-pill:active { transform: scale(0.97); }
.test-pill.test-pill-hot { animation: testPillPulse 2s ease-in-out infinite; }
@keyframes testPillPulse {
  0%, 100% { box-shadow: var(--test-glow); }
  50% { box-shadow: 0 0 4px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .test-pill.test-pill-hot { animation: none; }
}

.grade-buttons {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
/* Below ~360px, four columns squeeze each label into a sliver too
   narrow to comfortably aim a thumb at. Two rows of two gives each
   button roughly double the tap area at the width phones actually are. */
@media (max-width: 380px) {
  .grade-buttons { grid-template-columns: repeat(2, 1fr); }
}
.grade-buttons button {
  border-radius: 12px;
  border: none;
  padding: 12px 4px;
  min-height: 48px;
  font-size: 0.8rem;
  font-weight: 800;
  font-family: inherit;
  color: #fff;
  cursor: pointer;
  transition: transform 0.1s ease, filter 0.15s ease;
}
.grade-buttons button:hover { filter: brightness(1.08); }
.grade-buttons button:active { transform: scale(0.96); }
.grade-buttons button:disabled { opacity: 0.4; cursor: not-allowed; }
.btn.grade-again { background: var(--retry-grad); box-shadow: var(--retry-glow); }
.btn.grade-hard { background: var(--hard-grad); box-shadow: var(--hard-glow); }
.btn.grade-good { background: var(--good-grad); box-shadow: var(--good-glow); }
.btn.grade-easy { background: var(--easy-grad); box-shadow: var(--easy-glow); }
.grade-hint {
  text-align: center;
  font-size: 0.76rem;
  color: var(--text-muted);
  margin-top: 10px;
}

.status-chip {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  padding: 2px 7px;
  border-radius: 999px;
  margin-left: 6px;
  vertical-align: middle;
}
.status-new { background: color-mix(in srgb, var(--text-muted) 20%, transparent); color: var(--text-muted); }
.status-learning { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); }
.status-review { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary); }
.status-mastered { background: color-mix(in srgb, var(--secondary) 18%, transparent); color: var(--secondary); }

.due-note {
  font-size: 0.68rem;
  color: var(--text-muted);
  margin-top: 2px;
}

/* Card-front eyebrow already contains a status chip; keep it legible
   against the gradient rather than the flat chip colors above. */
.flip-face.front .status-chip {
  background: rgba(255,255,255,0.18);
  color: rgba(255,255,255,0.92);
}

code {
  background: color-mix(in srgb, var(--text-main) 8%, transparent);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 0.85em;
}

/* ---------- Tab bar (segmented control, bottom-stack style) ---------- */

.bottom-nav {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  background: var(--chrome-bg);
  border-top: 1px solid var(--border-color);
  box-shadow: 0 -8px 24px -8px rgba(0,0,0,0.15);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  z-index: 8;
}

.bottom-nav button {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: transparent;
  border: none;
  padding: 8px 4px 7px;
  cursor: pointer;
  color: var(--text-muted);
  transition: color 0.15s ease;
}

/* The active indicator is a filled pill BEHIND the icon (Material 3
   navigation-bar pattern) — a color change alone reads as too subtle
   at this size on a phone; a solid shape people can spot at a glance
   doesn't. */
.nav-icon-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 30px;
  border-radius: 15px;
  transition: background 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.nav-icon-pill svg {
  width: 22px;
  height: 22px;
  transition: color 0.15s ease;
}
.bottom-nav button:active .nav-icon-pill { transform: scale(0.88); }

.bottom-nav .nav-label {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.1px;
  transition: color 0.15s ease, font-weight 0.15s ease;
}

.bottom-nav button.active .nav-icon-pill {
  background: var(--primary-btn-grad);
  box-shadow: var(--primary-btn-glow);
  transform: translateY(-2px);
}
.bottom-nav button.active .nav-icon-pill svg {
  color: #fff;
}
.bottom-nav button.active .nav-label {
  color: var(--primary);
  font-weight: 800;
}

section.view { display: none; }
section.view.active { display: block; }

/* ---------- Panels / info states ---------- */

.info-box {
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 22px;
  color: var(--text-muted);
  line-height: 1.55;
}
.info-box strong { color: var(--text-main); }

/* ---------- Daily practice ---------- */

.progress-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-muted);
  margin-bottom: 14px;
}

.progress-track {
  flex: 1;
  height: 10px;
  background: var(--progress-bg);
  border-radius: 10px;
  margin: 0 12px;
  overflow: hidden;
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}
.progress-fill {
  height: 100%;
  background: var(--progress-fill);
  border-radius: 10px;
  transition: width 0.4s cubic-bezier(0.4,0,0.2,1);
}

.flip-card {
  perspective: 1200px;
  /* Was a flat 280px — too tall on short/landscape phone viewports
     (forces scrolling to reach the grade buttons) and wastes space
     on taller ones. Scales with viewport height instead, clamped to
     a sane range. */
  height: clamp(220px, 38vh, 300px);
  margin-bottom: 20px;
  cursor: pointer;
}
.flip-card:active .flip-card-inner { box-shadow: var(--shadow), 0 0 0 4px color-mix(in srgb, var(--primary) 18%, transparent); }
.flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform 0.4s cubic-bezier(0.4,0,0.2,1), box-shadow 0.15s ease;
  transform-style: preserve-3d;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.flip-card.flipped .flip-card-inner { transform: rotateY(180deg); }

.flip-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border-radius: var(--radius-lg);
  border: 2px solid var(--border-color);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(18px, 6vw, 32px);
  box-sizing: border-box;
}

.flip-face.front {
  background: var(--card-back-grad);
  overflow: hidden;
  box-shadow: inset 0 0 30px rgba(124,58,237,0.15);
  border-color: transparent;
  z-index: 2;
}
.flip-face.front::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 20px 20px;
  pointer-events: none;
}
.flip-face.front .eyebrow, .flip-face.front .word, .flip-face.front .example { position: relative; }
.flip-face.front .eyebrow { color: rgba(255,255,255,0.7); }
.flip-face.front .word {
  color: var(--card-back-text);
  text-shadow: var(--card-back-glow);
}
.flip-face.front .example {
  color: rgba(255,255,255,0.85);
}

.flip-face.back {
  transform: rotateY(180deg);
  background: var(--panel-bg);
}
.flip-face.back .word { color: var(--text-main); }

.eyebrow {
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 14px;
  color: var(--text-muted);
}
.word {
  font-family: 'Inter', sans-serif;
  /* Fluid instead of fixed: a long Swedish compound word (e.g.
     "sammanträde", "förutsättning") no longer risks overflowing the
     card or wrapping awkwardly on a narrow phone. */
  font-size: clamp(1.6rem, 8vw, 2.4rem);
  font-weight: 900;
  color: var(--text-main);
  line-height: 1.15;
  overflow-wrap: break-word;
  word-break: break-word;
  max-width: 100%;
}
.flip-face .example {
  margin-top: 16px;
  color: var(--text-muted);
  font-size: clamp(0.82rem, 3.6vw, 0.95rem);
  font-style: italic;
  max-width: 42ch;
}

/* The flashcard back face shows whichever translation language is
   selected in Settings (see TRANSLATION_LANGUAGES in app.js). For a
   right-to-left language like Urdu or Arabic, `dir="rtl"` on the face
   flips text flow and punctuation order correctly; the `[lang="ur"]`/
   `[lang="ar"]` selectors below additionally swap in a shaping webfont
   so the script renders with proper joined letterforms instead of a
   generic font's (often broken-looking) fallback glyphs. Adding another
   language later needs no new CSS unless it also needs a special font. */
.flip-face.back[dir="rtl"] { direction: rtl; }
.flip-face.back[lang="ur"] .word,
.flip-face.back[lang="ur"] .example {
  font-family: 'Noto Nastaliq Urdu', 'Noto Naskh Arabic', serif;
  line-height: 1.9;
}
.flip-face.back[lang="ur"] .word { font-size: clamp(1.15rem, 5.5vw, 1.5rem); }
.flip-face.back[lang="ar"] .word,
.flip-face.back[lang="ar"] .example {
  font-family: 'Noto Naskh Arabic', serif;
  line-height: 1.9;
}
.flip-face.back[lang="ar"] .word { font-size: clamp(1.15rem, 5.5vw, 1.5rem); }
/* Hindi (Devanagari, left-to-right) needs a font with proper conjuncts and
   matras; Devanagari also has tall ascenders/descenders, so give it room. */
.flip-face.back[lang="hi"] .word,
.flip-face.back[lang="hi"] .example {
  font-family: 'Noto Sans Devanagari', 'Mukta', 'Nirmala UI', sans-serif;
  line-height: 1.6;
}
.flip-face.back[lang="hi"] .word { font-size: clamp(1.15rem, 5.5vw, 1.5rem); }
.translation-fallback-note {
  display: block;
  font-size: 0.72rem;
  font-weight: 400;
  color: var(--text-muted);
  margin-top: 2px;
}

/* Small inline translation snippet next to a word row in Manage → Browse,
   shown in whichever language is selected (skipped entirely for English,
   since that's already the row's main text). */
.translation-inline {
  color: var(--text-muted);
  font-size: 0.88rem;
}
.translation-inline[lang="ur"] {
  font-family: 'Noto Nastaliq Urdu', 'Noto Naskh Arabic', serif;
}
.translation-inline[lang="ar"] {
  font-family: 'Noto Naskh Arabic', serif;
}
.translation-inline[lang="hi"] {
  font-family: 'Noto Sans Devanagari', 'Mukta', 'Nirmala UI', sans-serif;
}

.audio-btn {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 18px 9px 14px;
  border-radius: 999px;
  border: none;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.2px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.18);
  transition: box-shadow 0.15s ease, filter 0.15s ease;
}
.audio-btn svg { width: 18px; height: 18px; flex: none; }
.audio-btn-label { white-space: nowrap; }
.audio-btn:hover { box-shadow: 0 6px 18px rgba(0,0,0,0.24); }
.audio-btn:active { filter: brightness(0.94); }
.audio-btn[disabled] { opacity: 0.3; cursor: not-allowed; }
.flip-face.front .audio-btn {
  background: #fff;
  color: var(--primary);
}
.flip-face.front .audio-btn:hover { background: #fff; filter: brightness(0.97); }
.flip-face.back .audio-btn {
  background: var(--primary);
  color: #fff;
}
.flip-face.back .audio-btn:hover { filter: brightness(1.08); }
.audio-btn.speaking {
  animation: audio-glow 0.6s ease-in-out infinite;
}
@keyframes audio-glow {
  0%, 100% { box-shadow: 0 4px 14px rgba(0,0,0,0.18); }
  50% { box-shadow: 0 4px 20px 4px color-mix(in srgb, var(--primary) 55%, transparent); }
}

.flip-hint {
  text-align: center;
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-bottom: 22px;
}

.answer-buttons { display: flex; gap: 12px; }

.btn {
  border-radius: 12px;
  border: 1px solid var(--border-color);
  background: var(--panel-bg);
  color: var(--text-main);
  padding: 13px 18px;
  min-height: 48px;
  font-size: 0.9rem;
  font-weight: 800;
  font-family: inherit;
  cursor: pointer;
  flex: 1;
  transition: transform 0.1s ease, background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.btn:hover { background: color-mix(in srgb, var(--primary) 10%, transparent); border-color: color-mix(in srgb, var(--primary) 35%, transparent); }
.btn:active { transform: scale(0.97); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

/* Keyboard/switch-control users need a visible focus ring; mouse/touch
   users never trigger :focus-visible so this doesn't add clutter to
   the tap experience. */
.btn:focus-visible,
.control-btn:focus-visible,
.option-btn:focus-visible,
.bottom-nav button:focus-visible,
.theme-pick-btn:focus-visible,
.profile-pick-btn:focus-visible,
input:focus-visible,
select:focus-visible,
.cat-count-row-action:focus-visible,
.due-chip:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.btn-primary {
  background: var(--primary-btn-grad);
  border-color: transparent;
  color: #fff;
  box-shadow: var(--primary-btn-glow);
}
.btn-primary:hover { background: var(--primary-btn-grad); filter: brightness(1.08); }

.btn-outline { background: transparent; }

.btn-good {
  background: var(--good-grad);
  border-color: transparent;
  color: #fff;
  box-shadow: var(--good-glow);
}
.btn-good:hover { filter: brightness(1.08); }

.btn-retry {
  background: var(--retry-grad);
  border-color: transparent;
  color: #fff;
  box-shadow: var(--retry-glow);
}
.btn-retry:hover { filter: brightness(1.08); }

.btn-block { width: 100%; }

/* ---------- Test / quiz ---------- */

.quiz-card {
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 26px;
}

.quiz-prompt {
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  margin-bottom: 8px;
}
.quiz-word {
  font-family: 'Inter', sans-serif;
  font-size: clamp(1.4rem, 6.5vw, 1.9rem);
  font-weight: 900;
  color: var(--text-main);
  margin-bottom: 22px;
  overflow-wrap: break-word;
}

.quiz-options { display: grid; gap: 10px; }

.option-btn {
  text-align: left;
  border: 1px solid var(--border-color);
  background: var(--bg-base);
  color: var(--text-main);
  border-radius: 12px;
  padding: 13px 16px;
  min-height: 48px;
  font-size: 0.9rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
}
.option-btn:active:not(:disabled) { transform: scale(0.98); }
.option-btn:hover { border-color: var(--primary); }
.option-btn.correct { background: color-mix(in srgb, var(--secondary) 18%, transparent); border-color: var(--secondary); color: var(--text-main); }
.option-btn.incorrect { background: color-mix(in srgb, var(--danger) 16%, transparent); border-color: var(--danger); color: var(--text-main); }
.option-btn:disabled { cursor: default; }

.fill-blank-input {
  width: 100%;
  min-height: 44px;
  font-size: 16px;
  font-family: inherit;
  padding: 12px 14px;
  border: 1px solid var(--border-color);
  border-radius: 12px;
  background: var(--bg-base);
  color: var(--text-main);
  margin-bottom: 14px;
}
.fill-blank-input:focus { outline: 2px solid var(--primary); outline-offset: 1px; }

/* These two fields are built with inline styles in app.js that inherit
   a small label font-size; !important is needed here because inline
   style attributes otherwise always win over the stylesheet. Same
   iOS auto-zoom issue as above. */
#ai-category, #ai-count {
  font-size: 16px !important;
  min-height: 40px;
}
.fill-blank-input.correct { border-color: var(--secondary); background: color-mix(in srgb, var(--secondary) 12%, transparent); }
.fill-blank-input.incorrect { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); }

.feedback-line { margin-top: 12px; font-size: 0.85rem; font-weight: 700; min-height: 20px; }
.feedback-line.correct { color: var(--secondary); }
.feedback-line.incorrect { color: var(--danger); }

.quiz-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 18px;
}
.quiz-footer .quiz-index { font-size: 0.78rem; color: var(--text-muted); font-weight: 700; }

/* Results */

.result-score {
  font-family: 'Inter', sans-serif;
  font-size: clamp(2.4rem, 12vw, 3.2rem);
  font-weight: 900;
  color: var(--text-main);
  line-height: 1;
}
.result-score span { font-size: 1.4rem; color: var(--text-muted); font-weight: 700; }

.result-list { margin-top: 20px; border-top: 1px solid var(--border-color); }
.result-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-color);
  font-size: 0.85rem;
}
.result-row .tag {
  font-size: 0.68rem;
  font-weight: 800;
  padding: 2px 9px;
  border-radius: 20px;
  white-space: nowrap;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.tag.correct { background: color-mix(in srgb, var(--secondary) 18%, transparent); color: var(--secondary); }
.tag.incorrect { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.tag.demoted { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); }
.tag.promoted { background: color-mix(in srgb, var(--primary) 20%, transparent); color: var(--primary); }

/* Per-word mastery bar + tags on the test results screen */
.result-row { flex-wrap: wrap; }
.result-row-main {
  flex: 1 1 160px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.result-row-word {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.result-row-tags {
  display: flex;
  gap: 6px;
  align-items: center;
  flex: none;
}
.progress-track.mini {
  height: 5px;
  margin: 0;
  max-width: 220px;
}

/* Celebration banner for newly-mastered / leveled-up words after a test */
.celebrate-banner {
  margin-top: 14px;
  padding: 12px 16px;
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--secondary) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--secondary) 30%, transparent);
  color: var(--text-main);
  font-size: 0.85rem;
  font-weight: 700;
  text-align: center;
}

/* Test-entry stats row: tests taken / best / last / hot streak */
.test-stats-bar {
  display: flex;
  gap: 10px;
  margin: -4px 0 16px;
}
.test-stat {
  flex: 1;
  text-align: center;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: 10px 6px;
}
.test-stat-num {
  display: block;
  font-size: 1.1rem;
  font-weight: 900;
  color: var(--text-main);
}
.test-stat-label {
  display: block;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--text-muted);
  margin-top: 2px;
}
.test-stat-hot .test-stat-num { color: var(--accent); }

/* Test-entry mastery nudge: progress bar + status chips + callout */
.mastery-nudge {
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 16px 18px;
  margin-bottom: 16px;
}
.mastery-nudge .progress-row { margin-bottom: 12px; }
.mastery-nudge-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.mastery-callout {
  margin: 12px 0 0;
  font-size: 0.84rem;
  color: var(--text-main);
  line-height: 1.4;
}

.category-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.category-bar label {
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-muted);
  white-space: nowrap;
}
.category-bar select {
  flex: 1;
  min-height: 44px;
  padding: 9px 34px 9px 12px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background-color: var(--panel-bg);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  box-shadow: var(--shadow);
  /* Native select arrows look inconsistent between iOS and Android,
     and clash with the app's own rounded/pill visual language. A
     drawn chevron keeps it consistent everywhere. */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B57A0' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 16px;
}
[data-mode="dark"] .category-bar select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2393A5C4' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}

.category-tag {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  padding: 2px 8px;
  border-radius: 999px;
  margin-left: 8px;
}

.manage-subnav {
  display: flex;
  gap: 6px;
  padding: 5px;
  margin-bottom: 20px;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
}
.manage-subnav button {
  flex: 1;
  min-height: 42px;
  background: transparent;
  border: none;
  border-radius: calc(var(--radius-md) - 5px);
  padding: 10px 6px;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.manage-subnav button.active {
  background: var(--primary-btn-grad);
  color: #fff;
  box-shadow: var(--primary-btn-glow);
}

.cat-count-list { display: flex; flex-direction: column; gap: 8px; }
.cat-count-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--text-main);
}
.cat-count-row-action {
  width: 100%;
  text-align: left;
  font: inherit;
  border: 1px solid var(--border-color);
  border-left: 4px solid var(--primary);
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--primary) 6%, var(--panel-bg));
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
.cat-count-row-action:hover,
.cat-count-row-action:focus-visible {
  border-color: var(--primary);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--primary) 25%, transparent);
  transform: translateY(-1px);
}
.cat-count-row-action:active {
  transform: translateY(0) scale(0.99);
  background: color-mix(in srgb, var(--primary) 14%, var(--panel-bg));
}
.cat-count-label { flex: 1; min-width: 0; }
.cat-count-right { display: flex; align-items: center; gap: 8px; flex: none; }
.cat-count-new {
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.2px;
  color: #fff;
  background: var(--primary);
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.cat-count-done {
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--text-muted);
  white-space: nowrap;
}
.cat-count-num {
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 0.8rem;
}
.cat-count-chevron {
  color: var(--primary);
  font-weight: 800;
}

.profile-active-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border-radius: 12px;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  margin-bottom: 10px;
}
.account-link-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--secondary) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--secondary) 30%, transparent);
  margin-bottom: 10px;
  font-size: 0.88rem;
}
.profile-pick-avatar { font-size: 1.3rem; line-height: 1; }
.profile-pick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 8px;
}
.profile-pick-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  min-height: 44px;
  border-radius: 12px;
  border: 1px solid var(--border-color);
  background: var(--bg-base);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 0.15s ease;
}
.profile-pick-btn:hover { border-color: var(--primary); }
.profile-pick-btn.active {
  background: var(--primary-btn-grad);
  color: #fff;
  border-color: transparent;
  cursor: default;
}
.profile-pick-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.theme-pick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 10px;
}
.theme-pick-btn {
  padding: 12px 6px;
  min-height: 44px;
  border-radius: 12px;
  border: 1px solid var(--border-color);
  background: var(--bg-base);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 360px) {
  .theme-pick-btn { font-size: 0.72rem; padding: 10px 4px; }
}
.theme-pick-btn.active {
  background: var(--primary-btn-grad);
  color: #fff;
  border-color: transparent;
  box-shadow: var(--primary-btn-glow);
}

/* ---------- Languages to practice (Settings) — multi-select toggle
   chips, as opposed to the theme grid above which is single-select.
   Any number can be active at once; see the card-lang-* rules below for
   where they show up (the Practice/Focus flip card's language switcher). ---------- */
.lang-toggle-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.lang-toggle-btn {
  padding: 10px 16px;
  min-height: 40px;
  border-radius: 999px;
  border: 1.5px solid var(--border-color);
  background: var(--bg-base);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.lang-toggle-btn.active {
  background: var(--primary-btn-grad);
  color: #fff;
  border-color: transparent;
  box-shadow: var(--primary-btn-glow);
}
.lang-toggle-btn.active::before { content: "✓ "; }
/* Swedish's pinned chip — plainly disabled (muted, no colored fill),
   not styled like an active toggle, since it isn't one: it can't be
   turned off, so it shouldn't look like something someone just happened
   to check. The 🔒 in its label is what signals "always included". */
.lang-toggle-btn.pinned {
  background: var(--bg-base);
  color: var(--text-muted);
  border-color: var(--border-color);
  cursor: default;
  opacity: 0.7;
}

/* ---------- On-card language switcher (Practice / Focus) — appears
   above the flip card only when 2+ languages are active, letting
   someone flip between e.g. Urdu and Italian on the same word without
   opening Settings. Sits outside #flip-card so tapping a chip never
   also triggers the card's own flip-on-tap handler. ---------- */
.card-lang-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}
.card-lang-row-label {
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--text-muted);
  white-space: nowrap;
}
.card-lang-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.card-lang-chip {
  padding: 6px 12px;
  min-height: 32px;
  border-radius: 999px;
  border: 1.5px solid var(--border-color);
  background: var(--panel-bg);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.76rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.card-lang-chip.active {
  background: var(--primary-btn-grad);
  color: #fff;
  border-color: transparent;
  box-shadow: var(--primary-btn-glow);
}

/* ---------- Home / dashboard ---------- */

.home-greeting {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
}
.home-greeting h1 {
  font-size: 1.3rem;
  font-weight: 900;
  color: var(--text-main);
  margin: 0 0 4px;
  line-height: 1.25;
}
.hg-date {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text-muted);
  margin: 0;
}
.hg-dot { opacity: 0.5; margin: 0 1px; }
.hg-goal-line { color: var(--primary); font-weight: 700; }
.home-done-today { margin-bottom: 16px; }

/* Compact "today's goal" ring — lives in the header, top-right of the
   name, instead of its own separate panel (see renderHome). Tapping it
   goes to Settings, where the goal itself is adjusted. */
.hg-goal-ring {
  flex: none;
  position: relative;
  width: 52px;
  height: 52px;
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hg-goal-ring:hover, .hg-goal-ring:focus-visible { filter: brightness(1.08); }
.hg-goal-ring:active { transform: scale(0.96); }
.hg-goal-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.hg-goal-ring circle {
  fill: none;
  stroke-width: 6;
  stroke-linecap: round;
}
.hg-goal-ring .ring-track { stroke: var(--border-color); }
.hg-goal-ring .ring-progress {
  stroke: var(--primary);
  transition: stroke-dashoffset 0.4s ease;
}
.hg-goal-pct {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  font-weight: 900;
  color: var(--text-main);
}

/* The dominant "Start today's practice" panel. Deliberately kept as a
   full-bleed colored card (still the single most prominent thing on
   Home) but toned down from the raw --primary-btn-grad used on small
   buttons/pills: at full-panel size, that gradient's brighter stop plus
   its color-matched glow read as glare rather than "primary", especially
   in Neuro's neon cyan or against a light background. --primary-panel-grad
   is a deeper, richer cut of the same brand color per theme — same
   identity, easier to look at for more than a second. The neon-matched
   box-shadow glow is dropped entirely in favor of the same plain
   --shadow every other card on Home uses, and a soft diagonal sheen
   (::before) adds a bit of polish/depth without adding brightness. */
.primary-suggestion {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  border: none;
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  margin-bottom: 14px;
  background: var(--primary-panel-grad);
  box-shadow: var(--shadow);
  overflow: hidden;
  transition: transform 0.12s ease, filter 0.12s ease;
}
.primary-suggestion::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, rgba(255,255,255,0.16), rgba(255,255,255,0) 45%);
  pointer-events: none;
}
.primary-suggestion:hover, .primary-suggestion:focus-visible { filter: brightness(1.08); transform: translateY(-1px); }
.primary-suggestion:active { transform: translateY(0) scale(0.99); }
.ps-icon { flex: none; font-size: 1.8rem; line-height: 1; z-index: 1; }
.ps-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; z-index: 1; }
.ps-title { font-size: 1.02rem; font-weight: 800; color: #fff; }
.ps-desc { font-size: 0.82rem; font-weight: 500; color: rgba(255,255,255,0.88); line-height: 1.35; }
.ps-cta {
  flex: none;
  font-size: 0.78rem;
  font-weight: 800;
  color: #fff;
  background: rgba(255,255,255,0.18);
  padding: 8px 12px;
  border-radius: 999px;
  white-space: nowrap;
  z-index: 1;
}

/* Segmented "catalog progress" ring — composition of the whole visible
   catalog by learning stage (new / learning / review / mastered). Colors
   are pulled straight from the existing status-chip palette (see
   .status-new / .status-learning / .status-review / .status-mastered)
   so this card, its legend, and the chips in Manage → Browse all agree. */
.progress-hero {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: var(--progress-hero-text);
  border: 1px solid var(--progress-hero-border, transparent);
  cursor: pointer;
  border-radius: var(--radius-lg);
  background: var(--progress-hero-grad);
  box-shadow: var(--progress-hero-glow), var(--shadow);
  padding: 16px 16px 18px;
  margin-bottom: 22px;
  transition: transform 0.12s ease, filter 0.12s ease;
}
.progress-hero:hover, .progress-hero:focus-visible { filter: brightness(1.05); transform: translateY(-1px); }
.progress-hero:active { transform: translateY(0) scale(0.99); }

.ph-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 14px;
}
.ph-head-title { font-size: 0.92rem; font-weight: 800; }
.ph-head-sub { font-size: 0.74rem; font-weight: 600; opacity: 0.82; }

.progress-hero-card {
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--panel-bg);
  border-radius: var(--radius-md);
  padding: 16px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.ph-ring { position: relative; flex: none; width: 104px; height: 104px; }
.ph-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ph-ring circle { fill: none; }
.ph-track { stroke: var(--border-color); stroke-width: 12; }
.ph-seg { stroke-width: 12; stroke-linecap: round; }
.ph-new { stroke: var(--text-muted); }
.ph-new.ph-dot { background: var(--text-muted); }
.ph-learning { stroke: var(--accent); }
.ph-learning.ph-dot { background: var(--accent); }
.ph-review { stroke: var(--primary); }
.ph-review.ph-dot { background: var(--primary); }
.ph-mastered { stroke: var(--secondary); }
.ph-mastered.ph-dot { background: var(--secondary); }

.ph-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.ph-pct { font-size: 1.35rem; font-weight: 900; color: var(--text-main); line-height: 1.1; }
.ph-pct-label { font-size: 0.6rem; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.3px; }

.ph-streak-flame {
  font-size: 1.15rem;
  line-height: 1;
  filter: drop-shadow(0 2px 5px rgba(255, 106, 32, 0.4));
  animation: phFlameFlicker 2.6s ease-in-out infinite;
  transform-origin: 50% 85%;
}
.ph-streak-num {
  margin-top: 1px;
  font-size: 1.5rem;
  font-weight: 900;
  line-height: 1.05;
  background: linear-gradient(135deg, #FF9A3D 0%, #FF4D4D 60%, #E0247A 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.ph-streak-label { margin-top: 1px; font-size: 0.6rem; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }

@keyframes phFlameFlicker {
  0%, 100% { transform: scale(1) rotate(-3deg); }
  50% { transform: scale(1.1) rotate(3deg); }
}
@media (prefers-reduced-motion: reduce) {
  .ph-streak-flame { animation: none; }
}

.ph-legend { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 9px; }
.ph-legend-item { display: flex; align-items: center; gap: 8px; }
.ph-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; }
.ph-legend-label { flex: 1; min-width: 0; font-size: 0.8rem; font-weight: 700; color: var(--text-main); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ph-legend-count { flex: none; font-size: 0.82rem; font-weight: 800; color: var(--text-main); }

@media (max-width: 360px) {
  .progress-hero-card { gap: 12px; padding: 14px 12px; }
  .ph-ring { width: 88px; height: 88px; }
  .ph-pct { font-size: 1.1rem; }
  .ph-streak-flame { font-size: 1rem; }
  .ph-streak-num { font-size: 1.25rem; }
}

/* "Due for review today" home banner — promoted from a slim inline chip
   to a full banner, and moved up to right below the greeting, because
   it's the one home-page number that's genuinely time-sensitive (it
   changes what to do *right now*, unlike the vocabulary card's counts,
   which are stable across a session) and deserves to be seen first, not
   buried below "Your vocabulary". Deliberately given the exact same
   gradient-banner theme as .test-banner (same --primary-panel-grad
   background, same plain --shadow, same sheen overlay, and the shared
   .tb-icon/.tb-body/.tb-title/.tb-desc/.tb-cta content classes) so the
   two read as one consistent "this needs you now" visual language on
   Home, stacking cleanly when both are shown at once. Shown only when
   something is actually due, so an empty state doesn't add a "0 due"
   panel to look at. */
.due-banner {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  border: none;
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  margin-bottom: 14px;
  background: var(--primary-panel-grad);
  box-shadow: var(--shadow);
  overflow: hidden;
  transition: transform 0.12s ease, filter 0.12s ease;
}
.due-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, rgba(255,255,255,0.16), rgba(255,255,255,0) 45%);
  pointer-events: none;
}
.due-banner:hover, .due-banner:focus-visible { filter: brightness(1.08); transform: translateY(-1px); }
.due-banner:active { transform: translateY(0) scale(0.99); }

/* "Time to test" home banner. Deliberately given the exact same theme as
   .primary-suggestion right below it — same --primary-panel-grad
   background, same plain --shadow, same sheen overlay — on request, so
   the two read as one consistent "this is important" visual language on
   Home instead of two competing colors. The ONE difference, and the
   whole reason this is a separate class rather than reusing
   .primary-suggestion outright, is the pulsing ring below: it only
   applies when .test-banner-hot is added (a word is one correct answer
   from Mastered — see testReadiness() in app.js), and it's what tells
   the two panels apart at a glance. */
.test-banner {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  border: none;
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  margin-bottom: 14px;
  background: var(--primary-panel-grad);
  box-shadow: var(--shadow);
  overflow: hidden;
  transition: transform 0.12s ease, filter 0.12s ease;
}
.test-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, rgba(255,255,255,0.16), rgba(255,255,255,0) 45%);
  pointer-events: none;
}
.test-banner:hover, .test-banner:focus-visible { filter: brightness(1.08); transform: translateY(-1px); }
.test-banner:active { transform: translateY(0) scale(0.99); }
.tb-icon { flex: none; font-size: 1.8rem; line-height: 1; z-index: 1; }
.tb-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; z-index: 1; }
.tb-title { font-size: 1.02rem; font-weight: 800; color: #fff; }
.tb-desc { font-size: 0.82rem; font-weight: 500; color: rgba(255,255,255,0.88); line-height: 1.35; }
.tb-cta {
  flex: none;
  font-size: 0.78rem;
  font-weight: 800;
  color: #fff;
  background: rgba(255,255,255,0.18);
  padding: 8px 12px;
  border-radius: 999px;
  white-space: nowrap;
  z-index: 1;
}
/* The pulsing ring — the one intentional difference from
   .primary-suggestion. Animates box-shadow from "no ring" to a soft
   amber ring and back; see --pulse-ring above for why amber specifically.
   Applied to .due-banner too (not just .test-banner-hot): both are
   "attention" panels meant to pull the eye before the quieter panels
   below, so they share the same blinking-border treatment rather than
   the due panel sitting still next to a pulsing one.
   PRE-EXISTING BUG, now fixed: this used to pulse a plain white ring
   (0 0 0 6px rgba(255,255,255,0.22)). A box-shadow's spread ring is
   painted outside the element's own background, on top of whatever's
   behind it — i.e. the *page*, not the panel — so its visibility
   depends on contrast against the page background, not the panel color.
   That's fine on every theme here except light mode, whose page
   background (--bg-base: #F0EDFF) is itself pale and slightly lavender:
   a white ring at 22% opacity on top of that is barely distinguishable,
   so the "flashing border" was real but effectively invisible. Amber at
   higher opacity contrasts against every page background this app has,
   light or dark, which is what --pulse-ring is for. */
.test-banner.test-banner-hot, .due-banner { animation: testBannerPulse 2.2s ease-in-out infinite; }
@keyframes testBannerPulse {
  0%, 100% { box-shadow: var(--shadow), 0 0 0 0 transparent; }
  50% { box-shadow: var(--shadow), 0 0 0 6px var(--pulse-ring); }
}
@media (prefers-reduced-motion: reduce) {
  .test-banner.test-banner-hot, .due-banner { animation: none; }
}

/* 7-day activity: one progress ring per day (matches the Progress Calendar) */
.week-chart-card {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--panel-bg);
  box-shadow: var(--shadow);
  padding: 12px 8px 10px;
  margin-bottom: 22px;
}
.week-chart { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.wk-day {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 6px 0 4px; border: 0; border-radius: 14px;
  background: transparent; color: var(--text-main);
  font: inherit; cursor: pointer;
  transition: background 0.15s ease, transform 0.12s ease;
}
.wk-day:active { transform: scale(0.94); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.wk-ring { position: relative; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; }
.wk-ring svg { position: absolute; inset: 0; }
.wk-count { position: relative; font-size: 0.86rem; font-weight: 900; letter-spacing: -0.02em; line-height: 1; }
.wk-day.is-goal .wk-count { color: #F59E0B; }
.wk-label { font-size: 0.68rem; font-weight: 700; color: var(--text-muted); line-height: 1; }
.wk-day.is-today .wk-label {
  color: #fff; background: var(--accent);
  border-radius: 999px; padding: 3px 7px; margin: -3px 0; font-weight: 900;
}
.wk-day:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.home-section-title {
  font-size: 0.95rem;
  font-weight: 800;
  color: var(--text-main);
  margin: 0 0 12px;
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.home-section-sub {
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--text-muted);
}

.suggestion-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
.suggestion-card {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--panel-bg);
  box-shadow: var(--shadow);
  padding: 12px 14px;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
.suggestion-card:hover, .suggestion-card:focus-visible {
  border-color: var(--primary);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--primary) 22%, transparent);
  transform: translateY(-1px);
}
.suggestion-card:active { transform: translateY(0) scale(0.99); }
.sc-icon { flex: none; font-size: 1.3rem; line-height: 1; }
.sc-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sc-title { font-size: 0.88rem; font-weight: 700; color: var(--text-main); }
.sc-desc { font-size: 0.76rem; color: var(--text-muted); line-height: 1.35; }
.sc-cta {
  flex: none;
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--primary);
  white-space: nowrap;
}

@media (max-width: 380px) {
  .home-greeting h1 { font-size: 1.12rem; }
  .ps-desc, .sc-desc { display: none; }
  .hg-goal-ring { width: 44px; height: 44px; }
  .hg-goal-pct { font-size: 0.64rem; }
  .hg-date { font-size: 0.76rem; }
}

/* ---------- Manage ---------- */
.voice-diagnostic { display: flex; flex-direction: column; gap: 6px; }
.voice-diagnostic-row {
  font-size: 0.82rem;
  padding: 8px 10px;
  border-radius: 10px;
  line-height: 1.4;
}
.voice-diagnostic-ok {
  background: color-mix(in srgb, var(--secondary) 12%, var(--panel-bg));
  color: var(--text-main);
}
.voice-diagnostic-missing {
  background: color-mix(in srgb, var(--danger) 12%, var(--panel-bg));
  color: var(--text-main);
}
.btn.speaking { opacity: 0.7; }

/* ---------- Missing-voice help ---------- */

/* Small amber "!" on a Listen button whose language has no voice on this
   device — tapping it opens the install-help sheet instead of speaking. */
.audio-btn.voice-missing::after {
  content: "!";
  position: absolute;
  top: -5px;
  right: -5px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #F59E0B;
  color: #1F1300;
  font-size: 0.7rem;
  font-weight: 900;
  line-height: 1;
  box-shadow: 0 2px 6px rgba(0,0,0,0.3);
}
.voice-diagnostic-row .btn-link { margin-left: 6px; }

.voice-help-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(0,0,0,0.55);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.voice-help-sheet {
  width: 100%;
  max-width: 480px;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--bg-surface);
  color: var(--text-main);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 22px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -8px 40px rgba(0,0,0,0.35);
}
.voice-help-sheet h3 { margin: 0 0 8px; font-size: 1.05rem; }
.voice-help-text { margin: 0 0 10px; font-size: 0.88rem; line-height: 1.5; color: var(--text-muted); }
.voice-help-note { font-size: 0.8rem; }
.voice-help-platforms { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.voice-help-steps {
  margin: 0 0 12px;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-size: 0.88rem;
  line-height: 1.45;
}
.voice-help-status { margin: 0 0 10px; font-size: 0.82rem; font-weight: 700; color: var(--danger); min-height: 0; }
.voice-help-status:empty { display: none; }
.voice-help-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.voice-help-actions a.btn { text-decoration: none; display: inline-flex; align-items: center; justify-content: center; }
@media (min-width: 600px) {
  .voice-help-overlay { align-items: center; padding: 20px; }
  .voice-help-sheet { border-radius: var(--radius-lg); }
}

/* ---------- Focus session (Manage → counter → Practice) ---------- */

.focus-session-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  padding: 10px 14px;
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 30%, transparent);
}
.focus-session-tag { font-size: 0.82rem; font-weight: 700; color: var(--text-main); }
.btn-link {
  background: none;
  border: none;
  padding: 4px 6px;
  color: var(--primary);
  font-weight: 700;
  font-size: 0.82rem;
  cursor: pointer;
  text-decoration: underline;
}

.add-word-form {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--panel-bg);
  box-shadow: var(--shadow);
  padding: 18px;
  margin-bottom: 26px;
}
.add-word-form h3 { font-size: 0.95rem; font-weight: 800; margin-bottom: 12px; }

.field-row { display: flex; gap: 10px; margin-bottom: 10px; }
.field-row input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--border-color);
  border-radius: 10px;
  background: var(--bg-base);
  color: var(--text-main);
  /* Must stay ≥16px: iOS Safari auto-zooms the whole viewport on focus
     for any input under that size, which then requires the user to
     manually pinch back out — a jarring, very mobile-specific bug. */
  font-size: 16px;
  font-family: inherit;
}
.field-row input:focus { outline: 2px solid var(--primary); outline-offset: 1px; }

.form-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.form-hint { font-size: 0.76rem; color: var(--text-muted); }

.word-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border-color);
}
.word-row .sv { font-weight: 800; }
.word-row .en { color: var(--text-muted); font-size: 0.88rem; }
.word-row .meta { flex: 1; min-width: 0; }
.word-row .miss-count { font-size: 0.72rem; font-weight: 700; color: var(--danger); }
.word-row button.remove {
  background: transparent;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 0.76rem;
  font-weight: 700;
  padding: 9px 12px;
  min-height: 40px;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.word-row button.remove:hover { border-color: var(--primary); color: var(--primary); }

.empty-row { color: var(--text-muted); font-size: 0.88rem; padding: 16px 0; }

.toast {
  position: fixed;
  bottom: calc(76px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  color: var(--text-main);
  padding: 11px 18px;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 700;
  box-shadow: var(--shadow);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  max-width: 90vw;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(-4px); }

@media (prefers-reduced-motion: reduce) {
  .flip-card-inner, .btn, .toast, .control-btn, .nav-icon-pill, .option-btn, .progress-fill { transition: none !important; }
}

@media (max-width: 480px) {
  .brand-pill { padding: 8px 12px; gap: 6px; }
  .brand-pill .mark { font-size: 0.82rem; }
  .due-pill, .test-pill { font-size: 0.68rem; padding: 4px 7px; }
  /* Panels look generous on a laptop but eat too much of a 375px
     screen edge-to-edge; trim inner padding a touch on phones. */
  .quiz-card, .add-word-form, .info-box { padding: 16px; }
  .app-shell { padding-left: 14px; padding-right: 14px; }
}
@media (max-width: 400px) {
  /* The streak label used to be hidden here, leaving just a bare
     flame + number with nothing to say what it counts — easy to
     misread as some other stat (e.g. "studied"). Keep it visible,
     just tighter, so the streak pill always reads unambiguously. */
  .pill-label { font-size: 0.62rem; }
  .brand-pill .mark { font-size: 0.76rem; }
  /* With both due-pill and test-pill visible at once, a text label
     on each is too much for a 375px-and-under screen — the test-pill
     drops to just its icon (plus count, when there is one) since
     due-pill's message is the more time-sensitive of the two. */
  .test-pill .pill-label { display: none; }
  .test-pill { padding: 5px 8px; }
}

/* ============================================================
   Progress calendar (bottom sheet opened from Home -> "This week")
   Each day is a small progress ring; ".fun" on the sheet adds the
   playful layer (stars, bouncing emoji, confetti).
   ============================================================ */
.week-chart-card-tap { cursor: pointer; }
.week-chart-card-tap:active { transform: scale(0.99); }
.cal-open-link {
  margin-left: auto;
  border: 0;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary);
  font: inherit;
  font-size: 0.76rem;
  font-weight: 800;
  padding: 5px 11px;
  border-radius: 999px;
  cursor: pointer;
}
body.cal-open { overflow: hidden; }
.cal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(0,0,0,0.6);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  animation: cal-fade 0.18s ease;
}
.cal-sheet {
  /* Opaque surface color for everything inside the calendar. Some themes
     (e.g. the glass "neuro" theme) define --bg-surface/--panel-bg as
     semi-transparent, which made the sheet see-through. */
  --cal-solid: var(--bg-surface);
  --cal-gold: #F59E0B;
  width: 100%;
  max-width: 480px;
  max-height: 92vh;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--cal-solid);
  color: var(--text-main);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 10px 18px calc(22px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -8px 40px rgba(0,0,0,0.35);
  animation: cal-rise 0.22s ease;
}
[data-mode="dark"] .cal-sheet { --cal-solid: color-mix(in srgb, #ffffff 9%, var(--bg-base)); }
@keyframes cal-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes cal-rise { from { transform: translateY(24px); opacity: 0.6; } to { transform: none; opacity: 1; } }

.cal-grabber { width: 38px; height: 4px; border-radius: 4px; background: var(--border-color); margin: 0 auto 8px; }
.cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.cal-head-actions { display: flex; align-items: center; gap: 8px; }
.cal-icon-btn, .cal-close {
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--border-color);
  background: transparent; color: var(--text-muted);
  font-size: 0.95rem; cursor: pointer; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform 0.15s ease, background 0.15s ease;
}
.cal-icon-btn:active, .cal-close:active { transform: scale(0.9); }
.cal-icon-btn.active { background: color-mix(in srgb, var(--primary) 18%, var(--cal-solid)); border-color: var(--primary); }
.cal-icon-btn:not(.active) { filter: grayscale(0.7); opacity: 0.75; }

/* month navigation */
.cal-nav { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.cal-month { flex: 1; text-align: center; font-size: 1.15rem; font-weight: 800; text-transform: capitalize; }
.cal-nav-btn {
  width: 38px; height: 38px; border-radius: 50%;
  border: 0;
  background: color-mix(in srgb, var(--primary) 10%, var(--cal-solid)); color: var(--primary);
  font-size: 1.5rem; line-height: 1; font-weight: 800; cursor: pointer;
  transition: transform 0.12s ease;
}
.cal-nav-btn:active:not(:disabled) { transform: scale(0.9); }
.cal-nav-btn:disabled { opacity: 0.25; cursor: default; }
.cal-today-btn {
  width: 34px; height: 34px; border-radius: 50%;
  border: 0; cursor: pointer;
  background: var(--primary); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  animation: cal-pulse 1.8s ease-in-out infinite;
}
.cal-today-btn svg { width: 20px; height: 20px; }
@keyframes cal-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 45%, transparent); }
  50% { box-shadow: 0 0 0 8px transparent; }
}

/* hero: tapped day (or month) */
.cal-hero {
  margin-bottom: 14px; padding: 14px 16px;
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--primary) 9%, var(--cal-solid));
  border: 1px solid var(--border-color);
}
.cal-hero-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cal-hero-txt { min-width: 0; }
.cal-hero-date { font-size: 0.78rem; font-weight: 800; color: var(--text-muted); text-transform: capitalize; }
.cal-hero-main { display: flex; align-items: baseline; gap: 8px; margin-top: 2px; }
.cal-hero-num { font-size: 2.7rem; font-weight: 900; line-height: 1; color: var(--primary); letter-spacing: -0.03em; }
.cal-hero-unit { font-size: 1.1rem; font-weight: 700; }
.cal-hero-unit .cal-cap { font-size: 0.82rem; color: var(--text-muted); margin-left: 2px; }
.cal-sheet.fun .cal-cap { display: none; }
.cal-hero-goal { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.cal-hero-goaltxt { font-size: 0.7rem; font-weight: 800; color: var(--text-muted); }
.cal-hero-emoji { font-size: 1.6rem; line-height: 1; }
.cal-hero-emoji.hit { animation: cal-bob 1.8s ease-in-out infinite; }
.cal-sheet.fun .cal-hero-emoji { font-size: 1.9rem; }
.cal-ring-num { font-size: 1.05rem; font-weight: 900; color: var(--primary); }
@keyframes cal-bob { 0%, 100% { transform: translateY(0) rotate(-4deg); } 50% { transform: translateY(-4px) rotate(4deg); } }

.cal-ring { position: relative; display: inline-flex; align-items: center; justify-content: center; }
.cal-ring svg { display: block; }
.cal-ring-track { stroke: color-mix(in srgb, var(--primary) 18%, var(--cal-solid)); }
.cal-ring-bar { stroke: var(--primary); transition: stroke-dashoffset 0.8s cubic-bezier(.3,.8,.3,1); }
.cal-ring-bar.full { stroke: var(--cal-gold, #F59E0B); }
.cal-ring-inner { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }

.cal-test-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--border-color);
  font-size: 0.9rem;
}
.cal-face { font-size: 1.1rem; line-height: 1.2; }
.cal-test-stars { color: var(--cal-gold, #F59E0B); letter-spacing: 2px; font-size: 1rem; }
.cal-test-stars .off { color: color-mix(in srgb, var(--text-muted) 35%, transparent); }

/* the month grid */
.cal-swipe { touch-action: pan-y; }
.cal-swipe.slide-next { animation: cal-slide-next 0.24s ease; }
.cal-swipe.slide-prev { animation: cal-slide-prev 0.24s ease; }
@keyframes cal-slide-next { from { transform: translateX(28px); opacity: 0.2; } to { transform: none; opacity: 1; } }
@keyframes cal-slide-prev { from { transform: translateX(-28px); opacity: 0.2; } to { transform: none; opacity: 1; } }

.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); row-gap: 2px; column-gap: 2px; }
.cal-weekdays { margin-bottom: 4px; }
.cal-wd { text-align: center; font-size: 0.7rem; font-weight: 800; color: var(--text-muted); text-transform: uppercase; }

.cal-day {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 5px 0 4px; border: 0; border-radius: 14px;
  background: transparent; color: var(--text-main);
  font: inherit; cursor: pointer;
  transition: background 0.15s ease;
}
.cal-day.is-selected { background: color-mix(in srgb, var(--primary) 14%, var(--cal-solid)); }
.cal-day.is-future { opacity: 0.32; cursor: default; }
.cal-day.pop .cal-dring { animation: cal-pop 0.32s cubic-bezier(.3,1.6,.5,1); }
@keyframes cal-pop { 0% { transform: scale(0.8); } 100% { transform: scale(1); } }

.cal-dring { position: relative; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; }
.cal-dring svg { position: absolute; inset: 0; }
.cal-dtrack { stroke: color-mix(in srgb, var(--text-muted) 20%, transparent); }
.cal-dbar { stroke: var(--primary); }
.cal-dbar.full { stroke: var(--cal-gold, #F59E0B); }
.cal-dcount { position: relative; font-size: 0.86rem; font-weight: 900; letter-spacing: -0.02em; line-height: 1; }
.cal-day.is-goal .cal-dcount { color: var(--cal-gold, #F59E0B); }
.cal-ddate { font-size: 0.66rem; font-weight: 700; color: var(--text-muted); line-height: 1; }
.cal-day.is-today .cal-ddate {
  color: #fff; background: var(--accent);
  border-radius: 999px; padding: 2px 6px; margin: -2px 0;
  font-weight: 900;
}

.cal-tdot { position: absolute; top: -1px; right: -1px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--cal-solid); }
.cal-temoji { display: none; position: absolute; top: -4px; right: -5px; font-size: 0.7rem; line-height: 1; }
.cal-dstar { display: none; position: absolute; bottom: -3px; right: -5px; font-size: 0.7rem; line-height: 1; }
.cal-sheet.fun .cal-tdot { display: none; }
.cal-sheet.fun .cal-temoji, .cal-sheet.fun .cal-dstar { display: block; }
.cal-sheet.fun .cal-dstar { animation: cal-twinkle-plain 2.2s ease-in-out infinite; }
@keyframes cal-twinkle-plain { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.3); } }

/* slim month line */
.cal-monthline {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border-color);
  font-size: 0.95rem;
}
.cal-ml-item b { font-weight: 900; color: var(--primary); }
.cal-ml-label { font-size: 1.05rem; }

/* confetti (spawned on <body>, so it floats above the sheet) */
.cal-confetti-layer { position: fixed; inset: 0; z-index: 1200; pointer-events: none; overflow: hidden; }
.cal-confetti {
  position: absolute; width: 8px; height: 8px; border-radius: 2px;
  animation: cal-burst 1.1s cubic-bezier(.2,.7,.3,1) forwards;
}
@keyframes cal-burst {
  0% { transform: translate(0, 0) rotate(0) scale(1); opacity: 1; }
  70% { opacity: 1; }
  100% { transform: translate(var(--dx), calc(var(--dy) + 90px)) rotate(var(--rot)) scale(0.6); opacity: 0; }
}

.cal-day:focus-visible, .cal-nav-btn:focus-visible, .cal-close:focus-visible, .cal-icon-btn:focus-visible,
.cal-today-btn:focus-visible, .cal-open-link:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .cal-overlay, .cal-sheet, .cal-swipe, .cal-today-btn, .cal-dring, .cal-dstar, .cal-hero-emoji { animation: none !important; }
  .cal-ring-bar { transition: none; }
}

/* ============================================================
   Home (simplified): greeting -> hero ring + one action ->
   quick actions -> this week -> your words
   ============================================================ */
.hm-greet { margin: 2px 0 14px; }
.hm-greet h1 { margin: 0; font-size: 1.45rem; font-weight: 900; letter-spacing: -0.01em; color: var(--text-main); }
.hm-greet p { margin: 2px 0 0; font-size: 0.82rem; font-weight: 600; color: var(--text-muted); }

.hm-hero {
  display: flex; align-items: center; gap: 18px;
  padding: 18px 18px 16px; margin-bottom: 14px;
  border-radius: var(--radius-lg);
  background: var(--primary-panel-grad);
  box-shadow: var(--shadow);
  color: #fff;
}
.hm-hero-ring { flex: none; }
.hm-hero .cal-ring-track { stroke: rgba(255,255,255,0.25); }
.hm-hero .cal-ring-bar { stroke: #fff; }
.hm-hero .cal-ring-bar.full { stroke: #FCD34D; }
.hm-ring-in { display: flex; flex-direction: column; align-items: center; line-height: 1; gap: 3px; }
.hm-ring-num { font-size: 2.1rem; font-weight: 900; letter-spacing: -0.03em; }
.hm-ring-goal { font-size: 0.74rem; font-weight: 700; opacity: 0.85; }
.hm-hero-body { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.hm-hero-status { font-size: 1.12rem; font-weight: 900; line-height: 1.2; }
.hm-hero-sub { font-size: 0.8rem; font-weight: 600; opacity: 0.88; }
.hm-cta {
  margin-top: 10px; border: 0; cursor: pointer;
  background: #fff; color: var(--primary);
  font: inherit; font-size: 0.92rem; font-weight: 900;
  padding: 10px 18px; border-radius: 999px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.18);
  transition: transform 0.12s ease;
}
.hm-cta:active { transform: scale(0.96); }
.hm-chips { display: flex; gap: 8px; margin-top: 10px; }
.hm-chip {
  border: 0; font: inherit; font-size: 0.78rem; font-weight: 800; color: #fff;
  background: rgba(255,255,255,0.2); padding: 4px 10px; border-radius: 999px;
}
.hm-chip-btn { cursor: pointer; }
.hm-chip-btn:active { transform: scale(0.94); }

.hm-actions { display: flex; gap: 10px; margin-bottom: 22px; }
.hm-action {
  position: relative; flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 12px 6px 10px;
  border: 1px solid var(--border-color); border-radius: var(--radius-md);
  background: var(--panel-bg); color: var(--text-main);
  box-shadow: var(--shadow); font: inherit; cursor: pointer;
  transition: transform 0.12s ease;
}
.hm-action:active { transform: scale(0.95); }
.hm-a-icon { font-size: 1.5rem; line-height: 1; }
.hm-a-label { font-size: 0.76rem; font-weight: 800; }
.hm-a-label b { color: var(--accent); font-weight: 900; margin-left: 2px; }
.hm-a-badge {
  position: absolute; top: 8px; right: 10px;
  width: 10px; height: 10px; border-radius: 50%; background: var(--accent);
}
.hm-action.hot { border-color: var(--accent); }
.hm-action.hot .hm-a-badge { animation: hm-pulse 1.6s ease-in-out infinite; }
@keyframes hm-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); }
  50% { box-shadow: 0 0 0 6px transparent; }
}

.hm-words {
  display: block; width: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer;
  border: 1px solid var(--border-color); border-radius: var(--radius-lg);
  background: var(--panel-bg); box-shadow: var(--shadow);
  padding: 14px 16px; margin-bottom: 22px;
}
.hm-words:active { transform: scale(0.99); }
.hm-words-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.hm-words-title { font-size: 0.95rem; font-weight: 800; }
.hm-words-sub { font-size: 0.76rem; font-weight: 700; color: var(--text-muted); }
.hm-bar { display: flex; gap: 2px; height: 12px; border-radius: 8px; overflow: hidden; }
.hm-seg { display: block; min-width: 4px; }
.hm-new {
  /* 'New' = not started yet, so it should read as an empty/pending slot, not as a heavy
     filled block. A tint + hairline of the theme's muted color adapts to every theme. */
  background: color-mix(in srgb, var(--text-muted) 26%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--text-muted) 55%, transparent);
}
.hm-dot.hm-new { width: 8px; height: 8px; box-shadow: none; border: 1.5px solid color-mix(in srgb, var(--text-muted) 75%, transparent); box-sizing: border-box; }
.hm-learning { background: var(--accent); }
.hm-review { background: var(--primary); }
.hm-mastered { background: var(--secondary); }
.hm-legend { display: flex; justify-content: space-between; gap: 6px; margin-top: 10px; }
.hm-leg { display: inline-flex; align-items: center; gap: 4px; font-size: 0.78rem; min-width: 0; }
.hm-leg b { font-weight: 900; }
.hm-leg em { font-style: normal; font-size: 0.68rem; font-weight: 700; color: var(--text-muted); }
.hm-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; }

@media (max-width: 360px) {
  .hm-hero { gap: 12px; padding: 14px; }
  .hm-leg em { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hm-action.hot .hm-a-badge { animation: none; }
}

/* ============================================================
   Practice (simplified): slim top bar -> one card -> flip hint,
   then the 4 answers appear only after the card is flipped.
   ============================================================ */
.pr-top { margin-bottom: 16px; }
.pr-top-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; min-height: 40px; }
.pr-top-left { min-width: 0; flex: 1; }
.pr-top-right { display: flex; align-items: center; gap: 10px; flex: none; }
.pr-count { font-size: 1.05rem; font-weight: 900; color: var(--text-main); letter-spacing: -0.01em; }
.pr-count i { font-style: normal; color: var(--text-muted); font-weight: 700; margin: 0 1px; }
.pr-bar { height: 6px; border-radius: 6px; background: var(--progress-bg); overflow: hidden; }
.pr-bar i { display: block; height: 100%; border-radius: 6px; background: var(--progress-fill); transition: width 0.4s cubic-bezier(0.4,0,0.2,1); }

/* compact category picker: icon + native select styled as a pill */
.pr-cat {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  padding: 0 4px 0 12px; height: 38px; border-radius: 999px;
  border: 1px solid var(--border-color); background: var(--panel-bg);
  box-shadow: var(--shadow); cursor: pointer;
}
.pr-cat select {
  min-width: 0; max-width: 46vw; height: 100%; border: 0; background: transparent;
  color: var(--text-main); font: inherit; font-size: 0.85rem; font-weight: 800;
  padding: 0 6px; outline: none; cursor: pointer; text-overflow: ellipsis;
}
.pr-focus-tag {
  display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 8px 14px; border-radius: 999px; font-size: 0.85rem; font-weight: 800; color: var(--text-main);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 30%, transparent);
}
.pr-exit {
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer; line-height: 1;
  border: 1px solid var(--border-color); background: var(--panel-bg); color: var(--text-muted); font-size: 0.95rem;
}
.pr-exit:active { transform: scale(0.9); }

/* card tweaks */
.flip-card { height: clamp(240px, 42vh, 340px); margin-bottom: 14px; }
.pr-status { margin-left: 0; font-size: 0.68rem; padding: 3px 10px; }
.flip-face .eyebrow { margin-bottom: 12px; }

/* language chips: centered, no label, under the card */
.card-lang-row { justify-content: center; margin-bottom: 8px; }
.card-lang-row-label { display: none; }
.card-lang-chips { justify-content: center; }

.pr-hint { margin-bottom: 0; font-weight: 700; letter-spacing: 0.1px; }
.pr-grades {
  grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px;
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity 0.22s ease, transform 0.22s ease, visibility 0s linear 0.22s;
}
.flip-card.revealed ~ .pr-grades { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.flip-card.revealed ~ .pr-hint { display: none; }
.pr-grades button {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: 62px; padding: 8px 2px;
}
.gr-emoji { font-size: 1.35rem; line-height: 1; }
.gr-label { font-size: 0.74rem; font-weight: 800; }
@media (max-width: 380px) { .pr-grades { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* friendly empty / done states */
.pr-empty { text-align: center; padding: 34px 18px 10px; }
.pr-empty-emoji { font-size: 3.4rem; line-height: 1; margin-bottom: 12px; }
.pr-empty h2 { margin: 0 0 6px; font-size: 1.35rem; font-weight: 900; color: var(--text-main); }
.pr-empty p { margin: 0 0 18px; font-size: 0.92rem; font-weight: 600; color: var(--text-muted); line-height: 1.45; }
.pr-empty-btn {
  display: block; width: 100%; max-width: 320px; margin: 10px auto 0;
  padding: 14px 18px; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--primary-btn-grad); color: #fff; box-shadow: var(--primary-btn-glow);
  font: inherit; font-size: 0.95rem; font-weight: 900;
}
.pr-empty-btn.secondary { background: var(--panel-bg); color: var(--text-main); border: 1px solid var(--border-color); box-shadow: var(--shadow); }
.pr-empty-btn:active { transform: scale(0.97); }

@media (prefers-reduced-motion: reduce) {
  .pr-grades, .pr-bar i { transition: none; }
}

/* ============================================================
   Test (simplified): category pill -> hero ring + Start -> stage bar.
   Questions: one prompt card + big answers. Results: ring + review list.
   ============================================================ */
.tt-hero.is-hot { box-shadow: var(--shadow), 0 0 0 3px color-mix(in srgb, var(--accent) 55%, transparent); }
.hm-ring-num small { font-size: 0.95rem; font-weight: 800; margin-left: 1px; }
.tt-static { cursor: default; }
.tt-static:active { transform: none; }
.tt-dots { display: flex; justify-content: center; gap: 10px; margin: 6px 0 12px; }
.tt-dot { width: 14px; height: 14px; border-radius: 50%; background: var(--progress-bg); }
.tt-dot.on { background: var(--secondary); }

/* question screen */
.tq-dir { font-size: 1.15rem; font-weight: 800; letter-spacing: 1px; }
.tq-score { font-size: 0.95rem; font-weight: 900; color: var(--secondary); }
.tq-card {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: clamp(120px, 20vh, 170px); margin-bottom: 16px; padding: 22px 18px;
  border-radius: var(--radius-lg);
  background: var(--card-back-grad); box-shadow: var(--shadow);
}
.tq-word {
  font-size: clamp(1.7rem, 8vw, 2.4rem); font-weight: 900; line-height: 1.15;
  color: var(--card-back-text); text-shadow: var(--card-back-glow);
  overflow-wrap: anywhere; max-width: 100%;
}
.tq-options { display: grid; gap: 10px; }
.tq-opt {
  position: relative; display: block; width: 100%; text-align: center;
  min-height: 56px; padding: 14px 44px; font-size: 1rem; font-weight: 800;
  border-radius: 16px; border: 2px solid var(--border-color);
  background: var(--panel-bg); box-shadow: var(--shadow);
}
.tq-opt:active:not(:disabled) { transform: scale(0.98); }
.tq-opt.correct, .tq-opt.incorrect { color: var(--text-main); }
.tq-opt.correct::after, .tq-opt.incorrect::after {
  position: absolute; right: 16px; top: 50%; transform: translateY(-50%);
  font-size: 1.2rem; font-weight: 900;
}
.tq-opt.correct::after { content: "✓"; color: var(--secondary); }
.tq-opt.incorrect::after { content: "✕"; color: var(--danger); }
.tq-input { min-height: 56px; text-align: center; font-size: 1.1rem; font-weight: 700; border-radius: 16px; border-width: 2px; margin-bottom: 12px; }
.tq-check { margin-top: 0; }
.tq-feedback { min-height: 26px; margin: 14px 0 4px; text-align: center; font-size: 1.05rem; font-weight: 800; overflow-wrap: anywhere; }
.tq-feedback.correct { color: var(--secondary); }
.tq-feedback.incorrect { color: var(--danger); }
.tq-next { margin-top: 8px; }

/* results */
.ts-hero { text-align: center; padding: 22px 16px 18px; margin-bottom: 16px; border-radius: var(--radius-lg); background: var(--panel-bg); border: 1px solid var(--border-color); box-shadow: var(--shadow); }
.ts-hero .cal-ring { margin: 0 auto 8px; }
.ts-hero .cal-ring-track { stroke: color-mix(in srgb, var(--text-muted) 20%, transparent); }
.ts-great .cal-ring-bar { stroke: var(--secondary); }
.ts-ok .cal-ring-bar { stroke: var(--primary); }
.ts-low .cal-ring-bar { stroke: var(--accent); }
.ts-emoji { font-size: 2rem; line-height: 1; }
.ts-pct { font-size: 1.35rem; font-weight: 900; margin-top: 2px; }
.ts-hero h2 { margin: 6px 0 2px; font-size: 1.4rem; font-weight: 900; }
.ts-hero p { margin: 0; font-size: 0.9rem; font-weight: 700; color: var(--text-muted); }
.ts-pills { display: flex; justify-content: center; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.ts-pill { font-size: 0.8rem; font-weight: 800; padding: 5px 12px; border-radius: 999px; background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--primary); }
.ts-h { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: 0.95rem; font-weight: 800; }
.ts-h span { font-size: 0.75rem; padding: 2px 9px; border-radius: 999px; background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.ts-list { border: 1px solid var(--border-color); border-radius: var(--radius-md); background: var(--panel-bg); overflow: hidden; margin-bottom: 14px; }
.ts-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; }
.ts-row + .ts-row { border-top: 1px solid var(--border-color); }
.ts-mark { flex: none; width: 24px; height: 24px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 0.8rem; font-weight: 900; color: #fff; }
.ts-mark.ok { background: var(--secondary); }
.ts-mark.bad { background: var(--danger); }
.ts-w { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.ts-w b { font-size: 0.95rem; font-weight: 800; overflow-wrap: anywhere; }
.ts-w em { font-style: normal; font-size: 0.8rem; color: var(--text-muted); overflow-wrap: anywhere; }
.ts-row .tag { flex: none; font-size: 0.66rem; font-weight: 800; padding: 3px 8px; border-radius: 999px; }
.ts-all { margin-bottom: 10px; }
.ts-all summary { cursor: pointer; padding: 8px 4px; font-size: 0.85rem; font-weight: 800; color: var(--primary); list-style-position: inside; }
.ts-all .ts-list { margin-top: 6px; }

/* ============================================================
   Manage: search + filter chips + a clean word list.
   ============================================================ */
.mg-top { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.mg-sync {
  flex: none; width: 40px; height: 40px; border-radius: 50%; font-size: 1.1rem; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-color); background: var(--panel-bg); cursor: default;
}
button.mg-sync { cursor: pointer; }
.mg-sync.on { border-color: color-mix(in srgb, var(--secondary) 50%, var(--border-color)); }


/* words: search, filters, list */
.mg-search {
  display: flex; align-items: center; gap: 10px; height: 46px; padding: 0 14px; margin-bottom: 10px;
  border-radius: 999px; border: 1px solid var(--border-color); background: var(--panel-bg); box-shadow: var(--shadow);
}
.mg-search input {
  flex: 1; min-width: 0; height: 100%; border: 0; background: transparent; outline: none;
  color: var(--text-main); font: inherit; font-size: 16px; font-weight: 600;
}
.mg-filters { margin-bottom: 10px; }
.mg-chips { display: flex; gap: 8px; overflow-x: auto; padding: 2px 2px 8px; margin: 0 -2px 6px; scrollbar-width: none; }
.mg-chips::-webkit-scrollbar { display: none; }
.mg-chip {
  flex: none; display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 7px 12px; border-radius: 999px; font: inherit; font-size: 0.8rem; font-weight: 800;
  border: 1.5px solid var(--border-color); background: var(--panel-bg); color: var(--text-main);
}
.mg-chip b { font-weight: 900; color: var(--text-muted); font-size: 0.74rem; }
.mg-chip.active { background: var(--primary-btn-grad); color: #fff; border-color: transparent; box-shadow: var(--primary-btn-glow); }
.mg-chip.active b { color: rgba(255,255,255,0.85); }

.mg-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none; background: var(--text-muted); }
.mg-dot-new { background: color-mix(in srgb, var(--text-muted) 26%, transparent); border: 1.5px solid color-mix(in srgb, var(--text-muted) 75%, transparent); box-sizing: border-box; }
.mg-dot-learning { background: var(--accent); }
.mg-dot-review { background: var(--primary); }
.mg-dot-mastered { background: var(--secondary); }
.mg-chip.active .mg-dot { box-shadow: 0 0 0 2px rgba(255,255,255,0.55); }

.mg-count { font-size: 0.78rem; font-weight: 700; color: var(--text-muted); margin: 2px 4px 8px; }
.mg-list { border: 1px solid var(--border-color); border-radius: var(--radius-lg); background: var(--panel-bg); box-shadow: var(--shadow); overflow: hidden; margin-bottom: 14px; }
.mg-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; }
.mg-row + .mg-row { border-top: 1px solid var(--border-color); }
.mg-row.is-hidden { opacity: 0.6; }
.mg-row-main { flex: 1; min-width: 0; line-height: 1.25; }
.mg-sv { font-size: 1rem; font-weight: 800; overflow-wrap: anywhere; }
.mg-en { font-size: 0.85rem; color: var(--text-muted); overflow-wrap: anywhere; }
.mg-cat-tag { opacity: 0.75; }
.mg-trans { font-size: 0.85rem; margin-top: 1px; }
.mg-lapse { font-size: 0.7rem; font-weight: 800; color: var(--danger); margin-left: 4px; }
.mg-act {
  flex: none; width: 38px; height: 38px; border-radius: 50%; font-size: 1.05rem; line-height: 1; cursor: pointer;
  border: 1px solid var(--border-color); background: transparent; display: inline-flex; align-items: center; justify-content: center;
}
.mg-act:active { transform: scale(0.9); }


/* ============================================================
   Settings (simplified): header -> account -> goal -> theme ->
   languages -> voices. Admin tools render only for admins.
   ============================================================ */
.st-me {
  display: flex; align-items: center; gap: 14px; margin-bottom: 14px; padding: 16px;
  border-radius: var(--radius-lg); background: var(--primary-panel-grad); color: #fff; box-shadow: var(--shadow);
}
.st-me-avatar { flex: none; width: 54px; height: 54px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 1.9rem; background: rgba(255,255,255,0.2); }
.st-me-txt { flex: 1; min-width: 0; }
.st-me-name { font-size: 1.15rem; font-weight: 900; overflow-wrap: anywhere; }
.st-me-sub { font-size: 0.8rem; font-weight: 600; opacity: 0.88; overflow-wrap: anywhere; }
.st-me-chips { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; flex: none; }
.st-chip { font-size: 0.76rem; font-weight: 800; padding: 4px 10px; border-radius: 999px; background: rgba(255,255,255,0.2); color: #fff; white-space: nowrap; }
.st-chip-admin { background: #fff; color: var(--primary); }

.st-card {
  display: block; margin-bottom: 14px; padding: 16px;
  border: 1px solid var(--border-color); border-radius: var(--radius-lg);
  background: var(--panel-bg); box-shadow: var(--shadow);
}
.st-card h3 { display: flex; align-items: center; gap: 8px; margin: 0 0 12px; font-size: 1rem; font-weight: 800; }
.st-hint { margin: 8px 0 0; font-size: 0.78rem; font-weight: 600; color: var(--text-muted); line-height: 1.4; overflow-wrap: anywhere; }
.st-hint:empty { display: none; }
.st-center { text-align: center; }

.st-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 4px 0; }
.st-row-l { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 0.92rem; }
.st-prov { display: inline-flex; width: 22px; justify-content: center; }
.st-email { font-weight: 800; overflow-wrap: anywhere; }
.st-ok { color: var(--secondary); font-weight: 900; }
.st-row-link { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border-color); }

.st-actions { display: flex; gap: 10px; margin-top: 12px; }
.st-actions.st-wrap { flex-wrap: wrap; margin-top: 0; }
.st-btn {
  flex: 1; min-height: 44px; padding: 10px 14px; border-radius: 999px; cursor: pointer;
  border: 1.5px solid var(--border-color); background: transparent; color: var(--text-main);
  font: inherit; font-size: 0.88rem; font-weight: 800; transition: transform 0.12s ease;
}
.st-btn:active:not(:disabled) { transform: scale(0.97); }
.st-btn:disabled { opacity: 0.45; cursor: default; }
.st-btn-primary { background: var(--primary-btn-grad); color: #fff; border-color: transparent; box-shadow: var(--primary-btn-glow); }
.st-btn-danger { border-color: var(--danger); color: var(--danger); }
.st-mini { flex: none; padding: 6px 14px; border-radius: 999px; border: 1.5px solid var(--border-color); background: transparent; color: var(--primary); font: inherit; font-size: 0.8rem; font-weight: 800; cursor: pointer; }
.st-mini-danger { border-color: var(--danger); color: var(--danger); }
.st-link { display: block; margin: 10px 0 0; padding: 6px 0; border: 0; background: none; cursor: pointer; color: var(--primary); font: inherit; font-size: 0.85rem; font-weight: 800; }
.st-google {
  display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; min-height: 48px;
  border-radius: 999px; border: 1.5px solid var(--border-color); background: var(--bg-base); color: var(--text-main);
  font: inherit; font-size: 0.95rem; font-weight: 800; cursor: pointer;
}
#st-email-form input, .st-inline input, .st-field-label select, .st-inline select {
  width: 100%; min-height: 44px; padding: 10px 14px; margin-top: 10px; box-sizing: border-box;
  border-radius: 14px; border: 1.5px solid var(--border-color); background: var(--bg-base); color: var(--text-main);
  font: inherit; font-size: 16px;
}
#st-email-form[hidden] { display: none; }
.st-inline { display: flex; gap: 8px; align-items: stretch; }
.st-inline input, .st-inline select { flex: 1; min-width: 0; margin-top: 8px; }
.st-inline .st-btn { flex: none; margin-top: 8px; }
.st-inline-gen input[type="number"] { flex: none; width: 76px; }
.st-mono { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 0.82rem !important; }
.st-field-label { display: block; margin-top: 10px; font-size: 0.8rem; font-weight: 700; color: var(--text-muted); }

/* goal stepper */
.st-stepper { display: flex; align-items: center; justify-content: center; gap: 18px; }
.st-step {
  width: 52px; height: 52px; border-radius: 50%; cursor: pointer; font-size: 1.7rem; font-weight: 800; line-height: 1;
  border: 0; background: color-mix(in srgb, var(--primary) 14%, var(--panel-bg)); color: var(--primary);
  transition: transform 0.12s ease;
}
.st-step:active { transform: scale(0.9); }
.st-goal { display: flex; flex-direction: column; align-items: center; min-width: 96px; }
.st-goal output { font-size: 2.6rem; font-weight: 900; line-height: 1; color: var(--primary); letter-spacing: -0.03em; }
.st-goal span { font-size: 0.72rem; font-weight: 700; color: var(--text-muted); margin-top: 4px; }

/* appearance: light/dark/auto + country theme picker */
.st-mode { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; padding: 4px; border-radius: 16px; background: var(--progress-bg); }
.st-mode-btn { border: 0; border-radius: 12px; padding: 10px 6px; font: inherit; font-weight: 700; font-size: 0.86rem; color: var(--text-muted); background: transparent; cursor: pointer; transition: background .15s, color .15s; }
.st-mode-btn.active { background: var(--bg-surface); color: var(--text-main); box-shadow: var(--shadow); }
.st-hint { margin: 8px 2px 0; font-size: 0.78rem; color: var(--text-muted); }
.st-country-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 16px 0 10px; font-size: 0.9rem; }
.st-count { margin: 0; }
.st-dd { position: relative; }
.st-dd-btn { width: 100%; display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-radius: 16px; border: 2px solid var(--border-color); background: var(--bg-surface); color: var(--text-main); font: inherit; text-align: left; cursor: pointer; }
.st-dd.open .st-dd-btn, .st-dd-btn:focus-visible { border-color: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 22%, transparent); outline: none; }
.st-dd-name { flex: 1; min-width: 0; font-weight: 800; font-size: 0.95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-dd-caret { color: var(--text-muted); font-size: 1rem; transition: transform .15s ease; }
.st-dd.open .st-dd-caret { transform: rotate(180deg); }
.st-dd-panel { margin-top: 8px; padding: 10px; border-radius: 18px; border: 1px solid var(--border-color); background: var(--bg-surface); box-shadow: var(--shadow); }
.st-dd-panel[hidden] { display: none; }
.st-country-search { width: 100%; box-sizing: border-box; padding: 10px 14px; margin-bottom: 8px; border-radius: 12px; border: 1px solid var(--border-color); background: var(--bg-base); color: var(--text-main); font: inherit; font-size: 0.9rem; }
.st-dd-list { display: flex; flex-direction: column; gap: 2px; max-height: 280px; overflow-y: auto; overscroll-behavior: contain; }
.st-country { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 12px; border: 0; background: transparent; color: var(--text-main); font: inherit; text-align: left; cursor: pointer; }
.st-country[hidden] { display: none; }
.st-country:hover { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.st-country.active { background: color-mix(in srgb, var(--primary) 14%, transparent); }
.st-flag { flex: 0 0 auto; width: 38px; height: 26px; border-radius: 6px; border: 1px solid rgba(128,128,128,.35); box-shadow: 0 1px 3px rgba(0,0,0,.18); }
.st-country-name { flex: 1; min-width: 0; font-weight: 700; font-size: 0.9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-country-dots { display: flex; gap: 4px; }
.st-country-dots i { width: 13px; height: 13px; border-radius: 50%; border: 1px solid rgba(128,128,128,.4); }
.st-country-check { visibility: hidden; font-weight: 900; color: var(--primary); width: 16px; text-align: center; }
.st-country.active .st-country-check { visibility: visible; }

/* collapsible sections */
.st-more { margin-top: 12px; }
.st-more > summary, .st-danger > summary { cursor: pointer; font-size: 0.88rem; font-weight: 800; color: var(--primary); padding: 6px 0; }
.st-danger > summary { color: var(--danger); font-size: 0.95rem; }
.st-danger[open] > summary { margin-bottom: 4px; }
.st-danger .st-btn { margin-top: 12px; width: 100%; flex: none; }

/* admin block */
.st-admin { border-color: color-mix(in srgb, var(--primary) 45%, var(--border-color)); background: color-mix(in srgb, var(--primary) 6%, var(--panel-bg)); }
.st-badge { margin-left: auto; font-size: 0.64rem; font-weight: 800; padding: 3px 9px; border-radius: 999px; background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary); }
.st-admin-item { padding-top: 12px; border-top: 1px solid var(--border-color); }
.st-admin-item:first-of-type { border-top: 0; padding-top: 0; }
.st-admin-item > summary { font-size: 0.95rem; }
.st-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; margin-top: 4px; }
.st-table th { text-align: left; padding: 4px 6px; }
.st-table th:not(:first-child), .st-table td:not(:first-child) { text-align: right; font-weight: 800; }
.st-table td { padding: 4px 6px; border-top: 1px solid var(--border-color); }
.st-plist .st-row { border-top: 1px solid var(--border-color); }


/* ============================================================
   Practice by topic (Home): colorful cards, one hue per topic.
   --tc is set inline on each card.
   ============================================================ */
.tp-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 8px; }
.tp-card {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: stretch; gap: 8px;
  padding: 12px 12px 11px; text-align: left; font: inherit; cursor: pointer;
  color: var(--text-main);
  border: 1px solid color-mix(in srgb, var(--tc) 35%, var(--border-color));
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 90% at 100% 0%, color-mix(in srgb, var(--tc) 22%, transparent), transparent 60%),
    var(--panel-bg);
  box-shadow: var(--shadow);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.tp-card:active { transform: scale(0.97); }
.tp-card:focus-visible, .tp-more:focus-visible { outline: 3px solid color-mix(in srgb, var(--tc, var(--primary)) 60%, transparent); outline-offset: 2px; }
.tp-top { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.tp-icon { flex: none; font-size: 1.9rem; line-height: 1; }
.tp-badge { font-size: 0.72rem; font-weight: 900; padding: 4px 9px; border-radius: 999px; white-space: nowrap; }
.tp-badge.is-due { background: var(--tcd); color: #fff; }
.tp-badge.is-clear { background: var(--progress-bg); color: var(--text-muted); }
.tp-card.has-due .tp-badge.is-due { animation: tp-pulse 2s ease-in-out infinite; }
@keyframes tp-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tc) 55%, transparent); }
  50% { box-shadow: 0 0 0 6px transparent; }
}
.tp-name { font-size: 0.95rem; font-weight: 900; line-height: 1.2; min-height: 2.4em; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tp-bar { height: 6px; border-radius: 6px; background: color-mix(in srgb, var(--tc) 16%, transparent); overflow: hidden; }
.tp-bar i { display: block; height: 100%; border-radius: 6px; background: var(--tc); }
.tp-foot { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 0.72rem; font-weight: 700; color: var(--text-muted); }
.tp-count { white-space: nowrap; }
.tp-total { font-weight: 900; color: var(--text-main); white-space: nowrap; }
.tp-more {
  display: block; width: 100%; margin: 4px 0 8px; padding: 12px; cursor: pointer;
  border: 1px dashed var(--border-color); border-radius: var(--radius-md);
  background: transparent; color: var(--text-muted); font: inherit; font-size: 0.85rem; font-weight: 800;
}
.tp-more:active { transform: scale(0.98); }
@media (max-width: 340px) { .tp-grid { grid-template-columns: minmax(0, 1fr); } }
@media (prefers-reduced-motion: reduce) {
  .tp-card { transition: none; }
  .tp-card.has-due .tp-badge.is-due { animation: none; }
}

/* Manage header (Words list only) */
.mg-title { flex: 1; margin: 0; font-size: 1.35rem; font-weight: 900; color: var(--text-main); display: flex; align-items: baseline; gap: 8px; }
.mg-title-n { font-size: 0.85rem; font-weight: 800; color: var(--text-muted); }
