/* ============================================================================
   PRAXIS · DESIGN SYSTEM
   ----------------------------------------------------------------------------
   01 Tokens          07 Cards            13 Dashboard       19 Animations
   02 Reset & base    08 Badges & pills   14 Progress        20 Responsive
   03 Background      09 Forms            15 Chat            21 A11y & print
   04 Typography      10 Filters          16 Resume builder
   05 Layout          11 Navbar           17 Tracker/roadmap  22 Utilities
   06 Buttons         12 Hero             18 Feedback states
   ========================================================================== */

/* ── 01 · TOKENS ─────────────────────────────────────────────────────────── */
:root{
  /* brand + accents (one hue family, one success, one warning — no rainbow) */
  --pri:#4f46e5;          --pri-hover:#4338ca;   --pri-ink:#ffffff;
  --pri-soft:#eef0ff;     --pri-ring:rgba(79,70,229,.32);
  --pri-grad:linear-gradient(135deg,#4f46e5 0%,#6d5ce7 55%,#7c3aed 100%);

  --ok:#0a7c72;           --ok-soft:#e6f7f5;
  --warn:#a35f08;         --warn-soft:#fdf3e3;
  --danger:#dc2626;       --danger-soft:#fdecec;
  --stamp:#be1e6d;        --stamp-soft:#fceaf3;
  --eu:#4f46e5;           --eu-soft:#eef0ff;
  --teal:#0a6b86;         --teal-soft:#e4f4f8;

  /* neutrals — light theme is the default */
  --bg:#f6f7fb;
  --bg-2:#eef0f7;
  --paper:#ffffff;
  --surface:#ffffff;
  --surface-2:#f4f5fa;
  --surface-3:#e9ebf4;
  --ink:#0e1020;
  --ink-soft:#464d61;
  /* The faint tone carries timestamps, message counts, hint text and small
     print, so it has to clear 4.5:1 on the *lightest* surface it lands on
     (--surface-3) and not merely on white. Measured 5.7:1 on white, 4.8:1 on
     --surface-3. It used to be #7b8298, which measured 3.9:1 on white. */
  --ink-faint:#5f6679;
  --line:#e4e7f0;
  --line-strong:#cdd2e0;

  --shadow-xs:0 1px 2px rgba(14,16,32,.05);
  --shadow-sm:0 1px 2px rgba(14,16,32,.05),0 2px 6px rgba(14,16,32,.045);
  --shadow:0 2px 4px rgba(14,16,32,.04),0 8px 22px rgba(14,16,32,.07);
  --shadow-lg:0 4px 8px rgba(14,16,32,.05),0 20px 46px rgba(14,16,32,.11);
  --shadow-pop:0 12px 30px rgba(14,16,32,.14),0 2px 8px rgba(14,16,32,.07);

  /* geometry */
  --r-xs:6px; --r-sm:9px; --r:12px; --r-md:14px; --r-lg:18px; --r-xl:24px; --r-full:999px;
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px; --sp-6:24px;
  --sp-8:32px; --sp-10:40px; --sp-12:48px; --sp-16:64px; --sp-20:80px;
  --wrap:1200px;
  --nav-h:66px;

  /* motion */
  --t-fast:160ms; --t:240ms; --t-slow:340ms;
  --ease:cubic-bezier(.4,0,.2,1);
  --ease-out:cubic-bezier(.16,1,.3,1);

  --font-display:"Manrope","Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --font-body:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
}

[data-theme="dark"]{
  --pri:#8b8cf8;          --pri-hover:#a5a3fb;  --pri-ink:#0b0d18;
  --pri-soft:rgba(139,140,248,.13);
  --pri-ring:rgba(139,140,248,.38);
  --pri-grad:linear-gradient(135deg,#6d6df7 0%,#8a6af2 55%,#9b6bf8 100%);

  --ok:#2dd4bf;           --ok-soft:rgba(45,212,191,.13);
  --warn:#f0b429;         --warn-soft:rgba(240,180,41,.13);
  --danger:#f87171;       --danger-soft:rgba(248,113,113,.13);
  --stamp:#f472b6;        --stamp-soft:rgba(244,114,182,.13);
  --eu:#8b8cf8;           --eu-soft:rgba(139,140,248,.13);
  --teal:#38bdf8;         --teal-soft:rgba(56,189,248,.13);

  --bg:#08090f;
  --bg-2:#0d0f18;
  --paper:#12141f;
  --surface:#12141f;
  --surface-2:#191c2a;
  --surface-3:#212636;
  --ink:#eef0f8;
  --ink-soft:#a6adc4;
  /* Lightened for the same reason as the light theme's faint tone, measured
     against the *lightest* dark surface (--surface-3): 5.9:1 there, 7.1:1 on
     --surface. It used to be #7a819a, which measured 2.4:1 on --surface. */
  --ink-faint:#9aa1b8;
  --line:#242839;
  --line-strong:#333850;

  --shadow-xs:0 1px 2px rgba(0,0,0,.4);
  --shadow-sm:0 1px 2px rgba(0,0,0,.4),0 2px 6px rgba(0,0,0,.3);
  --shadow:0 2px 4px rgba(0,0,0,.3),0 8px 24px rgba(0,0,0,.42);
  --shadow-lg:0 4px 10px rgba(0,0,0,.35),0 22px 50px rgba(0,0,0,.55);
  --shadow-pop:0 14px 34px rgba(0,0,0,.6),0 2px 10px rgba(0,0,0,.4);
}

/* "auto" follows the OS unless the user has pinned a theme */
@media (prefers-color-scheme:dark){
  html:not([data-theme="light"]):not([data-theme="dark"]){
    --pri:#8b8cf8;      --pri-hover:#a5a3fb;  --pri-ink:#0b0d18;
    --pri-soft:rgba(139,140,248,.13); --pri-ring:rgba(139,140,248,.38);
    --pri-grad:linear-gradient(135deg,#6d6df7 0%,#8a6af2 55%,#9b6bf8 100%);
    --ok:#2dd4bf;  --ok-soft:rgba(45,212,191,.13);
    --warn:#f0b429;--warn-soft:rgba(240,180,41,.13);
    --danger:#f87171; --danger-soft:rgba(248,113,113,.13);
    --stamp:#f472b6; --stamp-soft:rgba(244,114,182,.13);
    --eu:#8b8cf8;  --eu-soft:rgba(139,140,248,.13);
    --teal:#38bdf8;--teal-soft:rgba(56,189,248,.13);
    --bg:#08090f; --bg-2:#0d0f18; --paper:#12141f; --surface:#12141f;
    --surface-2:#191c2a; --surface-3:#212636;
    --ink:#eef0f8; --ink-soft:#a6adc4; --ink-faint:#9aa1b8;
    --line:#242839; --line-strong:#333850;
    --shadow-xs:0 1px 2px rgba(0,0,0,.4);
    --shadow-sm:0 1px 2px rgba(0,0,0,.4),0 2px 6px rgba(0,0,0,.3);
    --shadow:0 2px 4px rgba(0,0,0,.3),0 8px 24px rgba(0,0,0,.42);
    --shadow-lg:0 4px 10px rgba(0,0,0,.35),0 22px 50px rgba(0,0,0,.55);
    --shadow-pop:0 14px 34px rgba(0,0,0,.6),0 2px 10px rgba(0,0,0,.4);
  }
}

/* ── 02 · RESET & BASE ───────────────────────────────────────────────────── */
*,*::before,*::after{ box-sizing:border-box; }
html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:calc(var(--nav-h) + 16px);
}
body{
  margin:0;
  /* dvh, not vh. On Android `100vh` is the viewport height with the URL bar
   * *hidden*, so a body sized to it is taller than the screen whenever the bar
   * is showing — the page then scrolls slightly too far and stops dead, which
   * reads as "the footer is stuck". `dvh` tracks the bar as it collapses.
   * No @supports guard: dvh shipped in Chrome 108, and this sheet already
   * requires color-mix(), which shipped in Chrome 111. */
  min-height:100dvh;
  font-family:var(--font-body);
  font-size:15.5px;
  line-height:1.65;
  color:var(--ink);
  background:var(--bg);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  font-feature-settings:"cv02","cv03","cv04","ss01";
  overflow-x:hidden;
}
h1,h2,h3,h4,h5{
  font-family:var(--font-display);
  color:var(--ink);
  letter-spacing:-.022em;
  line-height:1.18;
  margin:0 0 var(--sp-3);
  font-weight:700;
}
h1{ font-size:clamp(2rem,1.35rem + 2.6vw,3.3rem); font-weight:800; letter-spacing:-.035em; }
h2{ font-size:clamp(1.5rem,1.2rem + 1.3vw,2.05rem); font-weight:750; letter-spacing:-.03em; }
h3{ font-size:1.12rem; font-weight:700; letter-spacing:-.018em; }
h4{ font-size:1rem;   font-weight:700; }
p{ margin:0 0 var(--sp-4); }
p:last-child{ margin-bottom:0; }
a{ color:var(--pri); text-decoration:none; transition:color var(--t-fast) var(--ease); }
a:hover{ color:var(--pri-hover); }
img,svg{ max-width:100%; display:block; }
ul,ol{ margin:0 0 var(--sp-4); padding-left:1.3em; }
li{ margin-bottom:.3em; }
hr{ border:0; border-top:1px solid var(--line); margin:var(--sp-5) 0; }
strong,b{ font-weight:650; color:var(--ink); }
small{ font-size:.8em; }
code,kbd,samp,pre{ font-family:var(--font-mono); font-size:.875em; }
table{ border-collapse:collapse; width:100%; margin:var(--sp-4) 0; font-size:14px; }
th,td{ text-align:left; padding:9px 12px; border-bottom:1px solid var(--line); vertical-align:top; }
th{ font-weight:650; color:var(--ink-soft); font-size:12px; text-transform:uppercase; letter-spacing:.06em; width:34%; }
button,input,select,textarea{ font:inherit; color:inherit; }
button{ cursor:pointer; background:none; border:0; padding:0; }
::selection{ background:var(--pri); color:#fff; }

/* focus — visible, consistent, never removed */
:focus-visible{
  outline:2px solid var(--pri);
  outline-offset:2px;
  border-radius:var(--r-xs);
}
:focus:not(:focus-visible){ outline:none; }

.skip-link{
  position:fixed; top:-100px; left:var(--sp-4); z-index:200;
  background:var(--pri); color:var(--pri-ink); padding:11px 18px;
  border-radius:var(--r-sm); font-weight:600; font-size:14px;
  box-shadow:var(--shadow-lg); transition:top var(--t) var(--ease);
}
.skip-link:focus{ top:var(--sp-3); color:var(--pri-ink); }

/* scrollbars */
*{ scrollbar-width:thin; scrollbar-color:var(--line-strong) transparent; }
*::-webkit-scrollbar{ width:9px; height:9px; }
*::-webkit-scrollbar-track{ background:transparent; }
*::-webkit-scrollbar-thumb{ background:var(--line-strong); border-radius:var(--r-full); border:2px solid transparent; background-clip:content-box; }
*::-webkit-scrollbar-thumb:hover{ background:var(--ink-faint); background-clip:content-box; }

/* ── 03 · BACKGROUND ─────────────────────────────────────────────────────── */
body::before{
  content:""; position:fixed; inset:0; z-index:-2; pointer-events:none;
  background:
    radial-gradient(1100px 620px at 12% -8%,  color-mix(in srgb,var(--pri) 12%,transparent) 0%, transparent 62%),
    radial-gradient(900px 520px at 92% 4%,    color-mix(in srgb,#7c3aed 10%,transparent) 0%, transparent 60%),
    radial-gradient(1000px 700px at 50% 108%, color-mix(in srgb,var(--teal) 8%,transparent)  0%, transparent 62%),
    linear-gradient(180deg,var(--bg) 0%,var(--bg-2) 48%,var(--bg) 100%);
}
/* faint grid — gives the page texture without noise */
body::after{
  content:""; position:fixed; inset:0; z-index:-1; pointer-events:none; opacity:.5;
  background-image:
    linear-gradient(to right,color-mix(in srgb,var(--line) 55%,transparent) 1px,transparent 1px),
    linear-gradient(to bottom,color-mix(in srgb,var(--line) 55%,transparent) 1px,transparent 1px);
  background-size:64px 64px;
  -webkit-mask-image:radial-gradient(ellipse 90% 60% at 50% 0%,#000 0%,transparent 78%);
          mask-image:radial-gradient(ellipse 90% 60% at 50% 0%,#000 0%,transparent 78%);
}
#stage{ position:relative; z-index:1; min-height:60vh; }
#stage:focus{ outline:none; }

/* ── 04 · TYPOGRAPHY ─────────────────────────────────────────────────────── */
.grad{
  background:var(--pri-grad);
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent; color:transparent;
}
.eyebrow{
  display:inline-flex; align-items:center; gap:7px;
  font-family:var(--font-display);
  font-size:11.5px; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
  color:var(--pri); margin:0 0 10px;
}
.sec-h{
  display:flex; align-items:flex-end; justify-content:space-between;
  gap:var(--sp-4); flex-wrap:wrap;
  margin:var(--sp-10) 0 var(--sp-5);
  padding-bottom:var(--sp-4); border-bottom:1px solid var(--line);
}
.sec-h:first-child{ margin-top:0; }
.sec-h h2{ margin:0; }
.sec-h .eyebrow{ margin:0 0 6px; }
.folio{
  font-size:12.5px; color:var(--ink-faint); font-weight:500;
  display:inline-flex; align-items:center; gap:6px;
}
.deck{ font-size:1.06rem; color:var(--ink-soft); line-height:1.72; max-width:60ch; }
.num{ font-family:var(--font-display); font-weight:800; letter-spacing:-.03em; font-variant-numeric:tabular-nums; }
.lbl{
  font-family:var(--font-display);
  font-size:11.5px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--pri);
}
.k{
  display:inline-block; padding:3px 9px; border-radius:var(--r-full);
  background:var(--pri-soft); color:var(--pri);
  font-size:10.5px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
}
.more{ font-size:13px; font-weight:650; white-space:nowrap; }
.hint{ font-size:12.5px; color:var(--ink-faint); line-height:1.55; }
.privacy-note{
  display:flex; gap:10px; align-items:flex-start;
  background:var(--surface); border:1px solid var(--line); border-left:3px solid var(--ok);
  border-radius:var(--r); padding:12px 16px; margin:0 0 var(--sp-6);
  font-size:13px; color:var(--ink-soft); line-height:1.6; box-shadow:var(--shadow-xs);
}
.privacy-note b{ color:var(--ink); }
.live-dot{
  width:7px; height:7px; border-radius:50%; background:var(--ok);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--ok) 22%,transparent);
  animation:pulseDot 2.2s var(--ease) infinite; flex:none;
}

/* ── 05 · LAYOUT ─────────────────────────────────────────────────────────── */
.wrap{ width:100%; max-width:var(--wrap); margin-inline:auto; padding-inline:clamp(16px,4vw,32px); }
.page{ padding-block:var(--sp-10) var(--sp-20); }
.page > .wrap > *:last-child{ margin-bottom:0; }
.tworow{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-5); align-items:start; }
.cgrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(310px,1fr)); gap:var(--sp-4); }
.rgrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(268px,1fr)); gap:var(--sp-4); }
.lgrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); gap:var(--sp-4); }
.feat-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(258px,1fr)); gap:var(--sp-4); }
.tgrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(288px,1fr)); gap:var(--sp-4); }
.pgrid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-4); align-items:start; }
.kcols{ display:grid; grid-template-columns:repeat(6,minmax(184px,1fr)); gap:var(--sp-3); align-items:start; }
.why-grid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-5); }
.rbuild{ display:grid; grid-template-columns:minmax(0,1fr) 320px; gap:var(--sp-5); align-items:start; }
.sec{ padding-block:var(--sp-12); }
.sec-alt{
  background:color-mix(in srgb,var(--surface) 62%,transparent);
  border-block:1px solid var(--line);
}

