/* KC7 Dark Mode — Design Token Overrides
 *
 * Every rule in this file MUST be scoped under html[data-theme="dark"]. The CSS
 * ships to all users; it only activates when the html element has
 * data-theme="dark" (set server-side from the kc7_theme cookie and, in
 * Phase 2, by the toggle script).
 *
 * Pair with themes/dark-vendor.css which handles third-party styling
 * (Bootstrap 4, SB Admin 2, DataTables, Toastr).
 *
 * Palette: Slate. Chosen for low eye strain and good contrast with the
 * existing blue accent.
 *   bg               #0f172a   slate-900
 *   surface          #1e293b   slate-800
 *   surface-raised   #273449   slate-750ish
 *   text primary     #f1f5f9   slate-100
 *   text secondary   #cbd5e1   slate-300
 *   text muted       #94a3b8   slate-400
 *   text faint       #64748b   slate-500
 *
 * Authoring rule for future contributors: never put a rule in this file
 * that is not prefixed with html[data-theme="dark"]. The `html` prefix
 * is required so dark overrides beat `:root` definitions in
 * core-design-system.css regardless of stylesheet load order.
 */

html[data-theme="dark"] {
  /* Surfaces */
  --color-bg: #0f172a;
  --color-surface: #1e293b;
  --color-surface-raised: #273449;
  --color-border: rgba(248, 250, 252, 0.10);
  --color-border-subtle: rgba(248, 250, 252, 0.06);

  /* Text hierarchy */
  --color-text-primary: #f1f5f9;
  --color-text-secondary: #cbd5e1;
  --color-text-muted: #94a3b8;
  --color-text-faint: #64748b;

  /* Accent — lifted slightly so it pops against dark surfaces.
     accent-active stays darker-than-base: it's the hover bg for SOLID
     accent buttons, which keep white text. */
  --color-accent: #3b82f6;
  --color-accent-hover: #60a5fa;
  --color-accent-active: #2563eb;
  --color-accent-light: rgba(59, 130, 246, 0.18);

  /* Semantic — brighter on dark for readability, low-alpha bgs.
     Hover shades stay darker-than-base: they're used on SOLID buttons. */
  --color-success: #22c55e;
  --color-success-hover: #16a34a;
  --color-success-bg: rgba(34, 197, 94, 0.14);
  --color-success-border: rgba(34, 197, 94, 0.35);

  --color-warning: #fb923c;
  --color-warning-hover: #f97316;
  --color-warning-bg: rgba(251, 146, 60, 0.14);
  --color-warning-border: rgba(251, 146, 60, 0.35);

  --color-danger: #f87171;
  --color-danger-bg: rgba(248, 113, 113, 0.14);
  --color-danger-border: rgba(248, 113, 113, 0.35);

  --color-info-text: #38bdf8;
  --color-info-bg: rgba(56, 189, 248, 0.14);

  /* Competitive ranks — keep the warm hues, lift slightly */
  --rank-gold: #eac75c;
  --rank-gold-subtle: rgba(234, 199, 92, 0.16);
  --rank-gold-text: #f1d77a;

  --rank-silver: #cbd5e1;
  --rank-silver-subtle: rgba(203, 213, 225, 0.14);

  --rank-bronze: #d49a3a;
  --rank-bronze-subtle: rgba(212, 154, 58, 0.16);
  --rank-bronze-text: #e2b660;

  /* Depth — slightly stronger shadows since they're harder to see on dark */
  --shadow-subtle: 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-focus: 0 0 0 3px rgba(59, 130, 246, 0.35);

  /* core/custom.css token overrides — that file defines a second token
   * set used by older app/marketing CSS. Keep names identical so existing
   * `var(--color-primary)` references react to the theme switch.
   */
  --color-primary: #5b8def;
  --color-secondary: #94a3b8;
  --color-info: #38bdf8;
  --link-1: #93b8ff;
}

/* Base typography colors. core/custom.css hardcodes `body { color: #333; }`
 * and the design-system file only sets font-size/color via tokens on body.
 * Both end up rendering black-on-white in dark mode without the rules
 * below, so we restate them explicitly.
 */
html[data-theme="dark"] body {
  background-color: var(--color-bg);
  color: var(--color-text-primary);
}

/* :not(.btn) so anchor-styled buttons keep their own text color — this
   element-level `a` rule (specificity 0,1,2) otherwise outranks the
   .btn-* color declarations (0,1,0) and paints every link-button the
   light link color, which is unreadable on a solid accent fill. */
html[data-theme="dark"] a:not(.btn) {
  color: var(--link-1);
}

html[data-theme="dark"] a:not(.btn):hover {
  color: var(--color-accent-hover);
}

html[data-theme="dark"] hr {
  border-color: var(--color-border);
}

/* Form placeholder text — defaults to a very faint gray that's invisible
 * on the dark input bg until we lift it.
 */
html[data-theme="dark"] ::placeholder {
  color: var(--color-text-muted);
  opacity: 1;
}

/* Native form controls and selection */
html[data-theme="dark"] ::selection {
  background: var(--color-accent-light);
  color: var(--color-text-primary);
}

/* Color-scheme hint tells the browser to render scrollbars, native form
 * widgets, and the autofill highlight in dark variants. Cheap and high
 * impact.
 */
html[data-theme="dark"] {
  color-scheme: dark;
}

