/* ==========================================================================
   QuantaLearn Phase 2 — application shell (styles-v3.css).
   Loaded AFTER styles.css and styles-v2.css. Additive only.
   ========================================================================== */

/* ============================================================ NEW TOKENS */
:root {
  --violet:                #7C63F5;
  --violet-soft:           #1C1733;
  --violet-2:              #9A85FF;
  --on-violet:             #FFFFFF;
  --mint:                  #3ECFB2;
  --mint-soft:             #0E2D29;

  --sidebar-w:             240px;
  --sidebar-w-collapsed:   56px;
  --topbar-h:              52px;

  --z-sidebar:             60;
  --z-topbar:              70;
  --z-drawer:              110;

  --sidebar-bg:            #F5F7FA;
  --sidebar-border:        var(--rule);
  --topbar-bg:             var(--surface);
  --topbar-border:         var(--rule);

  --nav-item-h:            36px;
  --nav-item-radius:       var(--radius-md);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --violet:       #9A85FF;
    --violet-soft:  #1C1733;
    --violet-2:     #B3A3FF;
    --on-violet:    #0B0D14;
    --mint:         #3ECFB2;
    --mint-soft:    #0C2826;
    --sidebar-bg:   #0E1220;
  }
}
:root[data-theme="dark"] {
  --violet:       #9A85FF;
  --violet-soft:  #1C1733;
  --violet-2:     #B3A3FF;
  --on-violet:    #0B0D14;
  --mint:         #3ECFB2;
  --mint-soft:    #0C2826;
  --sidebar-bg:   #0E1220;
}

.pill.mint { background: var(--mint-soft); color: var(--mint); }

/* ============================================================ SHELL LAYOUT */
body.shell-active { overflow: hidden; }

#shell {
  display: flex;
  height: 100vh;
  overflow: hidden;
  position: relative;
  z-index: 1;
}

/* ---- sidebar ---- */
#shell-sidebar {
  flex: none;
  width: var(--sidebar-w);
  height: 100vh;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--sidebar-border);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition:
    width var(--motion-standard) var(--ease-standard),
    transform var(--motion-standard) var(--ease-standard);
  z-index: var(--z-sidebar);
}
#shell-sidebar.collapsed { width: var(--sidebar-w-collapsed); }

/* brand */
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  height: var(--topbar-h);
  padding: 0 14px;
  border-bottom: 1px solid var(--sidebar-border);
  flex: none;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
}
.sidebar-brand-mark {
  flex: none;
  font-family: "IBM Plex Mono", monospace;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -.02em;
  color: var(--violet);
  text-shadow: 0 0 18px color-mix(in srgb, var(--violet) 35%, transparent);
  min-width: 28px;
  text-align: center;
}
.sidebar-brand-name {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.015em;
  white-space: nowrap;
  transition: opacity var(--motion-standard) var(--ease-standard);
}
#shell-sidebar.collapsed .sidebar-brand-name { opacity: 0; pointer-events: none; }

/* nav scroll area */
.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 10px 8px;
  scrollbar-width: thin;
  scrollbar-color: var(--rule-2) transparent;
}
.sidebar-nav::-webkit-scrollbar { width: 4px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: var(--rule-2); border-radius: 2px; }

/* group headings */
.sidebar-group {
  margin: 16px 0 4px;
  padding: 0 8px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  transition: opacity var(--motion-standard) var(--ease-standard);
}
.sidebar-group:first-child { margin-top: 4px; }
#shell-sidebar.collapsed .sidebar-group { opacity: 0; }

/* nav items */
.sidebar-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: var(--nav-item-h);
  padding: 0 10px;
  border-radius: var(--nav-item-radius);
  border: 0;
  background: none;
  cursor: pointer;
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
  color: var(--ink-3);
  text-align: left;
  letter-spacing: 0.04em; /* the global button tracking truncated "Algorithm Playground" */
  white-space: nowrap;
  overflow: hidden;
  position: relative;
  transition:
    color var(--motion-quick) var(--ease-standard),
    background var(--motion-quick) var(--ease-standard);
}
.sidebar-item:hover { color: var(--ink); background: var(--surface-2); }
.sidebar-item[aria-current="true"],
.sidebar-item.active {
  color: var(--violet);
  background: var(--violet-soft);
  font-weight: 600;
}
.sidebar-item[aria-current="true"]::before,
.sidebar-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  background: var(--violet);
  border-radius: 0 2px 2px 0;
}
.sidebar-item-icon {
  flex: none;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  line-height: 1;
}
.sidebar-item-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: opacity var(--motion-standard) var(--ease-standard);
}
#shell-sidebar.collapsed .sidebar-item-label { opacity: 0; pointer-events: none; }

/* collapsed tooltips */
#shell-sidebar.collapsed .sidebar-item::after {
  content: attr(data-label);
  position: absolute;
  left: calc(var(--sidebar-w-collapsed) + 8px);
  top: 50%;
  transform: translateY(-50%);
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--rule-2);
  border-radius: var(--radius-md);
  padding: 5px 10px;
  font-size: 12px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  z-index: calc(var(--z-sidebar) + 1);
  box-shadow: var(--elev-1);
  transition: opacity var(--motion-quick) var(--ease-standard);
}
#shell-sidebar.collapsed .sidebar-item:hover::after { opacity: 1; }

/* separator */
.sidebar-sep { height: 1px; background: var(--sidebar-border); margin: 8px 0; }

/* footer */
.sidebar-footer {
  flex: none;
  padding: 8px;
  border-top: 1px solid var(--sidebar-border);
  overflow: hidden;
}
.sidebar-footer .sidebar-item { font-size: 11.5px; }

/* collapse toggle */
.sidebar-collapse-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-md);
  border: 1px solid var(--rule-2);
  background: var(--surface);
  cursor: pointer;
  color: var(--ink-3);
  margin: 4px auto 0;
  transition: color var(--motion-quick), background var(--motion-quick);
}
.sidebar-collapse-btn:hover { color: var(--ink); background: var(--surface-2); }
.sidebar-collapse-btn svg {
  transition: transform var(--motion-standard) var(--ease-standard);
}
#shell-sidebar.collapsed .sidebar-collapse-btn svg { transform: scaleX(-1); }

/* ============================================================ TOP BAR */
#shell-topbar {
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--topbar-h);
  padding: 0 16px;
  background: var(--topbar-bg);
  border-bottom: 1px solid var(--topbar-border);
  position: sticky;
  top: 0;
  z-index: var(--z-topbar);
  flex: none;
}

