/* QueryGrade Dark Theme
   Activated via html.dark class. Default: dark. Toggle persists to localStorage.
   Palette: deep space / developer-grade — navy blacks, precise type, vivid accents.

   Surface tokens (Slice C). Reusable design tokens for opt-in surfaces.
   Do not retrofit every Tailwind class; reach for these in NEW code where Tailwind
   does not already cover the case (e.g. chip rows, custom shells).
     --qg-surface     primary card / panel background
     --qg-surface-2   page background (slightly recessed in light mode)
     --qg-border      hairline boundary
     --qg-ink         primary text ink
     --qg-ink-muted   secondary text ink
*/
:root {
  --qg-surface:   #ffffff;
  --qg-surface-2: #f8fafc;
  --qg-border:    #e2e8f0;
  --qg-ink:       #0f172a;
  --qg-ink-muted: #475569;
}

/* ─── Smooth theme transition (structural elements only, not all children) ─── */
html,
body,
nav,
footer,
main,
.transition-theme {
  transition: background-color 0.2s ease, color 0.15s ease, border-color 0.2s ease;
}

/* ─── CSS custom properties ─── */
html.dark {
  --qg-surface:   #0a0a0a;
  --qg-surface-2: #111113;
  --qg-border:    #1f1f23;
  --qg-ink:       #e5e7eb;
  --qg-ink-muted: #94a3b8;

  --bg-base:     #0a0a0a;
  --bg-surface:  #111113;
  --bg-elevated: #17181c;
  --bg-hover:    #25272d;

  --border:      #1f1f23;
  --border-muted:#17181c;
  --border-focus: #818cf8;

  --text-primary:   #e7e5e0;
  --text-secondary: #8b949e;
  --text-muted:     #6e7681;
  --text-link:      #a5b4fc;
  --text-link-hover:#c7d2fe;

  --accent:      #818cf8;
  --accent-dim:  rgba(129, 140, 248, 0.15);

  --shadow-sm:   0 1px 3px rgba(0,0,0,0.4), 0 1px 2px rgba(0,0,0,0.3);
  --shadow-md:   0 4px 6px rgba(0,0,0,0.4), 0 2px 4px rgba(0,0,0,0.3);
  --shadow-lg:   0 10px 15px rgba(0,0,0,0.5), 0 4px 6px rgba(0,0,0,0.4);
}

