/* TNPSC PYQ vault — shared design system.
   Token names describe role, not appearance: the previous --bg-dark held a
   light colour, which made the dark-mode block impossible to reason about. */

:root {
  --surface-page: #f8fafc;
  --surface-card: #ffffff;
  --surface-sunken: #f1f5f9;
  --border-color: #e2e8f0;
  --border-hover: rgba(79, 70, 229, 0.3);

  --text-main: #0f172a;
  --text-muted: #64748b;

  --primary: #4f46e5;
  --primary-hover: #3730a3;
  --primary-glow: rgba(79, 70, 229, 0.08);

  --accent-green: #16a34a;
  --accent-green-bg: #f0fdf4;
  --accent-amber: #d97706;
  --accent-amber-bg: #fef3c7;
  --accent-red: #ef4444;
  --accent-red-bg: #fef2f2;

  --unit-1: #3b82f6; --unit-2: #10b981; --unit-3A: #8b5cf6;
  --unit-3B: #ec4899; --unit-4: #f59e0b; --unit-5A: #ef4444;
  --unit-5B: #06b6d4; --unit-6A: #a855f7; --unit-6B: #14b8a6;
  --unit-6C: #db2777; --unit-7: #f43f5e; --unit-8: #84cc16;

  --font-ui: 'Inter', system-ui, sans-serif;
  --font-display: 'Outfit', system-ui, sans-serif;
  --font-tamil: 'Noto Sans Tamil', 'Nirmala UI', sans-serif;

  --measure: 68ch;
  --tap-target: 44px;
}

/* Dark mode must override the accents, not only the surfaces. The light-mode
   accents are chosen to sit on white; the same values on #111827 fall below
   readable contrast — indigo --primary on --primary-glow measures 2.67:1,
   under even the 3:1 non-text floor, and it renders on the unit tag of every
   question card. These are the 300-weight equivalents, which clear 4.5:1
   against the dark card. Borders drawn with the same tokens get lighter too,
   which is the right direction on a dark surface. */
body.dark-mode {
  --surface-page: #0b1120;
  --surface-card: #111827;
  --surface-sunken: #1f2937;
  --border-color: #1f2937;
  --text-main: #e5e7eb;
  --text-muted: #9ca3af;

  --primary: #a5b4fc;
  --primary-hover: #c7d2fe;
  --primary-glow: rgba(165, 180, 252, 0.14);
  --border-hover: rgba(165, 180, 252, 0.45);

  --accent-green: #86efac;
  --accent-amber: #fcd34d;
  --accent-red: #fca5a5;
  --accent-green-bg: rgba(22, 163, 74, 0.12);
  --accent-amber-bg: rgba(217, 119, 6, 0.12);
  --accent-red-bg: rgba(239, 68, 68, 0.12);
}

/* Inter ships no Tamil glyphs. Without an explicit Tamil face every Tamil
   line falls back to whatever the OS provides — Nirmala UI on Windows,
   something arbitrary elsewhere, tofu in the worst case. Tamil also needs
   more leading than Latin at the same size. */

body {
  font-family: var(--font-ui);
  background: var(--surface-page);
  color: var(--text-main);
  margin: 0;
}

h1, h2, h3 { font-family: var(--font-display); }

.q-stem, .statement-text-container, .option-text-container {
  max-width: var(--measure);
}

.en-text {
  font-family: var(--font-ui);
  line-height: 1.6;
}

.q-tamil-text {
  font-family: var(--font-tamil);
  line-height: 1.9;
  margin-top: 6px;
  color: var(--text-muted);
}

body.lang-tamil .q-tamil-text { color: var(--text-main); }

/* The 6px above separates a Tamil line from the English line it follows. In
   Tamil-only mode there is no English line, so the Tamil text leads the block
   and the gap is wrong. The old pages suppressed this with an inline
   style="margin-top:0" written into every rendered node; this replaces it. */
.q-tamil-text:first-child { margin-top: 0; }