/* ── 06 · BUTTONS ────────────────────────────────────────────────────────── */
.btn{
  --btn-bg:var(--surface); --btn-fg:var(--ink); --btn-bd:var(--line-strong);
  position:relative; display:inline-flex; align-items:center; justify-content:center; gap:7px;
  padding:10px 18px; border:1px solid var(--btn-bd); border-radius:var(--r-sm);
  background:var(--btn-bg); color:var(--btn-fg);
  font-family:var(--font-display);
  font-size:14px; font-weight:650; letter-spacing:-.01em; line-height:1.2;
  text-align:center; white-space:nowrap; text-decoration:none;
  box-shadow:var(--shadow-xs);
  transition:background var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),
             color var(--t-fast) var(--ease),box-shadow var(--t) var(--ease),
             transform var(--t-fast) var(--ease);
}
.btn:hover{ background:var(--surface-2); border-color:var(--ink-faint); color:var(--btn-fg); transform:translateY(-1px); box-shadow:var(--shadow-sm); }
.btn:active{ transform:translateY(0); box-shadow:var(--shadow-xs); }
.btn:disabled,.btn[aria-disabled="true"]{ opacity:.5; pointer-events:none; }

.btn.dark{ --btn-bg:var(--pri); --btn-fg:var(--pri-ink); --btn-bd:var(--pri);
  box-shadow:0 1px 2px rgba(14,16,32,.14),0 6px 16px color-mix(in srgb,var(--pri) 26%,transparent); }
.btn.dark:hover{ --btn-bg:var(--pri-hover); --btn-bd:var(--pri-hover); color:var(--pri-ink); box-shadow:0 2px 4px rgba(14,16,32,.16),0 10px 24px color-mix(in srgb,var(--pri) 32%,transparent); }
.btn.lite{ --btn-bg:var(--surface); --btn-fg:var(--ink); }
.btn.gho{ --btn-bg:transparent; --btn-fg:var(--ink-soft); --btn-bd:var(--line-strong); box-shadow:none; }
.btn.gho:hover{ --btn-fg:var(--ink); background:var(--surface-2); }
.btn.ok{ --btn-bg:var(--ok-soft); --btn-fg:var(--ok); --btn-bd:transparent; box-shadow:none; }
.btn.danger{ --btn-bg:var(--danger-soft); --btn-fg:var(--danger); --btn-bd:transparent; box-shadow:none; }
.btn.danger:hover{ --btn-bg:var(--danger); --btn-fg:#fff; }
.btn.sm{ padding:7px 13px; font-size:12.5px; border-radius:var(--r-xs); }
.btn.lg{ padding:13px 24px; font-size:15px; border-radius:var(--r); }
.btn[aria-pressed="true"]{ border-color:var(--pri); color:var(--pri); background:var(--pri-soft); }
.btn-block{ width:100%; }

.icon-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:38px; height:38px; border-radius:var(--r-sm);
  border:1px solid var(--line); background:var(--surface); color:var(--ink-soft);
  font-size:16px; line-height:1;
  transition:all var(--t-fast) var(--ease);
}
.icon-btn:hover{ background:var(--surface-2); color:var(--ink); border-color:var(--line-strong); transform:translateY(-1px); }
.icon-btn.on{ background:var(--pri-soft); color:var(--pri); border-color:transparent; }

.theme-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:38px; height:38px; border-radius:var(--r-sm);
  border:1px solid var(--line); background:var(--surface); color:var(--ink-soft);
  font-size:15px; line-height:1;
  transition:all var(--t-fast) var(--ease);
}
.theme-btn:hover{ background:var(--surface-2); color:var(--ink); transform:translateY(-1px); }
.theme-btn .t-ico{ display:block; transition:transform var(--t-slow) var(--ease); }
.theme-btn:hover .t-ico{ transform:rotate(-18deg) scale(1.08); }

/* ── 07 · CARDS ──────────────────────────────────────────────────────────── */
.card,.panel,.feat,.icard,.ccard,.ocard,.tcard,.rcard,.lcard,.res-card,.kitem,.kcol{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r-md);
  box-shadow:var(--shadow-xs);
}
.panel{ padding:var(--sp-5); }
.panel + .panel{ margin-top:var(--sp-4); }
.panel-h{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3);
  margin:calc(var(--sp-5) * -1) calc(var(--sp-5) * -1) var(--sp-4);
  padding:var(--sp-4) var(--sp-5);
  border-bottom:1px solid var(--line);
}
.panel-h:first-child{ margin-top:calc(var(--sp-4) * -1); }
.panel-h h3{ margin:0; font-size:1.02rem; }
.panel-h h4{ margin:0; }

.feat{ padding:var(--sp-5); text-align:center; transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease),border-color var(--t) var(--ease); }
.feat:hover{ transform:translateY(-3px); box-shadow:var(--shadow); border-color:color-mix(in srgb,var(--pri) 26%,var(--line)); }
.feat .ic{
  display:inline-flex; align-items:center; justify-content:center;
  width:50px; height:50px; border-radius:var(--r);
  background:var(--pri-soft); font-size:23px; margin:0 auto var(--sp-3);
  border:1px solid color-mix(in srgb,var(--pri) 14%,transparent);
}
.feat h3{ margin:0 0 6px; }
.feat p{ font-size:13.8px; color:var(--ink-soft); line-height:1.62; margin:0; }
.feat .k{ margin-top:var(--sp-3); }

/* internship card */
.icard{
  position:relative; display:flex; flex-direction:column;
  padding:var(--sp-5); padding-top:calc(var(--sp-5) + 4px);
  transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease),border-color var(--t) var(--ease);
}
.icard:hover{ transform:translateY(-3px); box-shadow:var(--shadow); border-color:color-mix(in srgb,var(--pri) 30%,var(--line)); }
.icard h3{ margin:0 0 10px; font-size:1.06rem; }
.icard .cmp{ margin-bottom:8px; }
.icard .acts{ margin-top:auto; padding-top:var(--sp-4); }
.matchpill{
  position:absolute; top:var(--sp-4); right:var(--sp-4);
  padding:4px 10px; border-radius:var(--r-full);
  background:var(--pri-soft); color:var(--pri);
  font-size:11.5px; font-weight:750; letter-spacing:-.01em; white-space:nowrap;
  font-family:var(--font-display);
}
.matchpill.zero{ background:var(--surface-2); color:var(--ink-faint); }
.meta{ display:flex; flex-wrap:wrap; gap:5px; margin:0 0 10px; }
.meta > span{
  padding:3px 9px; border-radius:var(--r-xs);
  background:var(--surface-2); color:var(--ink-soft);
  font-size:11.5px; font-weight:550; white-space:nowrap;
}
.elig{ font-size:12.5px; color:var(--ink-soft); line-height:1.55; margin:0 0 6px; }
.elig b{ color:var(--ink); }
.deadline{ font-size:12.5px; color:var(--warn); font-weight:550; margin:0 0 4px; }
.acts{ display:flex; flex-wrap:wrap; gap:7px; }

/* course card */
.ccard{ display:flex; flex-direction:column; padding:var(--sp-5); transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease),border-color var(--t) var(--ease); }
.ccard:hover{ transform:translateY(-3px); box-shadow:var(--shadow); border-color:color-mix(in srgb,var(--pri) 26%,var(--line)); }
.ccard h3{ margin:8px 0 6px; font-size:1.04rem; }
.ccard > p{ font-size:13.5px; color:var(--ink-soft); line-height:1.6; margin:0 0 10px; }
.ccard .tags{ margin:0 0 10px; }
.ccard .why{ font-size:12.5px; color:var(--ink-soft); line-height:1.55; margin:0 0 6px; }
.ccard .sem{ font-size:12px; color:var(--ink-faint); }
.ccard .prog{ margin:var(--sp-3) 0; }
.ccard .acts,.ccard > div:last-child{ margin-top:auto; padding-top:var(--sp-3); }
.ccard.my{ border-color:color-mix(in srgb,var(--pri) 24%,var(--line)); }

/* opportunity card */
.ocard{ display:flex; flex-direction:column; padding:var(--sp-5); transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease),border-color var(--t) var(--ease); }
.ocard:hover{ transform:translateY(-3px); box-shadow:var(--shadow); border-color:color-mix(in srgb,var(--pri) 26%,var(--line)); }
.ocard h3{ margin:8px 0 6px; font-size:1.04rem; }
.ocard > p{ font-size:13.5px; color:var(--ink-soft); line-height:1.6; margin:0 0 10px; }
.ocard .dl{ font-size:12.5px; color:var(--ink-soft); margin:0 0 4px; }
.ocard .dl b{ color:var(--ink); }

/* AI tool card */
.tcard{ display:flex; flex-direction:column; padding:var(--sp-5); transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease),border-color var(--t) var(--ease); }
.tcard:hover{ transform:translateY(-3px); box-shadow:var(--shadow); }
.tc-head{ display:flex; align-items:center; gap:12px; margin:0 0 12px; }
.tc-logo{
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:44px; height:44px; border-radius:var(--r);
  background:var(--pri-soft); border:1px solid color-mix(in srgb,var(--pri) 15%,transparent);
  font-size:21px; line-height:1;
}
.tc-cat{ display:block; font-size:10.5px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--pri); }
.tc-head h3{ margin:1px 0 0; font-size:1rem; }
.tcard > p{ font-size:13.5px; color:var(--ink-soft); line-height:1.6; margin:0 0 10px; }
.tc-best{ font-size:12.5px; font-weight:600; color:var(--ink); margin:0 0 6px; }
.tc-meta{ font-size:12.5px; color:var(--ink-soft); line-height:1.6; margin:0 0 12px; }
.tcard .acts{ margin-top:auto; padding-top:var(--sp-3); }

/* resource card (anchor) */
.rcard{
  display:flex; flex-direction:column;
  padding:var(--sp-5); color:var(--ink); text-decoration:none;
  transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease),border-color var(--t) var(--ease);
}
.rcard:hover{ transform:translateY(-3px); box-shadow:var(--shadow); border-color:color-mix(in srgb,var(--pri) 30%,var(--line)); color:var(--ink); }
.rcard h3{ margin:0 0 6px; font-size:1rem; }
.rcard p{ font-size:13.2px; color:var(--ink-soft); line-height:1.58; margin:0 0 14px; flex:1; }
.rcard .go{
  align-self:flex-start; margin-top:auto;
  display:inline-flex; align-items:center; gap:5px;
  padding:5px 11px; border-radius:var(--r-full);
  font-family:var(--font-display); font-size:12.5px; font-weight:650;
  text-decoration:none; white-space:nowrap;
  background:var(--pri); color:var(--pri-ink);
  transition:background var(--t-fast) var(--ease),transform var(--t-fast) var(--ease);
}
.go:hover{ background:var(--pri-hover); transform:translateY(-1px); }
.rcard:hover .go{ gap:8px; }

/* learn list card */
.lcard{ padding:var(--sp-5); }
.lcard-h{ display:flex; align-items:center; gap:11px; margin:0 0 var(--sp-3); }
.lcard-ic{
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:36px; height:36px; border-radius:var(--r-sm);
  background:var(--pri-soft); font-size:17px;
}
.lcard-h h3{ margin:0; font-size:1rem; flex:1; }
.lcard-c{ font-size:11.5px; font-weight:650; color:var(--ink-faint); white-space:nowrap; }
.lul{ list-style:none; padding:0; margin:0; }
.lul li{ display:flex; flex-direction:column; gap:1px; padding:9px 0; border-bottom:1px dashed var(--line); }
.lul li:last-child{ border-bottom:0; }
.lil{ font-size:14px; font-weight:600; color:var(--ink); }
.lil:hover{ color:var(--pri); }
.lil-d{ font-size:12.2px; color:var(--ink-faint); line-height:1.5; }

.res-card{ padding:var(--sp-5); display:flex; flex-direction:column; }
.res-card h3{ margin:0 0 4px; font-size:1rem; }
.res-purpose{ display:block; font-size:12px; color:var(--pri); font-weight:600; margin:0 0 8px; }
.res-card p{ font-size:13.2px; color:var(--ink-soft); line-height:1.58; margin:0 0 14px; flex:1; }
.res-card .acts{ margin-top:auto; }

/* generic card / utility */
.card{ padding:var(--sp-5); transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease); }
.card:hover{ transform:translateY(-2px); box-shadow:var(--shadow-sm); }
.stats{ display:flex; flex-wrap:wrap; gap:var(--sp-3); }

/* ── 08 · BADGES, PILLS & CHIPS ──────────────────────────────────────────── */
.cat{
  display:inline-block; align-self:flex-start;
  padding:3px 10px; border-radius:var(--r-full);
  background:var(--pri-soft); color:var(--pri);
  font-size:10.5px; font-weight:750; letter-spacing:.07em; text-transform:uppercase;
}
.cat.c0{ background:var(--pri-soft);  color:var(--pri); }
.cat.c1{ background:var(--ok-soft);   color:var(--ok); }
.cat.c2{ background:var(--stamp-soft);color:var(--stamp); }
.cat.c3{ background:var(--teal-soft); color:var(--teal); }
.cat.c4{ background:var(--warn-soft); color:var(--warn); }
.tags{ display:flex; flex-wrap:wrap; gap:5px; }
.tags > span{
  padding:3px 9px; border-radius:var(--r-xs);
  background:var(--surface-2); border:1px solid var(--line);
  font-size:11.5px; font-weight:550; color:var(--ink-soft);
}
/* Course modules & lessons */
.course-mods{ margin-top:18px; padding-top:16px; border-top:1px solid var(--line); }
.course-mods h3{ font-family:var(--font-display); font-size:15px; font-weight:700; margin:0 0 10px; color:var(--ink); }
.course-prog{ margin:0 0 14px; }
.cm-mod{ margin:0 0 12px; }
.cm-mod-h{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:8px 12px; border-radius:var(--r-sm);
  background:var(--surface-2); border:1px solid var(--line);
  font-size:13.5px; font-weight:650; color:var(--ink);
}
.cm-mod-h .num{ font-size:12px; color:var(--ink-faint); font-weight:600; }
.cm-les{
  display:flex; align-items:flex-start; gap:10px;
  padding:8px 12px 8px 8px; border-radius:var(--r-sm);
}
.cm-les:hover{ background:var(--surface-2); }
.cm-les-check{
  width:22px; height:22px; border-radius:50%; flex:none; margin-top:1px;
  display:inline-flex; align-items:center; justify-content:center;
  border:1.5px solid var(--line-strong); background:var(--surface);
  color:var(--pri); font-size:12px; font-weight:700; cursor:pointer;
  transition:all var(--t-fast) var(--ease);
}
.cm-les-check:hover{ border-color:var(--pri); }
.cm-les.done .cm-les-check{ background:var(--ok); border-color:var(--ok); color:#fff; }
.cm-les-t{ font-size:13.5px; font-weight:600; color:var(--ink); }
.cm-les.done .cm-les-t{ color:var(--ink-faint); text-decoration:line-through; }
.cm-les-d{ font-size:12.5px; color:var(--ink-soft); line-height:1.55; margin-top:2px; }
.skills-pill{
  display:inline-block; padding:3px 10px; border-radius:var(--r-full);
  background:var(--surface-2); border:1px solid var(--line);
  font-size:12px; font-weight:550; color:var(--ink-soft);
}
.strip-chips{ display:flex; flex-wrap:wrap; gap:7px; margin:0 0 var(--sp-4); }
.strip-chips > button{
  padding:7px 14px; border-radius:var(--r-full);
  border:1px solid var(--line); background:var(--surface); color:var(--ink-soft);
  font-size:12.5px; font-weight:600;
  transition:all var(--t-fast) var(--ease);
}
.strip-chips > button:hover{ border-color:var(--pri); color:var(--pri); transform:translateY(-1px); }
.strip-chips > button.on{ background:var(--pri); border-color:var(--pri); color:var(--pri-ink); box-shadow:0 4px 12px color-mix(in srgb,var(--pri) 28%,transparent); }
.chiprow{ display:flex; flex-wrap:wrap; gap:7px; }
.chip{
  display:inline-flex; align-items:center; gap:6px;
  padding:6px 12px; border-radius:var(--r-full);
  border:1px solid var(--line); background:var(--surface-2);
  font-size:12.5px; font-weight:600; color:var(--ink-soft);
  transition:all var(--t-fast) var(--ease);
}
.chip:hover{ border-color:var(--pri); color:var(--pri); }
.chip[aria-pressed="true"],.chip.on{ background:var(--pri); border-color:var(--pri); color:var(--pri-ink); }
.chk{ color:var(--ok); font-weight:800; margin-right:5px; }
.tk{ color:var(--ok); font-weight:800; }
.mt{ color:var(--ink-faint); }

/* ── 09 · FORMS ──────────────────────────────────────────────────────────── */
/* input:not([type]) is here deliberately. An <input> with no type attribute is
   a text field, but it does not match input[type="text"], and the profile and
   resume editors emit bare <input> elements. Without it those got no styling
   at all: a white box carrying the dark theme's near-white text, which is
   legible in light mode and completely invisible in dark. */
input:not([type]),
input[type="text"],input[type="email"],input[type="password"],input[type="search"],
input[type="number"],input[type="url"],input[type="tel"],select,textarea{
  width:100%; padding:10px 13px;
  border:1px solid var(--line-strong); border-radius:var(--r-sm);
  background:var(--paper); color:var(--ink);
  font-size:14.5px; line-height:1.45;
  transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease),background var(--t-fast) var(--ease);
  appearance:none; -webkit-appearance:none;
}
select{
  padding-right:34px; cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5' fill='none' stroke='%237b8298' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 12px center;
}
[data-theme="dark"] select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5' fill='none' stroke='%237a819a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
textarea{ resize:vertical; min-height:82px; }
input:hover,select:hover,textarea:hover{ border-color:var(--ink-faint); }
input:focus,select:focus,textarea:focus{
  outline:none; border-color:var(--pri);
  box-shadow:0 0 0 3.5px var(--pri-ring);
}
input::placeholder,textarea::placeholder{ color:var(--ink-faint); opacity:1; }
input[type="range"]{
  -webkit-appearance:none; appearance:none;
  padding:0; height:22px; background:transparent; border:0; box-shadow:none;
}
input[type="range"]:focus{ box-shadow:none; }
input[type="range"]::-webkit-slider-runnable-track{ height:5px; border-radius:var(--r-full); background:var(--surface-3); }
input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none; margin-top:-5.5px;
  width:16px; height:16px; border-radius:50%;
  background:var(--pri); border:2.5px solid var(--paper);
  box-shadow:0 1px 5px rgba(14,16,32,.3); cursor:pointer;
  transition:transform var(--t-fast) var(--ease);
}
input[type="range"]::-webkit-slider-thumb:hover{ transform:scale(1.15); }
input[type="range"]::-moz-range-track{ height:5px; border-radius:var(--r-full); background:var(--surface-3); }
input[type="range"]::-moz-range-thumb{ width:16px; height:16px; border:2.5px solid var(--paper); border-radius:50%; background:var(--pri); cursor:pointer; }
input[type="file"]{ padding:8px; }
input[type="color"]{ padding:3px; height:38px; }