/* ─── Background scale ─── */
html.dark .bg-white         { background-color: #111113; }
html.dark .bg-gray-50       { background-color: #0a0a0a; }
html.dark .bg-gray-100      { background-color: #17181c; }
html.dark .bg-gray-200      { background-color: #25272d; }

/* ─── Primary indigo CTA mute (PR #60)
   Light-mode indigo-600 (#4f46e5) reads as a UI alert against #0a0a0a.
   At-rest drops to indigo-700; hover BRIGHTENS to indigo-500 so the
   affordance direction inverts vs light mode (where hover darkens). */
html.dark .bg-indigo-600           { background-color: #4338ca; }
html.dark .hover\:bg-indigo-700:hover { background-color: #6366f1; }

/* ─── Selected DB chip ───
   Even warm-cream (#e7e5e0) is essentially a near-white pill on near-black —
   95% luminance against ~4%. Wrong for dark mode regardless of the tint.
   Switch to a subtle indigo wash + soft indigo text + inset indigo border:
   uses brand color to signal "selected" instead of brute-force luminance. */
html.dark [role="radio"][aria-checked="true"] {
  background-color: rgba(99, 102, 241, 0.18);
  color: #c7d2fe;
  box-shadow: inset 0 0 0 1px rgba(99, 102, 241, 0.4);
}

/* ─── Text scale ─── */
html.dark .text-gray-950    { color: #e7e5e0; }
html.dark .text-gray-900    { color: #e7e5e0; }
html.dark .text-gray-800    { color: #cdd9e5; }
html.dark .text-gray-700    { color: #adbac7; }
html.dark .text-gray-600    { color: #8b949e; }
html.dark .text-gray-500    { color: #8b949e; }  /* was #6e7681, below WCAG AA on dark bg */
html.dark .text-gray-400    { color: #6e7681; }

/* ─── Borders ─── */
html.dark .border-gray-100  { border-color: #17181c; }
html.dark .border-gray-200  { border-color: #1f1f23; }
html.dark .border-gray-300  { border-color: #444c56; }

/* ─── Shadows ─── */
html.dark .shadow-sm        { box-shadow: var(--shadow-sm); }
html.dark .shadow           { box-shadow: var(--shadow-md); }
html.dark .shadow-lg        { box-shadow: var(--shadow-lg); }

/* ─── Indigo (primary brand / active states) ─── */
html.dark .bg-indigo-50     { background-color: rgba(129, 140, 248, 0.18); }
html.dark .bg-indigo-100    { background-color: rgba(129, 140, 248, 0.25); }
html.dark .text-indigo-600  { color: #818cf8; }
html.dark .text-indigo-700  { color: #a5b4fc; }
html.dark .text-indigo-800  { color: #a5b4fc; }
html.dark .text-indigo-900  { color: #c7d2fe; }  /* banner body text */
html.dark .border-indigo-200{ border-color: rgba(129, 140, 248, 0.3); }
html.dark .border-indigo-300{ border-color: rgba(129, 140, 248, 0.45); }
html.dark .ring-indigo-100  { --tw-ring-color: rgba(129, 140, 248, 0.25); }
html.dark .ring-indigo-500  { --tw-ring-color: #818cf8; }

/* ─── Gradient stops (Tailwind from- and to- utilities don't auto-darken) ─── */
html.dark .from-indigo-50 {
  --tw-gradient-from: rgba(129, 140, 248, 0.12) var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(129, 140, 248, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
html.dark .to-white      { --tw-gradient-to: #111113 var(--tw-gradient-to-position); }
html.dark .from-white    {
  --tw-gradient-from: #111113 var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(22, 27, 34, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
html.dark .to-purple-50  { --tw-gradient-to: rgba(168, 85, 247, 0.12) var(--tw-gradient-to-position); }

/* ─── Status banners ─── */
/* Error / red */
html.dark .bg-red-50        { background-color: rgba(220, 38, 38, 0.12); }
html.dark .text-red-600     { color: #f87171; }
html.dark .text-red-700     { color: #f87171; }
html.dark .text-red-800     { color: #fca5a5; }
html.dark .border-red-200   { border-color: rgba(220, 38, 38, 0.3); }

/* Success / green */
html.dark .bg-green-50      { background-color: rgba(22, 163, 74, 0.12); }
html.dark .text-green-700   { color: #4ade80; }
html.dark .text-green-800   { color: #86efac; }
html.dark .border-green-200 { border-color: rgba(22, 163, 74, 0.3); }

/* Warning / amber */
html.dark .bg-amber-50      { background-color: rgba(217, 119, 6, 0.12); }
html.dark .text-amber-700   { color: #fbbf24; }
html.dark .text-amber-800   { color: #fcd34d; }
html.dark .text-amber-900   { color: #fde68a; }
html.dark .text-amber-950   { color: #fef3c7; }
html.dark .border-amber-200 { border-color: rgba(217, 119, 6, 0.3); }

/* ─── Grade pill backgrounds (Slice C tightened — was too uniform at 15% bg)
   Per-color bg opacity bumps + brighter -300 text gives each grade a distinct read
   in dark mode while preserving WCAG AA contrast. Compound selectors (.bg-X.text-Y)
   beat the generic single-class fallbacks below.                                  */
/* PR #61: bg opacity ~halved (22-28% → 10-16%) so pills read as ambient
   indicators rather than saturated notification chips. Text colors preserved
   for legibility — the chip becomes a quiet wash with colored text floating
   on near-OLED, not a glowing brand block. */
html.dark .bg-emerald-100.text-emerald-700,
html.dark .bg-emerald-50.text-emerald-700,
html.dark .bg-emerald-50.text-emerald-900 { background-color: rgba(16, 185, 129, 0.10); color: #34d399; }
html.dark .bg-lime-100.text-lime-700,
html.dark .bg-lime-50.text-lime-700        { background-color: rgba(132, 204, 22, 0.10); color: #a3e635; }
html.dark .bg-amber-100.text-amber-700,
html.dark .bg-amber-50.text-amber-700      { background-color: rgba(217, 119, 6, 0.12); color: #fcd34d; }
html.dark .bg-orange-100.text-orange-700,
html.dark .bg-orange-50.text-orange-700    { background-color: rgba(234, 88, 12, 0.14); color: #fdba74; }
html.dark .bg-red-100.text-red-700,
html.dark .bg-red-50.text-red-700          { background-color: rgba(239, 68, 68, 0.14); color: #fca5a5; }
/* Schema-insight severity pills (low = slate, info = blue) */
html.dark .bg-slate-100.text-slate-600    { background-color: #17181c; color: #94a3b8; }
html.dark .bg-blue-50.text-blue-600,
html.dark .bg-blue-100.text-blue-600       { background-color: rgba(37, 99, 235, 0.14); color: #93c5fd; }

/* Single-class fallbacks (used outside the pill compound — e.g. icon backgrounds) */
html.dark .bg-emerald-100   { background-color: rgba(16, 185, 129, 0.18); }
html.dark .text-emerald-700 { color: #34d399; }
html.dark .bg-lime-100      { background-color: rgba(101, 163, 13, 0.18); }
html.dark .text-lime-700    { color: #a3e635; }
html.dark .bg-amber-100     { background-color: rgba(217, 119, 6, 0.18); }
html.dark .bg-orange-100    { background-color: rgba(234, 88, 12, 0.18); }
html.dark .text-orange-700  { color: #fb923c; }

/* ─── Navbar credits pill — handled by the grade-pill compound rules above ─── */

/* ─── Hover utility overrides ─── */
html.dark .hover\:bg-gray-100:hover { background-color: #17181c; }
html.dark .hover\:bg-gray-50:hover  { background-color: #17181c; }
html.dark .hover\:text-gray-900:hover { color: #e7e5e0; }
html.dark .hover\:bg-red-50:hover   { background-color: rgba(220,38,38,0.12); }

/* ─── Dropdown menus ─── */
html.dark .ring-1.ring-black        { --tw-ring-color: rgba(255,255,255,0.08); }
html.dark .ring-opacity-5           { --tw-ring-opacity: 1; }

/* ─── Form inputs — global selector (catches Django-rendered and JS-applied inputs) ─── */
html.dark input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]):not([type=range]),
html.dark select,
html.dark textarea {
  background-color: #0a0a0a;
  border-color: #1f1f23;
  color: #e7e5e0;
  color-scheme: dark;
}
html.dark input::placeholder,
html.dark textarea::placeholder {
  color: #8b949e;
}
html.dark input:focus,
html.dark select:focus,
html.dark textarea:focus {
  border-color: #818cf8;
  outline-color: #818cf8;
}

/* ─── Code / pre ─── */
html.dark pre,
html.dark code {
  background-color: #111113;
  border-color: #1f1f23;
  color: #e7e5e0;
}

/* ─── Table ─── */
html.dark table { border-color: #1f1f23; }
html.dark thead { background-color: #111113; }
html.dark tbody tr:hover { background-color: #17181c; }
html.dark th, html.dark td { border-color: #1f1f23; color: #e7e5e0; }

/* ─── Scrollbars (Chromium) ─── */
html.dark ::-webkit-scrollbar { width: 8px; height: 8px; }
html.dark ::-webkit-scrollbar-track { background: #0a0a0a; }
html.dark ::-webkit-scrollbar-thumb { background: #1f1f23; border-radius: 4px; }
html.dark ::-webkit-scrollbar-thumb:hover { background: #444c56; }

/* ─── CodeMirror — theme is toggled via window.QG.cmTheme() in base.html ─── */
/* Light mode uses CodeMirror's built-in 'default' theme; dark mode uses 'material-darker'.
   Editors register via window.QG.registerEditor() and re-theme on toggle. No CSS overrides needed. */

/* ─── Theme toggle button ─── */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  border: none;
  cursor: pointer;
  background: transparent;
  color: #6b7280;
  transition: background-color 0.15s ease, color 0.15s ease;
  flex-shrink: 0;
}
.theme-toggle:hover {
  background-color: #f3f4f6;
  color: #374151;
}
html.dark .theme-toggle {
  color: #8b949e;
}
html.dark .theme-toggle:hover {
  background-color: #17181c;
  color: #e7e5e0;
}
.theme-toggle .icon-moon { display: block; }
.theme-toggle .icon-sun  { display: none; }
html.dark .theme-toggle .icon-moon { display: none; }
html.dark .theme-toggle .icon-sun  { display: block; }

/* ─── Slate scale (Slice A chip row + asymmetric CTA secondary text) ─── */
/* bg-slate-900 / text-slate-900 intentionally NOT overridden here — */
/* the selected DB chip relies on Tailwind dark:bg-white / dark:text-slate-900 */
/* to invert in dark mode; an override at this level loses to dark: variants */
/* only by source order, which would silently invert the chip back to dark. */
html.dark .bg-slate-100        { background-color: #17181c; }
html.dark .bg-slate-800        { background-color: #17181c; }
html.dark .text-slate-200      { color: #adbac7; }
html.dark .text-slate-300      { color: #adbac7; }
html.dark .text-slate-600      { color: #8b949e; }
html.dark .text-slate-700      { color: #cdd9e5; }
html.dark .hover\:bg-slate-200:hover { background-color: #25272d; }
html.dark .hover\:bg-slate-700:hover { background-color: #25272d; }

/* ─── Warm-cream ink override for headings using dark:text-white ─── */
/* Pure white headings on a near-OLED background read clinical and cool. */
/* Soften every dark:text-white usage to the warm-cream ink without */
/* per-template churn. Same specificity as Tailwind's .dark .dark\:text-white; */
/* dark-mode.css loads after the Tailwind CDN, so source order wins here. */
html.dark .dark\:text-white { color: #e7e5e0; }

/* ─── Indeterminate loading bar (honest loading copy in anon path) ─── */
@keyframes qg-indeterminate-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(300%); }
}
@media (prefers-reduced-motion: no-preference) {
  .qg-indeterminate-bar {
    animation: qg-indeterminate-slide 1.4s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  }
}

/* ─── Field-error border (dark mode) ─── */
html.dark .border-red-500      { border-color: #f87171; }
html.dark .dark\:border-red-400 { border-color: #fca5a5; }

/* ─── Slice B: results-page anchor / pulse / line-highlight ─── */

/* Anchor targets clear the sticky navbar height when jumped to. */
.qg-anchor-target { scroll-margin-top: 5rem; }
.qg-anchor-target:focus { outline: none; }

/* CodeMirror line-highlight for the top-issue hero. Added via
   ed.addLineClass(line, 'wrap', 'qg-line-issue'). Class-based, no Tailwind purge concern. */
.CodeMirror .qg-line-issue {
  background: rgba(254, 226, 226, 0.6);
  border-left: 3px solid #ef4444;
}
html.dark .CodeMirror .qg-line-issue {
  background: rgba(127, 29, 29, 0.3);
  border-left: 3px solid #f87171;
}

/* Brief pulse on a jumped-to anchor target. Gated behind reduced-motion. */
@keyframes qg-pulse {
  0%   { background-color: rgba(99, 102, 241, 0.15); }
  100% { background-color: transparent; }
}
@media (prefers-reduced-motion: no-preference) {
  .qg-pulse-target {
    animation: qg-pulse 1.2s ease-out 1;
  }
}

/* TOC current-link marker */
#issues-toc-list a[aria-current="true"] {
  background-color: rgba(99, 102, 241, 0.12);
  color: #4338ca;
  font-weight: 600;
}
html.dark #issues-toc-list a[aria-current="true"] {
  background-color: rgba(129, 140, 248, 0.2);
  color: #c7d2fe;
}

/* Custom <details> chevron for index-recs collapse */
#index-recommendations summary::-webkit-details-marker { display: none; }
#index-recommendations summary { position: relative; padding-right: 1.5rem; }
#index-recommendations summary::after {
  content: "▾";
  position: absolute;
  right: 0;
  top: 0.25rem;
  color: #6b7280;
  font-size: 0.875rem;
  transition: transform 0.15s ease;
}
#index-recommendations[open] summary::after { transform: rotate(180deg); }
html.dark #index-recommendations summary::after { color: #8b949e; }


/* Shortcuts <dialog> — Slice D */
dialog#qg-shortcuts-dialog {
  max-width: calc(100vw - 2rem);
  width: 28rem;
  max-height: 80dvh;
  padding: 0;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  background: white;
  color: #111827;
  box-shadow: 0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04);
}
dialog#qg-shortcuts-dialog::backdrop {
  background: rgba(0,0,0,0.5);
  backdrop-filter: blur(2px);
}
html.dark dialog#qg-shortcuts-dialog {
  background: #111113;
  color: #e7e5e0;
  border-color: #1f1f23;
  box-shadow: 0 20px 40px -5px rgba(0,0,0,0.7);
}
html.dark dialog#qg-shortcuts-dialog::backdrop {
  background: rgba(0,0,0,0.65);
}

/* Mobile nav drawer — Slice D */
#qg-mobile-nav a {
  min-height: 44px;
  display: flex;
  align-items: center;
}
