/* ---------- Layout ---------- */
.app{display:flex;min-height:100vh}
.rail{
  width:238px;flex-shrink:0;background:var(--rail);color:var(--rail-text);
  display:flex;flex-direction:column;position:sticky;top:0;height:100vh;overflow-y:auto;
  border-right:3px solid #150f33;
}
.rail-head{padding:var(--s-9) var(--s-8) var(--s-6)}
.logo{display:flex;align-items:center;gap:9px;color:#fff;font-weight:900;letter-spacing:-.03em;font-size:var(--fs-lg)}
/* THE MARK IS THE MEDALLION — `Design\Images\Icons\Herophilus 3.png`, the user's choice
   on 2026-07-28, cut to a transparent circle in assets\icon-96.png.

   It replaced a rod-of-Asclepius glyph on a coral→gold gradient square, rotated
   -6deg. None of that survives, and deliberately: the medallion is ALREADY a
   navy disc with its own gold rule, so a coloured tile behind it reads as two
   badges stacked, and rotating a circular seal only tilts the wordmark inside
   it. Every mark below is therefore transparent-backed, unrotated and round.

   Referenced by path, not inlined. `<img src>` is not CORS-restricted the way a
   font or an ES module is, so a relative path works from file:// — inlining
   these would have added ~24 KB of base64 to the shell for nothing. The FAVICON
   is the one that still has to be inlined; see <head>. */
/* The hairline is not decoration. The medallion's ground is navy and the rail is
   near-black (--rail:#080d14), so at 32px the disc reads as a dark blob with no
   edge. A gold ring at 40% separates it and echoes the rule already drawn inside
   the medallion. Checked by rasterising the rail at 1:1, not by eye in source. */
.logo .blip{
  width:32px;height:32px;border-radius:50%;overflow:hidden;
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
  box-shadow:0 0 0 1px rgba(217,180,74,.4),0 4px 12px rgba(0,0,0,.45);
}
.blip img,.gmark img{width:100%;height:100%;display:block;border-radius:50%}
.rail-sub{font-size:var(--fs-xs);color:var(--rail-dim);margin-top:4px;letter-spacing:.09em;text-transform:uppercase;font-weight:700}

.streak{
  margin:8px 12px 4px;padding:var(--s-5) var(--s-6);border-radius:var(--r-lg);
  background:linear-gradient(135deg,rgba(255,201,74,.16),rgba(255,90,95,.13));
  border:1.5px solid rgba(255,201,74,.3);display:flex;align-items:center;gap:9px;
}
.streak .fl{font-size:var(--fs-body)}
.streak .n{color:#ffd977;font-weight:900;font-size:var(--fs-body);line-height:1}
.streak .t{font-size:var(--fs-xs);color:var(--rail-dim);line-height:1.25;font-weight:600}

.nav{padding:var(--s-3) var(--s-5) var(--s-9);flex:1}
.nav-label{font-size:var(--fs-xs);letter-spacing:.13em;text-transform:uppercase;color:var(--rail-dim);padding:var(--s-7) var(--s-4) var(--s-3);font-weight:800}
.nav-item{
  display:flex;align-items:center;gap:10px;width:100%;text-align:left;
  padding:var(--s-4) var(--s-5);border-radius:var(--r-lg);color:var(--rail-text);font-size:var(--fs-ui);font-weight:600;
  transition:transform var(--dur-2) ease,background var(--dur-2),color var(--dur-2);
}
.nav-item:hover{background:var(--rail-2);color:#fff}
.nav-item.on{background:var(--rail-3);color:#fff;font-weight:800;box-shadow:inset 3px 0 0 var(--gold)}
.nav-item .ic{width:19px;text-align:center;flex-shrink:0;font-size:var(--fs-ui)}
.nav-item .cnt{margin-left:auto;font-size:var(--fs-xs);color:var(--rail-dim);font-variant-numeric:tabular-nums;font-weight:700}
.nav-item.on .cnt{color:var(--rail-text)}
.badge-due{
  margin-left:auto;background:var(--ent);color:#fff;font-size:var(--fs-xs);font-weight:900;
  padding:var(--s-1) var(--s-3);border-radius:var(--r-lg);min-width:20px;text-align:center;
  box-shadow:0 0 0 3px rgba(255,90,95,.2);
}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{
  display:flex;align-items:center;gap:14px;padding:var(--s-6) var(--s-10);
  border-bottom:1px solid var(--line);background:var(--glass-2);
  position:sticky;top:0;z-index:20;backdrop-filter:blur(10px);
}
.search-wrap{position:relative;flex:1;max-width:440px}
.search{
  width:100%;padding:var(--s-4) var(--s-6) var(--s-4) 35px;border:2px solid var(--line-2);border-radius:var(--r-lg);
  background:var(--card);font-size:var(--fs-ui);color:var(--tx);font-weight:600;transition:box-shadow var(--dur-3),border-color var(--dur-3);
}
.search:focus{border-color:var(--neuro);box-shadow:var(--pop) rgba(125,88,144,.35);outline:none}
.search::placeholder{color:var(--ink-4);font-weight:500}
.keyin{
  width:100%;padding:var(--s-4) var(--s-6);border:2px solid var(--line-2);border-radius:var(--r-lg);
  background:var(--card);font-size:var(--fs-ui);color:var(--tx);font-weight:600;transition:box-shadow var(--dur-3),border-color var(--dur-3);
}
.keyin:focus{border-color:var(--neuro);box-shadow:var(--pop) rgba(125,88,144,.35);outline:none}
.keyin::placeholder{color:var(--ink-4);font-weight:500}
.search-ic{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:var(--fs-ui);pointer-events:none}
.results{
  position:absolute;top:calc(100% + 7px);left:0;right:0;background:var(--card);
  border:2px solid var(--line-2);border-radius:var(--r-lg);box-shadow:var(--pop-lg) var(--sh);
  max-height:380px;overflow-y:auto;z-index:40;display:none;
}
.results.show{display:block}
.res-item{display:block;width:100%;padding:var(--s-5) var(--s-7);border:0;border-bottom:1.5px solid var(--line);border-radius:0;cursor:pointer;font-size:var(--fs-md);color:inherit;text-align:left;background:none}
.res-item:last-child{border-bottom:none}
.res-item:hover{background:var(--bg-2)}
/* A button inside a listbox needs a focus ring the cursor cannot miss — the
   results list lives at the top of the screen, the items are dense, and the
   ring is the only signal that the next Enter is going somewhere real. */
.res-item:focus{outline:none;background:var(--bg-2);box-shadow:inset 3px 0 0 var(--neuro)}
.res-item.res-more{font-weight:700;color:var(--ink-3)}
.res-tag{display:block;font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.08em;font-weight:900;margin-bottom:3px}
.res-txt{display:block;color:var(--ink-2);line-height:1.45}
.res-empty{padding:var(--s-8) var(--s-7);color:var(--ink-4);font-size:var(--fs-md)}

.topbar-actions{margin-left:auto;display:flex;gap:7px;align-items:center}
/* On a narrow phone the topbar's fixed furniture leaves the search box 121px
   wide, of which 73px is text room: measured at 360px, and no useful
   placeholder fits in it — even "Search questions" needs 91px. The button
   that goes is the keyboard-shortcuts one, because a device with no keyboard
   cannot press anything the dialog lists; it is the only control here that is
   not merely cramped but meaningless. That returns 48px to the search. */
@media(max-width:520px){ .kbd-btn{display:none} }
.tb-btn{padding:var(--s-3) var(--s-6);border-radius:var(--r-lg);font-size:var(--fs-md);color:var(--ink-3);font-weight:700;transition:background var(--dur-2),transform var(--dur-2)}
.tb-btn:hover{background:var(--bg-2);color:var(--tx)}
/* Touch. The nav rows are 36px tall and the topbar buttons 33-36px, both under
   the 44px minimum. The nav is a vertical list, so it can simply grow. The
   topbar cannot: four 44px buttons would push a sticky bar to ~70px and take
   that height off every screen, so those get an invisible 44px hit area
   centred on the button instead and the bar keeps its size. The 14px gap
   between them is wider than the 3px each overlay adds, so they do not
   overlap — two overlapping targets only move the mis-tap elsewhere. */
@media(hover:none){
  .nav-item{min-height:44px}
  .tb-btn{position:relative}
  .tb-btn::after{
    content:"";position:absolute;left:50%;top:50%;width:100%;height:44px;
    min-width:44px;transform:translate(-50%,-50%);
  }
}

/* The saving warning is inserted as a sibling of .page rather than inside it,
   because the page is rebuilt on every answer and the notice must outlive that.
   Living outside the column, it has to restate the column's own width or it
   would run edge to edge while everything below it stays inset: 1124px is the
   page's 1180px capped column less its 28px of padding on either side, so the
   notice lines up with the heading underneath it rather than overhanging it. */
#saveWarning, #dataWarning{
  max-width:1124px;width:calc(100% - 56px);margin:22px auto -6px;padding:var(--s-8) var(--s-8);
  border:1px solid var(--bad);border-radius:var(--r-lg);background:var(--bad-bg);
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
}
#saveWarning p, #dataWarning p{margin:0;flex:1;min-width:260px;font-size:var(--fs-ui);line-height:1.55;color:var(--tx)}
#saveWarning strong, #dataWarning strong{color:var(--bad)}
#saveWarning .btn, #dataWarning .btn{flex:none}
#saveWarning .warnico, #dataWarning .warnico{flex:none;font-size:var(--fs-lg);font-weight:900;color:var(--bad)}
.page{padding:var(--s-11);max-width:1180px;width:100%;margin:0 auto;flex:1}
/* The dashboard is narrower than every other view, and deliberately so. Module
   cards are capped at two per row so the artwork is worth showing, which puts
   the grid's right edge at 880px — and against a 1180px column that left a
   244px hole down the right of the page that nothing filled and nothing
   explained. Everything on this view now ends at the same place: 880px of
   content plus the page's own 28px either side. Only this view moves; the
   reader, the quiz and the theory pages keep the wider measure they were set
   in. Scoped to screen so the print block's max-width still wins on paper. */
@media screen{body[data-view="home"] .page{max-width:936px}}
/* The dashboard narrows, so the notice above it narrows by the same amount,
   or it would hang past both edges of the only content on that screen. */
@media screen{body[data-view="home"] #saveWarning, body[data-view="home"] #dataWarning{max-width:880px}}

/* ---------- Type ---------- */
/* Display type is carved, not set: Roman capitals, letter-spaced OUT rather than
   in. The old -.035em tracking is wrong for capitals — it jams them together. */
h1{font-family:var(--font-display);font-size:var(--fs-2xl);font-weight:700;letter-spacing:.02em;
   margin:0 0 5px;line-height:1.18;text-transform:uppercase}
h2{font-size:var(--fs-lg);font-weight:800;letter-spacing:-.02em;margin:0 0 13px}
.page-sub{color:var(--ink-3);font-size:var(--fs-ui);margin:0 0 26px;font-weight:500;max-width:640px;line-height:1.55}
.eyebrow{
  display:inline-block;font-size:var(--fs-xs);letter-spacing:.13em;text-transform:uppercase;font-weight:900;
  padding:var(--s-2) var(--s-5);border-radius:var(--r-lg);background:var(--fill);color:#fff;margin-bottom:11px;
}

/* ---------- Cards ---------- */
.grid{display:grid;gap:15px}
.g3{grid-template-columns:repeat(auto-fill,minmax(258px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(158px,1fr))}
.card{
  background:var(--card);border:1px solid var(--neon);border-radius:var(--r-lg);
  padding:var(--s-8);text-align:left;width:100%;box-shadow:var(--neon-glow);
  transition:border-color .15s var(--ease-standard),background-color .15s var(--ease-standard),box-shadow .15s var(--ease-standard);
}
button.card:hover:not(:disabled){border-color:var(--gold);background-color:var(--bg-2);box-shadow:var(--gold-glow)}
button.card:active:not(:disabled){border-color:var(--gold)}

.mod-card{position:relative;overflow:hidden}
.mod-card::after{
  content:"";position:absolute;right:-24px;top:-24px;width:74px;height:74px;border-radius:50%;
  background:var(--c);opacity:.11;
}
.mod-top{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.mod-ic{
  width:36px;height:36px;border-radius:var(--r-lg);background:var(--c);display:flex;align-items:center;
  justify-content:center;font-size:var(--fs-lg);flex-shrink:0;box-shadow:0 5px 14px rgba(0,0,0,.2);
}
.mod-name{font-weight:700;font-size:var(--fs-body);letter-spacing:.045em}
.mod-meta{font-size:var(--fs-sm);color:var(--ink-3);margin-bottom:13px;font-weight:600}

.ringrow{display:flex;align-items:center;gap:13px}
.ring{width:52px;height:52px;flex-shrink:0;position:relative}
.ring svg{transform:rotate(-90deg)}
.ring .rv{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:var(--fs-md);font-weight:900;font-variant-numeric:tabular-nums;
}
.ringmeta{flex:1;min-width:0}
.ringmeta .a{font-size:var(--fs-ui);font-weight:700;font-variant-numeric:tabular-nums;line-height:1.1}
.ringmeta .b{font-size:var(--fs-sm);color:var(--ink-3);font-weight:600}
/* Stands in for the ring on a subject nobody has opened. Height is matched to
   the ring's 52px so a card that has just earned its first answer changes what
   it says without changing what it measures. Colour is --tx, not the module's
   own: brand colour as text on the card ground has not been measured, and §6
   says that is chosen by measurement rather than habit. */
.mod-card .startrow{min-height:52px}
.mod-card .startgo{
  font-family:var(--font-display);font-size:var(--fs-ui);font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;color:var(--tx);
}

.stat{
  background:var(--card);border:1px solid var(--neon);border-radius:var(--r-lg);padding:var(--s-7);
  box-shadow:var(--neon-glow);position:relative;overflow:hidden;
}
.stat .n{font-size:var(--fs-2xl);font-weight:900;letter-spacing:-.04em;font-variant-numeric:tabular-nums;line-height:1.05}
.stat .l{font-size:var(--fs-sm);color:var(--ink-3);margin-top:3px;font-weight:700}
.stat .emo{position:absolute;right:11px;top:10px;font-size:var(--fs-lg);opacity:.3}

/* ---------- Chapter rows ---------- */
.grouphdr{
  display:flex;align-items:center;gap:10px;margin:24px 0 11px;
  font-size:var(--fs-xs);letter-spacing:.11em;text-transform:uppercase;font-weight:900;color:var(--ink-3);
}
.grouphdr::after{content:"";flex:1;height:2.5px;background:var(--line);border-radius:var(--r-md)}
/* Paper heading (Pediatrics): sits above the first section of each paper. */
.paperhdr{margin:36px 0 -6px;font-family:var(--font-display);font-size:var(--fs-body);letter-spacing:.16em;text-transform:uppercase;font-weight:700;color:var(--ink)}
.ch-row{
  display:flex;align-items:center;gap:13px;padding:var(--s-6) var(--s-7);background:var(--card);
  border:1px solid var(--neon);border-radius:var(--r-lg);margin-bottom:9px;width:100%;text-align:left;
  box-shadow:var(--neon-glow);
  transition:border-color var(--dur-2) var(--ease-standard),background-color var(--dur-2) var(--ease-standard),box-shadow var(--dur-2) var(--ease-standard);
}
/* The Clepsydra is fixed bottom-right and a chapter list ends under her: the
   counts of the last rows could never be scrolled clear (measured on Pediatrics,
   rows 7-8 of Model Final Exams). Room at the foot of a list view for her. */
@media screen{.page>.ch-row:last-child{margin-bottom:120px}}
.ch-row:hover:not(:disabled){border-color:var(--gold);background-color:var(--bg-2);box-shadow:var(--gold-glow)}
.ch-row:disabled{opacity:.45;cursor:default;box-shadow:none;border-style:dashed}
.ch-dot{width:11px;height:11px;border-radius:50%;flex-shrink:0;border:2px solid var(--line-2)}
.ch-name{flex:1;font-size:var(--fs-ui);font-weight:700}
.ch-count{font-size:var(--fs-sm);color:var(--ink-4);font-variant-numeric:tabular-nums;font-weight:700}
.ch-acc{font-size:var(--fs-sm);font-weight:900;font-variant-numeric:tabular-nums;min-width:40px;text-align:right}
/* On the weakest-chapters page the rows come from four different modules, so
   each name has to say which one it belongs to. */
.wk-mod{display:block;font-size:var(--fs-xs);font-weight:700;color:var(--ink-4);
  letter-spacing:.05em;text-transform:uppercase;margin-top:2px}