.field{ margin-bottom:var(--sp-4); }
.field label,.filters label,.rsField label{
  display:block; margin:0 0 5px;
  font-size:12.5px; font-weight:600; color:var(--ink-soft);
  letter-spacing:.005em;
}
.forms .field:last-child{ margin-bottom:0; }
.rfield{ margin-bottom:var(--sp-4); }

/* ── 10 · FILTERS ────────────────────────────────────────────────────────── */
.filters{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-md);
  padding:var(--sp-4); margin:0 0 var(--sp-5); box-shadow:var(--shadow-xs);
}
.frow{ display:flex; flex-wrap:wrap; gap:var(--sp-3); align-items:flex-end; }
.f{ display:flex; flex-direction:column; min-width:150px; flex:1; }
.f.f-grow{ min-width:210px; }
.freset{ align-self:flex-end; }

/* ── 11 · NAVBAR ─────────────────────────────────────────────────────────── */
.navbar{
  position:sticky; top:0; z-index:60;
  background:color-mix(in srgb,var(--bg) 78%,transparent);
  -webkit-backdrop-filter:saturate(180%) blur(16px);
          backdrop-filter:saturate(180%) blur(16px);
  border-bottom:1px solid transparent;
  transition:border-color var(--t) var(--ease),background var(--t) var(--ease),box-shadow var(--t) var(--ease);
}
.navbar.stuck{ border-bottom-color:var(--line); box-shadow:0 1px 20px rgba(14,16,32,.06); background:color-mix(in srgb,var(--bg) 92%,transparent); }
.navbar > *{
  display:flex; align-items:center; gap:var(--sp-4);
  max-width:var(--wrap); min-height:var(--nav-h); margin-inline:auto;
  padding-inline:clamp(16px,4vw,32px);
}
.logo{
  display:inline-flex; align-items:center; gap:9px;
  font-family:var(--font-display); font-size:17px; font-weight:800;
  letter-spacing:-.035em; color:var(--ink); text-decoration:none; flex:none;
}
.logo:hover{ color:var(--ink); }
.logo-mark{
  display:inline-flex; align-items:center; justify-content:center;
  width:31px; height:31px; border-radius:9px;
  background:var(--pri-grad); color:var(--pri-ink);
  font-size:16px; font-weight:800; letter-spacing:-.04em;
  box-shadow:0 2px 8px color-mix(in srgb,var(--pri) 34%,transparent);
}
.logo-mark .rd{ opacity:.75; }
/* align-self:stretch lets the row match the navbar height (the stretch target
   is .nav-inner's content box, since .navbar > * is a centred flex row). That
   makes the More panel's "top:100%" resolve against the bar itself instead of
   the 34px button, so it clears the bar by a real 7px rather than overlapping
   its bottom edge. Purely geometric: the links stay centred by align-items. */
.navlinks{ display:flex; align-items:center; gap:1px; flex:1; min-width:0; align-self:stretch; }
.navlink{
  position:relative; display:inline-flex; align-items:center;
  padding:8px 12px; border-radius:var(--r-sm);
  font-size:14px; font-weight:550; color:var(--ink-soft);
  text-decoration:none; white-space:nowrap;
  transition:color var(--t-fast) var(--ease),background var(--t-fast) var(--ease);
}
.navlink:hover{ color:var(--ink); background:var(--surface-2); }
.navlink.on{ color:var(--pri); font-weight:650; }
.navlink.on::after{
  content:""; position:absolute; left:12px; right:12px; bottom:1px;
  height:2px; border-radius:2px; background:var(--pri);
  animation:navUnderline var(--t) var(--ease-out);
}
.nav-spacer{ flex:1; }
/* More menu. Grouped rather than flat because the navbar row is capped at
   --wrap and ten nowrap labels overflow it by roughly 200px. */
/* align-self:stretch makes .nav-drop as tall as the navbar row, so the panel's
   "top:100%" resolves against the bar itself rather than the centred button -
   otherwise the panel overlapped the bar's bottom edge by ~6px. */
.nav-drop{ position:relative; flex:none; align-self:stretch; display:flex; align-items:center; }
.nav-drop-btn{
  cursor:pointer; border:0; background:none; font:inherit; gap:5px;
}
.nav-drop-caret{
  width:0; height:0; flex:none;
  border-left:4px solid transparent; border-right:4px solid transparent;
  border-top:5px solid currentColor; opacity:.62;
  transition:transform var(--t-fast) var(--ease);
}
.nav-drop.open .nav-drop-caret{ transform:rotate(180deg); }
.nav-drop.has-on .nav-drop-btn{ color:var(--pri); font-weight:650; }
.nav-drop-panel{
  position:absolute; top:calc(100% + 7px); left:0; z-index:70;
  min-width:232px; display:flex; flex-direction:column; gap:1px;
  padding:6px; border-radius:var(--r-md);
  background:var(--surface); border:1px solid var(--line);
  box-shadow:var(--shadow-lg);
  opacity:0; visibility:hidden; transform:translateY(-6px);
  transition:opacity var(--t-fast) var(--ease),transform var(--t-fast) var(--ease),visibility var(--t-fast) var(--ease);
}
.nav-drop.open .nav-drop-panel{ opacity:1; visibility:visible; transform:none; }
/* Transparent bridge across the gap above the panel. Without it the pointer
   briefly sits over neither the trigger nor the panel, mouseleave fires, and
   hover-open closes the menu before it can be reached. */
.nav-drop-panel::before{
  content:""; position:absolute; left:0; right:0; top:-9px; height:9px;
}
.nav-drop-panel .navlink{ width:100%; justify-content:flex-start; }
.nav-cta{ flex:none; }
.askbtn{
  --btn-bg:var(--pri); --btn-fg:var(--pri-ink); --btn-bd:var(--pri);
  padding:9px 17px; font-size:13.5px;
  box-shadow:0 1px 2px rgba(14,16,32,.14),0 6px 16px color-mix(in srgb,var(--pri) 26%,transparent);
}
.askbtn:hover{ --btn-bg:var(--pri-hover); --btn-bd:var(--pri-hover); color:var(--pri-ink); transform:translateY(-1px); }
.user-chip{ display:none; align-items:center; gap:8px; font-size:13.5px; font-weight:600; color:var(--ink-soft); }
.av{
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:29px; height:29px; border-radius:50%;
  background:var(--pri-grad); color:var(--pri-ink);
  font-size:12.5px; font-weight:750;
}
.hamb{
  display:none; align-items:center; gap:7px;
  padding:8px 12px; border-radius:var(--r-sm);
  border:1px solid var(--line); background:var(--surface);
  font-size:13.5px; font-weight:600; color:var(--ink);
  transition:all var(--t-fast) var(--ease);
}
.hamb:hover{ background:var(--surface-2); }
.hamb .bars{ display:block; width:15px; height:2px; background:currentColor; border-radius:2px; position:relative; }
.hamb .bars::before,.hamb .bars::after{ content:""; position:absolute; left:0; width:15px; height:2px; background:currentColor; border-radius:2px; transition:transform var(--t) var(--ease); }
.hamb .bars::before{ top:-5px; } .hamb .bars::after{ top:5px; }
.hamb[aria-expanded="true"] .bars{ background:transparent; }
.hamb[aria-expanded="true"] .bars::before{ transform:translateY(5px) rotate(45deg); }
.hamb[aria-expanded="true"] .bars::after{ transform:translateY(-5px) rotate(-45deg); }
.nav-backdrop{
  position:fixed; inset:0; z-index:55;
  background:rgba(8,9,16,.5);
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
  opacity:0; visibility:hidden;
  transition:opacity var(--t) var(--ease),visibility var(--t) var(--ease);
}
.nav-backdrop.open{ opacity:1; visibility:visible; }

/* The sticky bar stays full-bleed; .nav-inner is the single child the
   `.navbar > *` rule above is aimed at, so the row is centred and padded once.
   Everything that is not a link lives in .nav-right, which is the only group
   that needs to stay together when the drawer collapses. */
.nav-inner{ width:100%; min-width:0; }
.nav-inner .logo{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* The auth controls live in the bar on wide screens and move into the
   drawer below, so the two are never both visible at once. */
.nav-drawer-auth{ display:none; }
.nav-right{ display:flex; align-items:center; gap:var(--sp-2); margin-left:auto; padding-left:var(--sp-4); }
.nav-right .btn{ white-space:nowrap; }
.nav-right .user-chip{ display:inline-flex; }
/* Signed-out destinations stay visible but read as locked, not broken. */
.navlink.is-gated{
  border:0; background:none; cursor:pointer; font-family:inherit;
  font-size:14px; font-weight:550; letter-spacing:inherit;
  color:var(--ink-faint); opacity:.85;
}
.navlink.is-gated::after{ display:none; }
.navlink.is-gated:hover{ color:var(--ink); background:var(--surface-2); opacity:1; }
.navlink.is-gated::before{
  content:""; display:inline-block; width:5px; height:5px; margin-right:6px;
  border-radius:50%; background:var(--line-strong); vertical-align:middle;
}
.hamb-t{ display:inline; }
@media (max-width:1000px){
  .nav-right .user-chip{ display:none; }
}
@media (max-width:720px){
  .nav-right{ margin-left:auto; padding-left:var(--sp-2); }
  .hamb-t{ display:none; }
}

/* ── 12 · HERO ───────────────────────────────────────────────────────────── */
.hero{
  position:relative; overflow:hidden; isolation:isolate;
  padding-block:clamp(48px,7vw,86px) clamp(40px,5vw,64px);
  color:var(--ink);
  background:
    radial-gradient(720px 420px at 86% -12%, color-mix(in srgb,var(--pri) 15%,transparent) 0%, transparent 66%),
    radial-gradient(600px 400px at 2% 4%, color-mix(in srgb,#a855f7 12%,transparent) 0%, transparent 64%),
    var(--surface-2);
  border-bottom:1px solid var(--line);
}
/* One blurred shape for depth. isolation on .hero keeps it behind the
   content without letting it fall through behind the page background. */
.hero::before{
  content:""; position:absolute; z-index:-1; pointer-events:none;
  right:-8%; top:4%; width:min(46%,420px); aspect-ratio:1; border-radius:50%;
  background:radial-gradient(circle at 34% 34%, color-mix(in srgb,var(--pri) 20%,transparent), transparent 68%);
  filter:blur(40px);
}
.hero::after{
  content:""; position:absolute; left:50%; bottom:-1px; transform:translateX(-50%);
  width:min(100%,var(--wrap)); height:1px;
  background:linear-gradient(90deg,transparent,var(--line),transparent);
}
.hero-grid{ display:grid; grid-template-columns:1.04fr .96fr; gap:clamp(28px,4vw,56px); align-items:center; }
.hero-eyebrow{
  display:inline-flex; align-items:center; gap:8px;
  padding:6px 14px 6px 11px; margin:0 0 var(--sp-5);
  border:1px solid color-mix(in srgb,var(--pri) 22%,var(--line)); border-radius:var(--r-full);
  background:var(--surface); color:var(--ink-soft);
  font-family:var(--font-display); font-size:12.5px; font-weight:600;
  box-shadow:var(--shadow-xs);
}
.hero-eyebrow .dot{
  width:7px; height:7px; border-radius:50%; background:var(--pri); flex:none;
  box-shadow:0 0 0 3px var(--pri-ring);
  animation:pulseDot 2.4s var(--ease) infinite;
}
.hero h1{ margin:0 0 var(--sp-4); max-width:16ch; color:var(--ink); }
.hero .deck{ margin:0 0 var(--sp-6); max-width:52ch; color:var(--ink-soft); }
.hero-btns{ display:flex; flex-wrap:wrap; gap:10px; margin:0 0 var(--sp-5); }
.hero-note{ display:flex; flex-wrap:wrap; gap:6px 16px; margin:0; font-size:12.8px; color:var(--ink-faint); }
.hero-note span{ display:inline-flex; align-items:center; gap:6px; }
.hero-trust{
  display:flex; flex-wrap:wrap; gap:var(--sp-5);
  margin-top:var(--sp-8); padding-top:var(--sp-5); border-top:1px solid var(--line);
}
.hero-trust div{ display:flex; flex-direction:column; }
.hero-trust b{ font-family:var(--font-display); font-size:1.5rem; font-weight:800; letter-spacing:-.03em; line-height:1.2; }
.hero-trust span{ font-size:12px; color:var(--ink-faint); }

/* product preview mock */
.preview{
  position:relative; border-radius:var(--r-lg); overflow:hidden;
  background:var(--surface); border:1px solid var(--line);
  box-shadow:var(--shadow-lg);
  animation:floatY 7s var(--ease) infinite;
}
.preview-tb{
  display:flex; align-items:center; gap:6px;
  padding:11px 14px; border-bottom:1px solid var(--line); background:var(--surface-2);
}
.preview-tb i{ width:10px; height:10px; border-radius:50%; display:block; }
.preview-tb .tb-dots{ margin-left:auto; display:flex; gap:4px; }
.preview-tb .tb-dots i{ width:5px; height:5px; background:var(--line-strong); }
.preview-body{ padding:var(--sp-5); display:flex; flex-direction:column; gap:var(--sp-4); }
.preview-foot{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3);
  padding:11px var(--sp-5); border-top:1px solid var(--line); background:var(--surface-2);
  font-size:11.8px; color:var(--ink-faint);
}
.preview-foot > span{ display:inline-flex; align-items:center; gap:7px; }
.scoreline{ display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3); font-size:13px; color:var(--ink-soft); font-weight:550; }
.scoreline .n{ font-size:1.3rem; color:var(--pri); }
.minichat{ display:flex; flex-direction:column; gap:9px; }
/* The hero's static conversation. Same class name as a chat row (.msg) but a
   different component, so it gets bubble styling of its own rather than
   inheriting the chat's flex-row reset. */
/* max-width bounds the bubble but not the words in it, and a flex item
   defaults to min-width:auto, so a long plan line could not shrink and ran
   50px past a 310px viewport. */
.minichat .msg{
  max-width:100%; min-width:0; overflow-wrap:anywhere;
  padding:11px 14px; border-radius:var(--r);
  font-size:13.4px; line-height:1.6; animation:none;
}
.minichat .msg.q{
  align-self:flex-end; max-width:88%;
  background:var(--pri); color:var(--pri-ink); border-bottom-right-radius:var(--r-xs);
}
.minichat .msg.a{
  border:1px solid var(--line); background:var(--surface-2); color:var(--ink);
  border-bottom-left-radius:var(--r-xs);
}
.minichat .msg.a b{ color:var(--ink); font-weight:650; }
.pcard{ display:flex; flex-direction:column; gap:5px; }
.pcard h3{ margin:0; font-size:.95rem; }
.pcard .m{ font-size:12.2px; color:var(--ink-faint); }
.pcard{
  padding:12px 14px; border-radius:var(--r);
  border:1px solid var(--line); background:var(--surface-2);
}
.scoreline + .bar{ margin-top:-6px; }

/* ── 13 · DASHBOARD ──────────────────────────────────────────────────────── */
.dash{ display:grid; grid-template-columns:236px minmax(0,1fr); gap:var(--sp-5); align-items:start; }
.dash-nav{
  position:sticky; top:calc(var(--nav-h) + var(--sp-4));
  display:flex; flex-direction:column; gap:2px;
  padding:var(--sp-3); border-radius:var(--r-md);
  background:var(--surface); border:1px solid var(--line); box-shadow:var(--shadow-xs);
}
.dash-nav a{
  display:flex; align-items:center; gap:10px;
  padding:9px 11px; border-radius:var(--r-sm);
  font-size:13.8px; font-weight:550; color:var(--ink-soft); text-decoration:none;
  transition:all var(--t-fast) var(--ease);
}
.dash-nav a i{ font-style:normal; font-size:15px; width:19px; text-align:center; flex:none; opacity:.85; }
.dash-nav a:hover{ background:var(--surface-2); color:var(--ink); }
.dash-nav a.on{ background:var(--pri-soft); color:var(--pri); font-weight:650; }
.dash-nav a.on i{ opacity:1; }
.dash-nav-note{
  margin-top:var(--sp-3); padding:10px 11px 2px; border-top:1px solid var(--line);
  font-size:11.5px; color:var(--ink-faint); line-height:1.5;
}
.dash-main{ display:flex; flex-direction:column; gap:var(--sp-4); min-width:0; }
/* Quick-access cards. Each one is a real link to a route that exists; the
   numbers come from the same data the rest of the dashboard already reads. */
.dash-cards{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:var(--sp-3); margin:0 0 var(--sp-4);
}
.dash-card{
  display:block; padding:var(--sp-4); text-decoration:none; color:inherit;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-md);
  box-shadow:var(--shadow-xs); transition:all var(--t-fast) var(--ease);
}
.dash-card:hover{ border-color:color-mix(in srgb,var(--pri) 34%,var(--line)); transform:translateY(-2px); box-shadow:var(--shadow-sm); }
.dash-card b{ display:block; font-family:var(--font-display); font-size:14.5px; font-weight:700; color:var(--ink); margin:2px 0 3px; }
.dash-card .dc-n{ font-size:1.5rem; font-weight:800; letter-spacing:-.02em; color:var(--pri); line-height:1.1; }
.dash-card span{ font-size:12.5px; color:var(--ink-faint); }
.dash-head{
  display:flex; align-items:flex-end; justify-content:space-between;
  gap:var(--sp-4); flex-wrap:wrap; margin:0 0 var(--sp-5);
}
.dash-head h1{ margin:0 0 4px; font-size:clamp(1.5rem,1.2rem + 1.2vw,2rem); }
.greet-sub{ margin:0; color:var(--ink-soft); font-size:14.5px; }
.wave{ display:inline-block; animation:waveHi 2.6s var(--ease) infinite; transform-origin:70% 70%; }
.dash-tools{ display:flex; align-items:center; gap:8px; }
.dash-menu-wrap{ position:relative; }
.dash-user{
  display:flex; align-items:center; gap:9px;
  padding:5px 10px 5px 5px; border-radius:var(--r-full);
  border:1px solid var(--line); background:var(--surface);
  transition:all var(--t-fast) var(--ease);
}
.dash-user:hover{ background:var(--surface-2); border-color:var(--line-strong); }
.du-txt{ display:flex; flex-direction:column; line-height:1.25; text-align:left; }
.du-txt b{ font-size:13.2px; font-weight:650; }
.du-txt small{ font-size:11px; color:var(--ink-faint); }
.du-caret{ font-size:10px; color:var(--ink-faint); }
.dash-menu{
  position:absolute; right:0; top:calc(100% + 7px); z-index:20;
  min-width:186px; padding:6px; border-radius:var(--r);
  background:var(--surface); border:1px solid var(--line); box-shadow:var(--shadow-pop);
  animation:popIn var(--t) var(--ease-out);
}
.dash-menu a,.dash-menu button{
  display:flex; align-items:center; gap:9px; width:100%;
  padding:8px 10px; border-radius:var(--r-xs);
  font-size:13.5px; color:var(--ink-soft); text-align:left; text-decoration:none;
  transition:all var(--t-fast) var(--ease);
}
.dash-menu a:hover,.dash-menu button:hover{ background:var(--surface-2); color:var(--ink); }