.topbar-hamburger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 0;
  background: none;
  cursor: pointer;
  border-radius: var(--radius-md);
  color: var(--ink-3);
  flex: none;
  transition: color var(--motion-quick), background var(--motion-quick);
}
.topbar-hamburger:hover { color: var(--ink); background: var(--surface-2); }

.topbar-title-area {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.topbar-breadcrumb {
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: .06em;
  color: var(--ink-3);
  overflow: hidden;
  white-space: nowrap;
}
.topbar-breadcrumb-sep { opacity: .4; }
.topbar-breadcrumb a { color: var(--ink-3); text-decoration: none; }
.topbar-breadcrumb a:hover { color: var(--accent); }
.topbar-page-title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.topbar-controls { display: flex; align-items: center; gap: 6px; flex: none; }

/* ============================================================ MAIN AREA */
#shell-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#shell-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
}
#shell-content .app {
  max-width: 1400px;
  margin: 0 auto;
  padding: 20px 24px 80px;
}

/* ============================================================ MOBILE DRAWER */
.shell-drawer-bg {
  display: none;
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--ground) 70%, transparent);
  z-index: calc(var(--z-drawer) - 1);
  backdrop-filter: blur(2px);
}
.shell-drawer-bg.open { display: block; }

/* ============================================================ BREADCRUMBS */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 10.5px;
  letter-spacing: .05em;
  color: var(--ink-3);
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.breadcrumb a { color: var(--ink-3); text-decoration: none; }
.breadcrumb a:hover { color: var(--accent); }
.breadcrumb-current { color: var(--ink-2); font-weight: 600; }
.breadcrumb-sep { opacity: .4; }

/* ============================================================ PAGE HEADER */
.page-header {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 20px;
}
.page-header-body { flex: 1; min-width: 0; }
.page-header-kicker {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--violet);
  font-weight: 700;
  display: block;
  margin-bottom: 4px;
}
.page-header-title {
  margin: 0 0 6px;
  font-size: clamp(22px, 2.8vw, 30px);
  font-weight: 800;
  letter-spacing: -.022em;
  line-height: 1.08;
  text-wrap: balance;
}
.page-header-desc {
  margin: 0;
  font-size: 15px;
  color: var(--ink-2);
  max-width: 72ch;
  line-height: 1.6;
}
.page-header-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-start; flex: none; }

/* ============================================================ ROLE CHIPS */
.role-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  padding: 2px 7px;
  white-space: nowrap;
}
.role-chip.student    { background: var(--surface-3);   color: var(--ink-2); }
.role-chip.instructor { background: var(--violet-soft); color: var(--violet); }
.role-chip.admin      { background: var(--warn-soft);   color: var(--warn); }

/* ============================================================ SIDEBAR USER CARD */
.sidebar-user {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  overflow: hidden;
}
.sidebar-user-avatar {
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--violet-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  color: var(--violet);
  font-weight: 700;
  font-family: "IBM Plex Mono", monospace;
}
.sidebar-user-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  transition: opacity var(--motion-standard) var(--ease-standard);
}
#shell-sidebar.collapsed .sidebar-user-info { opacity: 0; }
.sidebar-user-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sidebar-user-meta { font-family: "IBM Plex Mono", monospace; font-size: 9.5px; color: var(--ink-3); }

/* ============================================================ NOTIFICATION BADGE */
.topbar-notif-btn { position: relative; }
.notif-badge {
  position: absolute;
  top: 2px; right: 2px;
  min-width: 14px; height: 14px;
  border-radius: 7px;
  background: var(--signal);
  color: #fff;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  padding: 0 3px;
  border: 2px solid var(--ground);
  line-height: 1;
}

/* ============================================================ RESPONSIVE */

/* Tablet: collapse sidebar to icons */
@media (max-width: 1024px) {
  #shell-sidebar { width: var(--sidebar-w-collapsed); }
  #shell-sidebar .sidebar-brand-name,
  #shell-sidebar .sidebar-group,
  #shell-sidebar .sidebar-item-label,
  #shell-sidebar .sidebar-user-info { opacity: 0; pointer-events: none; }
}

/* Mobile: sidebar becomes a slide-in drawer */
@media (max-width: 768px) {
  body.shell-active { overflow: auto; }
  #shell { display: block; height: auto; overflow: visible; }
  #shell-main { overflow: visible; }
  #shell-content { overflow: visible; }

  #shell-sidebar {
    position: fixed;
    left: 0; top: 0;
    height: 100vh;
    width: var(--sidebar-w) !important;
    transform: translateX(-100%);
    z-index: var(--z-drawer);
    box-shadow: var(--elev-2);
  }
  #shell-sidebar.drawer-open { transform: translateX(0); }
  #shell-sidebar.drawer-open .sidebar-brand-name,
  #shell-sidebar.drawer-open .sidebar-group,
  #shell-sidebar.drawer-open .sidebar-item-label,
  #shell-sidebar.drawer-open .sidebar-user-info { opacity: 1; pointer-events: auto; }
  #shell-sidebar.drawer-open .sidebar-item::after { display: none; }

  .topbar-hamburger { display: flex; }
  .sidebar-collapse-btn { display: none; }

  #shell-topbar { position: fixed; top: 0; left: 0; right: 0; }
  #shell-content { padding-top: var(--topbar-h); }
  #shell-content .app { padding-top: 20px; }
}

/* Desktop: hide hamburger */
@media (min-width: 1025px) {
  .topbar-hamburger { display: none; }
  .shell-drawer-bg { display: none !important; }
}

/* ============================================================ NAV INTEGRATION */
/* When shell is mounted, hide the original top-bar header. */
body.shell-active header.bar { display: none; }

/* Keep contextual strip visible, repositioned to flow below shell topbar */
body.shell-active .header-contextual-strip {
  position: sticky;
  top: 0;
  z-index: calc(var(--z-topbar) - 1);
  margin: 0 -24px 16px;
  padding-left: 24px;
  padding-right: 24px;
}

body.shell-active #shell-content .app { padding-top: 16px; }

/* ============================================================ FOCUS STYLES */
.sidebar-item:focus-visible,
.sidebar-collapse-btn:focus-visible,
.topbar-hamburger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ============================================================ PRINT */
@media print {
  #shell-sidebar, #shell-topbar { display: none !important; }
  #shell { display: block; }
  #shell-main, #shell-content { overflow: visible; padding-top: 0 !important; }
  body.shell-active header.bar { display: flex; }
}

