:root {
  --bg: #ffffff;
  --fg: #1a1a2e;
  --muted: #6b7280;
  --card-bg: #f7f7fb;
  --card-border: #e8e8f0;
  --accent: #22b573;       /* primary green -- correct / progress / CTA */
  --accent-dark: #1a9c62;
  --accent-fg: #ffffff;
  --accent-soft: #e6f8ef;
  --gold: #ffb100;         /* locked/level badges */
  --danger: #ff5252;
  --border: #e5e7eb;
  --banner-bg: #fff4d6;
  --banner-border: #ffe19a;
  --shadow: 0 2px 0 rgba(0, 0, 0, 0.06);
}

/* Dark palette, applied two ways:
   1. @media (prefers-color-scheme: dark) -- the standalone-browser case,
      following the OS/browser setting. Guarded with :not([data-theme="light"])
      so an explicit Telegram override (below) can still force light.
   2. :root[data-theme="dark"] -- the in-Telegram case. app.js reads
      Telegram.WebApp.colorScheme (Telegram's OWN theme setting, which can
      disagree with the OS -- e.g. Telegram Desktop has its own light/dark
      toggle) and stamps data-theme on <html> to match, live-updating on
      Telegram's "themeChanged" event. This always wins over prefers-color-scheme. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0f1117;
    --fg: #f2f2f7;
    --muted: #9aa0ab;
    --card-bg: #171922;
    --card-border: #262936;
    --accent: #2ecf82;
    --accent-dark: #22b573;
    --accent-fg: #06120c;
    --accent-soft: #12281d;
    --gold: #ffc94d;
    --danger: #ff6b6b;
    --border: #262936;
    --banner-bg: #2a2410;
    --banner-border: #4a3f18;
    --shadow: 0 2px 0 rgba(0, 0, 0, 0.3);
  }
}

:root[data-theme="dark"] {
  --bg: #0f1117;
  --fg: #f2f2f7;
  --muted: #9aa0ab;
  --card-bg: #171922;
  --card-border: #262936;
  --accent: #2ecf82;
  --accent-dark: #22b573;
  --accent-fg: #06120c;
  --accent-soft: #12281d;
  --gold: #ffc94d;
  --danger: #ff6b6b;
  --border: #262936;
  --banner-bg: #2a2410;
  --banner-border: #4a3f18;
  --shadow: 0 2px 0 rgba(0, 0, 0, 0.3);
}

* { box-sizing: border-box; }

/* Form controls (button/select/input/textarea) don't inherit color/font
   from the page by default -- the <meta name="color-scheme"> tag in
   base.html makes browsers hand them native OS-scheme colors instead,
   which follow the device's raw light/dark state and can silently
   mismatch our own --fg/--bg (e.g. our JS-driven Telegram dark/light
   override vs. a phone set to the opposite scheme), producing
   near-invisible text. Every element below still overrides color/background
   explicitly per its own class; this is just the safety net for any that
   forget to. */
button, select, input, textarea {
  color: inherit;
  font-family: inherit;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  line-height: 1.5;
}

/* Full-page floor for the standalone website only (html.tg-app is set by
   app.js when actually running inside Telegram) -- see the "tg-app" class
   comment in app.js for why this must NOT apply inside the Mini App. */
html:not(.tg-app) body {
  min-height: 100vh;
}

#app, .center-page {
  max-width: 480px;
  margin: 0 auto;
  padding: 0 1rem 2.5rem;
}

.center-page { padding-top: 15vh; text-align: center; }

.view { padding-top: 0.75rem; }

/* ---- topbar / navigation ------------------------------------------------ */

.topbar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0 1rem;
  position: sticky;
  top: 0;
  background: var(--bg);
  z-index: 5;
}

.brand {
  font-weight: 800;
  font-size: 1.15rem;
  flex: 1;
}

.icon-btn {
  background: none;
  border: none;
  color: var(--fg);
  font-size: 1.3rem;
  cursor: pointer;
  padding: 0.25rem 0.4rem;
  border-radius: 8px;
  text-decoration: none;
  line-height: 1;
}
.icon-btn:hover { background: var(--card-bg); }

/* ---- stats row ------------------------------------------------------------ */