.statgrid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(158px,1fr)); gap:var(--sp-3); }
.stat{
  position:relative; overflow:hidden;
  padding:var(--sp-4) var(--sp-4) var(--sp-4) calc(var(--sp-4) + 3px);
  border-radius:var(--r); background:var(--surface);
  border:1px solid var(--line); box-shadow:var(--shadow-xs);
  transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease);
}
.stat:hover{ transform:translateY(-2px); box-shadow:var(--shadow-sm); }
.stat::before{ content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--line-strong); }
.stat.pri::before{ background:var(--pri); }  .stat.pri  .n{ color:var(--pri); }
.stat.eu::before{ background:var(--eu); }   .stat.eu   .n{ color:var(--eu); }
.stat.teal::before{ background:var(--teal); }.stat.teal .n{ color:var(--teal); }
.stat.warn::before{ background:var(--warn); }.stat.warn .n{ color:var(--warn); }
.stat.ok::before{ background:var(--ok); }   .stat.ok   .n{ color:var(--ok); }
.stat.stamp::before{ background:var(--stamp); }.stat.stamp .n{ color:var(--stamp); }
.stat .n{ display:block; font-size:1.7rem; line-height:1.15; margin:0 0 2px; }
.stat .l{ display:block; font-size:12.5px; font-weight:600; color:var(--ink); line-height:1.35; }
.stat small{ display:block; font-size:11.4px; color:var(--ink-faint); line-height:1.4; margin-top:2px; }

.insights{ display:flex; flex-direction:column; gap:8px; }
.insight{
  display:flex; gap:11px; align-items:flex-start;
  padding:12px 14px; border-radius:var(--r-sm);
  background:var(--surface-2); border-left:3px solid var(--pri);
  font-size:13.5px; line-height:1.6;
}
.insight > span{ font-size:15px; line-height:1.4; flex:none; }
.insight p{ margin:0; color:var(--ink-soft); }

.qa-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(158px,1fr)); gap:10px; }
.qa-card{
  display:flex; flex-direction:column; align-items:flex-start; gap:8px;
  padding:14px; border-radius:var(--r);
  background:var(--surface-2); border:1px solid var(--line);
  text-align:left; transition:all var(--t) var(--ease);
}
.qa-card:hover{
  background:var(--surface); transform:translateY(-2px);
  border-color:color-mix(in srgb,var(--pri) 40%,var(--line));
  box-shadow:var(--shadow-sm);
}
.qa-ic{ font-size:20px; line-height:1; }
.qa-h{ font-family:var(--font-display); font-size:13.2px; font-weight:650; color:var(--ink); line-height:1.32; }

.dash-resume{
  padding:var(--sp-5); border-radius:var(--r-md);
  background:var(--surface); border:1px solid var(--line); box-shadow:var(--shadow-xs);
}
.dash-resume h3{ margin:0 0 var(--sp-3); font-size:1.02rem; }
.dr-pct{ display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3); font-size:12.8px; color:var(--ink-soft); margin:0 0 6px; }
.dr-pct .val{ font-size:14px; color:var(--ink); }
.dr-saved{ font-size:12px; color:var(--ink-faint); margin:10px 0 var(--sp-3); line-height:1.5; }

.comp{ margin:0 0 var(--sp-3); }
.comp-top{ display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3); font-size:13px; color:var(--ink-soft); margin:0 0 7px; }
.comp-top .val{ font-size:15px; color:var(--ink); }

/* ── 14 · PROGRESS ───────────────────────────────────────────────────────── */
.bar{
  /* Legacy hardcoded width:3px and display:inline-block on this class, and
     the design system declared neither, so both survived: the track was a
     3px sliver sitting in a 518px panel, and the fill's percentage width
     resolved against that same shrink-to-fit box. A track fills its panel.
     The .vbars equalizer keeps its own 3px width at higher specificity. */
  display:block; width:100%;
  height:7px; border-radius:var(--r-full);
  background:var(--surface-3); overflow:hidden;
}
.bar > i{
  display:block; height:100%; border-radius:var(--r-full);
  background:var(--pri-grad);
  transition:width var(--t-slow) var(--ease-out);
}
.prog{ margin:var(--sp-3) 0; }
.prog-top{ display:flex; align-items:center; justify-content:space-between; font-size:12.5px; color:var(--ink-soft); margin:0 0 6px; }
.prog-top b{ font-family:var(--font-display); color:var(--ink); }
.bar > i.ok{ background:var(--ok); }
.bar > i.warn{ background:var(--warn); }

.rscore-head{ display:flex; align-items:center; gap:var(--sp-3); margin:0 0 var(--sp-3); }
.rscore-ring{
  display:grid; place-items:center; flex:none;
  width:66px; height:66px; border-radius:50%;
  background:conic-gradient(var(--pri) var(--p,0%),var(--surface-3) 0);
  position:relative;
}
.rscore-ring::before{ content:""; position:absolute; inset:6px; border-radius:50%; background:var(--surface); }
.rscore-ring b{ position:relative; font-size:14px; }

/* ── 15 · CHAT · STUDENT AI ASSISTANT ────────────────────────────────────── */
.ai-page{ padding-block:var(--sp-5) var(--sp-10); }
.ai-layout{ display:grid; grid-template-columns:258px minmax(0,1fr); gap:var(--sp-4); align-items:start; }

/* history sidebar */
.ai-side{
  position:sticky; top:calc(var(--nav-h) + var(--sp-4));
  display:flex; flex-direction:column; gap:var(--sp-3);
  max-height:calc(100vh - var(--nav-h) - var(--sp-8));
  padding:var(--sp-4); border-radius:var(--r-md);
  background:var(--surface); border:1px solid var(--line); box-shadow:var(--shadow-xs);
}
.ai-side-h{ display:flex; align-items:center; justify-content:space-between; gap:var(--sp-2); }
.ai-side-h h3{ margin:0; font-size:13px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-faint); font-weight:700; }
/* the list itself is what scrolls, not the whole sidebar — that keeps New chat
   and the privacy note pinned while a long history scrolls under them */
.ai-side-hist-wrap{ flex:1; min-height:0; display:flex; }
.ai-hist{ flex:1; min-height:0; }
/* Each history entry is a row so the delete affordance can sit outside the
   button's own hit area — nesting a <button> in a <button> is invalid HTML. */
.ai-hist-row{ position:relative; display:flex; align-items:center; }
.ai-hist-row .ai-hist-item{ padding-right:26px; }
.ai-hist-row .hx{
  position:absolute; right:4px; top:50%; transform:translateY(-50%);
  display:grid; place-items:center;
  width:20px; height:20px; flex:none; padding:0;
  border:0; border-radius:var(--r-xs);
  background:transparent; color:var(--ink-faint);
  font-size:15px; line-height:1; cursor:pointer;
  opacity:0;
  transition:opacity var(--t-fast) var(--ease),color var(--t-fast) var(--ease),background var(--t-fast) var(--ease);
}
.ai-hist-row:hover .hx,
.ai-hist-row .hx:focus-visible{ opacity:1; }
.ai-hist-row .hx:hover{ color:var(--danger); background:var(--danger-soft); }
.ai-new{
  display:flex; align-items:center; justify-content:center; gap:7px; width:100%;
  padding:10px 14px; border-radius:var(--r-sm);
  background:var(--pri); color:var(--pri-ink);
  font-family:var(--font-display); font-size:13.5px; font-weight:650;
  box-shadow:0 1px 2px rgba(14,16,32,.14),0 5px 14px color-mix(in srgb,var(--pri) 26%,transparent);
  transition:all var(--t-fast) var(--ease);
}
.ai-new:hover{ background:var(--pri-hover); transform:translateY(-1px); }
.ai-hist{ display:flex; flex-direction:column; gap:2px; overflow-y:auto; margin:0 -6px; padding:0 6px; }
.ai-hist-item{
  display:flex; align-items:center; gap:8px; width:100%;
  padding:8px 10px; border-radius:var(--r-sm);
  font-size:13px; color:var(--ink-soft); text-align:left;
  transition:all var(--t-fast) var(--ease);
}
.ai-hist-item:hover{ background:var(--surface-2); color:var(--ink); }
.ai-hist-item.on{ background:var(--pri-soft); color:var(--pri); font-weight:600; }
.ai-hist-item .ht{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ai-hist-item .hx{ flex:none; opacity:0; font-size:14px; line-height:1; padding:2px; border-radius:4px; color:var(--ink-faint); transition:opacity var(--t-fast) var(--ease); }
.ai-hist-item:hover .hx{ opacity:1; }
.ai-hist-item .hx:hover{ color:var(--danger); background:var(--danger-soft); }
.ai-hist-item .hn{ flex:none; font-size:10.5px; color:var(--ink-faint); font-variant-numeric:tabular-nums; }
.ai-side-foot{ border-top:1px solid var(--line); padding-top:var(--sp-3); }
.ai-side-note{ display:flex; gap:8px; font-size:11.5px; color:var(--ink-faint); line-height:1.5; }

/* capability buttons */
.ai-ctx{ display:flex; flex-direction:column; gap:6px; }
.ai-ctx h3{
  margin:0 0 4px; font-size:12px; letter-spacing:.09em;
  text-transform:uppercase; color:var(--ink-faint); font-weight:700;
}
/* Twenty capabilities in a multi-column grid rather than a 258px sidebar: at one
   per row they were a twenty-screen scroll. */
.cap-grid{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(212px,1fr));
  gap:8px;
}
.cap{
  display:flex; align-items:center; gap:9px; width:100%;
  padding:10px 12px; border-radius:var(--r-sm);
  border:1px solid var(--line); background:var(--surface);
  font-size:13.2px; font-weight:550; color:var(--ink-soft); text-align:left;
  transition:all var(--t-fast) var(--ease);
}
.cap:hover{
  background:var(--pri-soft); border-color:color-mix(in srgb,var(--pri) 34%,transparent);
  color:var(--pri); transform:translateX(2px);
}
.cap-cap{ margin:6px 0 0; font-size:11.5px; color:var(--ink-faint); line-height:1.5; }
.cap-cap b{ color:var(--ink-soft); }

/* chat shell */
.chatbox{
  display:flex; flex-direction:column;
  min-height:min(74vh,720px);
  border-radius:var(--r-lg); overflow:hidden;
  background:var(--surface); border:1px solid var(--line); box-shadow:var(--shadow);
}
.chathead{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-4);
  border-bottom:1px solid var(--line); background:var(--surface-2);
}
.chathead .t{ font-family:var(--font-display); font-size:14.5px; font-weight:700; }
.chathead .g{ font-size:12.2px; color:var(--ink-faint); }
.chathead .sp{ flex:1; }
.chathead-ic{
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; border-radius:9px;
  background:var(--pri-grad); font-size:15px; flex:none;
  box-shadow:0 2px 7px color-mix(in srgb,var(--pri) 30%,transparent);
}
.chip-btn{
  display:inline-flex; align-items:center; gap:6px;
  padding:6px 11px; border-radius:var(--r-full);
  border:1px solid var(--line); background:var(--surface);
  font-size:12px; font-weight:600; color:var(--ink-soft); white-space:nowrap;
  transition:all var(--t-fast) var(--ease);
}
.chip-btn:hover{ color:var(--pri); border-color:var(--pri); background:var(--pri-soft); }
.chip-btn:disabled{ opacity:.45; pointer-events:none; }
.chat-toolbar{ display:flex; align-items:center; gap:6px; }