/* ============================================================ PHASE 3 — DASHBOARD */

.dashboard {
  display: flex;
  flex-direction: column;
  gap: 40px;
  max-width: 1100px;
  margin: 0 auto;
  padding-bottom: 72px;
}

/* ---- Welcome hero ---- */
.dash-welcome {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 36px 40px 28px;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--violet) 14%, var(--surface)) 0%,
    var(--surface) 55%,
    color-mix(in srgb, var(--mint) 8%, var(--surface)) 100%);
  border: 1px solid color-mix(in srgb, var(--violet) 22%, var(--rule));
  border-radius: var(--radius-lg);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--violet) 10%, transparent), var(--elev-1);
  position: relative;
  overflow: hidden;
}
.dash-welcome::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 60% 140% at 90% -10%, color-mix(in srgb, var(--violet) 18%, transparent) 0%, transparent 65%);
  pointer-events: none;
}
.dash-welcome-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  position: relative;
}
.dash-welcome-body { flex: 1; min-width: 0; }
.dash-greeting {
  margin: 0 0 8px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--violet);
  font-weight: 600;
  opacity: .85;
}
.dash-title {
  margin: 0 0 12px;
  font-size: clamp(24px, 3vw, 34px);
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.1;
}
.dash-goal {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-size: 13px;
  color: var(--ink-2);
}
.dash-goal-label {
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  background: var(--violet-soft);
  color: var(--violet);
  padding: 3px 8px;
  border-radius: var(--radius-pill);
}
.dash-due-notice {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--warn);
}
.dash-due-btn {
  border: 0;
  background: none;
  color: var(--violet);
  font-size: 12px;
  font-family: "IBM Plex Mono", monospace;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
}
/* XP badge — top-right corner of hero */
.dash-xp-pill {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
  flex: none;
  background: color-mix(in srgb, var(--violet) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--violet) 24%, var(--rule));
  border-radius: var(--radius-md);
  padding: 10px 14px;
  min-width: 90px;
}
.dash-xp-level {
  font-size: 14px;
  font-weight: 800;
  color: var(--violet);
  letter-spacing: -.01em;
}
.dash-xp-count {
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  color: var(--ink-3);
}
/* XP progress bar — full-width in hero footer */
.dash-xp-bar-wrap {
  display: flex;
  align-items: center;
  gap: 14px;
  position: relative;
}
.dash-xp-bar {
  flex: 1;
  height: 8px;
  background: color-mix(in srgb, var(--violet) 12%, var(--surface-3));
  border-radius: 4px;
  overflow: hidden;
}
.dash-xp-bar i {
  display: block;
  height: 100%;
  width: var(--prog, 0%);
  background: linear-gradient(90deg, var(--violet), color-mix(in srgb, var(--violet) 70%, var(--mint)));
  border-radius: 4px;
  transition: width .6s var(--ease-standard);
}
.dash-xp-next {
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  color: var(--ink-3);
  white-space: nowrap;
  flex: none;
}

/* ---- Section wrapper ---- */
.dash-section { display: flex; flex-direction: column; gap: 16px; }
.dash-section-title {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.dash-section-sub {
  margin: -8px 0 0;
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  color: var(--ink-3);
}

/* ---- Continue learning card ---- */
.dash-continue-card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 0;
  box-shadow: var(--elev-1);
  transition: box-shadow var(--motion-quick);
}
.dash-continue-card:hover { box-shadow: var(--elev-2, 0 4px 20px rgba(0,0,0,.18)); }
/* Top color stripe */
.dash-continue-card::before {
  content: '';
  display: block;
  height: 4px;
  background: linear-gradient(90deg, var(--track-color, var(--violet)), color-mix(in srgb, var(--track-color, var(--violet)) 40%, transparent));
  flex: none;
}
.dash-continue-inner {
  padding: 20px 28px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.dash-continue-track {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--track-color, var(--violet));
  font-weight: 700;
}
.dash-continue-track-icon { font-size: 16px; }
.dash-continue-track-name { flex: 1; }
.dash-continue-track-pct {
  margin-left: auto;
  background: color-mix(in srgb, var(--track-color, var(--violet)) 15%, transparent);
  color: var(--track-color, var(--violet));
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: 10px;
}
.dash-continue-title {
  margin: 0;
  font-size: clamp(16px, 2vw, 21px);
  font-weight: 800;
  letter-spacing: -.02em;
}
.dash-continue-story {
  margin: 0;
  font-size: 13.5px;
  color: var(--ink-2);
  line-height: 1.65;
}
.dash-continue-meta { display: flex; gap: 10px; }
.dash-continue-meta-item {
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  color: var(--ink-3);
  background: var(--surface-2);
  padding: 2px 8px;
  border-radius: var(--radius-sm);
}
.dash-continue-prog-wrap { display: flex; align-items: center; gap: 12px; }
.dash-continue-prog {
  flex: 1;
  height: 6px;
  background: var(--surface-3);
  border-radius: 3px;
  overflow: hidden;
}
.dash-continue-prog i {
  display: block; height: 100%; width: var(--prog, 0%);
  background: var(--track-color, var(--violet));
  border-radius: 3px;
  transition: width .5s var(--ease-standard);
}
.dash-continue-prog-label {
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  color: var(--ink-3);
  flex: none;
}
.dash-continue-actions { display: flex; gap: 10px; align-items: center; }

