:root{
  --brand-blue:#2E6BFF; --brand-sky:#33A9FF; --navy:#131B63; --canvas:#EEF1F8;
  --ink:#0F1222; --ink-soft:#3A3F55; --ink-muted:#686F86; --success:#1FB66B;
  --sky:#15CAE8; --ice:#E5F0F8; --line:#E1E7F2; --wa:#25D366; --gold:#E8962E;
  --ease:cubic-bezier(.4,0,.2,1); --spring:cubic-bezier(.34,1.56,.64,1);
}
body{display:flex;min-height:100vh;align-items:flex-start;background:linear-gradient(168deg,#FBFCFE 0%,#EAF2FB 58%,#E1ECF8 100%)!important;color:var(--navy)}
.no-sb::-webkit-scrollbar{display:none}.no-sb{scrollbar-width:none;-ms-overflow-style:none}

/* ── stage: control rail + phone ── */
#stage{flex:1;display:flex;gap:34px;align-items:flex-start;justify-content:center;padding:30px 28px 60px;min-height:100vh}
@media (max-width:880px){#stage{flex-direction:column;align-items:center}}

#rail{width:320px;flex-shrink:0;position:sticky;top:32px;color:var(--navy);font-family:'Poppins',sans-serif}
#rail .bl{display:flex;align-items:center;gap:11px;margin-bottom:5px}
#rail .bl .lg{width:34px;height:34px;border-radius:10px;background:linear-gradient(135deg,var(--sky),var(--brand-blue));display:flex;align-items:center;justify-content:center;font-weight:800;font-size:17px;color:#fff;box-shadow:0 8px 18px rgba(21,202,232,.4)}
#rail h1{font-size:16px;font-weight:700;margin:0;color:var(--navy)}
#rail .sb{font-size:11px;color:var(--ink-muted);margin:4px 0 16px;line-height:1.5}
.panel{background:#fff;border:1px solid #E8EDF7;border-radius:16px;padding:14px;margin-bottom:12px;box-shadow:0 8px 22px -14px rgba(19,27,99,.22)}
.panel h2{font-size:9.5px;font-weight:700;letter-spacing:1.2px;text-transform:uppercase;color:var(--sky);margin:0 0 9px}
.seg{display:flex;flex-wrap:wrap;gap:6px}
.seg button{flex:1 1 auto;border:1px solid #E4E9F3;background:#F5F8FC;color:var(--ink-soft);font-family:inherit;font-size:11px;font-weight:600;padding:8px 9px;border-radius:9px;cursor:pointer;transition:all .18s var(--ease);white-space:nowrap}
.seg button:hover{background:var(--ice);color:var(--navy)}
.seg button.on{background:var(--navy);border-color:transparent;color:#fff;box-shadow:0 6px 14px rgba(19,27,99,.28)}
.seg.days button{flex:0 0 auto;width:30px;padding:8px 0;text-align:center}
.daylabel{font-size:10px;color:var(--ink-muted);margin-top:8px;line-height:1.4}
.scn{display:flex;flex-direction:column;gap:7px}
.scn button{text-align:left;border:1px solid #E4E9F3;background:#F5F8FC;color:var(--navy);font-family:inherit;padding:9px 12px;border-radius:11px;cursor:pointer;transition:all .18s var(--ease)}
.scn button:hover{background:var(--ice);transform:translateX(2px)}
.scn button b{font-size:12px;font-weight:700;display:block}
.scn button span{font-size:10px;color:var(--ink-muted)}
.edgewrap{display:flex;flex-wrap:wrap;gap:6px}
.edgewrap button{font-size:10px;font-weight:600;border:1px solid #E4E9F3;background:#F5F8FC;color:var(--ink-soft);padding:6px 9px;border-radius:9px;cursor:pointer;transition:all .16s var(--ease)}
.edgewrap button:hover{background:var(--ice);color:var(--navy)}
.edgewrap button.on{background:var(--sky);border-color:transparent;color:#fff;font-weight:700}
.railnote{font-size:10px;color:var(--ink-muted);line-height:1.5;margin-top:3px}
.railnote b{color:var(--navy)}

/* ── phone device (mirrors the signup build's frame) ── */
#device{width:393px;flex-shrink:0;position:relative}
.phone{width:393px;height:830px;background:#1B2148;border-radius:54px;padding:11px;box-shadow:0 30px 64px -26px rgba(19,27,99,.4);position:relative}
.phone .notch{position:absolute;top:11px;left:50%;transform:translateX(-50%);width:150px;height:30px;background:#1B2148;border-radius:0 0 18px 18px;z-index:60}
.viewport{position:relative;width:100%;height:100%;background:var(--canvas);border-radius:43px;overflow:hidden}
#screen{position:absolute;inset:0;display:flex;flex-direction:column}
.cap{position:absolute;left:0;right:0;bottom:-32px;text-align:center;color:var(--ink-muted);font-size:11px}
.cap b{color:var(--navy)}

@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}
/* ── motion ── */
.fade-up{opacity:0;transform:translateY(14px);animation:fu .5s var(--ease) forwards}
.stagger>*{opacity:0;transform:translateY(14px);animation:fu .5s var(--ease) forwards}
.stagger>*:nth-child(1){animation-delay:.04s}.stagger>*:nth-child(2){animation-delay:.1s}.stagger>*:nth-child(3){animation-delay:.16s}.stagger>*:nth-child(4){animation-delay:.22s}.stagger>*:nth-child(5){animation-delay:.28s}.stagger>*:nth-child(6){animation-delay:.34s}.stagger>*:nth-child(7){animation-delay:.4s}
@keyframes fu{to{opacity:1;transform:none}}
.pop{animation:pp .5s var(--spring) both}@keyframes pp{0%{opacity:0;transform:scale(.85)}100%{opacity:1;transform:scale(1)}}
.scr-in{animation:si .36s var(--ease) both}@keyframes si{from{opacity:0;transform:translateX(18px)}to{opacity:1;transform:none}}
.pulse{animation:pl 1.5s ease-in-out infinite}@keyframes pl{0%,100%{opacity:1}50%{opacity:.5}}
.tap{transition:transform .14s var(--ease)}.tap:active{transform:scale(.96)}

/* ── in-app primitives reused across freemium screens ── */
.fz-card{background:#fff;border-radius:18px;box-shadow:0 8px 24px -10px #1b1f5c33}
.fz-btn{display:flex;width:100%;align-items:center;justify-content:center;gap:8px;border:none;border-radius:16px;padding:15px;font-family:'Poppins',sans-serif;font-size:15px;font-weight:700;cursor:pointer;transition:transform .14s var(--ease)}
.fz-btn:active{transform:scale(.97)}
.fz-blue{background:var(--brand-blue);color:#fff;box-shadow:0 12px 26px -10px rgba(46,107,255,.6)}
.fz-grad{background:linear-gradient(to right,var(--brand-blue),var(--sky));color:#fff;box-shadow:0 12px 26px -10px rgba(21,202,232,.5)}
.fz-white{background:#fff;color:var(--brand-blue);box-shadow:0 8px 22px -10px rgba(27,31,92,.3)}
.fz-wa{background:var(--wa);color:#fff}
.fz-outline{background:#fff;border:1.5px solid #E2E6F0;color:var(--navy)}
.fz-ghost{background:transparent;color:var(--ink-muted);font-weight:600;font-size:13px;padding:11px;border:none;cursor:pointer;width:100%}
.eyebrow{font-size:10px;font-weight:700;letter-spacing:1px;text-transform:uppercase}
.cns-fab{position:absolute;right:14px;bottom:96px;z-index:40;display:flex;align-items:center;gap:8px;background:#fff;border-radius:9999px;padding:9px 14px 9px 9px;box-shadow:0 18px 40px -14px #1b1f5c66;cursor:pointer;animation:pp .5s var(--spring) both}
.cns-fab .d{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#19D3C5,var(--brand-sky));display:flex;align-items:center;justify-content:center}
.cns-fab span{font-size:11.5px;font-weight:700;color:var(--navy)}
.toast{position:absolute;left:50%;top:52px;transform:translateX(-50%) translateY(-12px);z-index:80;background:#0F1430;color:#fff;font-size:12.5px;font-weight:600;padding:11px 16px;border-radius:9999px;box-shadow:0 14px 30px rgba(0,0,0,.35);opacity:0;transition:all .35s var(--spring);display:flex;align-items:center;gap:8px;max-width:300px}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.sheet-ov{position:absolute;inset:0;z-index:90;background:rgba(10,12,30,.45);display:flex;align-items:flex-end;opacity:0;pointer-events:none;transition:opacity .3s var(--ease)}
.sheet-ov.show{opacity:1;pointer-events:auto}
.sheet{width:100%;background:#fff;border-radius:28px 28px 0 0;padding:10px 20px 26px;transform:translateY(100%);transition:transform .42s var(--spring)}
.sheet-ov.show .sheet{transform:none}
.sheet-h{width:38px;height:4px;border-radius:9999px;background:#D7DBEA;margin:0 auto 16px}
.pmnote{margin-top:14px;border:1px dashed #C5CBE6;background:rgba(19,27,99,.035);border-radius:12px;padding:10px 12px}
.pmnote .t{font-size:8.5px;font-weight:800;letter-spacing:1px;color:var(--ink-muted);text-transform:uppercase;margin-bottom:4px;display:flex;align-items:center;gap:5px}
.pmnote .t i{width:13px;height:13px;border-radius:3px;background:var(--navy);color:#fff;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-style:normal}
.pmnote .b{font-size:10.5px;color:var(--ink-soft);line-height:1.5}

/* supplementary utilities the freemium screens use that the app's compiled CSS doesn't include */
.text-\[8px\]{font-size:8px}.text-\[8\.5px\]{font-size:8.5px}.text-\[9px\]{font-size:9px}.text-\[9\.5px\]{font-size:9.5px}.text-\[10\.5px\]{font-size:10.5px}.text-\[11\.5px\]{font-size:11.5px}.text-\[12\.5px\]{font-size:12.5px}.text-\[13\.5px\]{font-size:13.5px}.text-\[14\.5px\]{font-size:14.5px}.text-\[15\.5px\]{font-size:15.5px}.text-\[21px\]{font-size:21px}.text-\[23px\]{font-size:23px}.text-\[30px\]{font-size:30px}.text-\[34px\]{font-size:34px}.text-\[44px\]{font-size:44px}.text-\[46px\]{font-size:46px}.text-\[48px\]{font-size:48px}.text-\[50px\]{font-size:50px}.text-\[52px\]{font-size:52px}
.mt-3\.5{margin-top:.875rem}.mb-2\.5{margin-bottom:.625rem}.mb-3\.5{margin-bottom:.875rem}.pt-3\.5{padding-top:.875rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.pt-7{padding-top:1.75rem}.pt-8{padding-top:2rem}.pt-9{padding-top:2.25rem}.pb-7{padding-bottom:1.75rem}.gap-3\.5{gap:.875rem}.leading-none{line-height:1}
.rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}
.space-y-2>:not([hidden])~:not([hidden]){margin-top:.5rem}.space-y-2\.5>:not([hidden])~:not([hidden]){margin-top:.625rem}

/* ═══════════════════════════════════════════════════════════════════
   DESIGN TOKENS — the fix for 36 font sizes / 17 radii / off-grid gaps.
   4 sizes · 2 weights · one 8-pt spacing scale · one radius family.
   ═══════════════════════════════════════════════════════════════════ */
:root{
  --fs-xl:24px;  --fs-lg:16px;  --fs-md:13px;  --fs-sm:11px;
  --fw-b:700;    --fw-m:500;
  --r-sm:12px;   --r-md:16px;   --r-lg:24px;   --r-pill:9999px;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:40px;
  --paper:#F7F9FD;                       /* 60 — the canvas */
  --line2:#E8EDF7;
  --green:#12A662; --green-bg:#E9F8F0; --amber:#E8962E; --amber-bg:#FEF3E4;
}
.t-xl{font-size:var(--fs-xl);font-weight:var(--fw-b);line-height:1.25;letter-spacing:-.4px;color:var(--navy)}
.t-lg{font-size:var(--fs-lg);font-weight:var(--fw-b);line-height:1.35;letter-spacing:-.2px;color:var(--navy)}
.t-md{font-size:var(--fs-md);font-weight:var(--fw-m);line-height:1.5;color:var(--ink-soft)}
.t-sm{font-size:var(--fs-sm);font-weight:600;line-height:1.4;color:var(--ink-muted)}
.mut{color:var(--ink-muted)}

/* ── screen chrome ── */
.scr{display:flex;flex-direction:column;height:100%;background:var(--paper)}
.topbar{display:flex;align-items:center;gap:var(--s3);padding:var(--s2) var(--s4) var(--s3);flex-shrink:0}
.iconbtn{width:44px;height:44px;border-radius:var(--r-pill);background:#fff;border:1px solid var(--line2);display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:all .2s var(--ease)}
.iconbtn:hover{background:var(--ice);border-color:#D5E3F3}
.iconbtn:active{transform:scale(.94)}
.track{flex:1;height:4px;border-radius:var(--r-pill);background:#DDE5F2;overflow:hidden}
.track i{display:block;height:100%;border-radius:var(--r-pill);background:linear-gradient(90deg,var(--sky),var(--brand-blue));transition:width .45s var(--ease)}
.body{flex:1;overflow-y:auto;padding:var(--s2) var(--s5) var(--s5)}
/* Q3 is five chips and a verdict — a third of a screen. Top-aligned like the other two questions
   it left ~300px of dead air between the footnote and the CTA, which is the same void a design
   pass already called out on the story. Only Q3 gets this: Q1 and Q2 fill their height honestly.
   The headline stays put and .hbody centres the controls in what is left, so the leftover is
   split above and below them instead of all landing in one lump at the bottom. */
.body-c{display:flex;flex-direction:column}
.body-c .hbody{flex:1;display:flex;flex-direction:column;justify-content:center}

/* ── setup: option cards ── */
.opts{display:flex;flex-direction:column;gap:var(--s3);margin-top:var(--s6)}
.opt{display:flex;align-items:center;gap:var(--s4);width:100%;background:#fff;border:1.5px solid var(--line2);border-radius:var(--r-md);padding:var(--s4);cursor:pointer;font-family:inherit;text-align:left;transition:transform .18s var(--ease),border-color .18s var(--ease),box-shadow .18s var(--ease);box-shadow:0 1px 2px rgba(19,27,99,.04)}
.opt:hover{border-color:#C9DDF2;transform:translateY(-2px);box-shadow:0 12px 24px -14px rgba(19,27,99,.3)}
.opt .oi{width:40px;height:40px;border-radius:var(--r-sm);background:var(--ice);display:flex;align-items:center;justify-content:center;font-size:var(--fs-lg);flex-shrink:0;transition:background .18s var(--ease)}
.opt .ot{flex:1;min-width:0}
.opt .ok{width:24px;height:24px;border-radius:var(--r-pill);flex-shrink:0;display:flex;align-items:center;justify-content:center;transition:all .18s var(--ease)}
.opt.on{border-color:var(--brand-blue);background:#F4F8FF;box-shadow:0 12px 28px -14px rgba(46,107,255,.55)}
.opt.on .oi{background:#E0EBFF}
.opt.on .ok{background:var(--brand-blue)}

/* ── Q1: stream card with an inline year dropdown ── */
.strm{background:#fff;border:1.5px solid var(--line2);border-radius:var(--r-md);overflow:hidden;transition:border-color .18s var(--ease),box-shadow .18s var(--ease);box-shadow:0 1px 2px rgba(19,27,99,.04)}
.strm:hover{border-color:#C9DDF2}
.strm.open{border-color:#C9DDF2;box-shadow:0 12px 26px -16px rgba(19,27,99,.35)}
.strm.on{border-color:var(--brand-blue);background:#F4F8FF;box-shadow:0 12px 28px -14px rgba(46,107,255,.45)}
.strm.on .oi{background:#E0EBFF}
.strm.on .ok{background:var(--brand-blue)}
.strm .opt:hover{transform:none;box-shadow:none!important}
.yrs{display:flex;flex-wrap:wrap;gap:var(--s2);padding:0 var(--s4) var(--s4);animation:yrIn .28s var(--ease) both}
@keyframes yrIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.yr{font-family:inherit;font-size:var(--fs-md);font-weight:600;color:var(--navy);background:var(--paper);border:1.5px solid var(--line2);border-radius:var(--r-sm);padding:9px 13px;cursor:pointer;transition:all .16s var(--ease)}
.yr:hover{border-color:var(--sky);background:#F6FCFE}
.yr.on{background:var(--brand-blue);border-color:transparent;color:#fff;box-shadow:0 8px 18px -8px rgba(46,107,255,.7)}

/* ── setup: 2×2 big grid ── */
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:var(--s3);margin-top:var(--s6)}
.big{background:#fff;border:1.5px solid var(--line2);border-radius:var(--r-md);padding:var(--s5) var(--s3);cursor:pointer;font-family:inherit;text-align:center;transition:transform .18s var(--ease),border-color .18s var(--ease),box-shadow .18s var(--ease);box-shadow:0 1px 2px rgba(19,27,99,.04)}
.big:hover{border-color:#C9DDF2;transform:translateY(-2px);box-shadow:0 12px 24px -14px rgba(19,27,99,.3)}
.big b{display:block;font-size:var(--fs-xl);font-weight:var(--fw-b);color:var(--navy);line-height:1}
.big span{display:block;font-size:var(--fs-sm);font-weight:600;color:var(--ink-muted);margin-top:var(--s1)}
.big.on{border-color:var(--brand-blue);background:#F4F8FF;box-shadow:0 12px 28px -14px rgba(46,107,255,.55)}

.callout{display:flex;gap:var(--s3);background:var(--ice);border-radius:var(--r-md);padding:var(--s4);margin-top:var(--s5)}
.cta{background:var(--brand-blue);color:#fff;border:none;border-radius:var(--r-md);padding:var(--s4);width:100%;font-family:inherit;font-size:var(--fs-lg);font-weight:var(--fw-b);cursor:pointer;box-shadow:0 12px 26px -10px rgba(46,107,255,.7);transition:transform .16s var(--ease)}
.cta:active{transform:scale(.97)}
.cta.navy{background:var(--navy);box-shadow:0 12px 26px -12px rgba(19,27,99,.7)}

/* ── plan header + the horizontal DAY BAR (replaces the sticky day headers, the
      7-day strip and the topper banner — Raj, 2026-07-16) ── */
.plan-hd{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);padding:var(--s2) var(--s4) var(--s3);flex-shrink:0}
/* all 7 days fit in one row — it is a SEVEN-day plan, so the whole week has to be visible at a
   glance; a bar you have to scroll to see Day 7 hides the finish line. Chips flex to the width. */
.dbar{display:flex;gap:6px;padding:0 var(--s4) var(--s3);flex-shrink:0;border-bottom:1px solid var(--line)}
.dchip{position:relative;flex:1 1 0;min-width:0;background:#fff;border:1.5px solid var(--line2);border-radius:var(--r-sm);padding:var(--s2) 0 6px;font-family:inherit;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:2px;transition:all .2s var(--ease)}
.dchip:hover{border-color:#C9D6EC;transform:translateY(-1px)}
.dchip-n{font-size:var(--fs-lg);font-weight:var(--fw-b);color:var(--navy);line-height:1.1}
/* Only the SELECTED chip spells the word (Raj, 2026-07-17). The other six stay bare numbers, so
   the bar reads as a quiet 1-7 index with one thing named — and "Day" appears once, not seven
   times in 358px. The selected chip stops flexing equally and takes the width the word needs. */
.dchip-d{display:none;font-size:var(--fs-md);font-weight:var(--fw-b);color:var(--navy);line-height:1.1;white-space:nowrap}
.dchip.on{flex:0 0 auto;padding-left:var(--s3);padding-right:var(--s3)}
.dchip.on .dchip-n{display:none}
.dchip.on .dchip-d{display:block;color:#fff}
/* the workload per day — only the desktop rail has room for it */
.dchip-m{display:none;font-size:var(--fs-sm);font-weight:500;color:var(--ink-muted)}
.dchip-s{height:10px;display:flex;align-items:center;justify-content:center}
.dchip-dot{width:5px;height:5px;border-radius:var(--r-pill);background:var(--sky);display:block}
/* done = green tick, today = a dot, selected = the brand ring. A day can be both. */
.dchip.done{background:var(--green-bg);border-color:#CFEEDF}
.dchip.done .dchip-n{color:var(--green)}
.dchip.done .dchip-s{background:var(--success);width:14px;height:14px;border-radius:var(--r-pill)}
.dchip.on{border-color:transparent;background:linear-gradient(160deg,var(--sky),var(--brand-blue));box-shadow:0 10px 20px -10px rgba(46,107,255,.8)}
.dchip.on .dchip-l,.dchip.on .dchip-n{color:#fff}
.dchip.on .dchip-dot{background:#fff}
.dchip.on.done .dchip-s{background:rgba(255,255,255,.28)}

/* ── each day's section (all 7 are in the scroll; the bar tracks which you're on) ── */
.dsec{padding:0 var(--s4) var(--s5)}
.dsec+.dsec{border-top:1px solid var(--line);padding-top:var(--s5)}
/* DAY: the outermost level, so it is the loudest line on the screen — but it is only ever two
   words, because Raj cut the theme and both progress counters off it. */
.dsec-d{font-size:var(--fs-lg);font-weight:800;letter-spacing:-.3px;color:var(--navy)}
.dsec-h{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s3);margin-bottom:var(--s4)}
/* .dsec-tag (the "AAJ" / "Poora hua" / "Ruka hua" pill) is gone — Raj, 2026-07-17: "remove that
   AAJ tag". Today is already dotted in the day bar and named by the header; the pill was a third
   telling. The `waiting` day still gets its amber note, which says something the pill could not. */
.chip{font-size:var(--fs-sm);font-weight:var(--fw-b);letter-spacing:.4px;text-transform:uppercase;padding:var(--s1) var(--s2);border-radius:var(--r-pill);white-space:nowrap;flex-shrink:0}

/* ── "download my plan" ── */
.dlbtn{display:flex;width:100%;align-items:center;justify-content:center;gap:var(--s2);background:#fff;border:1.5px solid var(--line2);border-radius:var(--r-md);padding:var(--s4);font-family:inherit;font-size:var(--fs-md);font-weight:var(--fw-b);color:var(--navy);cursor:pointer;transition:all .18s var(--ease)}
.dlbtn:hover{border-color:var(--brand-blue);color:var(--brand-blue);background:#F6F9FF}
.dlbtn:active{transform:scale(.98)}

/* ── plan: video / QBank cards ──
   Relationship spacing (Tim): the video and its test are ONE topic, so 6px inside the pair and

/* ── Q3: the hours picker. These styles were deleted when Q3 was cut in an earlier round and
   have to come back with it — the CTA fix above exposed that they were gone. ── */
.est{border-radius:var(--r-md);padding:var(--s4);margin-top:var(--s5);text-align:center;transition:background .35s var(--ease)}
.hrs{display:flex;gap:var(--s2);margin-top:var(--s5);overflow-x:auto;padding:var(--s3) var(--s1) var(--s2);align-items:center}
.hrs::-webkit-scrollbar{display:none}.hrs{scrollbar-width:none}
/* flex:1 1 0 let five chips squeeze themselves down to whatever was left, so the scroller could
   never actually scroll. Fixed-width chips keep their size and the row scrolls when it has to —
   which is what makes "scroll horizontally or tap" (Raj) true rather than nominal. At 358px all
   five still fit, so on a normal phone it is a tap; on a 320px screen it becomes a scroll. */
.hr{flex:0 0 auto;min-width:58px;background:transparent;border:1.5px solid transparent;font-family:inherit;cursor:pointer;text-align:center;padding:var(--s3) var(--s2);border-radius:var(--r-sm);transition:all .25s var(--spring);opacity:.55}
.hr b{display:block;font-size:var(--fs-lg);font-weight:var(--fw-b);color:var(--navy);line-height:1}
.hr span{display:block;font-size:var(--fs-sm);font-weight:500;color:var(--ink-muted);margin-top:2px}
.hr:hover{opacity:.85}
.hr.on{opacity:1;background:#fff;border-color:var(--line2);box-shadow:0 12px 26px -14px rgba(19,27,99,.5)}

/* ── Q2: the subject multi-select that builds the plan ── */
.subs{display:flex;flex-wrap:wrap;gap:8px;margin-top:var(--s5)}
/* ── the subject CHIPS (Raj, 2026-07-17: "fix the UI, the UI is very bad") ─────────────
   This went 58px rows -> 34px rows -> chips. Rows were the wrong shape for the question: twelve
   near-identical full-width bars is a list to read, and picking 3-5 out of 12 is a thing you want
   to SEE at once. Pills wrap two or three to a line, the picked ones are unmistakable, and the
   whole question is now a few rows tall.
   The tick sits INSIDE the chip and only exists when picked, so an unpicked pill is just a word —
   twelve empty checkboxes were twelve pieces of furniture saying nothing. */
.sub{display:inline-flex;align-items:center;gap:6px;width:auto;background:#fff;border:1.5px solid var(--line2);
  border-radius:var(--r-pill);padding:9px 13px;font-family:inherit;text-align:left;cursor:pointer;
  transition:all .16s var(--ease)}
.sub:hover{border-color:#C9D6EC;transform:translateY(-1px)}
.sub:active{transform:scale(.97)}
/* picked = a solid brand fill. White-on-brand-blue is 4.6:1 — above the AA floor, unlike
   white-on-sky (1.97:1) which this project has banned once already. */
.sub.on{border-color:transparent;background:var(--brand-blue);box-shadow:0 8px 18px -8px rgba(46,107,255,.7)}
.sub.on .sub-n{color:#fff}
.sub-cb{width:14px;height:14px;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:#fff}
.sub-n{font-size:var(--fs-md);font-weight:var(--fw-b);color:var(--navy);line-height:1.25;white-space:nowrap}
/* ── the 5-subject ceiling, made visible (Raj, 2026-07-17) ─────────────────────
   At the cap the unpicked chips go quiet. Deliberately NOT opacity on the whole chip: that would
   drag the subject name under the 4.5:1 contrast floor and make the list unreadable rather than
   unavailable. The fill and the border recede; the words stay legible, because a student has to
   be able to read what she is choosing between in order to trade one out. */
.sub.full{background:#F1F4F9;border-color:transparent;box-shadow:none}
.sub.full:hover{transform:none;border-color:transparent}
.sub.full .sub-n{color:var(--ink-soft)}
/* sticky, because the whole point is that it is readable while the list is being scrolled past.
   The paper wash + blur is the same treatment .thd uses when it pins, so a pinned thing looks
   like a pinned thing everywhere in this app. */
.subs-h{position:sticky;top:0;z-index:6;display:flex;align-items:center;justify-content:flex-end;
  margin:var(--s4) calc(-1 * var(--s5)) 6px;padding:6px var(--s5);
  background:rgba(247,249,253,.94);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.subs-c{font-size:var(--fs-sm);font-weight:800;color:var(--ink-muted);background:#fff;border:1px solid var(--line);border-radius:var(--r-pill);padding:3px 10px;transition:all .18s var(--ease)}
.subs-c.full{background:var(--brand-blue);border-color:transparent;color:#fff}
.subs-h+.subs{margin-top:0}

/* ── the "building your plan" loader ── */
.bld{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0 var(--s5);background:linear-gradient(180deg,#EAF7FD 0%,#F7FBFE 46%,#FFFFFF 100%)}
.bld-ring{position:relative;width:64px;height:64px;margin-bottom:var(--s5)}
.bld-ring svg{width:64px;height:64px;transform:rotate(-90deg)}
.bld-trk{fill:none;stroke:#D7EDF7;stroke-width:3}
.bld-arc{fill:none;stroke:var(--sky);stroke-width:3;stroke-linecap:round;stroke-dasharray:38 82;animation:bspin 1.1s linear infinite;transform-origin:center}
@keyframes bspin{to{transform:rotate(360deg)}}
.bld-em{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:24px}
.bld-h{font-size:var(--fs-xl);font-weight:var(--fw-b);color:var(--navy);text-align:center}
.bld-s{font-size:var(--fs-md);color:var(--ink-muted);font-weight:500;margin-top:var(--s1);text-align:center}
.bld-bar{width:100%;max-width:250px;height:4px;border-radius:var(--r-pill);background:#DDE7F3;overflow:hidden;margin:var(--s5) 0 var(--s5)}
.bld-bar i{display:block;height:100%;width:4%;border-radius:var(--r-pill);background:linear-gradient(90deg,var(--sky),var(--brand-blue))}
.bld-l{width:100%;max-width:290px;display:flex;flex-direction:column;gap:var(--s2)}
/* rows start invisible and stay put once ticked — the screen accumulates, it doesn't flicker */
.bld-row{display:flex;align-items:center;gap:var(--s3);background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);padding:var(--s3);opacity:0;transform:translateY(8px);transition:opacity .4s var(--ease),transform .4s var(--ease),border-color .3s var(--ease)}
.bld-row.in,.bld-row.ok{opacity:1;transform:none}
.bld-row.ok{border-color:#CFEEDF;background:#FBFFFD}
.bld-ic{width:26px;height:26px;border-radius:8px;background:var(--ice);display:flex;align-items:center;justify-content:center;font-size:13px;flex-shrink:0}
.bld-x{flex:1;min-width:0}
.bld-t{font-size:var(--fs-sm);font-weight:var(--fw-b);color:var(--navy);line-height:1.3}
.bld-m{font-size:10px;color:var(--ink-muted);font-weight:500;margin-top:1px}
.bld-st{width:18px;height:18px;flex-shrink:0;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:background .3s var(--ease)}
.bld-row.ok .bld-st{background:var(--success)}
.bld-sp{width:12px;height:12px;border-radius:50%;border:2px solid #DDE7F3;border-top-color:var(--sky);animation:bspin .7s linear infinite}
.bld-row.ok .bld-sp{display:none}

/* ── each topic: a STICKY heading over its videos + test ──
   Raj: "as soon as I scroll, that specific topic heading should stick, and as soon as I scroll
   the next one should stick." Sticky at top:0 inside #planScroll — each .thd pins while its
   topic is on screen and is pushed off by the next one, so you always know which topic you are
   looking at without a label on every card. */
.tgrp{margin-bottom:var(--s5)}
/* ── the workload rollup (Raj, 2026-07-17) ────────────────────────────────────
   "{V} min video · {Q} Ques · ~{T} min total" — the same string under the day's subjects and
   under each topic, because it is the same kind of number at a different radius.
   ink-muted, not ink-soft: this repeats ~14 times down one scroll and must stay quiet. It is
   still 5.0:1 on paper, i.e. above the 4.5:1 AA floor for body text — the point is to be
   secondary to the topic title, not unreadable in sunlight on a low-end panel. */
.rollup{font-size:var(--fs-sm);font-weight:600;color:var(--ink-muted)}
.rollup[data-lvl="day"]{margin-top:3px}
.rollup[data-lvl="topic"]{margin:5px 0 9px}
.thd{position:sticky;top:0;z-index:12;display:flex;align-items:center;gap:var(--s3);
  background:rgba(247,249,253,.94);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  padding:var(--s3) var(--s4);margin:0 calc(-1 * var(--s4));border-bottom:1px solid var(--line)}
.thd-x{flex:1;min-width:0}
/* ── the three levels, told apart by treatment and not by the reader's patience ──────
   SUBJECT (chapter): small, uppercase, tracked, brand blue. Nothing else on the plan looks
   like this, so "that blue caps line is the chapter" is learnable in one glance.
   TOPIC: the biggest thing in the group, navy, sentence case. */
.thd-s{font-size:9.5px;font-weight:800;letter-spacing:.9px;text-transform:uppercase;color:var(--brand-blue);margin-bottom:1px}
.thd-t{font-size:var(--fs-md);font-weight:var(--fw-b);color:var(--navy);line-height:1.3}
.thd.done .thd-t{color:var(--green)}
.thd.done .thd-s{color:var(--green);opacity:.75}
.thd-ck{width:18px;height:18px;border-radius:var(--r-pill);background:var(--success);display:flex;align-items:center;justify-content:center;flex-shrink:0}
/* CONTENTS: roped to their topic by a rule down the left edge. This is the answer to "what are
   the contents in those topics" — the rule says these cards hang off the heading above, and it
   ends where the topic ends. Every card sits at the SAME indent: the videos and the test are
   siblings under the topic, so nothing may look subordinate to the card above it. */
.tbody{padding-top:var(--s3);padding-left:var(--s3);margin-left:3px;border-left:2px solid var(--line)}
/* the always-there way in: subtle, round, quiet — never competing with the one labelled button */
.pc-go{width:26px;height:26px;border-radius:var(--r-pill);background:var(--ice);color:var(--brand-blue);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .18s var(--ease)}
.pcard[data-action]:hover .pc-go{background:var(--brand-blue);color:#fff}
.pc-go.off{background:#EDF0F6;color:#AEB6C8}

/* ── "download my plan" ── */
.dlbtn{display:flex;width:100%;align-items:center;justify-content:center;gap:var(--s2);background:#fff;border:1.5px solid var(--line2);border-radius:var(--r-md);padding:var(--s4);font-family:inherit;font-size:var(--fs-md);font-weight:var(--fw-b);color:var(--navy);cursor:pointer;transition:all .18s var(--ease)}
.dlbtn:hover{border-color:var(--brand-blue);color:var(--brand-blue);background:#F6F9FF}
.dlbtn:active{transform:scale(.98)}

/* ── plan: video / QBank cards ──
   Relationship spacing (Tim): the video and its test are ONE topic, so 6px inside the pair and
   24px between pairs — a 4x ratio the eye reads as grouping without needing a "TOPIC 1 OF 3"
   label to explain it. The test also sits slightly inset, so the pair reads parent -> child. */
.pcard{background:#fff;border:1px solid var(--line2);border-radius:var(--r-md);padding:var(--s4);margin-bottom:6px;box-shadow:0 1px 2px rgba(19,27,99,.04);transition:transform .18s var(--ease),box-shadow .18s var(--ease),border-color .18s var(--ease)}
/* No indent between items: a topic's videos and its test are SIBLINGS under the topic heading,
   and indenting everything after the first made video 2 look subordinate to video 1. The sticky
   heading is what groups them now, so the indent has nothing left to say. */
.tgrp .pcard:last-child{margin-bottom:0}
.pcard[data-action]:hover{transform:translateY(-2px);box-shadow:0 14px 28px -16px rgba(19,27,99,.4);border-color:#D8E4F5}
.pcard.done{background:var(--green-bg);border-color:#CFEEDF;box-shadow:none}
.pcard.wait{background:#F3F5FA;border-color:transparent;box-shadow:none}
.pcard.wait .pc-t,.pcard.wait .pc-m{color:var(--ink-muted)}
.pc-top{display:flex;align-items:center;gap:var(--s3)}
.pc-ic{width:44px;height:44px;border-radius:var(--r-sm);background:#EDF3FE;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.pcard.done .pc-ic{background:#DAF2E6}
.pcard.wait .pc-ic{background:#E7EAF2}
.pc-tx{flex:1;min-width:0}
.pc-t{font-size:var(--fs-md);font-weight:var(--fw-b);color:var(--navy);line-height:1.35}
.pc-m{font-size:var(--fs-sm);font-weight:var(--fw-m);color:var(--ink-muted);margin-top:2px}
.pc-bd{width:24px;height:24px;border-radius:var(--r-pill);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.pc-bd.pause{background:var(--amber-bg)}
.pc-bd.check{background:var(--green)}
.pbar{height:4px;border-radius:var(--r-pill);background:#E7ECF5;overflow:hidden;margin-top:var(--s3)}
.pbar i{display:block;height:100%;border-radius:var(--r-pill);background:var(--green);transition:width .5s var(--ease)}
.pbtn{display:flex;width:100%;align-items:center;justify-content:center;gap:var(--s2);background:var(--brand-blue);color:#fff;border:none;border-radius:var(--r-sm);padding:var(--s3);margin-top:var(--s3);font-family:inherit;font-size:var(--fs-md);font-weight:var(--fw-b);cursor:pointer;box-shadow:0 10px 20px -10px rgba(46,107,255,.7);transition:transform .16s var(--ease)}
.pbtn:active{transform:scale(.97)}
.note{border-radius:var(--r-md);padding:var(--s3) var(--s4);margin:0 var(--s4) var(--s3)}

/* ── embed mode (?embed=1): running inside the stitched overlay, the iframe IS the phone
   viewport — drop our own bezel, rail, caption and PM panel and fill the frame. The rail
   still exists in the DOM (hidden) so syncRail()/setSeg() keep working unchanged; the
   outer merged rail drives it over postMessage. ── */
body.embed{background:#fff!important;display:block;min-height:0}
body.embed #stage{display:block;padding:0;min-height:0;gap:0}
body.embed #rail,body.embed #cap,body.embed #pmpanel{display:none!important}
body.embed #device{width:100%;position:static}
body.embed .phone{width:100%;height:100vh;border-radius:0;padding:0;box-shadow:none;background:transparent}
body.embed .phone .notch{display:none}
body.embed .viewport{border-radius:0;height:100vh;width:100%}

/* ── bare mode (?bare=1): running in a REAL mobile browser (m.html), not in a mock phone.
   Same reasoning as `body.embed .phone .notch` right above — the real device already
   supplies this furniture, so drawing our own is a mock of a mock. Here that is the fake
   "9:41 / signal / battery" bar: on a real phone it lands directly under the actual status
   bar, forever reading 9:41 next to the real time. The device gives us the top of the
   screen back, so the app takes it. ── */
body.bare .sbar{display:none}

/* ════════════════════════════════════════════════════════════════════════
   DESKTOP APP (?desk=1) — the d.html view
   Raj, 2026-07-17: "I do not see any difference between the mobile and the desktop version.
   Desktop version should look like the desktop version."
   He was right: the last one was the same 375px app in a device frame. This is a real
   workspace — the plan becomes two panes (a vertical day rail + a wide content column), the
   questions become a centred card with the 12 subjects in a grid, and the type steps up.
   All of it is scoped to body.desk / #screen[data-s=...], so the phone views cannot regress:
   nothing below changes a single existing selector.
   ════════════════════════════════════════════════════════════════════════ */
body.desk .sbar{display:none}          /* a desktop browser draws its own chrome */
body.desk{
  /* the same FOUR tokens, stepped up — a desktop app is read further from the eye. Bumping the
     scale rather than adding sizes keeps the type system at 4 (Tim's ceiling). */
  --fs-xl:30px; --fs-lg:19px; --fs-md:14px; --fs-sm:12px;
  background:var(--paper)!important;
}
body.desk #device{width:100%;position:static}
body.desk .phone{width:100%;height:100vh;height:100dvh;border-radius:0;padding:0;box-shadow:none;background:transparent}
body.desk .phone .notch{display:none}
body.desk .viewport{border-radius:0;width:100%;height:100vh;height:100dvh;background:var(--paper)}

/* ── every screen: stop the phone-width layouts stretching to 1440 ───────── */
body.desk .body{padding:var(--s6) var(--s5) var(--s7)}
body.desk .topbar{padding:var(--s4) var(--s5)}
body.desk #screen[data-s="setup"] .body > *,
body.desk #screen[data-s="plan-intro"] .body > *{max-width:760px;margin-left:auto;margin-right:auto}
body.desk #screen[data-s="setup"] .topbar{max-width:760px;margin:0 auto;width:100%}
body.desk #screen[data-s="setup"] .scr > div:last-child{max-width:760px;margin:0 auto;width:100%}

/* Q2's twelve subjects: one column of twelve is a phone answer. On a desktop that is a scroll
   for something that fits on one screen — the whole question is "compare and pick". */
/* Chips wrap by themselves, so desktop needs no grid — it just gets more of them per line in a
   wider container. The 3-column grid this used to force is what made the phone and the desktop
   two different layouts of the same question. */
body.desk .sub{padding:10px 15px}
body.desk .opts{gap:var(--s3)}
body.desk .hrs{justify-content:flex-start;gap:var(--s3)}
body.desk .cta{max-width:340px;margin:0 auto;display:block}

/* ── plan-intro: the desktop app's front door ────────────────────────────── */
.intro{display:flex;flex-direction:column;justify-content:center;gap:var(--s6)}
.intro-hero{text-align:center}
/* the eyebrow replaced the gradient emoji tile: Raj's copy leads with a label, and a 78px tile
   above it would have made the label the third thing on a screen whose first line IS the label */
.intro-eb{font-size:11px;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;color:var(--brand-blue);margin-bottom:var(--s3);animation:syUp .5s var(--ease) both}
.intro-why{display:flex;flex-direction:column;gap:var(--s2);background:#fff;
  border:1px solid #DCE7F7;border-radius:var(--r-md);padding:6px;
  box-shadow:0 16px 34px -20px rgba(19,27,99,.55);animation:syUp .5s var(--ease) .18s both}
@keyframes syUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.iw{display:flex;align-items:flex-start;gap:10px;padding:9px 8px;border-radius:10px}
.iw-i{width:26px;height:26px;flex-shrink:0;border-radius:var(--r-pill);background:var(--ice);
  display:flex;align-items:center;justify-content:center;font-size:13px}
.iw-x{min-width:0}
.iw-t{font-size:var(--fs-md);font-weight:var(--fw-b);color:var(--navy)}
.iw-s{font-size:var(--fs-sm);font-weight:500;color:var(--ink-muted);margin-top:1px}
.intro-foot{width:100%}
body.desk .intro{gap:var(--s7)}
body.desk .intro-why{flex-direction:row;padding:var(--s3)}     /* three reasons across, not down */
body.desk .iw{flex:1 1 0;flex-direction:column;align-items:flex-start;gap:var(--s3);padding:var(--s4)}
body.desk .iw-i{width:40px;height:40px;font-size:18px;border-radius:var(--r-sm)}

/* ── plan-path: the two-pane workspace ───────────────────────────────────── */
body.desk #screen[data-s="plan-path"] .scr{
  display:grid;height:100%;
  grid-template-columns:280px minmax(0,1fr);
  grid-template-rows:auto minmax(0,1fr);
  grid-template-areas:"hd hd" "bar main";
}
body.desk #screen[data-s="plan-path"] .plan-hd{
  grid-area:hd;padding:var(--s4) var(--s5);border-bottom:1px solid var(--line);background:#fff;
}
/* the day bar turns 90°: seven equal chips across becomes a rail you can read */
body.desk #screen[data-s="plan-path"] .dbar{
  grid-area:bar;flex-direction:column;gap:var(--s2);align-items:stretch;
  padding:var(--s4);border-bottom:none;border-right:1px solid var(--line);
  overflow-y:auto;background:#fff;
}
/* The vertical rail names EVERY day and prices it — it has the room the phone bar does not, and a
   rail of bare numbers would be a worse sidebar than a worse day bar. (It used to name each day
   by its subject mix; Raj cut those names, so the honest label is the day and its workload.) */
body.desk .dchip{
  flex:0 0 auto;flex-direction:column;align-items:flex-start;justify-content:center;
  gap:2px;padding:var(--s3) var(--s4);text-align:left;position:relative;
}
body.desk .dchip-n{display:none}
body.desk .dchip-d{display:block}
body.desk .dchip.on{padding:var(--s3) var(--s4)}
body.desk .dchip.done .dchip-d{color:var(--green)}
body.desk .dchip-m{display:block}
body.desk .dchip.on .dchip-m{color:rgba(255,255,255,.85)}
body.desk .dchip-s{position:absolute;right:var(--s4);top:50%;transform:translateY(-50%)}

body.desk #screen[data-s="plan-path"] #planScroll{grid-area:main;padding:var(--s5) 0 var(--s7)}
body.desk .dsec{max-width:900px;margin:0 auto;padding:0 var(--s5) var(--s6)}
body.desk .dsec+.dsec{padding-top:var(--s6)}
/* the sticky heading bleeds edge-to-edge on the phone; inside a 900px column it should not */
body.desk .thd{margin:0;padding:var(--s3) 0;background:rgba(247,249,253,.94)}
/* a topic's videos sit side by side — the one screen where desktop width buys something real */
body.desk .tbody{display:grid;grid-template-columns:1fr 1fr;gap:var(--s3);align-items:start}
body.desk .pcard{margin-bottom:0}
body.desk .rollup[data-lvl="topic"]{margin:5px 0 var(--s3)}
/* there is no home to go to in the desktop app — the plan IS the app */
body.desk [data-action="go-home"]{display:none}

/* Below ~900px a two-pane workspace has nothing to stand on. Hand back to the single column the
   phone views use — same reason d.html itself falls back to full-bleed. */
@media (max-width:900px){
  body.desk #screen[data-s="plan-path"] .scr{display:flex;flex-direction:column}
  body.desk #screen[data-s="plan-path"] .dbar{flex-direction:row;border-right:none;
    border-bottom:1px solid var(--line);overflow-x:auto}
  /* the rail is a horizontal bar again, so it plays by the phone's rules: bare numbers, and only
     the selected chip spells the word. Seven "Day N"s and seven durations do not fit a bar. */
  body.desk .dchip{flex:1 1 0;flex-direction:column;align-items:center;justify-content:center;padding:var(--s2) 0 6px}
  body.desk .dchip-n{display:block}
  body.desk .dchip-m{display:none}
  body.desk .dchip-d{display:none}
  body.desk .dchip.on{flex:0 0 auto;padding:var(--s2) var(--s3) 6px}
  body.desk .dchip.on .dchip-n{display:none}
  body.desk .dchip.on .dchip-d{display:block}
  body.desk .dchip-s{position:static;transform:none}
  body.desk .subs,body.desk .tbody{grid-template-columns:1fr}
  body.desk .intro-why{flex-direction:column}
  body.desk .iw{flex-direction:row;align-items:flex-start}
}

/* ── PM notes live OUTSIDE the phone now — they were clutter inside it ── */
#pmpanel{width:393px;margin-top:var(--s7);background:#fff;border:1px dashed #C5CBE6;border-radius:var(--r-md);padding:var(--s4);opacity:0;transform:translateY(6px);transition:all .35s var(--ease)}
#pmpanel.show{opacity:1;transform:none}
#pmpanel .h{display:flex;align-items:center;gap:var(--s2);font-size:9px;font-weight:800;letter-spacing:1px;color:var(--ink-muted);text-transform:uppercase;margin-bottom:var(--s2)}
#pmpanel .h i{width:14px;height:14px;border-radius:4px;background:var(--navy);color:#fff;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-style:normal}
#pmpanel .b{font-size:12px;color:var(--ink-soft);line-height:1.6}
#pmpanel .b b{color:var(--navy)}