.chatlog{
  flex:1; overflow-y:auto; overscroll-behavior:contain;
  padding:var(--sp-5) clamp(14px,3vw,26px);
  display:flex; flex-direction:column; gap:var(--sp-5);
  scroll-behavior:smooth;
}

/* message rows
   The reset properties are not decoration. A legacy rule styles .msg as a
   light card (background #f8f9fa, padding, margin, colour #333) and the chat
   reuses the same class name for a flex row, so without these the row carried
   a hardcoded near-white block, correct-looking in light mode and a glaring
   white slab in dark. The cascade layer makes the design system win only for
   properties it actually declares, so they have to be declared here. */
.msg{
  display:flex; gap:11px; max-width:min(100%,760px);
  animation:msgIn var(--t-slow) var(--ease-out);
  background:transparent; border-radius:0; padding:0; margin:0;
  color:inherit; font-size:inherit;
}
.msg-avatar{
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:29px; height:29px; border-radius:9px;
  font-size:14px; line-height:1; user-select:none;
}
.msg.user{ align-self:flex-end; flex-direction:row-reverse; }
.msg.user .msg-avatar{ background:var(--surface-3); color:var(--ink-soft); font-size:12px; font-weight:700; }
.msg.bot .msg-avatar{ background:var(--pri-grad); color:var(--pri-ink); box-shadow:0 2px 7px color-mix(in srgb,var(--pri) 28%,transparent); }
.msg-body{ min-width:0; display:flex; flex-direction:column; gap:6px; }
.msg.user .msg-body{ align-items:flex-end; }
.msg .who{ font-size:11.5px; font-weight:700; color:var(--ink-faint); letter-spacing:.02em; }
.bubble{
  padding:13px 16px; border-radius:var(--r-md);
  font-size:14.6px; line-height:1.68;
  overflow-wrap:anywhere;
}
.msg.bot .bubble{
  background:var(--surface-2); border:1px solid var(--line);
  border-top-left-radius:var(--r-xs); color:var(--ink);
}
.msg.user .bubble{
  background:var(--pri); color:var(--pri-ink); border-top-right-radius:var(--r-xs);
  box-shadow:0 2px 10px color-mix(in srgb,var(--pri) 24%,transparent);
  white-space:pre-wrap; max-width:min(100%,560px);
}
.msg.err .bubble{ background:var(--danger-soft); border:1px solid color-mix(in srgb,var(--danger) 30%,transparent); color:var(--danger); }

/* message actions */
.msg-acts{ display:flex; align-items:center; gap:3px; opacity:0; transition:opacity var(--t) var(--ease); }
.msg:hover .msg-acts,.msg:focus-within .msg-acts{ opacity:1; }
.msg-act{
  display:inline-flex; align-items:center; gap:5px;
  padding:4px 8px; border-radius:var(--r-xs);
  font-size:11.5px; font-weight:600; color:var(--ink-faint);
  transition:all var(--t-fast) var(--ease);
}
.msg-act:hover{ background:var(--surface-2); color:var(--pri); }
.msg-act.done{ color:var(--ok); }
/* in-flight state for the copy buttons: the clipboard promise can hang, so the
   button says so rather than looking unresponsive */
.msg-act.busy,.copy-btn.busy{ color:var(--ink-faint); cursor:progress; opacity:.75; }
.msg-act.busy::before,.copy-btn.busy::before{
  content:""; width:9px; height:9px; flex:none; border-radius:50%;
  border:1.5px solid currentColor; border-top-color:transparent;
  animation:spin .6s linear infinite;
}

/* markdown body */
.md > *:first-child{ margin-top:0; }
.md > *:last-child{ margin-bottom:0; }
.md p{ margin:0 0 10px; }
.md h3{ font-size:.98rem; margin:16px 0 7px; padding-top:2px; }
.md ul,.md ol{ margin:0 0 10px; padding-left:1.35em; }
.md li{ margin-bottom:4px; }
.md li::marker{ color:var(--pri); font-weight:700; }
.md b,.md strong{ color:var(--ink); font-weight:650; }
.msg.user .bubble b{ color:var(--pri-ink); }
.md code{
  padding:2px 6px; border-radius:5px;
  background:var(--surface-3); color:var(--pri);
  font-size:.85em; border:1px solid var(--line);
  overflow-wrap:anywhere;
}
.md pre{
  margin:10px 0; padding:0; border-radius:var(--r-sm); overflow:hidden;
  background:var(--bg-2); border:1px solid var(--line-strong);
}
.md pre code{
  display:block; padding:13px 15px; overflow-x:auto;
  background:transparent; border:0; color:var(--ink);
  font-size:12.8px; line-height:1.65; white-space:pre;
}
/* code block toolbar + copy */
.codeblk{ position:relative; margin:10px 0; border-radius:var(--r-sm); overflow:hidden; border:1px solid var(--line-strong); background:var(--bg-2); }
.codeblk-bar{
  display:flex; align-items:center; gap:8px;
  padding:6px 8px 6px 13px; border-bottom:1px solid var(--line);
  background:var(--surface-2);
}
.codeblk-lang{ font-size:10.5px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--ink-faint); }
.codeblk-bar .sp{ flex:1; }
.codeblk pre{ margin:0; border:0; border-radius:0; }
.codeblk pre code{ display:block; padding:13px 15px; overflow-x:auto; background:transparent; font-size:12.8px; line-height:1.65; white-space:pre; }
.copy-btn{
  display:inline-flex; align-items:center; gap:5px;
  padding:4px 9px; border-radius:var(--r-xs);
  border:1px solid var(--line); background:var(--surface);
  font-size:11px; font-weight:650; color:var(--ink-soft);
  transition:all var(--t-fast) var(--ease);
}
.copy-btn:hover{ color:var(--pri); border-color:var(--pri); }
.copy-btn.done{ color:var(--ok); border-color:var(--ok); background:var(--ok-soft); }

/* typing indicator */
.msg.typing .msg-avatar{ animation:pulseDot 1.6s var(--ease) infinite; }
.typing-dots{ display:flex; align-items:center; gap:5px; padding:15px 18px; }
.typing-dots i{
  width:7px; height:7px; border-radius:50%; background:var(--pri);
  animation:bounceDot 1.3s var(--ease) infinite;
}
.typing-dots i:nth-child(2){ animation-delay:.16s; }
.typing-dots i:nth-child(3){ animation-delay:.32s; }

/* quick action chips inside chat */
.qa-strip{
  display:flex; gap:7px; flex-wrap:wrap;
  padding:0 clamp(14px,3vw,26px) var(--sp-3);
}
.qa-strip:empty{ display:none; }
.qa-chip{
  display:inline-flex; align-items:center; gap:7px;
  padding:7px 13px; border-radius:var(--r-full);
  border:1px solid var(--line); background:var(--surface-2);
  font-size:12.6px; font-weight:600; color:var(--ink-soft);
  transition:all var(--t-fast) var(--ease);
}
.qa-chip:hover{
  background:var(--pri-soft); border-color:color-mix(in srgb,var(--pri) 34%,transparent);
  color:var(--pri); transform:translateY(-1px);
}
.suggests{ display:none; }

/* composer */
.chatinput{
  display:flex; align-items:flex-end; gap:8px;
  padding:var(--sp-3) clamp(12px,3vw,18px) var(--sp-4);
  border-top:1px solid var(--line); background:var(--surface-2);
}
.chatinput-foot{ display:flex; align-items:center; gap:6px; padding-top:2px; }
.chatinput textarea{
  flex:1; min-height:44px; max-height:160px;
  padding:12px 15px; border-radius:var(--r-md);
  background:var(--paper); font-size:14.6px; line-height:1.5;
  resize:none; border:1px solid var(--line-strong);
}
.chatinput textarea:focus{ border-color:var(--pri); }
.send{
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:44px; height:44px; border-radius:var(--r-md);
  background:var(--pri); color:#fff; font-size:16px; line-height:1;
  box-shadow:0 2px 10px color-mix(in srgb,var(--pri) 30%,transparent);
  transition:all var(--t-fast) var(--ease);
}
.send:hover{ background:var(--pri-hover); transform:translateY(-1px); }
.send:disabled{ opacity:.45; pointer-events:none; box-shadow:none; }
.send svg{ width:17px; height:17px; }
.chat-foot{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3);
  flex-wrap:wrap; padding:0 clamp(12px,3vw,18px) var(--sp-4);
  font-size:11.5px; color:var(--ink-faint);
}
.engine-badge{
  display:inline-flex; align-items:center; gap:6px;
  padding:3px 9px; border-radius:var(--r-full);
  background:var(--surface-2); border:1px solid var(--line);
  font-size:11px; font-weight:600;
}

/* chat welcome / empty state */
.chat-welcome{
  flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:var(--sp-4); padding:var(--sp-10) var(--sp-5); text-align:center;
}
.chat-welcome .cw-ic{
  display:grid; place-items:center;
  width:56px; height:56px; border-radius:var(--r-lg);
  background:var(--pri-grad); font-size:26px;
  box-shadow:0 8px 24px color-mix(in srgb,var(--pri) 32%,transparent);
}
.chat-welcome h2{ margin:0; font-size:1.5rem; }
.chat-welcome p{ margin:0; color:var(--ink-soft); font-size:14.5px; max-width:52ch; }

/* ── 16 · RESUME BUILDER ─────────────────────────────────────────────────── */
.resume-main{ min-width:0; }
.rs-frame{
  position:relative; border-radius:var(--r-md);
  background:var(--surface-3); border:1px solid var(--line);
  padding:var(--sp-8) var(--sp-4) var(--sp-4); box-shadow:var(--shadow-sm);
  /* Neutralises the legacy `.rs-frame{width:794px;min-height:1123px}`: the frame
     is just the backdrop, the A4 size belongs to .rs-sheet inside it. */
  width:auto; min-height:0; margin:0; overflow:hidden;
}
/* The A4 sheet is 794px wide and is scaled down to whatever the frame can give
   it by rsFitPreview(). The wrapper clips the un-scaled layout box so a wide
   sheet never scrolls the page sideways; transform-origin matches the manual
   height that rsFitPreview() writes. */
#rsPreviewWrap{ overflow:hidden; }
#rsPreviewOuter{ transform-origin:top left; }
.rs-frame-tools{
  /* Legacy floated this row over the document with position:absolute and
     top/right offsets, so it covered the top of the A4 sheet and cut every
     button in half. A document toolbar belongs in normal flow, so the
     position is declared here rather than left to fall through. */
  position:static; top:auto; right:auto;
  display:flex; flex-wrap:wrap; gap:6px;
  margin-bottom:var(--sp-4); padding-bottom:var(--sp-4); border-bottom:1px dashed var(--line);
}
.rs-count{ align-self:center; margin-left:auto; font-size:12px; color:var(--ink-faint); }
#rsPreviewOuter{ overflow:auto; max-width:100%; }

/* The sheet is a printed document, so its paper stays white in both themes.
   The global heading and bold rules below set a colour directly, which stops
   those elements inheriting the sheet's ink -- in dark mode that painted the
   candidate's name and every bold run near-white on white. Id specificity
   hands them back the colour of the paper they sit on. */