.stats-row {
  display: flex;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.stat {
  flex: 1;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 14px;
  padding: 0.85rem 0.5rem;
  text-align: center;
}

.stat-value {
  display: block;
  font-size: 1.4rem;
  font-weight: 800;
  color: var(--accent-dark);
}

.stat-label {
  display: block;
  font-size: 0.75rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-top: 0.15rem;
}

/* ---- buttons -------------------------------------------------------------- */

.cta-btn {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font-size: 1.05rem;
  font-weight: 700;
  padding: 0.95rem 1.2rem;
  border-radius: 16px;
  border: none;
  background: var(--accent);
  color: var(--accent-fg);
  cursor: pointer;
  box-shadow: 0 3px 0 var(--accent-dark);
  margin: 0.5rem 0;
  transition: transform 0.05s;
  text-decoration: none;
  text-align: center;
}
.cta-btn:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--accent-dark); }

.secondary-btn {
  font-size: 0.95rem;
  padding: 0.65rem 1.1rem;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--card-bg);
  color: var(--fg);
  cursor: pointer;
  margin: 0.35rem 0.35rem 0.35rem 0;
}
.secondary-btn:active { opacity: 0.8; }

/* ---- section headers ------------------------------------------------------- */

.section-title {
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin: 1.5rem 0 0.75rem;
}

.course-path-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.mascot-icon {
  width: 28px;
  height: auto;
  flex: 0 0 auto;
}

.mascot-celebrate {
  width: 110px;
  height: auto;
  margin: 0.25rem 0;
}

/* Correct/incorrect exercise feedback, and the paywall's post-payment moment. */
.mascot-feedback {
  display: block;
  width: 84px;
  height: auto;
  margin: 0 auto 0.5rem;
}

/* Small inline icon inside a one-line "nothing due" message. */
.mascot-inline {
  width: 22px;
  height: auto;
  vertical-align: middle;
  margin-right: 0.35rem;
}

/* ---- course path ------------------------------------------------------------ */

.level-path {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding-bottom: 1rem;
}

.level-node {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  width: 100%;
  text-align: left;
  background: var(--card-bg);
  color: var(--fg);
  border: 1px solid var(--card-border);
  border-radius: 14px;
  padding: 0.8rem 1rem;
  cursor: pointer;
  box-shadow: var(--shadow);
}
.level-node:disabled { cursor: default; opacity: 0.55; box-shadow: none; }
.level-node.completed { border-color: var(--accent); background: var(--accent-soft); }

.level-node-badge {
  flex: 0 0 auto;
  width: 2.4rem;
  height: 2.4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--gold);
  color: #3a2a00;
  font-weight: 800;
  font-size: 1rem;
}
.level-node.completed .level-node-badge { background: var(--accent); color: var(--accent-fg); }
.level-node.locked .level-node-badge { background: var(--border); color: var(--muted); }

.level-node-body { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.level-node-title { font-weight: 700; }
.level-node-sub { font-size: 0.82rem; }

/* ---- progress bars ------------------------------------------------------------ */

.progress-track {
  height: 10px;
  border-radius: 6px;
  background: var(--card-border);
  overflow: hidden;
  margin: 0.5rem 0;
}
.progress-track.lesson-progress { flex: 1; margin: 0; height: 12px; }
.progress-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  transition: width 0.25s ease;
}

/* ---- cards -------------------------------------------------------------------- */

.card {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 16px;
  padding: 1.5rem;
  margin-bottom: 1rem;
  box-shadow: var(--shadow);
}
.card.center { text-align: center; }

.banner {
  background: var(--banner-bg);
  border: 1px solid var(--banner-border);
  border-radius: 16px;
  padding: 1rem;
  margin-bottom: 1rem;
}

.offline-banner {
  margin: 1rem 1rem 0;
  text-align: center;
  font-size: 0.9rem;
  font-weight: 600;
}

.instructions {
  font-size: 1.1rem;
  font-weight: 700;
  margin-top: 0;
}

.prompt {
  font-size: 1.4rem;
  margin: 1rem 0;
}

.grammar-note {
  font-size: 0.88rem;
  background: var(--accent-soft);
  color: var(--accent-dark);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  margin: 0 0 1rem;
}

.feedback-text { font-size: 1.15rem; font-weight: 700; }

.muted { color: var(--muted); font-size: 0.9rem; }
.center { text-align: center; }
.error { color: var(--danger); }
.big-emoji { font-size: 3rem; margin: 0.25rem 0; }

/* ---- inputs -------------------------------------------------------------------- */