.question-card {
  background: var(--surface-card);
  border: 1px solid var(--border-color);
  border-radius: 14px;
  padding: 20px;
  width: 100%;
  max-width: 900px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 14px;
}

.q-progress {
  font-family: var(--font-display);
  font-weight: 700;
  margin: 0;
}

.tag-row { display: flex; gap: 6px; flex-wrap: wrap; }

.tag-badge {
  font-size: 0.7rem;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-sunken);
  color: var(--text-muted);
}

.options-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 14px;
}

.option-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: var(--tap-target);
  padding: 10px 12px;
  border: 1px solid var(--border-color);
  border-radius: 10px;
  background: var(--surface-card);
}

.option-card.quiz-active { cursor: pointer; }
.option-card.quiz-active:hover { border-color: var(--border-hover); background: var(--primary-glow); }
.option-card.correct, .option-card.user-correct {
  border-color: var(--accent-green);
  background: var(--accent-green-bg);
}
.option-card.user-incorrect {
  border-color: var(--accent-red);
  background: var(--accent-red-bg);
  cursor: not-allowed;
}
.option-card.user-incorrect.shake { animation: shake 0.3s; }

@keyframes shake {
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

.option-label {
  font-weight: 700;
  min-width: 1.5em;
}

/* match_table questions render two columns that overflow a 360px viewport.
   Scroll the table inside its own box so the page body never scrolls
   sideways, and stack the lists on the narrowest screens. */
.q-content-block { overflow-x: auto; margin-top: 12px; }

.match-table { border-collapse: collapse; width: 100%; min-width: 320px; }
.match-table th, .match-table td {
  border: 1px solid var(--border-color);
  padding: 8px 10px;
  text-align: left;
  vertical-align: top;
}

@media (max-width: 600px) {
  .match-table, .match-table thead, .match-table tbody,
  .match-table tr, .match-table th, .match-table td { display: block; width: 100%; }
  .match-table thead { display: none; }
  .match-table tr { margin-bottom: 10px; border: 1px solid var(--border-color); border-radius: 8px; }
  .match-table td { border: none; border-bottom: 1px solid var(--border-color); }
  .match-table td:last-child { border-bottom: none; }

  /* Hiding the header leaves each stacked cell unlabelled — "Chola" with no
     hint that it belongs under "List I". Re-attach the column name from a
     data-label attribute on the cell. render.js must emit it (Task 12); until
     it does, attr() resolves empty and this renders nothing rather than
     breaking the layout. */
  .match-table td[data-label]::before {
    content: attr(data-label) ": ";
    font-weight: 700;
    color: var(--text-muted);
  }
}

/* The remaining selectors below are all emitted by render.js and the quiz
   state machine (Tasks 12-13). The plan's interface list named only
   .statements-list and .ar-container, but the renderer emits seventeen more —
   without these the quiz would show its correct/wrong verdict and its
   remaining-chances counter as unstyled body text. */

.q-source {
  font-size: 0.75rem;
  color: var(--text-muted);
}

.q-type-badge {
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 2px 8px;
  border-radius: 6px;
  background: var(--surface-sunken);
  color: var(--text-muted);
  white-space: nowrap;
}

/* Tag variants share .tag-badge's shape and only recolour. An empty tag still
   renders an element, so collapse it rather than leaving a stray pill. */
.tag-unit  { background: var(--primary-glow); color: var(--primary); }
.tag-theme { background: var(--accent-green-bg); color: var(--accent-green); }
.tag-topic { background: var(--accent-amber-bg); color: var(--accent-amber); }
.tag-badge:empty { display: none; }

.statements-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.statement-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.statement-label, .ar-label {
  font-weight: 700;
  color: var(--text-muted);
  white-space: nowrap;
}

.ar-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ar-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-left: 3px solid var(--primary);
  background: var(--surface-sunken);
  border-radius: 0 8px 8px 0;
}

.ar-label { min-width: 8.5em; }

.context-stem {
  margin-top: 12px;
  padding-left: 12px;
  border-left: 3px solid var(--border-color);
  color: var(--text-muted);
  max-width: var(--measure);
}