#rsSheet h1,
#rsSheet :is(b,strong){ color:inherit; }
.rs-sheet{
  width:794px; min-height:1123px; margin:0 auto;
  background:#fff; color:#111;
  box-shadow:0 3px 16px rgba(14,16,32,.16);
  transform-origin:top center;
}
.rs-sheet .p-name{ font-family:var(--font-display); font-size:26px; font-weight:800; letter-spacing:-.03em; margin:0 0 2px; }
.rs-sheet .p-title{ font-size:14px; font-weight:600; color:#444; margin:0 0 6px; }
.rs-sheet .p-contact{ font-size:12.5px; color:#333; line-height:1.6; }
.rs-sheet .p-contact .sep{ padding:0 5px; opacity:.5; }
.rs-sheet .rs-sec{ margin:18px 0 0; }
.rs-sheet .rs-sec h2{
  font-family:var(--font-display); font-size:12.5px; font-weight:800;
  text-transform:uppercase; letter-spacing:.11em; color:#111;
  margin:0 0 7px; padding-bottom:4px; border-bottom:1.5px solid #111;
}
.rs-sheet .rs-entry{ margin:10px 0 0; }
.rs-sheet .rs-line{ display:flex; justify-content:space-between; gap:10px; align-items:baseline; }
.rs-sheet .rs-what{ font-weight:700; font-size:14px; }
.rs-sheet .rs-org{ font-weight:400; color:#333; }
.rs-sheet .rs-when{ font-size:12px; color:#555; white-space:nowrap; font-weight:600; }
.rs-sheet .rs-tag{ font-size:12.5px; color:#333; margin-top:3px; }
.rs-sheet .rs-desc,.rs-sheet .rs-obj{ white-space:pre-wrap; color:#111; font-size:13.5px; line-height:1.6; margin-top:3px; }
.rs-sheet ul.rs-bullets{ margin:5px 0 0; padding-left:17px; font-size:13.5px; line-height:1.6; }
.rs-sheet ul.rs-bullets li{ margin:2px 0; }
.rs-sheet .rs-chips{ display:flex; flex-wrap:wrap; gap:4px 7px; margin-top:5px; }
.rs-sheet .rs-chip{ font-size:11.5px; background:#f0f0f4; color:#111; padding:2px 8px; border-radius:4px; }
.rs-sheet .rt-side{ display:grid; grid-template-columns:1fr 2fr; }
.rs-sheet .rt-side .rs-sb{ padding:0 22px 0 0; border-right:1px solid #e2e2e6; }
.rs-sheet .rt-side .rs-mn{ padding:0 0 0 22px; }
.rs-sheet .rt-professional{ font-family:Georgia,"Times New Roman",serif; }
.rs-sheet .rt-professional .p-name{ font-weight:700; letter-spacing:0; }
.rs-sheet .rt-professional .rs-sec h2{ font-weight:700; border-bottom-width:1px; }
.rs-sheet .rt-minimal .rs-sec h2{ border-bottom:0; padding-bottom:0; text-transform:none; font-size:13.5px; letter-spacing:0; }
.rs-sheet .rt-dev .rs-sec h2{ border-bottom-color:#4f46e5; color:#4f46e5; }
.rs-sheet .rt-ats .rs-sec h2{ border-bottom:1px solid #111; text-transform:none; letter-spacing:.02em; }
.rs-sheet .rs-ats-note{ display:none; }
.rs-sheet .rt-student{ font-size:13px; }
.rs-ats-note{ display:none; }
/* Empty resume state. The sheet is white paper in both themes, so this is
   deliberately calm: one icon, one heading, a short how-to, no colour noise. */
.rs-empty{
  min-height:640px; display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; padding:48px 40px;
}
.rs-empty-ic{ font-size:44px; margin-bottom:14px; opacity:.8; }
.rs-empty h2{ font-family:var(--font-display); font-size:26px; font-weight:800; letter-spacing:-.02em; margin:0 0 10px; color:var(--ink); }
.rs-empty p{ font-size:14.5px; color:var(--ink-soft); line-height:1.65; max-width:46ch; margin:0 0 18px; }
.rs-empty ul{ text-align:left; font-size:13.5px; color:var(--ink-soft); line-height:1.9; margin:0 0 22px; padding-left:20px; }
.rs-empty-cta{ font-size:13px; font-weight:650; color:var(--pri); }

/* background declared here rather than inherited: the legacy sheet paints this
   rail #fff, and a sticky white sidebar is a light leak in dark mode */
.resume-rail{
  /* Legacy set position:fixed and a hardcoded width:280px. The grid item is
     tracked at 238px inside a 320px viewport, and 280px overflowed the page by
     6px. Declaring the position and letting the width come from the track. */
  min-width:0; width:auto;
  position:sticky; top:calc(var(--nav-h) + var(--sp-4));
  display:flex; flex-direction:column; gap:var(--sp-4);
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg);
  padding:var(--sp-5); box-shadow:var(--shadow);
}
.rtpl-chips{ display:flex; flex-wrap:wrap; gap:6px; margin:0 0 var(--sp-3); }
.rtpl-chips > button{
  padding:7px 12px; border-radius:var(--r-full);
  border:1px solid var(--line); background:var(--surface-2);
  font-size:12.4px; font-weight:600; color:var(--ink-soft);
  transition:all var(--t-fast) var(--ease);
}
.rtpl-chips > button:hover{ border-color:var(--pri); color:var(--pri); }
.rtpl-chips > button.on{ background:var(--pri); border-color:var(--pri); color:var(--pri-ink); }
.tpl-desc{ font-size:12.2px; color:var(--ink-faint); line-height:1.55; }
.rai-actions{ display:flex; flex-direction:column; gap:6px; margin:0 0 var(--sp-3); }
.rai-actions button{
  padding:9px 12px; border-radius:var(--r-sm); text-align:left;
  border:1px solid var(--line); background:var(--surface-2);
  font-size:12.8px; font-weight:600; color:var(--ink-soft);
  transition:all var(--t-fast) var(--ease);
}
.rai-actions button:hover{ background:var(--pri-soft); border-color:color-mix(in srgb,var(--pri) 30%,transparent); color:var(--pri); transform:translateX(2px); }
.rai-ai-path{ font-size:11.2px; color:var(--ink-faint); line-height:1.55; padding:10px; border-radius:var(--r-sm); background:var(--surface-2); }
.rai-ai-path code{ background:var(--surface-3); padding:1px 5px; border-radius:4px; color:var(--pri); }
.rmiss{ list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:5px; }
.rmiss li{ position:relative; padding:6px 0 6px 22px; font-size:12.8px; color:var(--ink-soft); line-height:1.5; margin:0; }
.rmiss li::before{ content:"○"; position:absolute; left:0; top:6px; color:var(--ink-faint); font-size:12px; }
.rmiss li.done{ color:var(--ink-soft); }
.rmiss li.done::before{ content:"✓"; color:var(--ok); font-weight:800; }
.rmstep{ display:flex; gap:12px; padding:11px 0; border-bottom:1px solid var(--line); }
.rmstep:last-child{ border-bottom:0; }
.stepno{
  display:grid; place-items:center; flex:none;
  width:26px; height:26px; border-radius:50%;
  background:var(--pri-soft); color:var(--pri);
  font-family:var(--font-display); font-size:12px; font-weight:750;
}
.rmiss + .rmstep{ border-top:1px solid var(--line); }

/* resume preview overlay */
#resumePreviewLayer{
  position:fixed; inset:0; z-index:120; display:none;
  align-items:center; justify-content:center; padding:var(--sp-4);
  background:rgba(8,9,16,.62);
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
}
#resumePreviewLayer.open{ display:flex; animation:fadeIn var(--t) var(--ease); }
.rp-modal{
  width:min(900px,100%); max-height:88vh; display:flex; flex-direction:column;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg);
  box-shadow:var(--shadow-pop); overflow:hidden;
  animation:modalIn var(--t-slow) var(--ease-out);
}
.rp-head{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3);
  padding:var(--sp-4) var(--sp-5); border-bottom:1px solid var(--line);
  font-size:14px;
}
.rp-modal > div:last-child{ padding:var(--sp-4); background:var(--surface-3); }
#rsPrintArea{ display:none; }

/* ── 17 · TRACKER, ROADMAP, RECORDS, TABS ────────────────────────────────── */
.kcol{ padding:var(--sp-3); }
.kcol h4{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin:0 0 var(--sp-3); font-size:12.5px; letter-spacing:.07em; text-transform:uppercase; color:var(--ink-soft); }
.kcol .cnt{ font-size:12px; color:var(--ink-faint); }
.kitem{ padding:11px; margin-bottom:8px; border-radius:var(--r-sm); background:var(--surface-2); }
.kitem:last-child{ margin-bottom:0; }
.kitem .co{ font-size:11.5px; font-weight:700; color:var(--pri); margin:0 0 2px; }
.kitem .ti{ font-size:13.4px; font-weight:600; line-height:1.4; margin:0 0 3px; }
.kitem .folio{ font-size:11.2px; }
.kitem select{ margin-top:7px; padding:6px 10px; font-size:12.4px; }
.stsel{ display:flex; flex-direction:column; gap:6px; margin-top:8px; }
.stsel label{ font-size:10.5px; letter-spacing:.07em; text-transform:uppercase; }

.tabs{
  display:flex; gap:3px; flex-wrap:wrap; margin:0 0 var(--sp-5);
  padding:4px; border-radius:var(--r-md);
  background:var(--surface-2); border:1px solid var(--line);
}
.tab{
  padding:8px 15px; border-radius:var(--r-sm);
  font-family:var(--font-display); font-size:13.4px; font-weight:600; color:var(--ink-soft);
  transition:all var(--t-fast) var(--ease);
}
.tab:hover{ color:var(--ink); background:var(--surface); }
.tab.on{ background:var(--surface); color:var(--pri); box-shadow:var(--shadow-xs); }
.rmap{ display:flex; flex-direction:column; gap:0; }
/* ---------------------------------------------------- career roadmaps ----
   Laid out as a stacked list rather than a grid: a roadmap card is a narrow
   column of ordered stages, and two side by side would force the stage text to
   wrap at half width. */
.rm-intro{ font-size:13.8px; color:var(--ink-soft); line-height:1.65; margin:0 0 var(--sp-4); max-width:70ch; }
.rmlist{ display:flex; flex-direction:column; gap:var(--sp-4); }
.rmc{
  border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--surface); padding:var(--sp-5);
  transition:border-color var(--t) var(--ease);
}
.rmc:hover{ border-color:var(--line-strong); }
.rmc-h{ display:flex; align-items:flex-start; gap:12px; margin:0 0 var(--sp-4); }
.rmc-ic{
  width:38px; height:38px; flex:none; border-radius:11px;
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--pri-soft); color:var(--pri);
  font-size:12px; font-weight:800; letter-spacing:-.02em;
}
.rmc-t{ flex:1; min-width:0; }
.rmc-t h3{ margin:0 0 3px; font-size:16.5px; font-weight:700; color:var(--ink); }
.rmc-t p{ margin:0; font-size:13.2px; color:var(--ink-soft); line-height:1.55; }
.rmc-m{ display:flex; flex-direction:column; align-items:flex-end; gap:5px; flex:none; }
.rmc-pill{
  font-size:11.5px; font-weight:600; color:var(--ink-soft);
  background:var(--surface-2); border:1px solid var(--line);
  padding:3px 9px; border-radius:999px; white-space:nowrap;
}
.rmc-bar{ display:flex; align-items:center; gap:12px; }
.rmc-bar .bar{ flex:1; min-width:80px; margin:0; }
.rmc-bar .num{ font-size:12.2px; color:var(--ink-faint); font-weight:600; white-space:nowrap; }
.rmc-body{ margin-top:var(--sp-4); padding-top:var(--sp-4); border-top:1px solid var(--line); }
.rmc-stages{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; }
.rmc-stage{ display:flex; gap:11px; padding:11px 0; border-bottom:1px solid var(--line); }
.rmc-stage:last-child{ border-bottom:0; padding-bottom:0; }
.rmc-check{
  width:23px; height:23px; flex:none; margin-top:1px; cursor:pointer;
  border:1.5px solid var(--line-strong); border-radius:50%;
  background:var(--surface); color:var(--pri-ink);
  display:inline-flex; align-items:center; justify-content:center;
  font-size:12px; font-weight:800;
  transition:all var(--t-fast) var(--ease);
}
.rmc-check:hover{ border-color:var(--pri); }
.rmc-check:focus-visible{ outline:2px solid var(--pri); outline-offset:2px; }
.rmc-stage.on .rmc-check{ background:var(--pri); border-color:var(--pri); color:var(--pri-ink); }
.rmc-stage-b{ flex:1; min-width:0; }
.rmc-stage-b h4{ margin:0 0 5px; font-size:14px; font-weight:650; color:var(--ink); }
.rmc-stage.on .rmc-stage-b h4{ color:var(--ink-faint); text-decoration:line-through; }
.rmc-stage-b ul{ list-style:none; margin:0; padding:0; }
.rmc-stage-b ul > li{
  position:relative; padding-left:14px; margin:3px 0;
  font-size:13px; line-height:1.6; color:var(--ink-soft);
}
.rmc-stage-b ul > li::before{
  content:""; position:absolute; left:0; top:9px;
  width:5px; height:5px; border-radius:50%; background:var(--line-strong);
}
.rmc-f{ display:flex; flex-wrap:wrap; gap:8px; margin-top:var(--sp-4); }
@media (max-width:720px){
  .rmc{ padding:var(--sp-4); }
  .rmc-h{ flex-wrap:wrap; }
  .rmc-m{ flex-direction:row; align-items:center; flex-wrap:wrap; width:100%; }
  .rmc-bar{ flex-wrap:wrap; }
  .rmc-bar .bar{ flex:1 1 100%; }
}
.rmiss + .rmap,.rmap + *{ margin-top:0; }
.roadmap-step{ display:flex; gap:14px; padding:14px 0; border-bottom:1px solid var(--line); }
.roadmap-step:last-child{ border-bottom:0; }
.roadmap-step .stepno{ width:30px; height:30px; }
.roadmap-step h4{ margin:0 0 3px; }
.roadmap-step p{ margin:0; font-size:13.2px; color:var(--ink-soft); line-height:1.58; }
/* Registration stepper. The old rule styled .order as a 22px circle with
   place-items:center, which is right for a numbered dot and wrong for a dot
   plus a label -- the label overflowed the circle and overlapped. */
.orders{ display:flex; align-items:stretch; gap:0; margin:0 0 var(--sp-5); }
.order{
  display:flex; align-items:center; gap:9px; flex:1; min-width:0;
  position:relative; padding:2px 0;
}
.order .stepno{
  width:26px; height:26px; border-radius:50%; flex:none;
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--surface-3); color:var(--ink-soft);
  font-size:12.5px; font-weight:700;
  transition:all var(--t) var(--ease);
}
.order .lbl{ font-size:13px; font-weight:550; color:var(--ink-faint); white-space:nowrap; }
.order.done .stepno{ background:var(--ok-soft); color:var(--ok); }
.order.done .lbl{ color:var(--ink-soft); }
.order.here .stepno{ background:var(--pri); color:var(--pri-ink); box-shadow:0 0 0 3px var(--pri-ring); }
.order.here .lbl{ color:var(--ink); font-weight:650; }
.order:not(:last-child)::after{
  content:""; position:absolute; left:31px; right:6px; top:50%; height:2px;
  background:var(--line); z-index:-1;
}
.order.done:not(:last-child)::after{ background:var(--ok); }
.detail{ font-size:14.4px; }
.detail h3{ margin-top:0; }
.reason{ display:flex; gap:8px; align-items:flex-start; font-size:13.2px; color:var(--ink-soft); padding:4px 0; line-height:1.55; }
.timeline{ display:flex; flex-direction:column; }
.demo-box{
  margin-top:var(--sp-4); padding:11px 14px; border-radius:var(--r-sm);
  background:var(--surface-2); border:1px dashed var(--line-strong);
  font-size:12.2px; color:var(--ink-soft); line-height:1.7;
}
.demo-box b{ color:var(--ink); }
.completion-big{ font-size:2.4rem; }
.dash-resume .bar{ margin:0 0 4px; }
.rheader{ display:flex; justify-content:space-between; align-items:center; gap:var(--sp-3); flex-wrap:wrap; margin:var(--sp-8) 0 var(--sp-4); padding-bottom:var(--sp-3); border-bottom:1px solid var(--line); }

/* ── 18 · FEEDBACK STATES ────────────────────────────────────────────────── */
.empty,.gate{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:var(--sp-3); text-align:center;
  padding:var(--sp-10) var(--sp-5);
  border:1px dashed var(--line-strong); border-radius:var(--r-md);
  background:color-mix(in srgb,var(--surface) 60%,transparent);
  margin:0 0 var(--sp-5);
}
/* Legacy hardcoded #f0f0ff on the base .ic and the design system only
   overrode it inside .feat, so every card icon and every empty/error state
   was a near-white plate in both themes holding a near-white glyph --
   1.01:1 on /internships in dark mode. Declared once from tokens; the
   .feat and .empty variants below are two-class selectors and keep their
   own sizes. */
.ic{
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:48px; height:48px; margin:0 0 var(--sp-2);
  border-radius:var(--r); background:var(--pri-soft); color:var(--ink);
  font-size:21px; line-height:1;
}
.empty .ic{ font-size:34px; line-height:1; }
.empty h3,.gate h2{ margin:0; font-size:1.14rem; }
.empty p,.gate p{ margin:0; color:var(--ink-soft); font-size:14px; max-width:56ch; line-height:1.62; }
.gate{ border-style:solid; border-color:var(--line); background:var(--surface); box-shadow:var(--shadow-xs); }
.gate .logo{ justify-content:center; margin-bottom:6px; }
.lines{ display:flex; flex-direction:column; gap:11px; padding:var(--sp-5) 0; }
.skel{
  height:13px; border-radius:var(--r-xs);
  background:linear-gradient(90deg,var(--surface-2) 25%,var(--surface-3) 37%,var(--surface-2) 63%);
  background-size:400% 100%;
  animation:shimmer 1.5s linear infinite;
}
.skel + .skel{ margin-top:0; }
.errflag{
  display:block; margin:0 0 var(--sp-3); padding:10px 13px;
  border-radius:var(--r-sm); border:1px solid color-mix(in srgb,var(--danger) 32%,transparent);
  background:var(--danger-soft); color:var(--danger);
  font-size:13.2px; font-weight:550; line-height:1.5;
}
.empty.error{ border-color:color-mix(in srgb,var(--danger) 34%,var(--line)); background:var(--danger-soft); }
.empty.error h3{ color:var(--danger); }

.toast{
  position:fixed; left:50%; bottom:26px; z-index:150;
  transform:translate(-50%,calc(100% + 30px)); opacity:0; visibility:hidden;
  max-width:min(92vw,440px);
  padding:12px 18px; border-radius:var(--r-md);
  background:var(--ink); color:var(--bg);
  font-size:13.8px; font-weight:550; line-height:1.5; text-align:center;
  box-shadow:var(--shadow-pop);
  transition:transform var(--t-slow) var(--ease-out),opacity var(--t) var(--ease),visibility var(--t) var(--ease);
}
.toast.show{ transform:translate(-50%,0); opacity:1; visibility:visible; }

.modal{
  position:fixed; inset:0; z-index:110; display:none;
  align-items:center; justify-content:center; padding:var(--sp-4);
  background:rgba(8,9,16,.6);
  -webkit-backdrop-filter:blur(5px); backdrop-filter:blur(5px);
}
.modal.open{ display:flex; animation:fadeIn var(--t) var(--ease); }
.modal-card{
  position:relative; width:min(620px,100%); max-height:86vh; overflow-y:auto;
  padding:var(--sp-6);
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg);
  box-shadow:var(--shadow-pop);
  animation:modalIn var(--t-slow) var(--ease-out);
}
.modal-card h2{ margin:0 0 4px; font-size:1.32rem; }
.modal-card .sub{ margin:0 0 var(--sp-5); color:var(--ink-soft); font-size:14px; }
.modal-card p{ font-size:14.4px; line-height:1.68; color:var(--ink-soft); }
.modal-close{
  position:absolute; top:14px; right:14px; z-index:2;
  display:grid; place-items:center; width:32px; height:32px;
  border-radius:var(--r-sm); border:1px solid var(--line);
  background:var(--surface); color:var(--ink-soft); font-size:14px;
  transition:all var(--t-fast) var(--ease);
}
.modal-close:hover{ background:var(--danger-soft); color:var(--danger); border-color:transparent; }

/* ── 19 · FOOTER ─────────────────────────────────────────────────────────── */
.site-foot{
  position:relative; z-index:1; margin-top:var(--sp-16);
  padding-block:var(--sp-12) var(--sp-6);
  background:color-mix(in srgb,var(--surface) 72%,transparent);
  border-top:1px solid var(--line);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
}
.site-foot .wrap{ padding-inline:clamp(16px,4vw,32px); }
.foot-grid{
  /* Brand + the five link columns. auto-fit rather than a fixed count, so a
   * column added later reflows instead of silently wrapping onto an orphan row. */
  display:grid; grid-template-columns:1.5fr repeat(5,minmax(0,1fr));
  gap:var(--sp-6) var(--sp-5);
  padding-bottom:var(--sp-8);
}
.foot-brand .logo{ margin:0 0 var(--sp-3); }
.foot-brand p{ font-size:13.4px; color:var(--ink-soft); line-height:1.68; max-width:36ch; }
.foot-social{ display:flex; gap:7px; margin-top:var(--sp-4); }
.foot-social a{
  display:grid; place-items:center; width:34px; height:34px;
  border-radius:var(--r-sm); border:1px solid var(--line); background:var(--surface);
  color:var(--ink-soft); font-size:14px;
  transition:all var(--t-fast) var(--ease);
}
.foot-social a:hover{ color:var(--pri); border-color:var(--pri); transform:translateY(-2px); }
.foot-col h4{
  margin:0 0 var(--sp-3);
  font-size:11.5px; font-weight:700; letter-spacing:.11em; text-transform:uppercase; color:var(--ink);
}
.foot-col ul{ list-style:none; padding:0; margin:0; }
.foot-col li{ margin-bottom:2px; }
.foot-col a{
  display:inline-block; padding:4px 0;
  font-size:13.4px; color:var(--ink-soft); text-decoration:none;
  transition:color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease);
}
.foot-col a:hover{ color:var(--pri); transform:translateX(2px); }
/* The install row is a <button> rather than an <a> because it runs the native
 * install prompt, which needs a click handler and has no href to fall back on.
 * Reset the UA button styling and inherit the link treatment above, or it sits
 * in the column as a grey system button next to four identical links. */
.foot-col .foot-linkbtn{
  display:inline-block; padding:4px 0;
  font:inherit; font-size:13.4px; color:var(--ink-soft);
  text-align:left; background:none; border:0; cursor:pointer;
  transition:color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease);
}
.foot-col .foot-linkbtn:hover{ color:var(--pri); transform:translateX(2px); }
.foot-col .foot-linkbtn:focus-visible{ outline:2px solid var(--pri); outline-offset:2px; }
.foot-bottom{
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--sp-3) var(--sp-4); flex-wrap:wrap;
  padding-top:var(--sp-5); border-top:1px solid var(--line);
  font-size:12.6px; color:var(--ink-faint);
}
.foot-bottom nav{ display:flex; flex-wrap:wrap; gap:var(--sp-4); }
.foot-bottom a{ color:var(--ink-faint); }
.foot-bottom a:hover{ color:var(--pri); }