/* ---- Stats grid ---- */
.dash-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}
.dash-stat {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  padding: 18px 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  transition: box-shadow var(--motion-quick), transform var(--motion-quick);
  position: relative;
  overflow: hidden;
}
.dash-stat::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--stat-color, var(--surface-3));
  border-radius: 0;
}
.dash-stat:hover { box-shadow: var(--elev-1); transform: translateY(-1px); }
.dash-stat-value {
  font-size: 32px;
  font-weight: 900;
  letter-spacing: -.04em;
  color: var(--stat-color, var(--ink));
  line-height: 1;
  padding-top: 4px;
}
.dash-stat-label { font-size: 12px; color: var(--ink-2); font-weight: 600; }
.dash-stat-sub {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  color: var(--ink-3);
}
/* Per-stat accent colours injected via style attr */
.dash-stat[data-accent="violet"] { --stat-color: var(--violet); }
.dash-stat[data-accent="mint"]   { --stat-color: var(--mint); }
.dash-stat[data-accent="warn"]   { --stat-color: var(--warn); }
.dash-stat[data-accent="blue"]   { --stat-color: #3B82F6; }

/* ---- Recommendation card ---- */
.dash-rec-card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: relative;
  overflow: hidden;
}
.dash-rec-card::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  background: linear-gradient(180deg, var(--violet), var(--mint));
}
.dash-rec-concept { display: flex; align-items: center; gap: 10px; }
.dash-rec-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  background: var(--violet-soft);
  color: var(--violet);
  padding: 3px 8px;
  border-radius: var(--radius-pill);
}
.dash-rec-name { font-size: 17px; font-weight: 800; color: var(--ink); letter-spacing: -.01em; }
.dash-rec-reason { margin: 0; font-size: 13.5px; color: var(--ink-2); line-height: 1.65; }
.dash-rec-score-wrap { display: flex; align-items: center; gap: 12px; }
.dash-rec-score-bar {
  flex: 1; height: 6px;
  background: var(--surface-3);
  border-radius: 3px;
  overflow: hidden;
}
.dash-rec-score-bar i {
  display: block; height: 100%;
  width: var(--prog, 0%);
  background: linear-gradient(90deg, var(--warn), var(--violet));
  border-radius: 3px;
  transition: width .5s var(--ease-standard);
}
.dash-rec-score-num {
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  color: var(--ink-3);
  flex: none;
}
.dash-rec-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---- Learning path grid ---- */
.dash-path-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 12px;
}
.dash-track-card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  overflow: hidden;
  cursor: default;
  transition: box-shadow var(--motion-quick), transform var(--motion-quick);
}
.dash-track-card:hover { box-shadow: var(--elev-1); transform: translateY(-1px); }
/* Color band at top of each track card */
.dash-track-card::before {
  content: '';
  display: block;
  height: 5px;
  background: var(--track-color, var(--violet));
  flex: none;
}
.dash-track-header,
.dash-track-prog,
.dash-track-footer { padding: 0 14px; }
.dash-track-active {
  border-color: var(--track-color, var(--violet));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--track-color, var(--violet)) 30%, transparent);
}
.dash-track-done { border-color: var(--mint); }
.dash-track-done::before { background: var(--mint); }
.dash-track-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 14px !important;
  padding-bottom: 6px;
}
.dash-track-icon {
  font-size: 22px;
  line-height: 1;
  flex: none;
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--track-color, var(--violet)) 12%, var(--surface-2));
  border-radius: var(--radius-sm);
}
.dash-track-meta { flex: 1; min-width: 0; }
.dash-track-kicker {
  display: block;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--track-color, var(--violet));
  margin-bottom: 2px;
  opacity: .8;
}
.dash-track-name {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dash-track-badge {
  flex: none;
  width: 22px; height: 22px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
}
.dash-track-badge-done { background: var(--mint-soft); color: var(--mint); }
.dash-track-badge-active { background: var(--violet-soft); color: var(--violet); }
.dash-track-prog {
  height: 4px;
  background: var(--surface-3);
  overflow: hidden;
  margin: 10px 0 8px;
}
.dash-track-prog i {
  display: block; height: 100%;
  width: var(--prog, 0%);
  background: var(--track-color, var(--violet));
  transition: width .5s var(--ease-standard);
}
.dash-track-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding-bottom: 14px !important;
}
.dash-track-count {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10.5px;
  color: var(--ink-3);
}
.dash-track-complete {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  color: var(--mint);
}
.dash-path-all-btn { align-self: center; margin-top: 4px; }

/* ---- Activity feed ---- */
.dash-activity-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.dash-activity-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  background: var(--surface);
  font-size: 13px;
  border-bottom: 1px solid var(--rule);
}
.dash-activity-row:last-child { border-bottom: 0; }
.dash-activity-icon {
  width: 28px; height: 28px;
  border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; flex: none;
}
.dash-activity-correct .dash-activity-icon { background: var(--mint-soft); color: var(--mint); }
.dash-activity-wrong .dash-activity-icon { background: var(--warn-soft); color: var(--warn); }
.dash-activity-row-lesson .dash-activity-icon { background: var(--violet-soft); color: var(--violet); }
.dash-activity-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dash-activity-title { font-size: 13px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.dash-activity-meta {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  color: var(--ink-3);
}
.dash-empty-state { padding: 48px 0; text-align: center; }
.dash-empty-text { color: var(--ink-3); font-size: 13px; }

/* ============================================================ PHASE 3 — CATALOG */

.catalog-header { margin-bottom: 0; }

.catalog-filter-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.catalog-search-wrap { flex: 1; min-width: 200px; position: relative; }
.catalog-search {
  width: 100%;
  padding: 10px 16px;
  background: var(--surface);
  border: 1px solid var(--rule-2);
  border-radius: var(--radius-md);
  font-size: 13.5px;
  color: var(--ink);
  font-family: inherit;
  outline: none;
  transition: border-color var(--motion-quick), box-shadow var(--motion-quick);
}
.catalog-search:focus {
  border-color: var(--violet);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--violet) 16%, transparent);
}
.catalog-filter {
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--rule-2);
  border-radius: var(--radius-md);
  font-size: 13px;
  color: var(--ink);
  font-family: inherit;
  outline: none;
  cursor: pointer;
}
.catalog-filter:focus { border-color: var(--violet); }

.catalog-overview {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 20px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
}
.catalog-overview-text { display: flex; justify-content: space-between; align-items: center; }
.catalog-overview-count { font-size: 13.5px; color: var(--ink-2); font-weight: 500; }
.catalog-overview-pct {
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
  color: var(--violet);
  font-weight: 700;
}
.catalog-overview-bar {
  height: 8px;
  background: var(--surface-3);
  border-radius: 4px;
  overflow: hidden;
}
.catalog-overview-bar i {
  display: block; height: 100%;
  width: var(--prog, 0%);
  background: linear-gradient(90deg, var(--violet), var(--mint));
  transition: width .5s var(--ease-standard);
}