.card-footer { margin-top: 16px; }

.correct-ans {
  font-weight: 600;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--accent-green-bg);
  color: var(--accent-green);
}

/* Quiz verdict. A wrong answer deliberately does NOT reveal the correct
   option — it reports the chances that remain, so the next guess is still the
   student's to make. */
.quiz-result {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-weight: 600;
  padding: 10px 12px;
  border-radius: 10px;
}

.quiz-result-correct {
  background: var(--accent-green-bg);
  color: var(--accent-green);
}

.quiz-result-wrong {
  background: var(--accent-red-bg);
  color: var(--accent-red);
}

.chances-chip {
  font-size: 0.72rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-amber-bg);
  color: var(--accent-amber);
}

.nav-btn {
  font: inherit;
  min-height: var(--tap-target);
  padding: 10px 18px;
  border: 1px solid var(--border-color);
  border-radius: 10px;
  background: var(--surface-sunken);
  color: var(--text-main);
  cursor: pointer;
}

.nav-btn:hover { border-color: var(--border-hover); background: var(--primary-glow); }

.lock-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.72rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-amber-bg);
  color: var(--accent-amber);
}

.locked-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
  margin: 12px 0;
  border: 1px dashed var(--accent-amber);
  border-radius: 12px;
  background: var(--accent-amber-bg);
  color: var(--text-main);
}

/* Subscribe modal and account menu (Task 14). Without these the checkout
   dialog renders as inline text part-way down the page with no overlay — the
   one screen where a student is being asked to pay. */

.modal-host { position: fixed; inset: 0; z-index: 100; }

.modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
}

.modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(420px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 24px;
  border: 1px solid var(--border-color);
  border-radius: 16px;
  background: var(--surface-card);
  color: var(--text-main);
  box-shadow: 0 20px 50px rgba(15, 23, 42, 0.35);
}

.modal h2 { margin: 0; }
.modal p { margin: 0; color: var(--text-muted); }

.price-row { display: flex; align-items: baseline; gap: 8px; }

.price {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 700;
  color: var(--primary);
}

.promo-label { font-size: 0.8rem; font-weight: 600; color: var(--text-muted); }

.promo-row { display: flex; gap: 8px; }

.promo-row input {
  flex: 1;
  min-width: 0;
  font: inherit;
  min-height: var(--tap-target);
  padding: 10px 12px;
  border: 1px solid var(--border-color);
  border-radius: 10px;
  background: var(--surface-sunken);
  color: var(--text-main);
}

/* Empty until a code is tried, so it must not reserve a blank line. */
.promo-feedback { font-size: 0.82rem; margin: 0; }
.promo-feedback:empty { display: none; }
.promo-ok { color: var(--accent-green); }
.promo-error { color: var(--accent-red); }

.cta-btn {
  font: inherit;
  font-weight: 700;
  min-height: var(--tap-target);
  padding: 12px 20px;
  border: none;
  border-radius: 10px;
  background: var(--primary);
  color: #ffffff;
  cursor: pointer;
}

.cta-btn:hover { background: var(--primary-hover); }

/* --primary lightens in dark mode so white-on-primary would stop being
   readable; the dark surface takes the dark ink instead. */
body.dark-mode .cta-btn { color: #0b1120; }

.modal-footnote { font-size: 0.75rem; }

.account-menu {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.account-email { font-weight: 600; }

.account-status {
  font-size: 0.72rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-green-bg);
  color: var(--accent-green);
}

.empty-state {
  padding: 32px 16px;
  text-align: center;
  color: var(--text-muted);
}

.skeleton {
  height: 14px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--surface-sunken) 25%, var(--border-color) 50%, var(--surface-sunken) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.2s infinite;
}

@keyframes shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

.error-card {
  border: 1px solid var(--accent-red);
  background: var(--accent-red-bg);
  border-radius: 12px;
  padding: 16px;
  max-width: 520px;
}

@media (prefers-reduced-motion: reduce) {
  .skeleton, .option-card.user-incorrect.shake { animation: none; }
}