/* ── 20 · ANIMATIONS ─────────────────────────────────────────────────────── */
@keyframes navUnderline{ from{ transform:scaleX(0); opacity:0; } to{ transform:scaleX(1); opacity:1; } }
@keyframes pulseDot{ 0%,100%{ opacity:1; transform:scale(1); } 50%{ opacity:.5; transform:scale(.82); } }
@keyframes bounceDot{ 0%,60%,100%{ transform:translateY(0); opacity:.45; } 30%{ transform:translateY(-5px); opacity:1; } }
@keyframes msgIn{ from{ opacity:0; transform:translateY(9px); } to{ opacity:1; transform:translateY(0); } }
@keyframes popIn{ from{ opacity:0; transform:translateY(-5px) scale(.97); } to{ opacity:1; transform:translateY(0) scale(1); } }
@keyframes modalIn{ from{ opacity:0; transform:translateY(14px) scale(.98); } to{ opacity:1; transform:translateY(0) scale(1); } }
@keyframes fadeIn{ from{ opacity:0; } to{ opacity:1; } }
@keyframes floatY{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-9px); } }
@keyframes waveHi{ 0%,60%,100%{ transform:rotate(0); } 70%{ transform:rotate(16deg); } 80%{ transform:rotate(-9deg); } 90%{ transform:rotate(11deg); } 100%{ transform:rotate(0); } }
@keyframes shimmer{ from{ background-position:100% 0; } to{ background-position:-100% 0; } }
@keyframes spin{ to{ transform:rotate(360deg); } }

.reveal{ opacity:0; transform:translateY(18px); transition:opacity var(--t-slow) var(--ease-out),transform var(--t-slow) var(--ease-out); }
.reveal.in{ opacity:1; transform:translateY(0); }

/* ── 21 · RESPONSIVE ─────────────────────────────────────────────────────── */
@media (max-width:1120px){
  .kcols{ grid-template-columns:repeat(3,minmax(176px,1fr)); }
  .foot-grid{ grid-template-columns:1fr 1fr 1fr; }
  .foot-brand{ grid-column:1 / -1; }
  .rbuild{ grid-template-columns:minmax(0,1fr); }
  .resume-rail{ position:static; }
}
@media (max-width:1000px){
  .navlinks{
    position:fixed; inset:var(--nav-h) 0 auto 0; z-index:58;
    align-self:auto;
    flex-direction:column; align-items:stretch; gap:2px;
    max-height:calc(100dvh - var(--nav-h)); overflow-y:auto;
    padding:var(--sp-3) clamp(16px,4vw,32px) var(--sp-5);
    background:var(--paper); border-bottom:1px solid var(--line);
    box-shadow:var(--shadow-lg);
    transform:translateY(-8px); opacity:0; visibility:hidden;
    transition:transform var(--t) var(--ease-out),opacity var(--t) var(--ease),visibility var(--t) var(--ease);
  }
  .navlinks.open{ transform:translateY(0); opacity:1; visibility:visible; }
  .navlink{ padding:12px 14px; font-size:15px; border-radius:var(--r-sm); }
  .navlink.on::after{ display:none; }
  .navlink.on{ background:var(--pri-soft); }
  /* In the drawer there is no room for a floating panel, so More becomes a
     plain indented group and the toggle is removed from the a11y tree. */
  .nav-drop{ position:static; align-self:auto; display:block; }
  .nav-drop-btn{ display:none; }
  .nav-drop-panel{
    position:static; min-width:0; gap:2px; padding:0 0 0 9px;
    background:none; border:0; box-shadow:none;
    border-left:1px solid var(--line);
    opacity:1; visibility:visible; transform:none;
  }
  .nav-drop-panel .navlink{ padding:10px 12px; font-size:14.5px; }
  .hamb{ display:inline-flex; order:9; }
  .nav-spacer{ display:none; }
  .nav-cta{ order:8; }
  .nav-drawer-auth{
    display:flex; gap:var(--sp-2); margin-top:var(--sp-3); padding-top:var(--sp-4);
    border-top:1px solid var(--line);
  }
  .nav-drawer-auth .btn{ flex:1 1 auto; justify-content:center; }
  .user-chip{ display:none; }
  .ai-layout{ grid-template-columns:minmax(0,1fr); }
  .ai-side{
    position:static; max-height:none;
    display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-4);
  }
  .ai-side-hist-wrap{ grid-column:1 / -1; }
  .ai-hist{ max-height:190px; }
  .hero-grid{ grid-template-columns:minmax(0,1fr); gap:var(--sp-8); }
  .hero h1{ max-width:20ch; }
  .preview{ max-width:560px; }
  .dash{ grid-template-columns:minmax(0,1fr); }
  .dash-nav{
    position:static; flex-direction:row; flex-wrap:wrap; gap:5px;
    overflow-x:auto; padding:8px;
  }
  .dash-nav a{ white-space:nowrap; font-size:13px; padding:8px 11px; }
  .dash-nav a i{ display:none; }
  .dash-nav-note{ display:none; }
  .tworow,.pgrid,.why-grid{ grid-template-columns:minmax(0,1fr); }
}
@media (max-width:720px){
  :root{ --nav-h:60px; }
  body{ font-size:15px; }
  .page{ padding-block:var(--sp-8) var(--sp-12); }
  .cgrid,.rgrid,.lgrid,.feat-grid,.tgrid{ grid-template-columns:minmax(0,1fr); }
  .kcols{ grid-template-columns:1fr 1fr; }
  .statgrid{ grid-template-columns:1fr 1fr; }
  .qa-grid{ grid-template-columns:1fr 1fr; }
  .hero-btns .btn{ flex:1 1 auto; }
  .foot-grid{ grid-template-columns:1fr 1fr; gap:var(--sp-5); }
  .chatbox{ min-height:calc(100dvh - var(--nav-h) - 120px); border-radius:var(--r-md); }
  .chatlog{ padding:var(--sp-4) var(--sp-3); gap:var(--sp-4); }
  .msg{ max-width:100%; }
  .msg-avatar{ width:26px; height:26px; font-size:13px; }
  .bubble{ padding:11px 13px; font-size:14.4px; }
  .msg.user .bubble{ max-width:88%; }
  .msg-acts{ opacity:1; }
  .ai-side{ grid-template-columns:minmax(0,1fr); }
  .ai-side-hist-wrap{ grid-column:auto; }
  .ai-ctx{ display:grid; grid-template-columns:1fr 1fr; }
  .ai-ctx h3{ grid-column:1 / -1; }
  .chatinput{ padding:var(--sp-2) var(--sp-3) var(--sp-3); }
  .chatinput textarea{ font-size:16px; /* prevents iOS zoom on focus */ }
  .send{ width:42px; height:42px; }
  .filters{ padding:var(--sp-3); }
  .frow{ flex-direction:column; align-items:stretch; }
  .f{ min-width:0; width:100%; }
  .freset{ align-self:stretch; }
  .freset .btn{ width:100%; }
  /* Below this width the bar cannot hold Ask AI, both auth buttons, the theme
     toggle and Menu. Sign up drops out of the bar -- it is in the drawer --
     and the CTA collapses to its glyph, keeping its aria-label. */
  .nav-signup{ display:none; }
  .nav-cta .cta-label{ display:none; }
  .nav-cta{ padding-inline:12px; }
  .nav-right{ padding-left:var(--sp-2); gap:6px; }
  .hamb-t{ display:none; }
  .hamb{ padding:8px 10px; }
  .tabs{ overflow-x:auto; flex-wrap:nowrap; scrollbar-width:none; }
  .tabs::-webkit-scrollbar{ display:none; }
  .tab{ white-space:nowrap; }
  .dash-head{ align-items:flex-start; }
  .du-txt{ display:none; }
  .panel,.icard,.ccard,.ocard,.tcard,.rcard,.lcard,.feat,.res-card{ padding:var(--sp-4); }
  .panel-h{ margin:calc(var(--sp-4) * -1) calc(var(--sp-4) * -1) var(--sp-3); padding:var(--sp-3) var(--sp-4); }
  .modal-card{ padding:var(--sp-5) var(--sp-4); }
  .rs-frame{ padding:var(--sp-4) var(--sp-2) var(--sp-2); }
  .rs-frame-tools .btn{ flex:1 1 auto; }
  .rs-count{ margin-left:0; width:100%; text-align:center; }
  .preview{ animation:none; }
  .toast{ bottom:14px; }
}
@media (max-width:420px){
  /* One button too many for a 320px bar; Sign in is in the drawer. */
  .nav-right .btn.lite{ display:none; }
  .kcols{ grid-template-columns:minmax(0,1fr); }
  .statgrid{ grid-template-columns:minmax(0,1fr); }
  .qa-grid,.ai-ctx,.foot-grid{ grid-template-columns:minmax(0,1fr); }
  .hero-btns{ flex-direction:column; }
  .hero-btns .btn{ width:100%; }
}

/* ── 22 · A11Y, MOTION & PRINT ───────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important;
  }
  .reveal{ opacity:1; transform:none; }
  .preview{ animation:none; }
}
@media (prefers-contrast:more){
  :root{ --line:#9aa1b5; --line-strong:#5d6478; --ink-soft:#333a4d; --ink-faint:#454c60; }
  .card,.panel,.icard,.btn,.filters{ border-width:2px; }
}
@supports not (color:color-mix(in srgb,red 50%,blue)){
  .navbar{ background:var(--bg); }
  .hero-eyebrow,.stat,.insight{ border-color:var(--line-strong); }
}
@media print{
  body::before,body::after{ display:none; }
  .navbar,.site-foot,.skip-link,.toast,.modal,#resumePreviewLayer,.chatbox{ display:none !important; }
  #stage{ display:none !important; }
  #rsPrintArea{ display:block !important; }
  #rsPrintArea .rs-sheet{ box-shadow:none; width:100%; min-height:0; }
  @page{ size:A4; margin:11mm; }
}

/* ── 23 · ANDROID, TOUCH & SAFE AREAS ───────────────────────────────────────
 *
 * Everything here exists because a phone is not a narrow desktop. The layout
 * already reflowed correctly at 320px, which is a different problem: a mouse
 * is a precise pointing device that reports hover, a phone has a status bar, a
 * notch or punch-hole, a gesture bar, a collapsing URL bar, and a finger.
 *
 * The rules fall into four groups:
 *   1. safe-area insets  — content must not sit under the system UI
 *   2. touch behaviour   — no sticky hover, no tap flash, no double-tap zoom
 *   3. dynamic viewports — `dvh` instead of `vh` where the URL bar moves
 *   4. the install bar   — the only new component, and it is user-facing
 */

/* ── 23.1 · Safe-area insets as tokens ──────────────────────────────────────
 *
 * env() resolves to 0 on a desktop browser and to the real inset on a device
 * with a cutout or gesture bar. It is zero unless the viewport meta carries
 * viewport-fit=cover, which index.html now does — without that single token the
 * entire group below is inert and looks like it does nothing.
 *
 * --nav-eff is the navbar's *effective* height, which is --nav-h plus whatever
 * top inset the device has. Every element that positions itself below the bar
 * has to use that, not --nav-h, or on a notched phone in landscape the sticky
 * offsets all land under the cutout. */
:root{
  --sat:env(safe-area-inset-top,0px);
  --sar:env(safe-area-inset-right,0px);
  --sab:env(safe-area-inset-bottom,0px);
  --sal:env(safe-area-inset-left,0px);
  --nav-eff:calc(var(--nav-h) + var(--sat));
}
/* In landscape the cutout is on one side, so body carries the side insets and
 * the navbar carries the top one. The background washes are position:fixed
 * with inset:0, so they are unaffected and still bleed edge to edge. */
body{ padding-left:var(--sal); padding-right:var(--sar); padding-bottom:var(--sab); }

.navbar{ padding-top:var(--sat); }
html{ scroll-padding-top:calc(var(--nav-eff) + 16px); }

/* Everything that hangs below the bar. Previously all of these used --nav-h. */
.dash-nav,
.ai-side,
.resume-rail{ top:calc(var(--nav-eff) + var(--sp-4)); }
.ai-side{ max-height:calc(100dvh - var(--nav-eff) - var(--sp-8)); }
/* Legacy set .resume-rail to position:fixed with max-height:calc(100vh - 100px).
 * The design sheet took over the position but not the max-height, so it was
 * still sized against `vh` and against a hardcoded 100px instead of the real
 * bar height. */
.resume-rail{ max-height:calc(100dvh - var(--nav-eff) - var(--sp-8)); }

/* The mobile drawer and the scrim behind it. */
.navlinks{ inset:var(--nav-eff) 0 0 0; max-height:none; padding-bottom:calc(var(--sab) + var(--sp-4)); }
.nav-backdrop{ inset:var(--nav-eff) 0 0 0; }

/* Bottom-anchored floating UI has to clear the gesture bar, or the bar eats
 * the primary action. .toast is a notification so it is allowed to sit close. */
.pinbar{ bottom:calc(var(--sab) + var(--sp-4)); }
.modal-card{ max-height:calc(100dvh - var(--sp-8) - var(--sat) - var(--sab)); }

/* ── 23.2 · Touch behaviour ──────────────────────────────────────────────────
 *
 * `hover: none` is the media feature that says "there is no mouse". Android
 * Chrome reports it on every phone, and it is the only reliable way to stop
 * desktop hover styling from being applied — and then *staying* applied after
 * a tap, which is what makes a phone UI feel broken: you tap a card, it lifts,
 * and it stays lifted until you tap somewhere else. */