/* ===================================================================
 * Per-page overrides — /manage (challenges/manage_challenge.html and
 * its tab partials). The custom classes in css/custom/manage-challenges.css
 * hardcode pale yellow/red alert backgrounds that look out of place on
 * a dark slate page. Re-skin them to use our semantic warning/danger
 * tokens (low-alpha bg + brighter text) so they read as alerts without
 * fighting the dark surface.
 * =================================================================== */
html[data-theme="dark"] .alert-modern {
  background: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
}
html[data-theme="dark"] .alert-modern .alert-icon {
  background: var(--color-warning-bg);
}
html[data-theme="dark"] .alert-modern .alert-icon i,
html[data-theme="dark"] .alert-modern .alert-heading {
  color: var(--color-warning);
}

html[data-theme="dark"] .danger-card {
  background-color: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border);
}

html[data-theme="dark"] .btn-outline-danger:hover {
  background: var(--color-danger-bg);
  border-color: var(--color-danger);
  color: var(--color-danger);
}

/* Settings sidebar / tab nav uses pill-style nav-links; the inactive
 * state needs a readable color on the dark sidebar background. */
html[data-theme="dark"] .settings-nav .nav-link {
  color: var(--color-text-secondary);
}
html[data-theme="dark"] .settings-nav .nav-link:hover {
  color: var(--color-text-primary);
  background-color: var(--color-surface-raised);
}

/* Game status bar dark mode */
html[data-theme="dark"] .game-status-bar-wrapper {
  background: var(--color-surface);
  border-bottom-color: var(--color-border);
}

html[data-theme="dark"] .nav-meta-count {
  background: rgba(59, 130, 246, 0.18);
  color: var(--color-accent);
}

html[data-theme="dark"] .nav-meta-empty {
  background: rgba(248, 250, 252, 0.06);
  color: var(--color-text-muted);
}

/* ===== Main topbar (navbar.html) =====
   Bootstrap's bg-white utility uses !important, so the surface needs
   !important to win. navbar-light forces dark text on nav-links via
   .navbar-light .navbar-nav .nav-link { color: rgba(0,0,0,.5) }; the
   topbar.css already overrides this with var(--color-text-primary). */
html[data-theme="dark"] .topbar.bg-white {
  background-color: var(--color-surface) !important;
}
html[data-theme="dark"] .topbar {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
html[data-theme="dark"] .topbar .dropdown-menu {
  background-color: var(--color-surface-raised);
  border-color: var(--color-border);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
html[data-theme="dark"] .topbar .dropdown-divider {
  border-color: var(--color-border);
}
html[data-theme="dark"] .topbar .dropdown-item:hover,
html[data-theme="dark"] .topbar .dropdown-item:focus {
  background-color: var(--color-accent-light);
  color: var(--color-text-primary);
}
html[data-theme="dark"] .topbar .dropdown-header {
  color: var(--color-text-muted);
}
html[data-theme="dark"] .topbar-divider {
  border-right-color: var(--color-border);
}
/* Active-players stat: topbar.css paints the users icon and count with
   --detective-blue (#00416b), which is invisible on the dark surface.
   Same story for the nav-link hover color. !important is required to
   beat topbar.css's own !important on .fa-users; the html prefix wins
   the specificity tie. */
html[data-theme="dark"] .topbar .fa-users,
html[data-theme="dark"] .topbar #navbar-active-users-count {
  color: var(--color-accent) !important;
}
html[data-theme="dark"] .topbar .nav-link:hover {
  color: var(--color-accent-hover) !important;
}

/* ===== Main sidebar submenus =====
   SB Admin 2's .collapse-item uses #3a3b45 text on .bg-white panels,
   which is invisible on dark surfaces. Only the expanded submenu
   surfaces are themed here. The main sidebar bg/nav links are
   intentionally left alone (handled elsewhere).

   Selector matches SB Admin 2's high-specificity rule
   (.sidebar .nav-item .collapse .collapse-inner .collapse-item)
   so the dark override actually wins. */
html[data-theme="dark"] .sidebar .collapse-inner.bg-white {
  background-color: var(--color-surface-raised) !important;
}
html[data-theme="dark"] .sidebar .nav-item .collapse .collapse-inner .collapse-item,
html[data-theme="dark"] .sidebar .nav-item .collapsing .collapse-inner .collapse-item {
  color: var(--color-text-primary);
}
html[data-theme="dark"] .sidebar .nav-item .collapse .collapse-inner .collapse-item:hover,
html[data-theme="dark"] .sidebar .nav-item .collapsing .collapse-inner .collapse-item:hover {
  background-color: var(--color-accent-light);
  color: var(--color-text-primary);
}
html[data-theme="dark"] .collapse-header {
  color: var(--color-text-muted);
}

/* ===== Leaderboard (features/leaderboard.css) =====
   The file defines its own `--p-*` palette in :root. Override those
   tokens so the bulk of the file recolors automatically, then patch
   the few hardcoded surfaces individually. */
html[data-theme="dark"] {
  --p-bg: var(--color-bg);
  --p-card: var(--color-surface);
  --p-border: var(--color-border);
  --p-text: var(--color-text-primary);
  --p-muted: var(--color-text-secondary);
  --p-faint: var(--color-text-muted);
}

/* Hero title gradient: the original starts at near-black which vanishes
   on a dark bg. Lift the first stop. */
html[data-theme="dark"] .lb-hero-title {
  background: linear-gradient(95deg, #e5e7eb 0%, #818cf8 45%, #fbbf24 95%);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
}

/* Indigo CTA banner */
html[data-theme="dark"] .lb-yt-cta {
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.14) 0%, rgba(139, 92, 246, 0.12) 100%);
  border-color: rgba(99, 102, 241, 0.35);
}