/* Cards: tall with a large color banner at top */
.catalog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
}
.catalog-card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: box-shadow var(--motion-quick), transform var(--motion-quick);
  cursor: default;
}
.catalog-card:hover { box-shadow: 0 6px 24px rgba(0,0,0,.16); transform: translateY(-2px); }
.catalog-card-expanded { border-color: var(--track-color, var(--violet)); }
.catalog-card-done { border-color: var(--mint); }
/* Wide color banner */
.catalog-card-bar {
  height: 56px;
  background: linear-gradient(135deg, var(--track-color, var(--violet)), color-mix(in srgb, var(--track-color, var(--violet)) 50%, transparent));
  display: flex;
  align-items: flex-end;
  padding: 0 20px 10px;
  position: relative;
}
/* Icon floated over the banner */
.catalog-card-bar::after {
  content: attr(data-icon);
  position: absolute;
  right: 18px;
  bottom: -18px;
  font-size: 36px;
  line-height: 1;
  opacity: .9;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.3));
}
.catalog-card-body { padding: 20px 20px 16px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.catalog-card-header { display: flex; align-items: flex-start; gap: 12px; padding-top: 4px; }
.catalog-card-icon { display: none; } /* now in bar::after */
.catalog-card-titles { flex: 1; min-width: 0; }
.catalog-card-kicker {
  display: block;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--track-color, var(--violet));
  margin-bottom: 5px;
}
.catalog-card-title { margin: 0; font-size: 16px; font-weight: 800; letter-spacing: -.015em; }
.catalog-card-done-badge {
  flex: none;
  background: var(--mint-soft);
  color: var(--mint);
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
}
.catalog-card-blurb { margin: 0; font-size: 13px; color: var(--ink-2); line-height: 1.65; flex: 1; }
.catalog-card-stats { display: flex; gap: 8px; flex-wrap: wrap; }
.catalog-card-stat {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10.5px;
  color: var(--ink-3);
  background: var(--surface-2);
  padding: 2px 7px;
  border-radius: var(--radius-sm);
}
.catalog-card-progress { background: color-mix(in srgb, var(--track-color, var(--violet)) 14%, var(--surface-2)); color: var(--track-color, var(--violet)); }
.catalog-card-prog {
  height: 5px;
  background: var(--surface-3);
  border-radius: 3px;
  overflow: hidden;
}
.catalog-card-prog i {
  display: block; height: 100%;
  width: var(--prog, 0%);
  background: var(--track-color, var(--violet));
  transition: width .5s var(--ease-standard);
}
.catalog-card-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  padding-top: 4px;
  border-top: 1px solid var(--rule);
  margin-top: 4px;
}
.catalog-card-detail-btn { margin-left: auto; }

.catalog-empty { text-align: center; padding: 60px 20px; }
.catalog-empty.hidden { display: none; }

/* ---- Detail panel ---- */
.catalog-detail {
  background: var(--surface);
  border: 1px solid var(--rule-2);
  border-top: 4px solid var(--track-color, var(--violet));
  border-radius: var(--radius-lg);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-top: 8px;
  overflow: hidden;
}
.catalog-detail.hidden { display: none; }
.catalog-detail-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 24px 28px 16px;
}
.catalog-detail-header-left { display: flex; align-items: center; gap: 16px; }
.catalog-detail-icon {
  font-size: 32px;
  flex: none;
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--track-color, var(--violet)) 12%, var(--surface-2));
  border-radius: var(--radius-md);
}
.catalog-detail-kicker {
  display: block;
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--track-color, var(--violet));
  margin-bottom: 5px;
}
.catalog-detail-title { margin: 0; font-size: 22px; font-weight: 900; letter-spacing: -.02em; }
.catalog-detail-close { margin-left: auto; flex: none; }
.catalog-detail-blurb {
  margin: 0;
  font-size: 14px;
  color: var(--ink-2);
  line-height: 1.7;
  padding: 0 28px;
}
.catalog-detail-meta {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding: 12px 28px;
}
.catalog-detail-meta span {
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  color: var(--ink-3);
  background: var(--surface-2);
  padding: 3px 9px;
  border-radius: var(--radius-sm);
}
.catalog-detail-prog {
  height: 6px;
  background: var(--surface-3);
  overflow: hidden;
  margin: 0 0 4px;
}
.catalog-detail-prog i {
  display: block; height: 100%;
  width: var(--prog, 0%);
  background: var(--track-color, var(--violet));
  transition: width .6s var(--ease-standard);
}
.catalog-detail-action {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 28px;
  background: color-mix(in srgb, var(--track-color, var(--violet)) 6%, var(--surface-2));
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  flex-wrap: wrap;
}
.catalog-detail-action-done { justify-content: center; }
.catalog-detail-next { display: flex; flex-direction: column; gap: 4px; }
.catalog-detail-next-label {
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: .1em;
  font-weight: 700;
  color: var(--ink-3);
}
.catalog-detail-next-title { font-size: 15px; font-weight: 700; color: var(--ink); }
.catalog-detail-complete-badge {
  font-size: 15px;
  font-weight: 800;
  color: var(--mint);
}
.catalog-detail-lessons-title {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding: 16px 28px 8px;
}

/* Lesson list in detail */
.catalog-lesson-list { display: flex; flex-direction: column; padding: 0 28px 20px; }
.catalog-lesson-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--rule);
  font-size: 13px;
}
.catalog-lesson-row:last-child { border-bottom: 0; }
.catalog-lesson-done .catalog-lesson-title { color: var(--ink-3); }
.catalog-lesson-next .catalog-lesson-title { font-weight: 700; color: var(--ink); }
.catalog-lesson-num {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10.5px;
  color: var(--ink-3);
  width: 24px;
  flex: none;
}
.catalog-lesson-status { font-size: 13px; width: 20px; text-align: center; flex: none; }
.catalog-lesson-done .catalog-lesson-status { color: var(--mint); }
.catalog-lesson-next .catalog-lesson-status { color: var(--violet); }
.catalog-lesson-body { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 10px; }
.catalog-lesson-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.catalog-lesson-meta {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  color: var(--ink-3);
  flex: none;
}
.catalog-lesson-btn { flex: none; }

/* ============================================================ RESPONSIVE (Phase 3) */
@media (max-width: 768px) {
  .dashboard { gap: 28px; }
  .dash-welcome { padding: 24px 20px 20px; }
  .dash-stats-grid { grid-template-columns: repeat(2, 1fr); }
  .dash-path-grid { grid-template-columns: 1fr 1fr; }
  .catalog-grid { grid-template-columns: 1fr; }
  .catalog-detail { }
  .catalog-detail-header, .catalog-detail-blurb, .catalog-detail-meta,
  .catalog-detail-action, .catalog-detail-lessons-title, .catalog-lesson-list { padding-left: 20px; padding-right: 20px; }
  .catalog-detail-action { flex-direction: column; align-items: stretch; }
}
@media (max-width: 480px) {
  .dash-path-grid { grid-template-columns: 1fr; }
  .dash-stats-grid { grid-template-columns: repeat(2, 1fr); }
  .dash-welcome-top { flex-direction: column; }
  .dash-xp-pill { align-items: flex-start; }
}