@media (hover:none) and (pointer:coarse){
  /* Neutralise every lift-on-hover. Listed explicitly rather than with a
   * blanket `*:hover{transform:none}` because that would also kill legitimate
   * hover-driven state (the AI history rows reveal a delete button on hover,
   * the message actions appear on hover) which has no touch equivalent and
   * therefore must simply not be gated on hover. */
  .btn:hover,
  .icon-btn:hover,
  .theme-btn:hover,
  .theme-btn:hover .t-ico,
  .askbtn:hover,
  .go:hover,
  .send:hover,
  .ai-new:hover,
  .card:hover,
  .feat:hover,
  .icard:hover,
  .ccard:hover,
  .ocard:hover,
  .tcard:hover,
  .rcard:hover,
  .rcard:hover .go,
  .dash-card:hover,
  .stat:hover,
  .strip-chips > button:hover,
  .rai-actions button:hover,
  .foot-social a:hover,
  .foot-col a:hover{ transform:none; }
  .btn:hover,
  .icon-btn:hover,
  .card:hover,
  .feat:hover,
  .icard:hover,
  .ccard:hover,
  .ocard:hover,
  .tcard:hover,
  .rcard:hover,
  .dash-card:hover,
  .stat:hover{ box-shadow:var(--shadow-xs); border-color:var(--line); }
  .btn:hover,.btn.dark:hover,.btn.gho:hover,.btn.danger:hover{ --btn-bg:var(--pri); --btn-bd:var(--pri); color:var(--pri-ink); }
  .askbtn:hover,.go:hover,.send:hover,.ai-new:hover{ background:var(--pri); }

  /* Reveal-on-hover has no touch trigger, so make the destructive actions
   * permanently visible. The alternative is a delete button that cannot be
   * reached at all — a wall of icons in a list is a fair trade for that.
   *
   * Note the selector: .hx is a SIBLING of .ai-hist-item, both children of
   * .ai-hist-row. Two of the rules above this block use `.ai-hist-item .hx`,
   * which matches nothing in the rendered markup; the working reveal is
   * `.ai-hist-row:hover .hx`. */
  .ai-hist-row .hx{ opacity:1; }
  .msg-acts{ opacity:1; pointer-events:auto; }

  /* Replace hover with :active, which a finger does produce. Without this,
   * removing the hover lift leaves a button with no press feedback at all. */
  .btn:active,
  .icon-btn:active,
  .askbtn:active,
  .send:active,
  .hamb:active,
  .navlink:active{ transform:scale(.975); }
  .card:active,
  .feat:active,
  .rcard:active,
  .tcard:active,
  .icard:active{ transform:scale(.99); }
}

/* Android Chrome paints a grey rectangle over anything tappable unless told
 * not to, which on a designed surface reads as a rendering bug. The :active
 * rules above are the replacement. */
a,
button,
summary,
label,
[role="button"],
input[type="checkbox"],
input[type="radio"],
.btn,
.navlink,
.card,
.rcard,
.icard,
.ccard,
.ocard,
.tcard,
.feat,
.stat,
.chip,
.chip-btn,
.qa-card,
.lcard,
.hamb,
.icon-btn,
.theme-btn,
.rmc,
.rmc-check,
.rai-actions button,
.strip-chips > button,
.rtpl-chips > button,
.foot-social a,
.foot-col a,
.foot-col .foot-linkbtn,
.copied{ -webkit-tap-highlight-color:transparent; }

/* `manipulation` drops the 300ms double-tap-zoom delay without disabling
 * pinch-zoom, so the accessibility path stays open. Applied to controls rather
 * than to the document, so double-tap-zoom still works over body copy. */
a,
button,
summary,
label,
[role="button"],
.btn,
.navlink,
.card,
.rcard,
.icard,
.ccard,
.ocard,
.tcard,
.feat,
.stat,
.chip,
.chip-btn,
.qa-card,
.lcard,
.hamb,
.icon-btn,
.theme-btn,
.rmc,
.rmc-check,
.strip-chips > button,
.rtpl-chips > button,
.foot-social a,
.foot-col a,
.foot-col .foot-linkbtn{ touch-action:manipulation; }

/* A long press on a nav link or footer icon raises Android's system callout
 * ("Open in new tab"), which is wrong for chrome that behaves like app UI.
 * Only on chrome — not on body copy, where copy/paste is expected. */
.navbar,
.site-foot,
.skip-link{ -webkit-touch-callout:none; }
/* Nav labels are not text to be selected; a stray selection while tapping
 * around leaves a blue smear across the bar. Inputs and prose are untouched. */
.navbar,
.site-foot{ -webkit-user-select:none; user-select:none; }

/* Android Chrome and the Samsung browser both "boost" font sizes on wide or
 * long pages, which silently breaks every clamp()-based type step. The reset
 * already sets text-size-adjust:100% on html; this is the belt to that
 * suspenders, and costs nothing on a browser that ignores it. */

/* Android Chrome zooms the whole page in when a text field it considers "too
 * small" takes focus, and the zoom does not reset when the keyboard closes
 * unless the element is focused again. The threshold is 16px of *computed* font
 * size, which is why a `font-size:max(16px,1em)` on the bare elements is not
 * enough: component rules like `.kitem select{font-size:12.4px}` sit at a higher
 * specificity and win.
 *
 * `!important` is the right tool here rather than a workaround. This is not a
 * styling preference being asserted over another rule — it is a platform
 * behaviour being suppressed, in a query that only matches a real touchscreen,
 * and the alternative is a specificity war with every form control in the app.
 * Removing it brings the zoom straight back. */
@media (hover:none) and (pointer:coarse){
  input,
  select,
  textarea{ font-size:16px !important; }
  /* A range has no text to zoom into, and its own rule sizes the thumb and
   * track in em, so it is left exactly as the design has it. */
  input[type="range"]{ font-size:14.5px !important; }
}
@media (min-width:721px) and (hover:hover){
  /* On a real pointer the 14.5px control text is the design's intent, and
   * there is no zoom-to-focus behaviour to defend against. */
  input,
  select,
  textarea{ font-size:14.5px; }
  input[type="checkbox"],
  input[type="radio"]{ font-size:initial; }
}

/* ── 23.2b · Touch target floor ──────────────────────────────────────────────
 *
 * Measured on a 412px viewport, 849 controls across the 14 routes came out
 * under 44px tall. The distribution, which is why this is grouped the way it is:
 *
 *   ~500  .btn / .btn.sm          31px   the primary action primitive
 *    80  <label for>              21px   NOT a target — a field caption, fine
 *    61  input / select            43px   one pixel under
 *    40  .chip                     34px
 *    49  a.lil  (resource rows)   35px
 *     6  input[type=range]         22px   under even the WCAG 2.2 AA 24px floor
 *
 * WCAG 2.2 AA (2.5.8) only requires 24x24, so most of these pass the letter of
 * the standard. They fail the 44x44 of 2.5.5 (AAA) and of both Android's and
 * Apple's own guidelines, and a 31px button is genuinely hard to hit with a
 * thumb. So this is ergonomics, applied only where `(hover:none) and
 * (pointer:coarse)` is true — a mouse is unaffected and the design keeps its
 * original density on the desktop.
 *
 * min-height rather than height, so a button whose label wraps grows instead of
 * clipping. */
@media (hover:none) and (pointer:coarse){
  /* Primary actions. */
  .btn{ min-height:44px; }
  .btn.sm{ min-height:44px; }

  /* Square icon controls need both axes. */
  .icon-btn,
  .theme-btn,
  .send,
  .ri-del,
  .cm-les-check,
  .rmc-check{ min-width:44px; min-height:44px; }

  /* Rows that behave like list items: already full-width, so height only. */
  .ai-hist-item,
  .ai-new,
  .tab,
  .dash-user,
  .cap,
  .lil,
  .dash-nav a,
  .foot-col a,
  .foot-bottom a{ min-height:44px; }

  /* Inline chips. A little shorter than a button because they sit in wrapping
   * filter rows where a full 44px would dominate the layout, and because the
   * surrounding chips give them the spacing 2.5.8 asks for. The width floor is
   * only there because a two-character chip ("AI", "ML") is content-sized and
   * would otherwise land under 44 in both axes. */
  .chip,
  .chip-btn,
  .strip-chips > button,
  .rtpl-chips > button{ min-height:40px; min-width:44px; }

  /* Text links that are the only way to reach a destination. */
  .more{ min-height:44px; display:inline-flex; align-items:center; }

  /* Small inline actions inside chat bubbles. */
  .msg-act{ min-height:36px; padding-inline:10px; }

  /* The delete affordance on an AI history row is absolutely positioned at
   * 20x20, so it needs its own hit area rather than a min-height alone. */
  .ai-hist-row .hx{ width:44px; height:44px; right:-8px; font-size:19px; }
  .ai-hist-row .ai-hist-item{ padding-right:52px; }

  /* Form controls were 43px. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select,
  textarea{ min-height:44px; }

  /* A range's box is its hit area; the 5px track inside it is decoration. At
   * 22px it failed even the 24px AA minimum, and a thumb cannot reliably grab
   * a 5px line.
   *
   * This has to be `height`, not `padding-block`: the base rule sets an explicit
   * `height:22px`, and with border-box sizing padding is absorbed into it, so
   * the box never grows. The track stays vertically centred by the UA and the
   * thumb's `margin-top:-5.5px` is derived from the 5px track rather than from
   * the input's height, so a taller box moves the control without shifting the
   * handle off the line. */
  input[type="range"]{ height:44px; }

  /* Checkbox and radio are 1px boxes wrapped by their label; the label is the
   * real target, so give it the height. */
  .stsel label,
  .f > label,
  .field > label{ min-height:44px; display:flex; align-items:center; }
}

/* The scoring-weight sliders on Settings.
 *
 * These were inline styles. That is not a style preference, it was an
 * overflow: `grid-template-columns:150px 1fr 46px` plus the gaps needs 216px
 * of minimum width, and inside a panel with padding on a 320px phone the
 * content box is 244px - so the row ran 105px past its container and pushed the
 * whole document 75px sideways. An inline declaration cannot be overridden from
 * a stylesheet, so the fix is not a media query against it; the dimension has
 * to leave the markup. */
.sw-list{ display:grid; gap:12px; max-width:520px; }
.sw-row{
  display:grid; grid-template-columns:150px minmax(0,1fr) 46px;
  align-items:center; gap:10px;
}
.sw-lbl{ font-size:13px; font-weight:600; color:var(--ink-soft); }
.sw-val{ font-weight:800; text-align:right; }
@media (max-width:420px){
  /* Below this the 150px label starves the slider, and a slider narrower than
   * about 100px cannot be positioned accurately with a thumb. Put the label on
   * its own line instead: the row grows, but nothing overflows and the track
   * keeps a usable length. */
  .sw-row{ grid-template-columns:minmax(0,1fr) 46px; row-gap:4px; }
  .sw-lbl{ grid-column:1 / -1; }
  .sw-row input[type="range"]{ grid-column:1; }
  .sw-val{ grid-column:2; }
}

/* Inner scrollers should not drag the page behind them. Pull-to-refresh on the
 * document is left alone: in a browser tab it is a normal expectation, and
 * disabling it is a surprising thing to do to someone. */
.navlinks,
.modal-card,
.resume-rail,
.rs-sheet,
.codeblk pre{ overscroll-behavior:contain; }

/* ── 23.3 · Small-phone type floor ──────────────────────────────────────────
 *
 * Section 21 already steps body copy down at 720px, but several components
 * carry their own px font sizes below the 12px legibility floor once a phone is
 * also accounting for its own text scaling. These are the ones that get read
 * rather than scanned. */
@media (max-width:420px){
  .hero-note{ font-size:12.5px; }
  .kitem .folio,
  .kitem select{ font-size:12.5px; }
  .dash-card span{ font-size:12.5px; }
  .du-txt small{ font-size:11.5px; }
  .rai-ai-path{ font-size:11.5px; }
  .rmc-t p{ font-size:13.4px; }
}

/* ── 23.4 · Install bar ─────────────────────────────────────────────────────
 *
 * The one genuinely new component. Android has no browser UI to hint at
 * "Add to Home screen" and no installed icon to tap, so without a prompt the
 * feature is invisible. It is shown only when Chrome actually offers the
 * prompt, is hidden once the app is installed or running standalone, and
 * remembers a dismissal — a bar that reappears on every visit is worse than no
 * bar. */
.pinbar{
  position:fixed; left:50%; transform:translateX(-50%);
  z-index:145; width:min(100% - 24px,430px);
  display:flex; align-items:center; gap:var(--sp-3);
  padding:11px 11px 11px 15px;
  border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--surface);
  -webkit-backdrop-filter:saturate(180%) blur(16px);
          backdrop-filter:saturate(180%) blur(16px);
  box-shadow:var(--shadow-pop);
  animation:pinIn var(--t-slow) var(--ease-out);
}
.pinbar[hidden]{ display:none; }
@keyframes pinIn{
  from{ opacity:0; transform:translate(-50%,14px); }
  to{ opacity:1; transform:translate(-50%,0); }
}
.pinbar .ic{
  flex:none; width:34px; height:34px; border-radius:var(--r-sm);
  display:grid; place-items:center; font-size:17px;
  background:var(--pri-soft); color:var(--pri);
}
.pinbar-txt{ flex:1; min-width:0; }
.pinbar-txt b{ display:block; font-size:13.5px; font-weight:650; color:var(--ink); line-height:1.3; }
.pinbar-txt small{ display:block; font-size:12px; color:var(--ink-faint); line-height:1.4; }
.pinbar .btn{ flex:none; }
.pinbar .icon-btn{ flex:none; width:32px; height:32px; }
/* On a 320px screen the three parts cannot share a row at this type size;
 * the label takes the full first row and the buttons sit under it. */
@media (max-width:380px){
  .pinbar{ flex-wrap:wrap; }
  .pinbar .ic{ display:none; }
  .pinbar-txt{ flex:1 1 100%; }
  .pinbar .btn{ flex:1 1 auto; }
}
/* On a phone the sheet is the wrong container for a two-word prompt, and a
 * dismiss control under the gesture bar is unreachable. */
@media (hover:none) and (pointer:coarse){
  .pinbar{ padding-bottom:calc(11px + var(--sab)); }
}
@media (prefers-reduced-motion:reduce){
  .pinbar{ animation:none; }
}

/* ================================================================
   GET THE APP  ·  #/get-app
   The install page. The download button is deliberately the largest,
   highest-contrast element on the page: it is the reason the page
   exists, and on a phone it is the only thing the visitor came for.
   ================================================================ */
.ga-hero{
  display:flex; align-items:center; gap:var(--sp-5);
  flex-wrap:wrap; margin-bottom:var(--sp-8);
}
.ga-icon{
  width:88px; height:88px; border-radius:22px; flex:none;
  box-shadow:var(--shadow-sm);
}
.ga-hero-tx{ flex:1 1 260px; min-width:0; }
.ga-hero h1{ margin:0 0 8px; font-size:clamp(26px,4.4vw,36px); line-height:1.15; letter-spacing:-.02em; }
.ga-sub{ margin:0; color:var(--ink-soft); font-size:15px; line-height:1.6; max-width:52ch; }

/* The action block. Padded and ruled off so the buttons read as the page's
   subject rather than as one more row of links under the copy. */
.ga-cta{
  display:flex; flex-direction:column; align-items:stretch; gap:var(--sp-3);
  padding:var(--sp-5); margin-bottom:var(--sp-8);
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r-lg); box-shadow:var(--shadow-sm);
}
.ga-btn{
  width:100%; justify-content:center; text-align:center;
  min-height:56px; font-size:16.5px; font-weight:650;
  text-decoration:none;
}
.ga-note{ margin:2px 0 0; font-size:13px; line-height:1.6; color:var(--ink-faint); }
.ga-note b{ color:var(--ink-soft); }

.ga-steps{
  margin:2px 0 0; padding-left:20px;
  font-size:13.6px; line-height:1.75; color:var(--ink-soft);
}
.ga-steps li{ margin-bottom:4px; }
.ga-steps b{ color:var(--ink); }

.ga-grid{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:var(--sp-4); margin-bottom:var(--sp-6);
}
.ga-card{ padding:var(--sp-5); }
.ga-ic{ font-size:22px; line-height:1; display:block; margin-bottom:10px; }
.ga-card h3{ margin:0 0 6px; font-size:15.5px; }
.ga-card p{ margin:0; font-size:13.4px; line-height:1.65; color:var(--ink-soft); }

@media (max-width:560px){
  .ga-hero{ gap:var(--sp-4); }
  .ga-icon{ width:64px; height:64px; border-radius:17px; }
  /* 56px is the minimum comfortable touch target; below that a phone user
     misses the button and assumes the page is broken. */
  .ga-btn{ min-height:58px; font-size:16px; }
  .ga-cta{ padding:var(--sp-4); }
}