/* "View more" footer of each card */
html[data-theme="dark"] .lb-view-more { background: var(--color-surface-raised); }
html[data-theme="dark"] .lb-view-more:hover { background: var(--color-accent-light); }

/* Soft purple icon tiles */
html[data-theme="dark"] .lb-suggest-icon,
html[data-theme="dark"] .lb-cta-ic {
  background: rgba(99, 102, 241, 0.18);
  color: #a5b4fc;
}

/* Tier-band counters (gold/silver/bronze/blue/purple dots) — keep their
   tints but darken the bg so light pastel doesn't shout on dark. */
html[data-theme="dark"] .lb-band-dot-gold   { background: rgba(245, 158, 11, 0.18); color: #fbbf24; }
html[data-theme="dark"] .lb-band-dot-silver { background: rgba(148, 163, 184, 0.20); color: #cbd5e1; }
html[data-theme="dark"] .lb-band-dot-bronze { background: rgba(200, 149, 108, 0.18); color: #d4a574; }
html[data-theme="dark"] .lb-band-dot-blue   { background: rgba(59, 130, 246, 0.18); color: #93c5fd; }
html[data-theme="dark"] .lb-band-dot-purple { background: rgba(139, 92, 246, 0.18); color: #c4b5fd; }

/* Climber/streak delta pills */
html[data-theme="dark"] .lb-delta-up   { background: rgba(245, 158, 11, 0.18); color: #fbbf24; }
html[data-theme="dark"] .lb-delta-down { background: rgba(16, 185, 129, 0.18); color: #6ee7b7; }

/* Row dividers + hover tints inside cards */
html[data-theme="dark"] .lb-row + .lb-row,
html[data-theme="dark"] .lb-row {
  border-bottom-color: var(--color-border);
}

/* Top-3 podium card surfaces — the pastel gradients become unreadable
   on dark. Use a darker tinted surface that still hints at the medal. */
html[data-theme="dark"] .lb-pod-1,
html[data-theme="dark"] .lb-yt.lb-tier-gold {
  background: linear-gradient(135deg, rgba(212, 160, 23, 0.15) 0%, var(--color-surface) 60%);
  border-color: rgba(212, 160, 23, 0.45);
}
html[data-theme="dark"] .lb-pod-2,
html[data-theme="dark"] .lb-yt.lb-tier-silver {
  background: linear-gradient(135deg, rgba(148, 163, 184, 0.18) 0%, var(--color-surface) 60%);
  border-color: rgba(148, 163, 184, 0.45);
}
html[data-theme="dark"] .lb-pod-3,
html[data-theme="dark"] .lb-yt.lb-tier-bronze {
  background: linear-gradient(135deg, rgba(200, 149, 108, 0.18) 0%, var(--color-surface) 60%);
  border-color: rgba(200, 149, 108, 0.45);
}

/* The gold champion (.lb-pod-1) and gold-tier "Your Standing" (.lb-yt.lb-tier-gold)
   cards fill their centre with a bright cream gradient via an ::after pseudo-element
   (the ::before is the spinning gold ring). The element-level background override
   above doesn't touch that fill, so it survived into dark mode and left the light
   --p-text unreadable on top of it. Recolor the fill to the same dark medal tint as
   the other tiers, and lift the gold accent numerals to the brighter dark-mode gold. */
html[data-theme="dark"] .lb-pod-1::after,
html[data-theme="dark"] .lb-yt.lb-tier-gold::after {
  background: linear-gradient(135deg, rgba(212, 160, 23, 0.15) 0%, var(--color-surface) 60%);
}
html[data-theme="dark"] .lb-pod-1 .lb-pod-pts,
html[data-theme="dark"] .lb-yt.lb-tier-gold .lb-yt-rank-num {
  color: #fbbf24;
}

/* ===== User profile (features/user_profile.css) =====
   Uses the same `--p-*` palette as leaderboard, so the token
   overrides above already cover most of this page. These rules
   patch the remaining hardcoded surfaces. */

/* Career-path progress track + generic light surfaces */
html[data-theme="dark"] .p-cp-card-bar,
html[data-theme="dark"] .p-sb-bar {
  background: var(--color-surface-raised);
}

/* Private-profile banner: light blue → dark-aware tinted accent */
html[data-theme="dark"] .p-private-banner {
  background: var(--color-accent-light);
  border-color: rgba(96, 165, 250, 0.35);
  color: #93c5fd;
}

/* Badge hover popover arrow — was a white triangle aimed downward; on
   dark the arrow needs to match the surface it points from. */
html[data-theme="dark"] .p-bdg-pop::after {
  border-top-color: var(--color-surface);
}

/* Difficulty pills in the recently-solved list — pastel bg + saturated
   text gets washed out on dark. Use translucent semantic tints. */
html[data-theme="dark"] .p-sb-diff-1 { background: rgba(16, 185, 129, 0.18); color: #6ee7b7; }
html[data-theme="dark"] .p-sb-diff-2 { background: rgba(59, 130, 246, 0.18); color: #93c5fd; }
html[data-theme="dark"] .p-sb-diff-3 { background: rgba(245, 158, 11, 0.18); color: #fbbf24; }
html[data-theme="dark"] .p-sb-diff-4 { background: rgba(239, 68, 68, 0.18); color: #fca5a5; }
html[data-theme="dark"] .p-sb-diff-5 { background: rgba(139, 92, 246, 0.18); color: #c4b5fd; }

/* Solved-list inner table surface */
html[data-theme="dark"] .p-sb-stats {
  background: var(--color-surface-raised);
}
html[data-theme="dark"] .p-sb-table,
html[data-theme="dark"] .p-sb-empty {
  background: var(--color-surface);
  border-color: var(--color-border);
}
html[data-theme="dark"] .p-sb-row {
  border-bottom-color: var(--color-border);
}
html[data-theme="dark"] .p-sb-row:hover {
  background: var(--color-surface-raised);
}

/* Top-3 podium / tier cards on profile mirror the leaderboard
   treatment — translucent medal tints over surface. */
html[data-theme="dark"] .p-tier-gold,
html[data-theme="dark"] .p-pod-1 {
  background: linear-gradient(135deg, rgba(212, 160, 23, 0.15) 0%, var(--color-surface) 60%);
  border-color: rgba(212, 160, 23, 0.45);
}
html[data-theme="dark"] .p-tier-silver,
html[data-theme="dark"] .p-pod-2 {
  background: linear-gradient(135deg, rgba(148, 163, 184, 0.18) 0%, var(--color-surface) 60%);
  border-color: rgba(148, 163, 184, 0.45);
}
html[data-theme="dark"] .p-tier-bronze,
html[data-theme="dark"] .p-pod-3 {
  background: linear-gradient(135deg, rgba(200, 149, 108, 0.18) 0%, var(--color-surface) 60%);
  border-color: rgba(200, 149, 108, 0.45);
}

/* Same gold ::after fill bug as the leaderboard: the gold-tier header card
   fills its centre via .p-tier-gold::after, which the element override above
   misses. Recolor it and lift the gold rank numeral. */
html[data-theme="dark"] .p-tier-gold::after {
  background: linear-gradient(135deg, rgba(212, 160, 23, 0.15) 0%, var(--color-surface) 60%);
}
html[data-theme="dark"] .p-tier-gold .p-hdr-rank-num {
  color: #fbbf24;
}

/* XP bar track */
html[data-theme="dark"] .p-xp-bar {
  background: var(--color-surface-raised);
}

/* ===== Activity grid (features/activity_grid.css) =====
   The grid is rendered as SVG by activity_grid.js. Inactive cells
   default to #ebedf0 (nearly white) — switch to a muted surface so
   they read against the dark page. SVG text uses `fill`, not `color`.
   Orange heat cells (.active-l1..l4) already pop on dark, leave alone. */
html[data-theme="dark"] .activity-cell:not(.active-l1):not(.active-l2):not(.active-l3):not(.active-l4) {
  fill: var(--color-surface-raised);
}
html[data-theme="dark"] .year-label    { fill: var(--color-text-primary); }
html[data-theme="dark"] .month-label,
html[data-theme="dark"] .day-label     { fill: var(--color-text-muted); }
html[data-theme="dark"] .year-summary  { color: var(--color-text-secondary); }
html[data-theme="dark"] .activity-freeze-summary { color: var(--color-text-secondary); }
html[data-theme="dark"] .activity-cell:hover { stroke: var(--color-accent-hover); }

/* Gold tier header card paints an OPAQUE pale-cream gradient via
   ::after (inset 2px, z-index -1), which hides the username text on
   dark. Replace it with a translucent gold tint over the dark surface,
   keeping the spinning gold border (::before) intact. */
html[data-theme="dark"] .p-tier-gold::after {
  /* The tint must sit on an OPAQUE surface layer: ::after is the panel that
     hides the conic ::before, so any transparency lets the full spinning
     gold gradient bleed through and flood the header. */
  background: linear-gradient(135deg, rgba(212, 160, 23, 0.15) 0%, rgba(212, 160, 23, 0) 60%), var(--color-surface);
}

/* Share affordances added with the stat-tile/career-path share modals —
   LinkedIn brand blue is too dark against dark surfaces. */
html[data-theme="dark"] .p-share-ic { color: #70b5f9; }
html[data-theme="dark"] .p-cp-share {
  background: rgba(96, 165, 250, 0.16);
  color: #93c5fd;
}
html[data-theme="dark"] .p-cp-share:hover { background: #0a66c2; color: #fff; }

/* ===== Badge backpack (features/badges.css) =====
   Defines its own palette inside :root (--primary-color, --card-background,
   --background-color, etc.). Overriding those once recolors most surfaces.
   Then patch the pastel earned/unearned gradients and the orange banner. */
html[data-theme="dark"] {
  --background-color: var(--color-surface);
  --card-background: var(--color-surface-raised);
  --text-color: var(--color-text-primary);
  --text-muted: var(--color-text-secondary);
  --border-color: var(--color-border);
}
html[data-theme="dark"] .badge-card-earned {
  background: linear-gradient(135deg, var(--color-surface-raised) 0%, rgba(255, 87, 2, 0.08) 100%);
}
html[data-theme="dark"] .badge-card-unearned {
  background: var(--color-surface);
  border-color: var(--color-border) !important;
}
html[data-theme="dark"] .badge-earned-banner {
  background: linear-gradient(135deg, rgba(255, 87, 2, 0.12) 0%, rgba(255, 87, 2, 0.20) 100%);
  color: #ffb38a;
}
html[data-theme="dark"] .badge-earned-banner i { color: #ffb38a; }
/* Filter-tabs active links use --primary-color (#00416b) which is too
   dark to read on the dark surface. Lift to the dark accent. */
html[data-theme="dark"] .filter-tabs .nav-link.active,
html[data-theme="dark"] .filter-tabs .nav-link:hover {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}
html[data-theme="dark"] .filter-tabs .nav-link {
  color: var(--color-text-muted);
}
html[data-theme="dark"] .filter-tabs {
  border-bottom-color: var(--color-border);
}

/* Badge card unearned — hardcoded #fafbfc bg */
html[data-theme="dark"] .badge-card-unearned {
  background: var(--color-surface) !important;
  border-color: var(--color-border) !important;
}

/* Badge card hover shadow — stronger on dark */
html[data-theme="dark"] .badge-card:hover {
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
  border-color: var(--color-accent) !important;
}

/* Stat number — --primary-color is too dark on dark surfaces */
html[data-theme="dark"] .stat-number {
  color: var(--color-accent);
}

/* Badge modal — header gradient and title */
html[data-theme="dark"] #badgeModal .modal-header {
  background: linear-gradient(180deg, rgba(59, 130, 246, 0.08) 0%, transparent 100%);
  border-bottom-color: var(--color-border);
}
html[data-theme="dark"] #badgeModal .modal-title {
  color: var(--color-accent);
}
html[data-theme="dark"] #badgeModal .modal-title i {
  color: #ff8c4a;
}
html[data-theme="dark"] #badgeModal .modal-body {
  background: var(--color-surface);
}
html[data-theme="dark"] #badgeModal .modal-description,
html[data-theme="dark"] #badgeModal .modal-description p {
  color: var(--color-text-secondary);
}
html[data-theme="dark"] #badgeModal .modal-footer {
  border-top-color: var(--color-border);
}

/* ============================================================
   Pass A — local :root palette mirrors
   Each block remaps a file-local palette so dark mode "just works"
   on that surface without touching the source CSS. Token namespaces
   are file-specific (--daily7-*, --bs-*, --gallery-*, etc.) so these
   don't leak across pages.
   ============================================================ */

/* daily7/daily7-base.css — invert the gray scale so light surfaces
   become dark surfaces. Keep primary blue and success green. */
html[data-theme="dark"] {
  --daily7-gray-50:  var(--color-surface);
  --daily7-gray-100: var(--color-surface-raised);
  --daily7-gray-200: var(--color-border);
  --daily7-gray-300: var(--color-border);
  --daily7-gray-400: var(--color-text-muted);
  --daily7-gray-500: var(--color-text-secondary);
  --daily7-gray-600: var(--color-text-secondary);
  --daily7-gray-700: var(--color-text-primary);
  --daily7-gray-900: var(--color-text-primary);
}

/* Daily7 — hardcoded whites and pastel chips the gray-scale remap can't
   reach (daily7-base, header-nav, challenge-card, calendar-modal,
   leaderboard). Brand-blue gradients, medals, and white-on-blue CTA
   buttons are intentionally untouched. */
html[data-theme="dark"] .daily7-page {
  background-color: var(--color-bg);
}
html[data-theme="dark"] .daily7-header-card,
html[data-theme="dark"] .daily7-challenge-card,
html[data-theme="dark"] .daily7-challenge-nav .btn,
html[data-theme="dark"] .daily7-nav-arrow,
html[data-theme="dark"] .daily7-calendar-btn,
html[data-theme="dark"] .daily7-user-stats-card,
html[data-theme="dark"] .daily7-leaderboard-card {
  background: var(--color-surface);
}

/* Chips: pastel blue/green backgrounds become translucent tints */
html[data-theme="dark"] .daily7-badge-points,
html[data-theme="dark"] .daily7-share-btn {
  background: rgba(59, 130, 246, 0.15);
  color: var(--color-accent-hover);
  border-color: rgba(59, 130, 246, 0.35);
}
html[data-theme="dark"] .daily7-badge-solved {
  background: var(--color-success-bg);
  color: var(--color-success);
  border-color: rgba(34, 197, 94, 0.40);
}

/* Code-block copy button: frosted white → frosted dark */
html[data-theme="dark"] .daily7-challenge-description .copy-button {
  background: rgba(30, 41, 59, 0.92);
}

html[data-theme="dark"] .daily7-answer-input {
  background: var(--color-surface-raised);
}

/* Success checkmark animation uses white shapes to mask the circle;
   they must match the dark card surface or they flash as white boxes. */
html[data-theme="dark"] .sa-success::before,
html[data-theme="dark"] .sa-success::after,
html[data-theme="dark"] .sa-fix {
  background: var(--color-surface);
}

/* Calendar modal */
html[data-theme="dark"] .daily7-calendar-day.has-challenges,
html[data-theme="dark"] .daily7-calendar-legend-box.none,
html[data-theme="dark"] .daily7-calendar-nav-btn,
html[data-theme="dark"] .daily7-today-btn {
  background: var(--color-surface-raised);
}
html[data-theme="dark"] .daily7-today-btn {
  color: var(--color-accent-hover);
}
html[data-theme="dark"] .daily7-calendar-day.partial-completion,
html[data-theme="dark"] .daily7-calendar-legend-box.partial {
  background: var(--color-success-bg);
  border-color: rgba(34, 197, 94, 0.40);
}
html[data-theme="dark"] .daily7-calendar-day.partial-completion {
  color: var(--color-success);
}

/* Leaderboard: white hover states and gradients that fade to white */
html[data-theme="dark"] .daily7-user-stat-item:hover,
html[data-theme="dark"] .daily7-leaderboard-item:hover {
  background: var(--color-surface-raised);
}
html[data-theme="dark"] .daily7-stat-item-large,
html[data-theme="dark"] .daily7-your-rank-content {
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.10) 0%, var(--color-surface) 100%);
}

/* Daily7 manager surfaces (/daily7/edit, edit modal, bulk upload) */
html[data-theme="dark"] .daily7-edit-header-card,
html[data-theme="dark"] .daily7-edit-table-card,
html[data-theme="dark"] .daily7-stat-card,
html[data-theme="dark"] .results-table-wrapper,
html[data-theme="dark"] #bulkUploadResultsModal .modal-header,
html[data-theme="dark"] #bulkUploadResultsModal .modal-footer {
  background: var(--color-surface);
}
html[data-theme="dark"] .daily7-edit-modal .btn-secondary,
html[data-theme="dark"] .daily7-action-btn {
  background: var(--color-surface-raised);
}
html[data-theme="dark"] .daily7-status-upcoming {
  background: rgba(59, 130, 246, 0.15);
  color: var(--color-accent-hover);
}
html[data-theme="dark"] .daily7-status-active {
  background: var(--color-success-bg);
  color: var(--color-success);
}
html[data-theme="dark"] .validation-loading-overlay {
  background: rgba(15, 23, 42, 0.90);
}
html[data-theme="dark"] .error-popover-suggestion {
  background: var(--color-warning-bg);
  border-left-color: var(--color-warning);
}
html[data-theme="dark"] .error-popover-suggestion,
html[data-theme="dark"] .error-popover-suggestion * {
  color: var(--color-text-primary);
}

/* features/badge-share.css — same --bs-* pattern as leaderboard. */
html[data-theme="dark"] {
  --bs-bg:     var(--color-surface);
  --bs-card:   var(--color-surface-raised);
  --bs-border: var(--color-border);
  --bs-text:   var(--color-text-primary);
  --bs-muted:  var(--color-text-secondary);
  --bs-faint:  var(--color-text-muted);
}

/* Badge earned page (/badges/earned/*) — elements the token remap
   can't reach because they use hardcoded values. */
html[data-theme="dark"] .bs-hero.bs-tier-gold::after {
  background: linear-gradient(135deg, rgba(212, 160, 23, 0.15) 0%, var(--color-surface) 60%);
}
html[data-theme="dark"] .bs-badge-frame::before {
  box-shadow: 0 10px 36px rgba(0, 0, 0, 0.35);
}
html[data-theme="dark"] .bs-badge-frame {
  background: radial-gradient(circle at 30% 25%, rgba(99, 102, 241, 0.12), transparent 62%);
}
html[data-theme="dark"] .bs-share-btn:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
html[data-theme="dark"] .bs-next a:hover {
  box-shadow: 0 6px 16px rgba(99, 102, 241, 0.20);
}
/* Certificate button: the band is the same bright indigo gradient in both
   themes, so keep the base solid-white fill (a translucent override blended
   in). It's a button-styled <a>, so restore the indigo text the a:not(.btn)
   link rule would otherwise tint light-blue. */
html[data-theme="dark"] a.bs-cert-btn,
html[data-theme="dark"] a.bs-cert-btn:hover {
  color: var(--bs-indigo);
}
/* SweetAlert LinkedIn modal */
html[data-theme="dark"] .bs-swal {
  background: var(--color-surface) !important;
  color: var(--color-text-primary) !important;
}

/* teams-scoreboard.css — ink/surface/border layered system. Keep
   tactical blue and rank gold/silver/bronze (they're brand). */
html[data-theme="dark"] {
  --ink-primary:     var(--color-text-primary);
  --ink-secondary:   var(--color-text-secondary);
  --ink-tertiary:    var(--color-text-muted);
  --ink-muted:       var(--color-text-muted);
  --surface-base:    var(--color-surface);
  --surface-raised:  var(--color-surface-raised);
  --surface-sunken:  var(--color-bg);
  --border-standard: var(--color-border);
  --border-emphasis: var(--color-border);
  --border-strong:   var(--color-border);
}

/* components/career-paths.css — pastel role-light/role-mid invisible
   on dark. Recolor with translucent tints over the surface. */
html[data-theme="dark"] {
  --role-light: rgba(37, 99, 235, 0.12);
  --role-mid:   rgba(37, 99, 235, 0.30);
}


/* blog-editor.css */
html[data-theme="dark"] {
  --editor-bg:         var(--color-surface);
  --editor-sidebar-bg: var(--color-surface-raised);
  --editor-border:     var(--color-border);
  --editor-text:       var(--color-text-primary);
  --editor-text-muted: var(--color-text-secondary);
  /* Accent stays GitHub blue — it pops on dark fine. */
}

/* admin/pages/{view-stats, module-stats, module-stats-detail,
   growth-insights}.css — share an identical token system using
   --surface-base/subtle/raised/elevated, --border*, --text-*.
   One mirror covers all four pages. */
html[data-theme="dark"] {
  --surface-subtle:   var(--color-surface);
  --surface-elevated: var(--color-surface-raised);
  --text-primary:     var(--color-text-primary);
  --text-secondary:   var(--color-text-secondary);
  --text-muted:       var(--color-text-muted);
  --text-faint:       var(--color-text-muted);
  /* surface-base / surface-raised / border* already remapped above
     by teams-scoreboard block; safe because semantics match. */
}

/* admin/pages/images.css — /images gallery and /admin/gifs.
   Token mirror first, then the hardcoded light values the mirror
   cannot reach. */
html[data-theme="dark"] {
  /* The gallery paints its own full-height ground (min-height: 100vh),
     so --gallery-bg has to be the page bg or the whole container reads
     as a lighter slab floating on the admin shell. bg / surface / hover
     must also land on three DISTINCT steps: the previous mirror pointed
     --gallery-surface and --gallery-hover at the same value, which made
     every hover state a no-op (filter buttons, modal close, secondary
     button, thumbnail wells). */
  --gallery-bg:      var(--color-bg);
  --gallery-surface: var(--color-surface);
  --gallery-hover:   var(--color-surface-raised);
  --gallery-border:  var(--color-border);
  --gallery-text:    var(--color-text-primary);
  --gallery-muted:   var(--color-text-secondary);
  /* The light primary (#2563eb) sits at ~2.6:1 on the dark surface,
     which is too dim for the icons, meta rows and badge that use it.
     Use the lifted dark accent, same as the rest of the app. The coral
     --gallery-accent already reads fine, so leave it (and the
     success/warning toast colors) alone. */
  --gallery-primary: var(--color-accent);
}

/* Card action buttons sit on the hover overlay as a frosted WHITE pill
   labelled in var(--gallery-text) — which the mirror above turns into
   near-white text on near-white glass. Flip the glass, keep the pill. */
html[data-theme="dark"] .image-action-btn {
  background: rgba(15, 23, 42, 0.88);
  border: 1px solid var(--color-border);
  color: var(--color-text-primary);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}
html[data-theme="dark"] .image-action-btn:hover {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: #fff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.55);
}

/* Depth. Every shadow in images.css is tuned for a white page
   (rgba(0,0,0,0.03)–0.05) and disappears on dark, so the header, cards,
   dropzone and modal all flatten into the background. Each :hover /
   :focus variant has to be restated too — these dark selectors carry an
   extra element+attribute, so they would otherwise outrank the
   single-class hover rules in images.css and freeze the shadow. */
html[data-theme="dark"] .gallery-header {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
}
html[data-theme="dark"] .image-card,
html[data-theme="dark"] .upload-zone,
html[data-theme="dark"] .filter-btn,
html[data-theme="dark"] .search-input {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}
html[data-theme="dark"] .image-card:hover {
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55),
              0 0 0 1px rgba(59, 130, 246, 0.35);
}
html[data-theme="dark"] .filter-btn:hover {
  background: var(--gallery-hover);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}
html[data-theme="dark"] .vault-modal {
  box-shadow: 0 24px 48px rgba(0, 0, 0, 0.6);
}
html[data-theme="dark"] .search-input:focus,
html[data-theme="dark"] .vault-input:focus {
  box-shadow: var(--shadow-focus);
}

/* "Manage GIFs" is an <a> styled as a button, so the global dark link
   rule repaints its label link-blue while the identical <button> beside
   it keeps the text color. */
html[data-theme="dark"] a.filter-btn,
html[data-theme="dark"] a.filter-btn:hover {
  color: var(--color-text-primary);
}

/* Dropzone feedback. The hover wash is a 2%-alpha blue/coral gradient
   and the drag wash is 8% — both invisible on slate, so dragging a file
   over the zone looks like nothing happened. */
html[data-theme="dark"] .upload-zone:hover {
  background: rgba(59, 130, 246, 0.07);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
}
html[data-theme="dark"] .dropzone.dz-drag-hover {
  background: rgba(59, 130, 246, 0.16) !important;
}

/* Dropzone's own preview chrome (light-gray thumbnail well, near-black
   filename/size) is visible while an upload is in flight. */
html[data-theme="dark"] .dropzone .dz-preview .dz-image,
html[data-theme="dark"] .dropzone .dz-preview .dz-details {
  background: var(--color-surface-raised);
}
html[data-theme="dark"] .dropzone .dz-preview .dz-details {
  color: var(--color-text-primary);
}

/* Solid accent buttons hardcode #1d4ed8 on hover, which against the
   lifted dark accent reads as the button switching off rather than
   responding. */
html[data-theme="dark"] .vault-btn-primary:hover,
html[data-theme="dark"] .vault-url-copy:hover {
  background: var(--color-accent-active);
}

/* Modal badge: a 10%-alpha wash of light blue and coral goes muddy on
   slate, and its label inherits the dim light primary. */
html[data-theme="dark"] .vault-modal-badge {
  background: rgba(59, 130, 246, 0.16);
  border-color: rgba(59, 130, 246, 0.35);
  color: var(--color-accent-hover);
}

/* 20% opacity on an already-muted gray leaves the empty-state icon
   invisible against the dark ground. */
html[data-theme="dark"] .empty-icon {
  opacity: 0.45;
}

/* ===== Glossary public pages (glossary.css + glossary-detail.css) =====
   Both files define a --g-* local palette in :root. Remap those tokens
   once here so the entire glossary feature dark-modes automatically. */
html[data-theme="dark"] {
  --g-surface:        var(--color-surface);
  --g-raised:         var(--color-surface-raised);
  --g-hover:          var(--color-surface-raised);
  --g-border:         var(--color-border);
  --g-border-input:   var(--color-border);
  --g-border-section: var(--color-border);
  --g-text:           var(--color-text-primary);
  --g-text-heading:   var(--color-text-primary);
  --g-text-secondary: var(--color-text-secondary);
  --g-text-muted:     var(--color-text-muted);
  --g-text-result:    var(--color-text-muted);
  --g-text-desc:      var(--color-text-secondary);
  --g-text-blockquote:var(--color-text-secondary);
  --g-text-faint:     var(--color-text-muted);
  --g-link:           var(--link-1);
  --g-badge-bg:       rgba(56, 105, 212, 0.18);
  --g-badge-text:     #93b4ff;
  --g-warn-bg:        rgba(251, 146, 60, 0.14);
  --g-warn-text:      #fb923c;
  --g-mark-bg:        rgba(251, 191, 36, 0.18);
  --g-shadow:         rgba(0, 0, 0, 0.3);
  --g-shadow-strong:  rgba(0, 0, 0, 0.4);
  --g-card-shadow:    rgba(0, 0, 0, 0.4);
}

/* Glossary autocomplete dropdown — needs stronger shadow on dark */
html[data-theme="dark"] #autocompleteDropdown {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5), 0 2px 4px rgba(0, 0, 0, 0.3);
}

/* Glossary detail: section title branded blue → use primary on dark */
html[data-theme="dark"] .section-header-kc7 .section-title {
  color: var(--color-primary);
}

/* Glossary detail: hljs already loads github-dark.min.css which
   handles syntax colours, but the wrapper bg needs remapping. */
html[data-theme="dark"] .markdown-content .hljs {
  background: var(--color-surface-raised);
  color: var(--color-text-primary);
}

/* admin-glossary.css — invert the gray scale, keep brand primary. */
html[data-theme="dark"] {
  --kc7-gray-100: var(--color-surface);
  --kc7-gray-200: var(--color-surface-raised);
  --kc7-gray-300: var(--color-border);
  --kc7-gray-400: var(--color-text-muted);
  --kc7-gray-500: var(--color-text-secondary);
  --kc7-gray-600: var(--color-text-primary);
  --kc7-gray-700: var(--color-text-primary);
}

/* ===== /admin/tags (admin-glossary.css) =====
   Palette mirror (gray-100..700) handles most surfaces. These rules
   replace the bare `background: white` and the light category-badge
   tint that the mirror can't reach. */
html[data-theme="dark"] .stat-card,
html[data-theme="dark"] .search-input,
html[data-theme="dark"] .terms-table-container,
html[data-theme="dark"] .modal-container,
html[data-theme="dark"] .selectize-input,
html[data-theme="dark"] .selectize-dropdown {
  background: var(--color-surface-raised);
  color: var(--color-text-primary);
}
html[data-theme="dark"] .category-badge {
  background: rgba(56, 105, 212, 0.18);
  color: #93b4ff;
}
html[data-theme="dark"] .markdown-preview code {
  background: var(--color-surface-raised);
  color: var(--color-text-primary);
}
/* The <pre> code block was already dark (`#202124`/`#F8F9FA`) — keep as-is. */

/* ===== Bootstrap nav-tabs (email console _shell.html, scheduled-emails
   filter tabs, and any other admin tab bars). BS5's defaults hardcode
   light grays, so restate the chrome with tokens. */
html[data-theme="dark"] .nav-tabs {
  border-bottom-color: var(--color-border);
}
html[data-theme="dark"] .nav-tabs .nav-link {
  color: var(--color-text-secondary);
}
html[data-theme="dark"] .nav-tabs .nav-link:hover,
html[data-theme="dark"] .nav-tabs .nav-link:focus {
  color: var(--color-text-primary);
  border-color: var(--color-border-subtle) var(--color-border-subtle) var(--color-border);
  isolation: isolate;
}
html[data-theme="dark"] .nav-tabs .nav-link.active,
html[data-theme="dark"] .nav-tabs .nav-item.show .nav-link {
  color: var(--color-text-primary);
  background-color: var(--color-surface);
  border-color: var(--color-border) var(--color-border) var(--color-surface);
}

/* ===== admin/admin-unified.css badges & chips =====
   The role/difficulty ramps and muted badges keep their light-mode pastels
   in admin-unified.css; mirror them here as low-alpha fills with lifted
   text, same approach as the semantic --color-*-bg tokens above. */
html[data-theme="dark"] .admin-badge-muted,
html[data-theme="dark"] .admin-badge-status.inactive,
html[data-theme="dark"] .admin-badge-status.archived {
  background: rgba(148, 163, 184, 0.14);
}
html[data-theme="dark"] .admin-badge-role.direct    { background: rgba(59, 130, 246, 0.18); color: #93b8ff; }
html[data-theme="dark"] .admin-badge-role.inherited { background: rgba(34, 197, 94, 0.16);  color: #6ee7a0; }
html[data-theme="dark"] .admin-badge-role.essential { background: rgba(248, 113, 113, 0.16); color: #fca5a5; }

html[data-theme="dark"] .admin-badge-difficulty-1 { background: rgba(34, 197, 94, 0.16);  color: #6ee7a0; }
html[data-theme="dark"] .admin-badge-difficulty-2 { background: rgba(16, 185, 129, 0.16); color: #5eead4; }
html[data-theme="dark"] .admin-badge-difficulty-3 { background: rgba(250, 204, 21, 0.16); color: #fde047; }
html[data-theme="dark"] .admin-badge-difficulty-4 { background: rgba(251, 146, 60, 0.16); color: #fdba74; }
html[data-theme="dark"] .admin-badge-difficulty-5 { background: rgba(248, 113, 113, 0.16); color: #fca5a5; }

/* Selection list active state (deeper-than-hover #cfe2ff in light) */
html[data-theme="dark"] .admin-selection-item.active {
  background: rgba(59, 130, 246, 0.28);
}