input[type="text"] {
  font-size: 1.1rem;
  padding: 0.65rem 0.8rem;
  width: 100%;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--fg);
  margin-bottom: 0.75rem;
}

.translate-direction-select, .translate-textarea {
  font-size: 1.05rem;
  padding: 0.65rem 0.8rem;
  width: 100%;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--fg);
  margin-bottom: 0.75rem;
  font-family: inherit;
}

.translate-textarea {
  min-height: 5.5rem;
  resize: vertical;
}

.translate-output {
  font-size: 1.15rem;
  white-space: pre-wrap;
}

#exercise-prompt, #dialogue-line {
  background: var(--bg);
  border-radius: 10px;
  padding: 0.85rem 1rem;
  border: 1px solid var(--card-border);
}

/* ---- level preview list --------------------------------------------------------- */

.items-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.item-row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 12px;
  padding: 0.65rem 0.9rem;
}
.item-row.mastered { border-color: var(--accent); }

.item-row-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.item-vi { font-weight: 700; flex: 0 0 auto; }
.item-en { font-size: 0.85rem; flex: 1; text-align: right; }
.item-check { color: var(--accent); font-weight: 800; flex: 0 0 auto; }

/* ---- exercise-type preview (level detail, tap-to-expand) ------------------------ */

.preview-details {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--card-border);
}
.preview-row {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.85rem;
}
.preview-row.passed .preview-label { color: var(--accent-dark); }
.preview-label { font-weight: 600; flex: 0 0 auto; }
.preview-sample { text-align: right; }

/* ---- practice mode cards (level detail) -------------------------------------------- */

.mode-card {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 16px;
  padding: 1.1rem;
  margin-bottom: 1rem;
}
.mode-card-head {
  display: flex;
  justify-content: space-between;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

/* ---- dialogue chat transcript -------------------------------------------------------- */

.chat-transcript {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: 45vh;
  overflow-y: auto;
  margin: 0.75rem 0;
  padding: 0.25rem;
}
.chat-bubble {
  max-width: 80%;
  padding: 0.6rem 0.9rem;
  border-radius: 14px;
  font-size: 1rem;
}
.chat-bubble.persona {
  align-self: flex-start;
  background: var(--card-border);
  border-bottom-left-radius: 4px;
}
.chat-bubble.learner {
  align-self: flex-end;
  background: var(--accent);
  color: var(--accent-fg);
  border-bottom-right-radius: 4px;
}

.chat-input-row {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
#chat-input {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  margin-bottom: 0;
}
#chat-record-btn {
  flex: 0 0 auto;
  width: auto;
  margin: 0;
}
.icon-send-btn {
  /* Fixed square, not width:auto -- the old #chat-send-btn ID rule beat
     this class rule on specificity regardless of source order, leaving
     height:40px fixed but width unconstrained, which stretched the
     button into an oval. Sized to match the record button's natural
     footprint rather than a large circular FAB. */
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: var(--accent);
  color: var(--accent-fg);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  margin: 0;
  box-shadow: 0 2px 0 var(--accent-dark);
}
.icon-send-btn:active { transform: translateY(1px); box-shadow: none; }
.icon-send-btn:disabled { opacity: 0.6; cursor: default; }

/* The input bar is pinned to the true bottom of the viewport (like every
   chat app, including Telegram's own) rather than relying on the chat
   view's container height matching Telegram's actual allocated frame --
   that measurement (via vh units or Telegram's own viewportHeight API)
   turned out to be unreliable inside the Mini App during in-session view
   switches, so anchoring to the real viewport directly sidesteps the
   problem instead of depending on a number that can't be trusted. */
.chat-view .chat-input-row {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  max-width: 480px;
  margin: 0 auto;
  padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
  background: var(--bg);
  border-top: 1px solid var(--card-border);
  z-index: 10;
}
.chat-view .chat-transcript {
  max-height: none;
  padding-bottom: 5rem; /* room for the fixed input bar so the last message isn't hidden behind it */
}
.chat-view #chat-record-status {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 4.5rem;
  max-width: 480px;
  margin: 0 auto;
  padding: 0 1rem;
  text-align: center;
}
.chat-bubble-controls { display: flex; gap: 0.4rem; margin-top: 0.25rem; margin-bottom: 0.35rem; }
.chat-bubble-controls.right { justify-content: flex-end; }
.chat-bubble-controls button {
  font-size: 0.8rem;
  padding: 0.2rem 0.5rem;
  margin: 0;
}