/* ============================================================ PREFERS-REDUCED-MOTION */
@media (prefers-reduced-motion: reduce) {
  .dash-xp-bar i,
  .dash-continue-prog i,
  .dash-rec-score-bar i,
  .dash-track-prog i,
  .catalog-overview-bar i,
  .catalog-card-prog i,
  .catalog-detail-prog i { transition: none; }
}
[data-reduced-motion="true"] .dash-xp-bar i,
[data-reduced-motion="true"] .dash-continue-prog i,
[data-reduced-motion="true"] .dash-rec-score-bar i,
[data-reduced-motion="true"] .dash-track-prog i,
[data-reduced-motion="true"] .catalog-overview-bar i,
[data-reduced-motion="true"] .catalog-card-prog i,
[data-reduced-motion="true"] .catalog-detail-prog i { transition: none; }

/* ============================================================ COMPONENT LIBRARY */

/* ---- Button variants ---- */
/* Violet-primary overrides the legacy indigo .btn.primary */
.btn.primary {
  background: var(--violet);
  border-color: var(--violet);
  color: var(--on-violet);
}
.btn.primary:hover {
  background: var(--violet-2);
  border-color: var(--violet-2);
  color: var(--on-violet);
}
/* Medium button (default) and large */
.btn.lg {
  padding: 9px 18px;
  font-size: 13px;
  border-radius: var(--radius-md);
  min-height: 40px;
}
/* Icon button */
.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  background: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  color: var(--ink-3);
  transition: color var(--motion-quick) var(--ease-standard),
              background var(--motion-quick) var(--ease-standard);
}
.btn-icon:hover { color: var(--ink); background: var(--surface-2); }
.btn-icon:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (pointer: coarse) { .btn-icon { width: 44px; height: 44px; } }

/* Success / danger button variants */
.btn.success {
  background: var(--good-soft);
  border-color: var(--good);
  color: var(--good);
}
.btn.success:hover { background: var(--good); color: #fff; }
.btn.danger {
  background: var(--signal-soft);
  border-color: var(--signal);
  color: var(--signal);
}
.btn.danger:hover { background: var(--signal); color: #fff; }

/* ---- Badge / pill variants using design tokens ---- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  padding: 2px 8px;
  white-space: nowrap;
  line-height: 1.6;
}
.badge.primary   { background: var(--violet-soft);  color: var(--violet); }
.badge.success   { background: var(--good-soft);    color: var(--good); }
.badge.warning   { background: var(--warn-soft);    color: var(--warn); }
.badge.danger    { background: var(--signal-soft);  color: var(--signal); }
.badge.info      { background: var(--accent-soft);  color: var(--accent); }
.badge.neutral   { background: var(--surface-3);    color: var(--ink-2); }
.badge.mint      { background: var(--mint-soft);    color: var(--mint); }

/* ---- Input / form field ---- */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.field-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
  letter-spacing: .01em;
}
.field-input {
  background: var(--surface);
  border: 1.5px solid var(--rule-2);
  border-radius: var(--radius-md);
  padding: 9px 12px;
  font-size: 13px;
  color: var(--ink);
  font-family: inherit;
  transition: border-color var(--motion-quick) var(--ease-standard),
              box-shadow var(--motion-quick) var(--ease-standard);
  outline: none;
}
.field-input:focus {
  border-color: var(--violet);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--violet) 18%, transparent);
}
.field-input::placeholder { color: var(--ink-3); }
.field-hint {
  font-size: 11px;
  color: var(--ink-3);
}
.field-error .field-input { border-color: var(--signal); }
.field-error .field-label { color: var(--signal); }
.field-error .field-hint  { color: var(--signal); }

/* ---- Progress bar ---- */
.progress-bar {
  height: 6px;
  background: var(--surface-3);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.progress-bar i {
  display: block;
  height: 100%;
  width: var(--prog, 0%);
  background: var(--violet);
  border-radius: var(--radius-pill);
  transition: width .5s var(--ease-standard);
}
.progress-bar.mint i    { background: var(--mint); }
.progress-bar.warn i    { background: var(--warn); }
.progress-bar.success i { background: var(--good); }
.progress-bar.thin { height: 3px; }
.progress-bar.thick { height: 10px; }

/* ---- Dialog / modal ---- */
.dialog-overlay {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--ground) 75%, transparent);
  backdrop-filter: blur(3px);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.dialog {
  background: var(--surface);
  border: 1px solid var(--rule-2);
  border-radius: var(--radius-xl);
  box-shadow: var(--elev-2);
  padding: 28px;
  max-width: 480px;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 18px;
  position: relative;
}
.dialog-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.dialog-title {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -.015em;
}
.dialog-close {
  flex: none;
  margin-top: -4px;
}
.dialog-body {
  font-size: 14px;
  color: var(--ink-2);
  line-height: 1.6;
  margin: 0;
}
.dialog-footer {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  flex-wrap: wrap;
}

/* ---- Tabs (violet accent variant) ---- */
.tab-bar {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--rule);
  overflow-x: auto;
  scrollbar-width: none;
}
.tab-bar::-webkit-scrollbar { display: none; }
.tab-btn {
  flex: none;
  padding: 8px 16px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  cursor: pointer;
  font-family: "IBM Plex Mono", monospace;
  font-size: 11.5px;
  letter-spacing: .06em;
  color: var(--ink-3);
  white-space: nowrap;
  transition: color var(--motion-quick) var(--ease-standard),
              border-color var(--motion-quick) var(--ease-standard);
  margin-bottom: -1px;
}
.tab-btn:hover { color: var(--ink); }
.tab-btn[aria-selected="true"] {
  color: var(--violet);
  border-bottom-color: var(--violet);
  font-weight: 600;
}
.tab-panel { display: none; padding: 18px 0; }
.tab-panel.on { display: block; }

