/* ============================================================
   NORCET Study Planner — NPrep design system
   Poppins · Midnight Blue #131B63 · Clear Sky Blue #15CAE8 · Ice Blue #E5F0F8
   70% brand anchor / 30% modern (gradients, glass, soft shadows, motion).
   Visual layer only — no markup class was renamed, logic untouched.
   ============================================================ */

:root{
  /* brand */
  --navy:#131B63; --sky:#15CAE8; --ice:#E5F0F8; --ice-soft:#EEF4FB;
  --white:#fff; --gray:#CCCCCC;
  /* derived / neutrals (30% expanded) */
  --ink:#1b2240; --muted:#5b6683; --line:#e7edf6; --bg:#FAFBFF;   /* --muted darkened for WCAG AA (was #6b7793, 4.48:1) */
  --navy-2:#232f8f;               /* lighter navy for gradient stops */
  /* fill vs text split: --sky/--ok/--warn/--hi stay BRIGHT for backgrounds, dots, bars,
     gradients; the *-text tokens are the AA-safe (≥4.5:1 on white) versions for small text. */
  --sky-deep:#0b6f80;             /* AA-safe sky text/icon (was #0fb3cf, 2.5:1) */
  --ok-text:#157a4e; --warn-text:#a85a12; --hi-text:#c0344a;
  /* priority + status */
  --hi:#EF5D6F; --med:#F4B740; --lo:#9AA3AF; --ok:#18b26b; --warn:#e8823a;
  /* gradients */
  --grad-brand:linear-gradient(120deg,var(--navy) 0%,#2740b8 55%,var(--sky) 130%);
  --grad-sky:linear-gradient(120deg,var(--sky),#2f6bff);
  /* shape + depth (multi-layer soft shadows) */
  --r:16px; --r-lg:22px;
  --shadow2:0 1px 3px rgba(19,27,99,.06),0 6px 18px rgba(19,27,99,.06);
  --shadow:0 2px 8px rgba(19,27,99,.07),0 16px 40px rgba(19,27,99,.10);
  --shadow-sky:0 10px 30px rgba(21,202,232,.28);
  --glow:0 0 0 3px rgba(21,202,232,.22);
  --stick:150px;
  --ease:cubic-bezier(.4,0,.2,1); --spring:cubic-bezier(.68,-.55,.265,1.55);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;font-family:'Poppins',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;color:var(--ink);background:var(--bg);line-height:1.55;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4{margin:0;font-weight:700;letter-spacing:-.015em}
button{font-family:inherit;cursor:pointer}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto!important}}

/* faint dot texture on the app canvas (30% trendy) */
body::before{content:'';position:fixed;inset:0;z-index:-2;
  background:radial-gradient(circle at 1px 1px,rgba(19,27,99,.035) 1px,transparent 0);background-size:26px 26px;pointer-events:none}
/* soft brand blobs behind everything */
body::after{content:'';position:fixed;z-index:-1;top:-160px;right:-140px;width:520px;height:520px;pointer-events:none;
  background:radial-gradient(closed,transparent);
  background:radial-gradient(circle,rgba(21,202,232,.16),transparent 62%);filter:blur(10px)}

/* ---------------------------------------------------------------------------
   REMOVED: styles for features that no longer exist in the markup.
   The device-preview toggle, the rationale/"logic" side panel, the
   how-it-works drawer and its backdrop, the mobile FAB, and the stat strip
   were all deleted from the UI in earlier passes; their CSS was left behind.
   None of these class names is emitted by any code path — verified against
   app.js and index.html, and by diffing the computed style of every element
   across 10 rendered states before and after this deletion.
   --------------------------------------------------------------------------- */

/* ===== app shell ===== */
.app-wrap{display:flex;min-height:100vh;align-items:stretch}
.main{flex:1;min-width:0}
/* The 480px phone MOCK-UP that `body.m` used to draw is gone. It existed for a
   device-preview toggle that is no longer in the markup — and a real phone was
   getting the mock-up's constraints (capped width, fake device frame, unusable grey
   gutter) with none of its purpose. The app now simply fills whatever it is given;
   the reading measure is held by max-width on the CONTENT further down, not by a
   fake device frame around it. */
.app-wrap{width:100%}


/* Brand lock-up: the real NPrep wordmark, with the product name under it. The old
   `.logo` rule (a navy square containing the letter "N") stood in for the real mark
   and has been deleted along with it. */
.brand{display:flex;flex-direction:column;align-items:flex-start;gap:9px;margin-bottom:20px}
.brand-mark{height:30px;width:auto;display:block}
/* The wordmark is solid navy artwork on transparent; on a dark canvas it would vanish,
   so it gets a light plate rather than being recoloured (never recolour a logo). */
@media (prefers-color-scheme:dark){
  .brand-mark{background:#fff;padding:5px 9px;border-radius:8px;box-sizing:content-box}
}
.brand-txt h1{font-size:17px;color:var(--navy);letter-spacing:-.02em}
.brand h1{font-size:17px;color:var(--navy)}
.brand small{color:var(--muted);font-size:12px;font-weight:500}

/* ============ WIZARD ============ */
.wizard{max-width:820px;margin:0 auto;padding:26px clamp(16px,4vw,40px) 140px}
.wz-top{display:flex;align-items:center;gap:16px;margin:8px 0 44px}
.wz-back{width:46px;height:46px;border-radius:50%;border:1px solid var(--line);background:#fff;color:var(--navy);font-size:20px;box-shadow:var(--shadow2);flex:none;display:grid;place-items:center;transition:.25s var(--ease)}
.wz-back:hover{background:var(--navy);color:#fff;transform:translateX(-2px)}
.wz-back.hide{visibility:hidden}
.bar{flex:1;height:9px;background:var(--ice);border-radius:9px;overflow:hidden;box-shadow:inset 0 1px 2px rgba(19,27,99,.06)}
.bar>i{display:block;height:100%;background:var(--grad-sky);border-radius:9px;transition:width .5s var(--ease);box-shadow:var(--shadow-sky)}
.wz-step{font-size:14px;font-weight:600;color:var(--muted)}
.wz-panel{animation:slidein .45s var(--ease)}
.wz-h{font-size:clamp(25px,4vw,38px);font-weight:800;line-height:1.14;
  background:linear-gradient(115deg,var(--navy),#2c3bb0 60%,var(--sky));-webkit-background-clip:text;background-clip:text;color:transparent}
.wz-sub{color:var(--muted);font-size:16px;margin:12px 0 32px}

.tiles{display:flex;gap:14px;flex-wrap:wrap;justify-content:center;margin:8px 0}
.tile{min-width:96px;padding:20px 10px;border-radius:18px;border:2px solid var(--line);background:#fff;text-align:center;transition:.28s var(--ease);box-shadow:var(--shadow2)}
.tile:hover{transform:translateY(-4px);border-color:#bfe9f4;box-shadow:var(--shadow)}
.tile.sel{border-color:var(--sky);background:linear-gradient(180deg,#fff,#f2fcfe);box-shadow:0 10px 26px rgba(21,202,232,.22);transform:translateY(-4px)}
.tile .big{font-size:32px;font-weight:800;color:var(--navy)}
.tile.sel .big{color:var(--sky-deep)}
.tile .u,.tile div:last-child{font-size:12px;color:var(--muted);font-weight:500;margin-top:2px}
.summary{max-width:520px;margin:22px auto 4px;background:var(--ice);border-radius:18px;padding:22px;text-align:center;border:1px solid #d8e8f4}
.summary .lab{font-size:14px;color:#33406b}
.summary .pace{font-size:30px;font-weight:800;color:var(--navy);margin-top:2px}
.centre{text-align:center}
.hint{font-size:12.5px;color:var(--muted);font-weight:400}
.pills{display:flex;flex-wrap:wrap;gap:11px;justify-content:center}
.pill{border:2px solid var(--line);background:#fff;border-radius:30px;padding:12px 22px;font-size:15px;font-weight:600;color:var(--navy);transition:.22s var(--ease);box-shadow:var(--shadow2)}
.pill:hover{border-color:#bfe9f4;transform:translateY(-2px)}
.pill.sel{border-color:transparent;background:var(--navy);color:#fff;box-shadow:0 8px 20px rgba(19,27,99,.26)}
.pill.sel::before{content:'✓  ';color:var(--sky)}
.pill.sm{padding:9px 16px;font-size:13.5px}
.opt-cards{display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px}
.opt-cards.two{grid-template-columns:1fr 1fr;max-width:620px;margin:0 auto}
@media(max-width:560px){.opt-cards,.opt-cards.two{grid-template-columns:1fr}}
.ocard{border:2px solid var(--line);border-radius:18px;padding:22px 18px;background:#fff;text-align:left;transition:.26s var(--ease);box-shadow:var(--shadow2);position:relative;overflow:hidden}
.ocard::before{content:'';position:absolute;inset:0 auto 0 0;width:4px;background:var(--grad-sky);transform:scaleY(0);transform-origin:bottom;transition:transform .3s var(--ease)}
.ocard:hover{transform:translateY(-4px);border-color:#bfe9f4;box-shadow:var(--shadow)}
.ocard.sel{border-color:var(--sky);box-shadow:0 10px 26px rgba(21,202,232,.18)}
.ocard.sel::before{transform:scaleY(1)}
.ocard .em{font-size:26px}
.ocard b{display:block;font-size:16px;margin:9px 0 3px;color:var(--navy)}
.ocard span{font-size:12.5px;color:var(--muted)}

.wz-cta-wrap{position:fixed;left:0;right:0;bottom:0;padding:20px;background:linear-gradient(#FAFBFF00,#FAFBFF 34%);display:flex;flex-direction:column;align-items:center;gap:9px;z-index:5}
/* The CTA used to be pinned to the 480px phone mock-up's centre line. With the
   mock-up gone it spans the viewport and centres its own contents, matching the
   wizard's max-width above it. */
.cta{background:var(--grad-brand);color:#fff;border:none;border-radius:30px;padding:16px 44px;font-weight:700;font-size:17px;min-width:min(320px,84vw);transition:transform .3s var(--spring),box-shadow .3s var(--ease);box-shadow:0 12px 30px rgba(21,202,232,.32)}
.cta:hover{transform:translateY(-2px) scale(1.02);box-shadow:0 18px 40px rgba(21,202,232,.42)}
.cta:active{transform:scale(.97);transition:transform .1s ease}
.cta:disabled{background:#c7cfe0;box-shadow:none;cursor:not-allowed;transform:none}
.subrow{display:flex;gap:24px;flex-wrap:wrap;justify-content:center;align-items:center;margin-top:28px}
input[type=date]{font-family:inherit;border:2px solid var(--line);border-radius:12px;padding:11px 14px;font-size:15px;color:var(--navy);transition:.2s var(--ease);background:#fff}
input[type=date]:focus{outline:none;border-color:var(--sky);box-shadow:var(--glow)}
.mini-label{font-size:13px;font-weight:600;color:var(--muted)}

/* ============ PLAN — sticky header stack ============ */
.plan-sticky{position:sticky;top:0;z-index:30;background:rgba(255,255,255,.82);backdrop-filter:blur(16px) saturate(140%);border-bottom:1px solid var(--line);box-shadow:0 6px 22px rgba(19,27,99,.06)}
.countdown{display:flex;align-items:center;justify-content:center;gap:9px;background:var(--grad-brand);color:#fff;font-size:13px;font-weight:600;padding:10px 14px;letter-spacing:.005em}
.countdown b{font-variant-numeric:tabular-nums;font-weight:700}
.countdown .cd-x{opacity:.7;font-weight:500}
@media(max-width:520px){.countdown .cd-x{display:none}}
.plan-head{padding:15px clamp(16px,3vw,40px) 11px}
.ph-row{display:flex;align-items:flex-start;gap:12px}
.ph-title{flex:1;min-width:0;display:flex;align-items:center;gap:10px}
.ph-mark{width:28px;height:28px;flex:none;display:block}
.ph-title h2{font-size:22px;color:var(--navy);min-width:0;overflow-wrap:anywhere}
.ph-title .subj{color:var(--muted);font-size:12.5px;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ph-actions{display:flex;gap:8px;flex:none}
.iconbtn{border:1px solid var(--line);background:#fff;color:var(--navy);height:38px;min-width:38px;border-radius:12px;display:inline-flex;align-items:center;justify-content:center;gap:7px;font-size:13px;font-weight:600;padding:0 12px;box-shadow:var(--shadow2);transition:.2s var(--ease)}
.iconbtn:hover{background:var(--navy);color:#fff;border-color:var(--navy);transform:translateY(-1px)}
.iconbtn.wide span{font-size:14px}

.daybar{display:flex;gap:9px;overflow-x:auto;padding:12px clamp(16px,3vw,40px);scrollbar-width:thin;scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch}
.daybar::-webkit-scrollbar{height:6px}
.daybar::-webkit-scrollbar-thumb{background:#d5deee;border-radius:6px}
.daychip{flex:none;border:1px solid var(--line);background:#fff;border-radius:14px;padding:9px 15px;min-width:86px;text-align:left;transition:.22s var(--ease);box-shadow:var(--shadow2);scroll-snap-align:center}
.daychip:hover{border-color:#bfe9f4;transform:translateY(-2px)}
.daychip.sel{background:var(--navy);border-color:transparent;color:#fff;box-shadow:0 8px 20px rgba(19,27,99,.28)}
.daychip b{display:block;font-size:13.5px}
.daychip small{font-size:10.5px;opacity:.85}
.daychip.nash{background:#fff5f6;border-color:#fbd6dc}
.daychip.nash.sel{background:var(--hi-text);color:#fff}

.day-sec{padding:24px clamp(16px,3vw,40px);border-bottom:1px solid var(--line);animation:fade .4s var(--ease);scroll-margin-top:var(--stick)}
.day-sec h3{font-size:20px;color:var(--navy)}
.day-meta{color:var(--muted);font-size:13px;margin:5px 0 6px}
.badges{display:flex;gap:8px;flex-wrap:wrap;margin:7px 0 4px}
.badge{font-size:10.5px;font-weight:700;padding:4px 11px;border-radius:20px;letter-spacing:.02em}
.b-pyq{background:var(--ice);color:#2563c9}
.b-pyq2{background:#ece0ff;color:#6b3fa0}
.b-phase{font-weight:700;background:var(--navy);color:#fff}
.b-rev{background:#e7f7ef;color:var(--ok-text)}
.unit{margin-top:22px}
.subj-label{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--sky-deep)}
.unit .ttl{font-size:17px;font-weight:600;color:var(--navy);margin:3px 0 4px}
.unit .usum{font-size:12.5px;color:var(--muted);border-bottom:1px solid var(--line);padding-bottom:12px;margin-bottom:15px}
/* NOTE: this auto-fill is overridden to a single column further down (the
   'one card per lecture' declutter pass). Kept as the base so the grid still
   has sane behaviour, but a single column IS the intended design at every
   width — don't 'fix' it back to multi-column without asking. */
.cards-row{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(290px,100%),1fr));gap:12px}
/* The old JS-class-gated single-column rule was removed here; the max-width:768px
   media query in the RESPONSIVE section does that job without depending on JS. */
.ucard{display:flex;align-items:center;gap:13px;border:1px solid var(--line);border-radius:15px;padding:14px 16px;background:#fff;box-shadow:var(--shadow2);transition:.24s var(--ease)}
.ucard:hover{transform:translateY(-4px);box-shadow:var(--shadow);border-color:#dbe6f5}
.ucard .ic{width:44px;height:44px;border-radius:12px;display:grid;place-items:center;flex:none;font-size:17px}
.ic-v{background:var(--ice);color:var(--navy)}
.ic-p{background:#e4f0ff;color:#2563c9}
.ucard .cbody{flex:1;min-width:0}
.ucard .cttl{font-weight:600;font-size:14px;color:var(--navy);line-height:1.3}
.ucard .csub{font-size:12px;color:var(--muted);margin-top:3px}
.ucard .act{width:30px;height:30px;border-radius:10px;background:var(--ice);color:var(--sky-deep);display:grid;place-items:center;flex:none;font-size:13px;transition:.2s var(--spring)}
.ucard:hover .act{background:var(--sky);color:#fff;transform:scale(1.08)}
.sugg{border:1px dashed #cfe3d6;background:linear-gradient(180deg,#f4fcf8,#eefaf3);border-radius:15px;padding:16px 18px;margin-top:15px}
.sugg h4{font-size:14px;color:var(--ok-text);display:flex;align-items:center;gap:8px}
.sugg ul{margin:8px 0 0;padding-left:20px;font-size:13px;color:#3a4a63}
.sugg li{margin:4px 0}
.revchips{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.revchip{font-size:12px;padding:7px 13px;border-radius:20px;background:#fff;border:1px solid var(--line);color:var(--navy);box-shadow:var(--shadow2);transition:.2s var(--ease)}
.revchip:hover{background:var(--ice);transform:translateY(-2px)}
.nashta-card{display:flex;align-items:center;gap:14px;border:1px solid #fbd6dc;background:linear-gradient(120deg,#fff,#fff5f6);border-radius:15px;padding:16px 18px;margin-top:15px}
.nashta-card .ic{width:44px;height:44px;border-radius:12px;background:#fde3e7;color:var(--hi-text);display:grid;place-items:center;font-size:19px;flex:none}
.note{background:var(--ice);border-radius:14px;padding:15px 17px;font-size:13px;color:var(--navy);margin:16px clamp(16px,3vw,40px);box-shadow:var(--shadow2)}
.note.warn{background:#fdf2e7;color:#8a4a17}
.note.addl{background:var(--ice);color:#25308f;border-left:4px solid var(--sky)}

/* FAB (mobile only) */

/* ============ LOGIC PANEL ============ */

/* mobile: logic becomes bottom sheet */

/* ============ HOW-IT-WORKS drawer ============ */

/* ============ motion ============ */
@keyframes fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes slidein{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}
@keyframes fabPop{0%{opacity:0;transform:translateX(-50%) scale(.8)}100%{opacity:1;transform:translateX(-50%) scale(1)}}
@keyframes cardPop{0%{opacity:0;transform:translateY(24px) scale(.96)}70%{transform:translateY(-4px) scale(1.01)}100%{opacity:1;transform:none}}
@keyframes shimmer{100%{background-position:200% 0}}

/* scroll-entrance: applied by anim.js */
.reveal{opacity:0;transform:translateY(22px);transition:opacity .6s var(--ease),transform .6s var(--ease)}
.reveal.visible{opacity:1;transform:none}
.reveal-pop.visible{animation:cardPop .55s var(--spring)}
/* stagger children */
.stagger>*{opacity:0;transform:translateY(16px);transition:opacity .5s var(--ease),transform .5s var(--ease)}
.stagger.visible>*{opacity:1;transform:none}
.stagger.visible>*:nth-child(1){transition-delay:.04s}
.stagger.visible>*:nth-child(2){transition-delay:.09s}
.stagger.visible>*:nth-child(3){transition-delay:.14s}
.stagger.visible>*:nth-child(4){transition-delay:.19s}
.stagger.visible>*:nth-child(5){transition-delay:.24s}
.stagger.visible>*:nth-child(6){transition-delay:.29s}

.hidden{display:none!important}

/* ============ generating moment ============ */
.genwrap{position:fixed;inset:0;z-index:300;display:none;place-items:center;background:rgba(250,251,255,.88);backdrop-filter:blur(10px)}
.genwrap.show{display:grid;animation:fade .3s var(--ease)}
.gen-card{text-align:center;padding:24px;animation:cardPop .55s var(--spring)}
/* The mark itself now, not a navy tile with a letter in it. No background plate:
   the gen card is white, and the mark reads cleanly on it. */
.gen-logo{width:64px;height:64px;display:block;margin:0 auto 22px;animation:pulseLogo 1.4s var(--ease) infinite}
.gen-spin{display:flex;gap:9px;justify-content:center;margin-bottom:20px}
.gen-spin i{width:10px;height:10px;border-radius:50%;background:var(--sky);animation:bounceDot 1s var(--ease) infinite}
.gen-spin i:nth-child(2){animation-delay:.15s}
.gen-spin i:nth-child(3){animation-delay:.3s}
.gen-title{font-size:19px;font-weight:700;color:var(--navy)}
.gen-sub{font-size:13px;color:var(--muted);margin:7px auto 0;max-width:280px}
@keyframes pulseLogo{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
@keyframes bounceDot{0%,100%{transform:translateY(0);opacity:.45}50%{transform:translateY(-9px);opacity:1}}

/* ============ single coaching signal ============ */
.coach{display:flex;gap:11px;align-items:flex-start;margin:16px clamp(16px,3vw,40px);padding:15px 17px;border-radius:16px;font-size:14px;line-height:1.5;font-weight:500;box-shadow:var(--shadow2);animation:cardPop .5s var(--spring)}
.coach .coach-ic{font-size:20px;flex:none;line-height:1.35}
.coach.good{background:linear-gradient(120deg,#eefaf3,#e8f7ef);border:1px solid #c8e9d6;color:#166b43}
.coach.warn{background:linear-gradient(120deg,var(--ice),#eaf2fb);border:1px solid #d5e6f5;color:#2a3a7a}

/* decluttered day: one card per lecture + one compact practice card */
.ucard.lec{align-items:center}
a.ucard{text-decoration:none;color:inherit}
a.ucard:active{transform:scale(.98)}
a.ucard:active .act{background:var(--sky);color:#fff}
/* `white-space:nowrap` kept the subject chip on one line, which is right for "MSN" and
   wrong for "OBSTETRIC & GYNAECOLOGICAL NURSING" — at 320px that single unbreakable
   run pushed the card 33px past the screen edge. It may still wrap as a unit; the
   nowrap now only applies where there is room for it. */
.cttl .tag-subj{font-size:10.5px;font-weight:700;margin-left:8px;opacity:.9;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;display:inline-block}
@media (max-width:420px){
  .cttl .tag-subj{white-space:normal;margin-left:0;display:block;margin-top:3px}
}
.practice{display:flex;gap:13px;align-items:flex-start;border:1px solid var(--line);border-left:3px solid var(--sky);border-radius:15px;padding:14px 16px;background:linear-gradient(120deg,#fff,#f4fcfe);box-shadow:var(--shadow2);margin-top:12px}
.practice>.ic{width:40px;height:40px;border-radius:11px;background:#e6f9fd;color:var(--sky-deep);display:grid;place-items:center;flex:none;font-size:16px}
.practice .cttl{font-weight:700;font-size:14px;color:var(--navy)}
.practice .csub{font-size:12.5px;color:#3a4a63;margin-top:3px;line-height:1.55}

/* ============ B2C: centered column + collapsible day cards ============ */
#daySecs{max-width:740px;margin-inline:auto}
.coach{max-width:740px;margin-inline:auto}
/* Reading measure for the plan. Was gated on `body.w`, so a stale/missing class
   made the whole plan go full-bleed across a 27in monitor. It is a typographic
   constraint, not a device one — it applies always, and simply has no effect
   below 740px. */
#plan .plan-head, #plan .statstrip, #plan .daybar, #plan>.day-sec{max-width:740px;margin-left:auto;margin-right:auto}
.day-card{border:1px solid var(--line);border-radius:16px;background:#fff;box-shadow:var(--shadow2);margin:12px clamp(16px,3vw,40px);overflow:hidden;transition:box-shadow .25s var(--ease);scroll-margin-top:var(--stick)}
.day-card[open]{box-shadow:var(--shadow)}
.day-sum{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:15px 18px;transition:background .2s var(--ease)}
.day-sum::-webkit-details-marker{display:none}
.day-sum:hover{background:var(--ice-soft)}
.day-sum-date{font-size:16px;font-weight:700;color:var(--navy)}
.day-sum-n{font-size:12px;font-weight:500;color:var(--muted);margin-left:5px}
.day-sum-meta{font-size:12.5px;color:var(--muted);margin-top:2px}
.day-sum-r{display:flex;align-items:center;gap:11px;flex:none}
.day-time{font-size:13.5px;font-weight:700;color:var(--sky-deep)}
.day-tag{font-size:11px;font-weight:700;padding:4px 11px;border-radius:20px}
.day-tag.rev{background:#e7f7ef;color:var(--ok-text)}
.day-tag.nash{background:#fde3e7;color:var(--hi-text)}
.day-body{padding:2px 18px 18px;animation:fade .3s var(--ease)}
.day-body .day-meta{margin-top:0;margin-bottom:10px}
.day-body .badges{margin-top:0}
.cards-row{grid-template-columns:minmax(0,1fr)}   /* minmax(0,..) not 1fr: `1fr`'s implicit min is min-content, which overflowed narrow screens */

/* contextual mentor nudge (subject-test <60% gate) — small inline link */
.help-cta{display:inline-flex;align-items:center;gap:6px;margin-top:12px;font-size:12.5px;font-weight:600;color:var(--sky-deep);text-decoration:none;padding:9px 13px;border-radius:11px;background:#fff;border:1px solid #d5e6f5;transition:.2s var(--ease)}
.help-cta:hover{background:var(--sky);color:#fff;border-color:transparent;transform:translateY(-1px);box-shadow:var(--shadow-sky)}

/* mentor support card — shown once at the end of the plan */
.mentor{display:flex;align-items:center;gap:16px;max-width:740px;margin:22px clamp(16px,3vw,40px);margin-inline:auto;padding:20px 22px;border-radius:18px;
  background:linear-gradient(120deg,var(--navy) 0%,#2740b8 60%,var(--sky) 140%);color:#fff;box-shadow:0 14px 34px rgba(21,202,232,.28)}
.mentor-av{width:52px;height:52px;border-radius:16px;background:rgba(255,255,255,.16);display:grid;place-items:center;font-size:26px;flex:none;backdrop-filter:blur(4px)}
.mentor-main{flex:1;min-width:0}
.mentor-h{font-size:15.5px;font-weight:700;line-height:1.3}
.mentor-p{font-size:12.5px;opacity:.9;margin-top:3px;line-height:1.5}
.mentor-btn{flex:none;background:#fff;color:var(--navy);font-weight:700;font-size:13.5px;text-decoration:none;padding:12px 18px;border-radius:24px;white-space:nowrap;transition:transform .25s var(--spring),box-shadow .2s var(--ease)}
.mentor-btn:hover{transform:translateY(-2px) scale(1.03);box-shadow:0 8px 20px rgba(0,0,0,.18)}
@media(max-width:560px){.mentor{flex-direction:column;text-align:center}.mentor-btn{width:100%;text-align:center}}

/* ============ single-day pager ============ */
#dayView{max-width:740px;margin-inline:auto}
.day-card{box-shadow:var(--shadow)}                 /* always the raised, in-focus card */
.day-sum{cursor:default}
.day-sum:hover{background:transparent}
.day-body{padding:2px 18px 18px}
/* one dominant "next day" action; back is a quiet chevron */
.daynav-row{display:flex;gap:10px;align-items:stretch;max-width:740px;margin:16px clamp(16px,3vw,40px) 6px;margin-inline:auto}
.daynav{font-family:inherit;cursor:pointer;border:none;transition:transform .25s var(--spring),box-shadow .2s var(--ease)}
.daynav.prev{flex:none;width:54px;background:#fff;border:1.5px solid var(--line);color:var(--navy);font-size:24px;border-radius:16px;display:grid;place-items:center;line-height:1}
.daynav.prev:hover{border-color:var(--navy);background:var(--ice);transform:translateY(-1px)}
.daynav.next{flex:1;background:var(--grad-brand);color:#fff;border-radius:18px;padding:16px 24px;display:flex;align-items:center;justify-content:center;gap:9px;box-shadow:0 12px 30px rgba(21,202,232,.34);font-size:15.5px;font-weight:700}
.daynav.next:hover{transform:translateY(-2px);box-shadow:0 18px 42px rgba(21,202,232,.46)}
.daynav.next .dn-d{font-weight:600;opacity:.9}
.daynav.next .dn-a{transition:transform .2s var(--ease);font-size:18px}
.daynav.next:hover .dn-a{transform:translateX(4px)}
.daynav.done{flex:1;text-align:center;font-size:13.5px;color:#166b43;background:linear-gradient(120deg,#eefaf3,#e8f7ef);border:1px solid #c8e9d6;border-radius:18px;padding:18px 22px;line-height:1.55}
.daynav.done b{font-weight:700;display:block;font-size:15px;margin-bottom:2px}
/* help is a whisper, never a competing button */
.mentor-whisper{display:block;text-align:center;max-width:740px;margin:2px auto 52px;padding:10px;font-size:13px;color:var(--muted);text-decoration:none}
.mentor-whisper b{color:var(--sky-deep);font-weight:600}
.mentor-whisper:hover b{text-decoration:underline}

/* onboarding payoff line */
.summary .pace-sub{font-size:13px;color:#3a4a63;margin-top:7px;min-height:18px;transition:opacity .25s var(--ease)}

/* clear the mobile FAB so it never covers the last card */
body.m.on-plan #daySecs{padding-bottom:88px}

/* slim the sticky header on phones — it was eating a third of the screen */
@media(max-width:520px){
  .countdown{padding:8px 12px;font-size:12px}
  .plan-head{padding:11px 16px 9px}
  .ph-title h2{font-size:19px}
  .daybar{padding:9px 16px;gap:8px}
  .daychip{min-width:78px;padding:7px 12px}
  .coach{margin:14px 16px;font-size:13.5px}
}

/* web ↔ mobile layout switches */
/* ============================================================
   PRINT / SAVE AS PDF
   The screen is a one-day-at-a-time pager, so printing what is on screen gave a
   one-day PDF. printPlan() injects #printAll — a cover sheet plus every day — and
   removes it again afterwards. Here we hide the interactive shell and show that.
   ============================================================ */
#printAll{display:none}

@media print{
  @page{ margin:14mm 12mm; }
  /* The entire interactive plan is hidden and replaced by #printAll. Hiding it piecemeal
     was wrong: #plan carries its own copy of the "Straight with you" block, which then
     printed a second time above the cover sheet. #printAll is appended to <body>, not
     inside #plan, so one rule covers all of it. */
  /* .app-wrap carries min-height:100vh. With everything inside it hidden it still
     reserved a full viewport, so the PDF opened with a blank page before the cover.
     Hide the shell itself — #printAll is a sibling of it, not a child. */
  #plan,#setup,.genwrap,.app-wrap{display:none!important}
  body{background:#fff!important}
  body::before,body::after{display:none}

  #printAll{display:block}

  /* Cover sheet gets the first page to itself. */
  .pr-cover{break-after:page;padding-top:8mm;text-align:center}
  .pr-logo{height:44px;width:auto;margin:0 auto 22px;display:block}
  .pr-cover h1{font-size:30px;color:var(--navy);letter-spacing:-.02em}
  .pr-sub{font-size:14px;color:var(--ink);margin:8px 0 2px}
  .pr-cfg{font-size:13px;color:var(--muted);margin:0 0 22px}
  .pr-stats{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin-bottom:22px}
  .pr-stat{border:1px solid var(--line);border-radius:12px;padding:11px 16px;min-width:96px}
  .pr-stat b{display:block;font-size:21px;color:var(--navy);font-weight:700}
  .pr-stat span{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
  .pr-cover .honest{text-align:left;max-width:none;margin:0 0 18px;background:#fffdf7}
  .pr-foot{font-size:12px;color:var(--muted);margin-top:6px}

  /* A day is ALLOWED to break across pages. Forcing break-inside:avoid on the day made
     Chrome push a too-tall day wholesale, leaving half a blank page behind it. Breaking
     is avoided on the individual cards instead, which is where a split actually hurts. */
  .pr-day{break-inside:auto;margin-bottom:12px}
  /* Never leave a day's header stranded at the foot of a page. */
  .day-sum{break-after:avoid;page-break-after:avoid}
  .day-card{border:1px solid #d8dfec;box-shadow:none!important;margin-bottom:0}
  .unit,.practice,.ucard,.sugg,.nashta-card{break-inside:avoid;page-break-inside:avoid}
  .ucard,.practice,.qb-chip{box-shadow:none!important}

  /* Entrance animations must never survive into print. anim.js adds .reveal/.stagger
     (opacity:0) and only clears them when an element scrolls into view; the print tree is
     never on screen, so day bodies printed BLANK — header only, no lectures, no Q-bank.
     This is the guarantee: it cannot be defeated by timing, unlike the JS-side guards. */
  .reveal,.stagger,.stagger>*,.reveal-pop{opacity:1!important;transform:none!important;
    animation:none!important;transition:none!important}
  .day-sec,.day-body,.wz-panel{animation:none!important;opacity:1!important}

  /* Question banks must be visible on paper — printPlan opens every <details>, and the
     disclosure control itself is meaningless once printed. */
  .qb-detail>summary{display:none!important}
  .qb-group{break-inside:avoid}

  /* Links: the deeplinks are unusable on paper and their raw URLs are noise, so keep the
     label and drop the underline rather than printing href text. */
  a{text-decoration:none!important;color:inherit!important}
  .ucard .act{display:none}
  /* A tap target is meaningless on paper, and `color:inherit` above turned the button's
     label white-on-white. The number is in the card's text either way. */
  .mentor-btn,.help-cta{display:none!important}
}

/* ============================================================
   Question-bank disclosure — the day's linked Q-bank categories.
   Collapsed by default so the day card stays quiet (LOGIC.md §4:
   the day shows ONE Q-bank activity, not 40 block titles), but one
   tap from the real banks now that each carries its own deeplink.
   ============================================================ */
.qb-detail{margin-top:11px}
.qb-detail>summary{display:inline-flex;align-items:center;gap:6px;cursor:pointer;list-style:none;
  font-size:12.5px;font-weight:600;color:var(--sky-deep);background:#e6f9fd;border:1px solid #c9edf5;
  border-radius:999px;padding:6px 13px;transition:.2s var(--ease);-webkit-tap-highlight-color:transparent}
.qb-detail>summary::-webkit-details-marker{display:none}
.qb-detail>summary::before{content:'▸';font-size:10px;transition:transform .2s var(--ease)}
.qb-detail[open]>summary::before{transform:rotate(90deg)}
.qb-detail>summary:hover{background:#d8f4fb;border-color:#a9e3f0}
.qb-detail>summary:focus-visible{outline:none;box-shadow:var(--glow)}
.qb-group{margin-top:12px}
.qb-grp-ttl{font-size:11.5px;font-weight:700;color:var(--navy);text-transform:uppercase;
  letter-spacing:.04em;display:flex;justify-content:space-between;gap:10px;margin-bottom:6px}
.qb-grp-ttl span{color:var(--muted);font-weight:600;text-transform:none;letter-spacing:0;flex:none}
.qb-chips{display:flex;flex-wrap:wrap;gap:6px}
.qb-chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:500;
  color:var(--navy);background:#fff;border:1px solid var(--line);border-radius:10px;
  padding:6px 10px;text-decoration:none;transition:.2s var(--ease);max-width:100%}
.qb-chip>span{flex:none;font-size:10.5px;font-weight:700;color:var(--sky-deep);
  background:var(--ice);border-radius:6px;padding:1px 6px}
a.qb-chip:hover{border-color:#9fdcea;background:#f4fcfe;transform:translateY(-1px)}
a.qb-chip:focus-visible{outline:none;box-shadow:var(--glow)}
.qb-chip.flat{opacity:.62}

/* ============================================================
   "Straight with you" — what the plan could NOT fit.
   Deliberately plain and calm: this is the honesty surface, and a
   loud red panel would read as an error rather than a fact.
   ============================================================ */
.honest{max-width:740px;margin:16px clamp(16px,3vw,40px);margin-inline:auto;padding:17px 19px;
  border-radius:16px;background:#fffdf7;border:1px solid #f0e2c4;box-shadow:var(--shadow2)}
.honest h3{font-size:13.5px;color:var(--warn-text)}
.honest ul{margin:9px 0 0;padding-left:19px;display:flex;flex-direction:column;gap:7px}
.honest li{font-size:12.5px;color:#3a4a63;line-height:1.55}
.honest .mentor{margin-top:15px;margin-inline:0;max-width:none}

/* ============================================================
   RESPONSIVE
   The prototype leaned on a JS class (body.m / body.w) flipped at a
   single 800px breakpoint, so layout depended on scripting and had
   exactly two states. These are real media queries: they work with
   JS off, and they cover the sizes students actually hold.
   Breakpoints: 1024 (small laptop) · 768 (tablet) · 560 (large phone)
                · 400 (small phone) · landscape-short.
   ============================================================ */

/* Never let anything push the page sideways. Wide content scrolls in its
   own box instead — the daybar and stat strip already do this. */
html,body{max-width:100%;overflow-x:hidden}
img,svg,video{max-width:100%;height:auto}
/* Long lecture and block names are unbreakable strings on narrow screens. */
.ucard .cttl,.unit .ttl,.qb-chip,.qb-grp-ttl,.daychip b{overflow-wrap:anywhere}

@media (max-width:1024px){
  .wizard{padding:22px clamp(16px,4vw,32px) 140px}
}

@media (max-width:768px){
  /* One column of cards — two 290px columns cannot fit and were collapsing
     into a cramped 1.2-column grid with clipped titles. */
  .cards-row{grid-template-columns:minmax(0,1fr)}   /* minmax(0,..) not 1fr: `1fr`'s implicit min is min-content, which overflowed narrow screens */
  .day-sec{padding:20px 16px}
  .coach{margin:14px 16px;padding:13px 15px}
  .honest{margin:14px 16px;padding:15px 16px}
  .tiles{gap:10px}
  .unit{margin-top:18px}
  .unit .ttl{font-size:16px}
  /* The mentor card stacks: side-by-side left an 80px-wide button. */
  .mentor{flex-direction:column;align-items:flex-start;text-align:left;gap:12px}
  .mentor-btn{width:100%;text-align:center}
}

@media (max-width:560px){
  .wizard{padding:18px 16px 132px}
  .wz-h{font-size:clamp(21px,6vw,27px)}
  .wz-sub{font-size:13px}
  .summary{padding:17px;margin:18px auto 4px}
  .practice{padding:12px 13px;gap:10px}
  .practice>.ic{width:34px;height:34px;font-size:14px}
  .ucard{padding:12px 13px;gap:11px}
  .ucard .ic{width:38px;height:38px;font-size:15px}
  .day-sec{padding:17px 14px}
  .coach{margin:12px 14px}
  .honest{margin:12px 14px}
  /* Chips wrap rather than forcing a horizontal scroll inside a card. */
  .qb-chip{font-size:11.5px;padding:5px 9px}
}

@media (max-width:400px){
  .tiles{gap:8px}
  .tile{min-width:0;flex:1 1 calc(33.333% - 6px)}
  .ph-row{gap:8px}
  .ph-title h2{font-size:17px}
  .iconbtn.wide{padding:6px 10px;font-size:12px}
  .day-sec{padding:15px 12px}
  .coach{margin:11px 12px;font-size:13px}
  .honest{margin:11px 12px}
  .daynav-row{margin-inline:12px}
}

/* A phone held sideways has ~380px of height. A 150px sticky header plus a
   fixed CTA leaves almost nothing, so both shrink and the header unsticks. */
@media (max-height:480px) and (orientation:landscape){
  :root{--stick:0px}
  .plan-sticky{position:static}
  .wizard{padding-bottom:110px}
  .wz-cta-wrap{padding:12px}
}

/* Touch targets: the WCAG 2.2 minimum is 24px, Apple/Google advise ~44px.
   The chevron day-nav and icon buttons were under both on a phone. */
@media (hover:none) and (pointer:coarse){
  .daynav,.iconbtn,.qb-detail>summary,.qb-chip,.pill,.daychip{min-height:44px}
  .daynav.prev{min-width:44px}
  .ucard:hover{transform:none}   /* no hover lift where there is no hover */
  .daychip:hover{transform:none}
  a.qb-chip:hover{transform:none}
}

/* Honour the OS dark preference at least enough not to flash white. The app is a
   light-first brand surface, so this only softens the page canvas rather than
   inventing a full dark theme that has not been designed or contrast-checked. */
@media (prefers-color-scheme:dark){
  html{background:#0e1330}
}