/* ---- Alert / notice variants ---- */
.alert {
  display: flex;
  gap: 12px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  border: 1px solid;
  font-size: 13.5px;
  line-height: 1.55;
}
.alert.info    { background: var(--accent-soft); border-color: var(--accent); color: var(--ink-2); }
.alert.success { background: var(--good-soft);   border-color: var(--good);   color: var(--ink-2); }
.alert.warning { background: var(--warn-soft);   border-color: var(--warn);   color: var(--ink-2); }
.alert.danger  { background: var(--signal-soft); border-color: var(--signal); color: var(--ink-2); }
.alert.violet  { background: var(--violet-soft); border-color: var(--violet); color: var(--ink-2); }
.alert-icon { flex: none; font-size: 16px; line-height: 1.4; }
.alert-body { flex: 1; min-width: 0; }
.alert-title { font-weight: 700; color: var(--ink); margin-bottom: 2px; }

/* ---- Focus style — violet ring for shell components ---- */
.sidebar-item:focus-visible,
.sidebar-collapse-btn:focus-visible,
.topbar-hamburger:focus-visible,
.tab-btn:focus-visible,
.btn-icon:focus-visible {
  outline: 2px solid var(--violet);
  outline-offset: 2px;
}

/* ---- Skeleton / loading placeholder ---- */
.skeleton {
  background: linear-gradient(
    90deg,
    var(--surface-2) 25%,
    var(--surface-3) 50%,
    var(--surface-2) 75%
  );
  background-size: 200% 100%;
  border-radius: var(--radius-sm);
  animation: skeleton-shimmer 1.6s ease-in-out infinite;
}
@keyframes skeleton-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }
[data-reduced-motion="true"] .skeleton { animation: none !important; }

/* ---- Empty state ---- */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 60px 20px;
  text-align: center;
  color: var(--ink-3);
}
.empty-state-icon { font-size: 36px; line-height: 1; opacity: .6; }
.empty-state-title { margin: 0; font-size: 17px; font-weight: 700; color: var(--ink-2); }
.empty-state-desc { margin: 0; font-size: 13.5px; max-width: 42ch; line-height: 1.6; }

/* =====================================================================
   Phase 5 — the ambient lab backdrop
   =====================================================================
   Two static gradient layers behind the app's scrolling content, shown only
   while Build is the current view. There is no keyframe animation here on
   purpose: the only thing that ever moves these layers is a real desktop
   pointermove writing --lab-*-x/y (ui/lab-backdrop.js), and when the pointer
   stops they stop. A backdrop that animated by itself would compete with the
   circuit, which is the one thing on this screen that matters.

   Why position:fixed behind #shell-content rather than inside #view-build:
   Build's panels tile that section with opaque var(--surface), so a backdrop
   placed there paints only into the grid's 14px gutters and is invisible.
   The ground this can actually be seen against is the page's own.

   Everything is drawn from the existing theme tokens, so both layers follow
   light/dark automatically and neither needs a second colour system. */

.lab-bg {
  position: fixed;
  /* Bled past the viewport so a 7px parallax can never reveal an edge. */
  inset: -16px;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  --lab-far-x: 0px; --lab-far-y: 0px;
  --lab-near-x: 0px; --lab-near-y: 0px;
}
.lab-bg[hidden] { display: none; }
/* #shell-content is a plain scroller; its children need a stacking context
   above the fixed layer or the whole app would render underneath it. */
#shell-content > *:not(.lab-bg) { position: relative; z-index: 1; }

.lab-bg > i {
  position: absolute;
  inset: -4%;
  display: block;
  /* transform, not background-position — the compositor can move a layer
     without repainting it, which is what keeps this at zero measurable cost. */
  transition: transform var(--motion-emphasis) var(--ease-standard);
  will-change: transform;
}

/* Far layer: the bench. A faint lattice on exactly the circuit's own cell
   pitch (--cw/--rh), so the room the learner is in and the thing they are
   building are visibly the same grid. */
.lab-bg-far {
  transform: translate3d(var(--lab-far-x), var(--lab-far-y), 0);
  opacity: .85;
  background-image:
    linear-gradient(to right, color-mix(in srgb, var(--rule-2) 60%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--rule-2) 60%, transparent) 1px, transparent 1px);
  background-size: var(--cw) var(--rh);
  /* Fades toward the bottom so no gridline ever runs behind the long prose
     panels lower down the page. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 34%, transparent 78%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 34%, transparent 78%);
}

/* Near layer: two very soft pools of light, one accent, one violet. */
.lab-bg-near {
  transform: translate3d(var(--lab-near-x), var(--lab-near-y), 0);
  opacity: .9;
  background-image:
    radial-gradient(60% 50% at 12% 4%, color-mix(in srgb, var(--accent) 18%, transparent) 0%, transparent 72%),
    radial-gradient(52% 46% at 94% 24%, color-mix(in srgb, var(--violet) 14%, transparent) 0%, transparent 72%);
}

/* ---- Stage: the lab fills in as real modules are actually completed ----
   Four steps, each one quieter than a learner would expect. Stage 0 is a
   bare bench and is the honest default for someone who has finished nothing;
   nothing here is awarded, announced, or reversible-by-accident, because it
   is only ever read from completedModules(). */
.lab-bg[data-stage="0"] .lab-bg-far  { opacity: .45; }
.lab-bg[data-stage="0"] .lab-bg-near { opacity: .5; }
.lab-bg[data-stage="1"] .lab-bg-far  { opacity: .7; }
.lab-bg[data-stage="2"] .lab-bg-far  { opacity: .85; }
.lab-bg[data-stage="2"] .lab-bg-near { opacity: 1; }
.lab-bg[data-stage="3"] .lab-bg-far  { opacity: 1; }
.lab-bg[data-stage="3"] .lab-bg-near { opacity: 1; }
/* Stage 3 alone earns one extra detail: a faint horizon across the bench. */
.lab-bg[data-stage="3"]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 30%;
  height: 1px;
  background: linear-gradient(to right, transparent, color-mix(in srgb, var(--accent) 34%, transparent) 45%, transparent);
}

/* Dark themes carry more contrast in the panels already, so the backdrop
   steps back rather than matching it. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .lab-bg-far  { opacity: .55; }
  :root:not([data-theme="light"]) .lab-bg-near { opacity: .75; }
}
:root[data-theme="dark"] .lab-bg-far  { opacity: .55; }
:root[data-theme="dark"] .lab-bg-near { opacity: .75; }

/* Reduced motion: the layers still render (they are static paint and cost
   nothing) but the transition that would smooth a parallax step is removed,
   and lab-backdrop.js never binds the pointer listener in the first place. */
@media (prefers-reduced-motion: reduce) { .lab-bg > i { transition: none; } }
[data-reduced-motion="true"] .lab-bg > i { transition: none !important; }

/* Phones: no pointer to parallax against, and the panels come much closer to
   the viewport edges, so the backdrop is dialled right back. */
@media (max-width: 840px) {
  .lab-bg-far  { opacity: .3 !important; }
  .lab-bg-near { opacity: .45 !important; }
  .lab-bg[data-stage="3"]::after { display: none; }
}

/* ---- Hidden perf panel (?perf=1 or QuantaLearn.perf.show(true)) ----
   A developer surface. Never shown to a learner, never focusable, and it
   reports frames the app already drew rather than scheduling any. */
.perf-panel {
  position: fixed;
  /* Left, not right: the copilot FAB sits bottom-right, and although this
     panel is pointer-events:none and cannot block it, printing a frame
     counter across the button reads as breakage rather than as a tool. */
  left: 10px;
  bottom: 10px;
  z-index: 9999;
  pointer-events: none;
  padding: 5px 9px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--rule-2);
  background: var(--surface);
  color: var(--ink-2);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10.5px;
  letter-spacing: .04em;
  white-space: nowrap;
  box-shadow: var(--shadow);
}

/* ================================================= PRACTISE CHALLENGE HUB
   (ui/assess.js renderChallenges.) The circuit-challenge list as a place to
   come back to: a record strip on top, then the challenges grouped Warm-up /
   Core / Stretch. Every colour is an existing token, so both themes follow;
   the medal colours repeat the HUD's .chud-medal recipe (styles-v2.css) so a
   gold means the same thing on both screens. Stable hooks for tests and live
   checks: .practise-summary .practise-tier .pcard-medal .pcard-bans
   .pcard-solved. */

/* #chals is a .chal-grid, whose 310px minimum track would overflow a phone.
   The hub is its only child and lays itself out, so the grid steps aside. */
#chals { display: block; }
.practise-hub { display: grid; gap: var(--space-8); min-width: 0; }

/* ---- the record strip ---- */
.practise-summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3) var(--space-7);
  align-items: center;
  padding: var(--space-5) var(--space-7);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--good);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.ps-record {
  grid-column: 1;
  font-size: var(--text-base);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.ps-record b { color: var(--ink); font-weight: 700; }
.ps-solved b { font-size: var(--text-xl); letter-spacing: -.01em; }
.ps-medal { white-space: nowrap; }
.ps-medal::before {
  content: "";
  display: inline-block;
  width: 8px; height: 8px;
  margin-right: 5px;
  border-radius: 50%;
  vertical-align: 1px;
  background: var(--medal, var(--ink-3));
}
.ps-medal.gold   { --medal: var(--warn); }
.ps-medal.silver { --medal: var(--ink-2); }
.ps-medal.bronze { --medal: color-mix(in srgb, var(--signal) 55%, var(--warn)); }
.ps-bar {
  grid-column: 1;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  overflow: hidden;
}
.ps-bar > i {
  display: block;
  height: 100%;
  background: var(--good);
  border-radius: inherit;
  transition: width var(--motion-emphasis) var(--ease-standard);
}
.ps-streak {
  grid-column: 2;
  grid-row: 1 / span 2;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2);
}
.ps-combo {
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--text-sm);
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
}
.ps-days {
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--text-xs);
  color: var(--ink-3);
}
.ps-days.on {
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: var(--warn-soft);
  color: var(--warn);
  font-weight: 600;
}

/* ---- one tier ---- */
.practise-tier { min-width: 0; }
.practise-tier-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin: 0 0 var(--space-5);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--rule);
}
.practise-tier-head h4 {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -.005em;
}
.practise-tier-hint { font-size: var(--text-sm); color: var(--ink-3); }
.practise-tier-count {
  margin-left: auto;
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--text-xs);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.practise-tier-grid {
  display: grid;
  /* min(100%, …) so a single card never forces a phone-width overflow */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: var(--space-6);
}

/* ---- one card (keeps .chal's surface, status and golf styling) ---- */
.pcard { display: flex; flex-direction: column; min-width: 0; }
/* the goal soaks up spare height, so a row's actions line up */
.pcard .goal { flex: 1 0 auto; }
.pcard .chal-actions { margin-top: var(--space-4); }
.pcard-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
}
.pcard-title {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: 700;
  line-height: 1.3;
  min-width: 0;
  overflow-wrap: anywhere;
}
.pcard-solved {
  flex: none;
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 2px 7px;
  border-radius: var(--radius-sm);
  background: var(--good-soft);
  color: var(--good);
}
.pcard-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-2) 0 var(--space-4);
}
.pcard-fact {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10.5px;
  color: var(--ink-3);
  padding: 1px 7px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-pill);
  font-variant-numeric: tabular-nums;
}
.pcard-medal {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  border: 1px solid currentColor;
}
.pcard-medal.gold   { color: var(--warn); background: var(--warn-soft); }
.pcard-medal.silver { color: var(--ink-2); background: color-mix(in srgb, var(--ink-2) 12%, transparent); }
.pcard-medal.bronze {
  --bronze: color-mix(in srgb, var(--signal) 55%, var(--warn));
  color: var(--bronze);
  background: color-mix(in srgb, var(--bronze) 13%, transparent);
}
.pcard-medal.none {
  color: var(--ink-3);
  border-style: dashed;
  border-color: var(--rule-2);
  font-weight: 600;
}
.pcard-bans {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
}
.pcard-bans-label {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--signal);
}
.pcard-ban {
  font-size: 11px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: var(--radius-sm);
  color: var(--signal);
  background: var(--signal-soft);
  border: 1px solid color-mix(in srgb, var(--signal) 40%, transparent);
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
}
/* Checked: still focusable (aria-disabled, not disabled), but quiet, and it
   must not light up on hover as if pressing it would do something. */
.pcard-check[aria-disabled="true"] { opacity: .65; cursor: default; }
.pcard-check[aria-disabled="true"]:hover { border-color: var(--rule-2); color: var(--ink); }

@media (max-width: 560px) {
  .practise-summary { grid-template-columns: minmax(0, 1fr); padding: var(--space-4) var(--space-5); }
  .ps-streak {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .practise-tier-count { margin-left: 0; }
}
@media (prefers-reduced-motion: reduce) { .ps-bar > i { transition: none; } }
:root[data-reduced-motion="true"] .ps-bar > i { transition: none; }
/* ============================================= END PRACTISE CHALLENGE HUB */
