/* Self-hosted so no visitor IP reaches Google. The latin subset (U+0000-00FF)
   covers every character this app renders, umlauts and ß included; ẞ appears
   only inside glossary regexes, never on screen. Variable, 400-700 in one file. */
@font-face{
  font-family:'Archivo';
  font-style:normal;
  font-weight:400 700;
  font-display:swap;
  src:url('font/archivo-latin-var.woff2') format('woff2-variations');
}

:root{
  /* the shared colours are in tokens.css; these are the app's own */
  --nobg:#FAE4E2;
  /* map only: three reds, an even grey and four greens, the last being --ok.
     Under dichromacy no red or grey clears every green, so red cells carry a
     slash and the even cell a dash -- the colour is never the only signal */
  --cellno1:#F4B4AE; --cellno2:#D9534F; --cellno3:#9E2B26;
  --celleven:#828D9F;
  --cellmark:var(--card);              /* a red cell's slash                  */
  --cellmark1:var(--cellno3);          /* ...on the palest red, where --card vanishes */
  --cellok1:#ABE0C0; --cellok2:#72B68F; --cellok3:#3E815D;
  --picked:#E3EEEB;                    /* a chosen answer, chip, copy button  */
  --gloss:#C9E4D6;                     /* a glossed word in an answer         */
  --imgdim:none;                       /* catalogue scans keep a white plate  */
  --shell:62rem; --rail:17rem;
  --font:"Archivo",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;

  /* safe areas, named once so every fixed edge can use them */
  --sat:env(safe-area-inset-top,0px);
  --sab:env(safe-area-inset-bottom,0px);
  --sal:env(safe-area-inset-left,0px);
  --sar:env(safe-area-inset-right,0px);
  --peek:calc(3.7rem + var(--sab));    /* the progress sheet at rest */
}
/* Dark: the app's own colours, lifted the way tokens.css lifts the shared
   ones and measured in brand/PALETTE.md. */
:root[data-theme="dark"]{
  --nobg:#3F2220;
  /* The greens run the other way, more right being brighter on a dark page.
     The reds do not: the lightest red sits next to even in both themes, so
     one miss reads as the mild end and three as the dim, heavy one */
  --cellno1:#D0524C; --cellno2:#972622; --cellno3:#5A2522;
  --celleven:#5F6A7B;
  --cellmark:var(--ink); --cellmark1:var(--ink);   /* a dark slash is lost on dark red */
  --cellok1:#214D34; --cellok2:#367854; --cellok3:#56A276;
  --picked:#1F3531;
  --gloss:#284B3B;
  --imgdim:brightness(.9);
}
/* theme.js sets this for the instant a theme changes, so every surface
   switches at once instead of each running its own colour transition */
.theming, .theming *, .theming *::before, .theming *::after{transition:none!important}
*{box-sizing:border-box}
html,body{margin:0;padding:0}

/* The app is a fixed shell, not a scrolling document: the question area
   scrolls inside itself so the answers can stay under your thumb. */
body{
  background:var(--paper); color:var(--ink); font-family:var(--font);
  font-size:17px; line-height:1.5; font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased; -webkit-text-size-adjust:100%;
  overflow-wrap:break-word;
  height:100dvh; overflow:hidden;
  display:flex; flex-direction:column;
  padding-bottom:var(--peek);          /* the sheet's resting strip */
  overscroll-behavior:none;
}
button,select,input{font:inherit;color:inherit}
:focus-visible{outline:2.5px solid var(--accent); outline-offset:2px; border-radius:4px}

.skip{position:absolute;left:-9999px;top:0;z-index:99;background:var(--ink);color:var(--paper);padding:.6rem 1rem;border-radius:0 0 8px 0}
.skip:focus{left:0}

/* ------------------------------------------------ top bar */
.bar{
  flex:0 0 auto; z-index:30; background:var(--paper); border-bottom:1px solid var(--rule);
  padding:calc(.4rem + var(--sat)) calc(.7rem + var(--sar)) .4rem calc(.7rem + var(--sal));
  display:flex; align-items:center; gap:.6rem; min-height:3rem;
}
.brand{font-weight:700; letter-spacing:-.022em; font-size:1rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.wide{display:none}                    /* long labels are a wide-screen luxury */
.brand span{color:var(--muted); font-weight:500; display:none}
.streak{margin-left:auto; display:flex; align-items:baseline; font-size:.86rem; color:var(--muted); white-space:nowrap; cursor:default}
.streak b{display:inline-block; min-width:1.4ch; margin-left:.3rem; color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums}
.streak span + span{margin-left:.7rem; padding-left:.7rem; border-left:1px solid var(--rule)}
#s-now{color:var(--accent); font-weight:700}
.streak[hidden]{display:none}

.field{display:block; margin-bottom:.55rem}
.bigbtn + .field{margin-top:.9rem}            /* the catalogue pickers, under the exam */
.field>span{display:block; padding-left:13px; font-size:.78rem; color:var(--muted); margin-bottom:.22rem}
/* Native select rendering adds its own internal text inset on top of CSS
   padding, so the value never lands on the same edge as its label. Dropping
   the native appearance puts the text exactly where the padding says, and we
   draw the chevron ourselves. */
.field select, .field input[type=number], .pick{
  appearance:none; -webkit-appearance:none;
  width:100%; background:var(--card); border:1px solid var(--edge); border-radius:8px;
  padding:.55rem 2.3rem .55rem 12px; font-size:.9rem; cursor:pointer;
  line-height:1.45; min-height:2.6rem;
  background-image:var(--chev);
  background-repeat:no-repeat;
  background-position:right 12px center;
}
.field select:hover, .field input[type=number]:hover, .pick:hover{border-color:var(--muted)}
.pick:disabled{opacity:.45; cursor:default}
.field[hidden]{display:none}

.opt-row{display:flex; align-items:center; gap:.7rem; padding:.55rem 0 .55rem 13px; border-radius:8px; cursor:pointer; user-select:none}
.opt-row:hover{background:var(--sunk)}
.opt-row .lb{flex:1; font-size:.9rem}
.opt-row .lb em{display:block; font-style:normal; font-size:.78rem; color:var(--muted); margin-top:.1rem; line-height:1.35}
.sw{flex:0 0 auto; width:2.4rem; height:1.4rem; border-radius:99px; background:var(--edge); position:relative; transition:background .15s}
.sw::after{content:''; position:absolute; top:2px; left:2px; width:calc(1.4rem - 4px); height:calc(1.4rem - 4px); border-radius:50%; background:var(--card); transition:transform .15s}
.opt-row[aria-checked=true] .sw{background:var(--accent)}
.opt-row[aria-checked=true] .sw::after{transform:translateX(1rem)}

.danger{width:100%; text-align:left; background:transparent; border:1px solid var(--rule); padding:.6rem 12px; border-radius:8px; cursor:pointer; font-size:.9rem; color:var(--no)}
.danger:hover{background:var(--nobg); border-color:var(--no)}
.note{padding:.2rem 0 0; font-size:.78rem; color:var(--muted); line-height:1.4}
.note[hidden]{display:none}

.about{margin-top:.9rem; border-top:1px solid var(--soft); padding-top:.7rem}
.about summary{cursor:pointer; padding-left:13px; font-size:.8rem; color:var(--muted); font-weight:500}
.about p{padding-left:13px; font-size:.74rem; color:var(--muted); line-height:1.55}

/* ------------------------------------------------ the question stage */
main{flex:1 1 auto; min-height:0; overflow-y:auto; -webkit-overflow-scrolling:touch; overscroll-behavior:contain}
.stage{display:block}
/* the part that scrolls: question text and picture */
.scroll{
  padding:.4rem calc(.85rem + var(--sar)) .4rem calc(.85rem + var(--sal));
}
/* the part that stays under your thumb: answers and the Next button */
.answers{
  position:sticky; bottom:0; z-index:5; background:var(--paper);
  padding:.5rem calc(.85rem + var(--sar)) .6rem calc(.85rem + var(--sal));
  border-top:1px solid transparent;
}
.answers.stuck{border-top-color:var(--rule); box-shadow:0 -6px 16px rgba(10,18,20,.05)}
/* With subtitles under a missed question the answers can outgrow a phone's
   screen, and pinned they would cover the question for good. So they scroll
   with the page, and only the Back / Next row stays under your thumb. */
.answers.read{position:static; border-top-color:transparent; box-shadow:none}
.answers.read .act{position:sticky; bottom:0; z-index:5; background:var(--paper);
  margin:.6rem calc(-.85rem - var(--sar)) -.6rem calc(-.85rem - var(--sal));
  padding:.5rem calc(.85rem + var(--sar)) .6rem calc(.85rem + var(--sal));
  border-top:1px solid var(--rule); box-shadow:0 -6px 16px rgba(10,18,20,.05)}

.meta{position:sticky; top:0; z-index:6; background:var(--paper); display:flex; align-items:center; gap:.55rem; flex-wrap:wrap;
  font-size:.8rem; color:var(--muted); margin:0;
  padding:.55rem calc(.85rem + var(--sar)) .35rem calc(.85rem + var(--sal))}
.tools{margin-left:auto; display:flex; gap:.4rem; flex-shrink:0}
.copy{display:inline-flex; align-items:center; gap:.3rem; background:var(--card); border:1px solid var(--edge);
  border-radius:8px; padding:.36rem .6rem; font-size:.8rem; font-weight:500; color:var(--muted);
  cursor:pointer; white-space:nowrap; text-decoration:none; line-height:1.4; min-height:2rem}
.copy:hover{color:var(--ink)}
.copy.done{border-color:var(--ok); color:var(--ok)}
.meta b{color:var(--ink); font-weight:600}
.tag{display:inline-flex; align-items:center; min-height:2rem; border:1px solid var(--rule);
  border-radius:99px; padding:0 .7rem; font-size:.77rem; font-weight:500; background:var(--card)}
.tag.land{border-color:var(--gold); color:var(--gold); background:var(--goldbg)}

.q{font-size:1.3rem; line-height:1.28; font-weight:600; letter-spacing:-.021em; margin:0 0 .9rem; max-width:34ch; text-wrap:pretty}

/* picture questions: the image is the question, so let it have the room */
.shot{background:#fff; border:1px solid var(--rule); border-radius:10px; padding:0; margin:0 0 .8rem; text-align:center; position:relative; overflow:hidden}
.shot img{max-width:100%; height:auto; display:block; margin:0 auto; cursor:zoom-in; filter:var(--imgdim)}


.opts{display:flex; flex-direction:column; gap:.45rem; margin:0; padding:0; list-style:none}
.opt{display:flex; align-items:flex-start; gap:.7rem; width:100%; text-align:left; background:var(--card);
  border:1px solid var(--edge); border-radius:9px; padding:.72rem .8rem; cursor:pointer;
  transition:border-color .12s, background .12s; min-height:2.9rem}
.opt:hover:not([aria-disabled=true]){border-color:var(--muted)}
.opt[aria-disabled=true]{cursor:default}
.cap{flex:0 0 auto; width:1.5rem; height:1.5rem; border-radius:5px; border:1px solid var(--edge);
  background:var(--sunk); display:grid; place-items:center; font-size:.8rem; font-weight:600; color:var(--muted); margin-top:.06rem}
.opt .txt{flex:1; min-width:0; overflow-wrap:break-word; hyphens:auto}
.mark{flex:0 0 auto; font-weight:700; line-height:1.5rem}
.opt.right{border-color:var(--ok); background:var(--okbg)}
.opt.right .cap{border-color:var(--ok); background:var(--ok); color:var(--card)}
.opt.right .mark{color:var(--ok)}
.opt.wrong{border-color:var(--no); background:var(--nobg)}
.opt.wrong .cap{border-color:var(--no); background:var(--no); color:var(--card)}
.opt.wrong .mark{color:var(--no)}
.opt.dim{color:var(--dim); border-color:var(--rule); background:var(--card)}
.opt.dim .cap{color:var(--dim); border-color:var(--rule)}
/* mid-exam: "this is the one I picked", NOT "this one is correct" */
.opt.picked{border-color:var(--accent); background:var(--picked); box-shadow:inset 0 0 0 1px var(--accent)}
.opt.picked .cap{border-color:var(--accent); background:var(--accent); color:var(--card)}

/* 36 of the 39 picture questions answer with "Bild 3" or a bare "2" — the
   option text carries no information, so four stacked full-width rows are
   ~200px spent on nothing. One row of four big buttons instead. */
.opts.pointer{flex-direction:row; gap:.5rem}
.opts.pointer li{flex:1 1 0; min-width:0}
.opts.pointer .opt{
  flex-direction:column; align-items:center; justify-content:center; gap:.15rem;
  padding:.5rem .2rem; min-height:3.4rem; text-align:center;
}
.opts.pointer .cap{width:1.9rem; height:1.9rem; font-size:1rem; margin:0}
.opts.pointer .txt{flex:0 0 auto; font-size:.7rem; color:var(--muted); line-height:1.2}
.opts.pointer .mark{position:absolute; top:.2rem; right:.35rem; line-height:1}
.opts.pointer .opt{position:relative}
.opts.pointer .opt.right .txt, .opts.pointer .opt.wrong .txt{color:inherit}

.act{display:flex; align-items:center; gap:.5rem; margin-top:.6rem}
.next{background:var(--ink); color:var(--paper); border:0; border-radius:9px; padding:.75rem 1.05rem; font-weight:600; font-size:.95rem; cursor:pointer; min-height:2.9rem}
.next:disabled{opacity:.32; cursor:default}
.next.quiet{background:transparent; color:var(--ink); border:1px solid var(--edge)}
.act .grow{flex:1 1 auto}
.kbd{border:1px solid var(--rule); border-bottom-width:2px; border-radius:5px; padding:.03rem .36rem;
  font-size:.75rem; color:var(--muted); background:var(--card); font-weight:600; white-space:nowrap}
.hint{display:none; font-size:.82rem; color:var(--muted); align-items:center; gap:.35rem; flex-wrap:wrap}

/* the verdict line that replaces the keyboard hints on a phone */
.verdictline{font-size:.86rem; font-weight:600; flex:1 1 auto; min-width:0}
.verdictline.ok{color:var(--ok)} .verdictline.bad{color:var(--no)}

/* ------------------------------------------------ English subtitles */
.sub{display:block; margin-top:.2rem; font-size:.86rem; line-height:1.35; font-weight:400;
  color:var(--muted); letter-spacing:0}
.qsub{font-size:.95rem; margin:-.55rem 0 .9rem; max-width:44ch; text-wrap:pretty}
.al{border-radius:3px; transition:background .1s, box-shadow .1s}
.al.lit, .al.pin{background:var(--goldbg); box-shadow:0 0 0 2px var(--goldbg), inset 0 -2px 0 var(--gold); color:var(--ink)}
.sub .al{cursor:pointer}

/* ------------------------------------------------ glossary term + tooltip */
.gl{border-bottom:1.5px dotted var(--gold); cursor:help}
.opt:not([aria-disabled=true]) .gl{cursor:pointer}
#tip{position:fixed; z-index:60; max-width:19rem; background:var(--tipbg); color:var(--tipink);
  border:1px solid var(--tipline);
  border-radius:8px; padding:.5rem .65rem; font-size:.84rem; line-height:1.4;
  box-shadow:0 8px 22px rgba(0,0,0,.24); pointer-events:none}
#tip[hidden]{display:none}
#tip b{display:block; font-size:.79rem; opacity:.62; font-weight:600; margin-bottom:.1rem}

/* ------------------------------------------------ fullscreen picture */
.lens{position:fixed; inset:0; z-index:70; background:rgba(8,14,16,.94); display:flex; align-items:flex-start; justify-content:center; padding:calc(3.6rem + var(--sat)) .5rem calc(1rem + var(--sab)); overflow:auto; overscroll-behavior:contain}
.lens[hidden]{display:none}
/* fill the width and let it scroll rather than shrinking a tall map to fit --
   on the map questions, reading the picture IS answering the question */
.lens img{width:100%; height:auto; max-width:none; max-height:none; background:#fff; border-radius:6px; touch-action:pinch-zoom}
.lensclose{position:absolute; top:calc(.7rem + var(--sat)); right:.7rem; width:2.75rem; height:2.75rem; border-radius:50%; border:0; background:rgba(255,255,255,.14); color:#fff; font-size:1.05rem; cursor:pointer}
.lensclose:hover{background:rgba(255,255,255,.26)}

/* ------------------------------------------------ glossary panel */
.veil{position:fixed; inset:0; z-index:50; background:rgba(10,18,20,.42); display:flex; justify-content:center; align-items:flex-start; padding:4vh 1rem}
.veil[hidden]{display:none}
.sheet{background:var(--card); border:1px solid var(--rule); border-radius:12px; width:min(40rem,100%); max-height:88dvh; display:flex; flex-direction:column; overflow:hidden}
.sheet header{display:flex; align-items:center; gap:.7rem; padding:.9rem 1.1rem; border-bottom:1px solid var(--soft)}
.sheet h2{margin:0; font-size:1.05rem; letter-spacing:-.02em}
.sheet input{flex:1; background:var(--sunk); border:1px solid var(--edge); border-radius:7px; padding:.4rem .6rem; font-size:.9rem; min-width:6rem}
.sheet .body{overflow:auto; padding:.4rem 1.1rem 1.1rem}
.icon{background:var(--card); border:1px solid var(--edge); border-radius:8px; padding:.44rem .7rem; font-size:.86rem; cursor:pointer; color:var(--muted); white-space:nowrap}
.icon:hover{color:var(--ink)}
.gcat{font-size:.76rem; font-weight:600; color:var(--muted); margin:1rem 0 .3rem; border-bottom:1px solid var(--soft); padding-bottom:.25rem}
.gitem{display:flex; gap:.8rem; padding:.32rem 0; font-size:.9rem; align-items:baseline}
.gitem b{flex:0 0 11rem; font-weight:600}
.gitem span{flex:1; color:var(--muted)}
@media(max-width:560px){ .gitem{flex-direction:column; gap:.05rem} .gitem b{flex:none} }

/* ------------------------------------------------ progress sheet
   At rest only the grab bar shows. Drag or tap it for the numbers, again
   for the full grid. Desktop overrides this back into a static bottom bar. */
.dock{
  position:fixed; left:0; right:0; bottom:0; z-index:20;
  height:min(88dvh,42rem);
  background:var(--card); border-top:1px solid var(--rule);
  border-radius:14px 14px 0 0; box-shadow:0 -8px 28px rgba(10,18,20,.10);
  display:flex; flex-direction:column;
  transform:translateY(calc(100% - var(--peek)));
  transition:transform .28s cubic-bezier(.22,.61,.36,1);
  padding-left:var(--sal); padding-right:var(--sar);
}
body.sheet-open .dock{transform:translateY(0)}
body.sheet-drag .dock{transition:none}

.grab{
  flex:0 0 auto; width:100%; background:transparent; border:0; cursor:pointer;
  display:grid; grid-template-columns:1fr; align-items:center; gap:.5rem;
  padding:.5rem calc(.85rem + var(--sar)) .45rem calc(.85rem + var(--sal)); text-align:left;
  touch-action:none; -webkit-tap-highlight-color:transparent;
}
.grab:active .grab-bar{background:var(--edge)}
.grab-bar{
  grid-column:1/-1; justify-self:center; width:2.4rem; height:4px; border-radius:99px;
  background:var(--rule); margin-bottom:.45rem; transition:background .15s;
}
.grab-txt{font-size:.82rem; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.grab-txt b{color:var(--ink); font-weight:600}

.dock-body{flex:1 1 auto; min-height:0; overflow-y:auto; -webkit-overflow-scrolling:touch; overscroll-behavior:contain}
.dock-in{padding:.2rem 1rem calc(1.2rem + var(--sab))}

/* the numbers */
.stats{margin-bottom:1rem}
.headline{display:flex; align-items:baseline; gap:.6rem; margin:0 0 .15rem}
.headline .big{font-size:2.6rem; font-weight:700; letter-spacing:-.04em; line-height:1}
.headline .of{font-size:.95rem; color:var(--muted); font-weight:500}
.headline .big.pass{color:var(--ok)} .headline .big.fail{color:var(--no)}
.headline .big.none{color:var(--muted)}
.headnote{font-size:.82rem; color:var(--muted); margin:0 0 .9rem; max-width:44ch}
.chips{display:flex; gap:.45rem; flex-wrap:wrap; margin-bottom:1rem}
.chip{background:var(--sunk); border:1px solid var(--rule); border-radius:8px; padding:.4rem .65rem; font-size:.8rem; color:var(--muted); cursor:pointer; text-align:left}
.chip b{display:block; font-size:1.1rem; color:var(--ink); font-weight:700; line-height:1.2}
.chip:hover{border-color:var(--edge)}
.chip.on{border-color:var(--accent); background:var(--picked)}

.brk{margin:0 0 1rem}
.brk h4{margin:0 0 .45rem; font-size:.74rem; font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--muted)}
.trow{display:grid; grid-template-columns:1fr 3.4rem; gap:.6rem; align-items:center; width:100%;
  background:transparent; border:0; border-radius:7px; padding:.34rem .4rem; cursor:pointer; text-align:left; font-size:.85rem}
.trow:hover{background:var(--sunk)}
.trow .nm{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.trow .bar2{grid-column:1/-1; height:5px; border-radius:99px; background:var(--soft); overflow:hidden}
.trow .bar2 i{display:block; height:100%; background:var(--accent); border-radius:99px}
.trow .num{text-align:right; color:var(--muted); font-size:.8rem}

.exams{display:flex; gap:.4rem; flex-wrap:wrap; margin-bottom:.4rem}
.ex{border:1px solid var(--rule); border-radius:8px; padding:.3rem .55rem; font-size:.82rem; font-weight:600; background:var(--card)}
.ex.pass{border-color:var(--ok); color:var(--ok); background:var(--okbg)}
.ex.fail{border-color:var(--no); color:var(--no); background:var(--nobg)}

.dock-head{display:none; align-items:center; gap:.8rem; flex-wrap:wrap; font-size:.79rem; color:var(--muted); margin-bottom:.5rem}
.legend{display:flex; gap:.7rem; flex-wrap:wrap}
.legend i{display:inline-block; width:.6rem; height:.6rem; border-radius:2px; margin-right:.28rem; vertical-align:-1px}

/* cells big enough to actually hit with a thumb */
.map{display:none; grid-template-columns:repeat(auto-fill,minmax(1.6rem,1fr)); gap:4px}
.map[hidden]{display:none}
.cell{aspect-ratio:1; border-radius:4px; background:var(--sunk); border:0; padding:0; cursor:pointer;
  min-height:1.6rem; box-shadow:inset 0 0 0 1px var(--edge)}
.cell:hover{outline:1.5px solid var(--ink); outline-offset:1px}
.cell:is(.g1,.g2,.g3,.g4,.even,.r1,.r2,.r3){box-shadow:none}
.cell.g1,.legend .g1{background:var(--cellok1)}
.cell.g2,.legend .g2{background:var(--cellok2)}
.cell.g3,.legend .g3{background:var(--cellok3)}
.cell.g4,.legend .g4{background:var(--ok)}
/* The marks are the ✗ and the = a bare square has no room for: under
   protanopia a red lands on one of the greens, and a grey on another, so
   colour alone would call them right. --cellmark1 is the palest red's slash,
   which a --card line would vanish into on a light page. */
.cell:is(.r1,.r2,.r3),.legend :is(.r1,.r2,.r3){--mark:var(--cellmark); background:
  linear-gradient(to top right, transparent calc(50% - .8px), var(--mark) calc(50% - .8px) calc(50% + .8px), transparent calc(50% + .8px)),
  var(--fill)}
.cell.r1,.legend .r1{--fill:var(--cellno1); --mark:var(--cellmark1)}
.cell.r2,.legend .r2{--fill:var(--cellno2)}
.cell.r3,.legend .r3{--fill:var(--cellno3)}
.cell.even,.legend .even{background:
  linear-gradient(transparent calc(50% - .8px), var(--card) calc(50% - .8px) calc(50% + .8px), transparent calc(50% + .8px)) center / 60% 100% no-repeat,
  var(--celleven)}
.legend .g0{background:var(--sunk); box-shadow:inset 0 0 0 1px var(--edge)}
.legend .land{box-shadow:inset 0 0 0 1.5px var(--gold)}
.legend .ramp i{margin-right:2px}
.legend .ramp i:first-of-type{margin-left:.35rem}
.legend .ramp i:last-of-type{margin-right:.28rem}
.cell.land{box-shadow:inset 0 0 0 1.5px var(--gold)!important}
.cell.now{outline:2px solid var(--ink); outline-offset:1px}

/* ------------------------------------------------ panels & result */
.scroll>.panel:first-child{margin-top:.6rem}
.panel{background:var(--card); border:1px solid var(--rule); border-radius:10px; padding:1.2rem; margin-bottom:1rem}
.panel h2{margin:0 0 .5rem; font-size:1.2rem; letter-spacing:-.02em}
.panel p{margin:0 0 1rem; color:var(--muted); max-width:56ch}
.score{font-size:3.3rem; font-weight:700; letter-spacing:-.04em; line-height:1; margin:0}
.score small{font-size:1rem; font-weight:500; color:var(--muted); letter-spacing:0}
.verdict{font-weight:600; margin:.5rem 0 0}
.verdict.pass{color:var(--ok)} .verdict.fail{color:var(--no)}
.rows{border-top:1px solid var(--soft); margin-top:.9rem}
.row{display:flex; gap:.7rem; padding:.65rem 0; border-bottom:1px solid var(--soft); font-size:.9rem; align-items:flex-start}
.row .n{flex:0 0 2rem; color:var(--muted); font-size:.8rem; padding-top:.12rem}
.row .s{flex:0 0 1rem; font-weight:700}
.row .s.ok{color:var(--ok)} .row .s.bad{color:var(--no)}
.row .b{flex:1; min-width:0}
.row .b em{display:block; font-style:normal; color:var(--muted); font-size:.85rem; margin-top:.12rem}
.empty{text-align:center; padding:3rem 1rem; color:var(--muted)}
.empty b{display:block; color:var(--ink); font-size:1.08rem; margin-bottom:.3rem}

/* ------------------------------------------------ exam is its own page
   No menu, no progress sheet, nothing to tap by accident. */
body.exam .bar, body.exam .dock, body.exam .burger{display:none}
body.exam .nav{transform:translateX(-101%)}
.exambar{
  position:relative;
  flex:0 0 auto; display:flex; align-items:center; gap:.7rem; background:var(--tipbg); color:var(--tipink);
  padding:calc(.5rem + var(--sat)) calc(.85rem + var(--sar)) .55rem calc(.85rem + var(--sal));
  font-size:.88rem;
}
.exambar .quit{background:transparent; border:1px solid rgba(242,245,244,.34); color:inherit; border-radius:8px; padding:.36rem .6rem; font-size:.8rem; cursor:pointer}
.exambar .pos{font-weight:600}
.exambar .clock{margin-left:auto; font-weight:700; font-variant-numeric:tabular-nums}
.exambar .clock.low{color:#FF9A92}
.exambar .prog{position:absolute; left:0; right:0; bottom:0; height:3px; background:rgba(242,245,244,.2)}
.exambar .prog i{display:block; height:100%; background:var(--tipink)}

/* ------------------------------------------------ desktop
   The drawer stops overlaying and becomes a permanent rail; the progress
   sheet goes back to being the static bottom bar it was. */
@media(min-width:62rem){
  body{
    font-size:17px;
    display:grid;
    padding-bottom:0;                  /* the dock is its own bar here */
    --railw:17rem;
    grid-template-columns:var(--rail) 1fr;
    grid-template-rows:auto 1fr;
    transition:grid-template-columns .24s cubic-bezier(.22,.61,.36,1);
  }
  body.rail-off{--rail:0px}
  body.rail-off .nav{border-right-width:0}
  .navclose, .grab-bar{display:none}
  .scrim{display:none!important}
  /* the burger stops opening a drawer and starts collapsing the rail */
  .burger{display:grid}
  body.nav-open .burger span{transform:none; opacity:1}
  .wide{display:inline}
  .brand span{display:inline}

  .nav{
    position:static; grid-column:1; grid-row:1/3;
    width:auto; transform:none!important; transition:none;
    border-right:1px solid var(--rule); overflow:hidden;
  }
  /* fixed inner width so the contents do not reflow while the column animates */
  .nav-head, .nav-body{width:var(--railw)}
  /* the rail's header and the top bar are one continuous band */
  .nav-head{min-height:3rem; padding-top:calc(.4rem + var(--sat)); padding-bottom:.4rem}
  /* the rail already says the name; the bar shows where you are instead */
  body:not(.rail-off) .brand{display:none}

  .bar{grid-column:2; grid-row:1; padding-left:1.5rem; padding-right:calc(1.5rem + var(--sar))}
  .streak{font-size:.88rem}

  /* a wide screen reads as a document: nothing is pinned to the bottom,
     because there is no thumb reaching for it */
  main{grid-column:2; grid-row:2; overflow-y:auto}
  .stage{display:block}
  .scroll{flex:none; overflow:visible; min-height:0; display:block}
  /* full-bleed bands whose CONTENT still lands on the centred column, so the
     tag and the question start on the same x at any window width */
  .meta, .exambar{
    margin-bottom:.2rem;
    padding-left:max(1.5rem, calc((100% - var(--shell)) / 2));
    padding-right:max(1.5rem, calc((100% - var(--shell)) / 2));
  }
  .answers{position:static; bottom:auto}
  .act .grow{flex:0 0 auto; margin-left:auto}
  .scroll{padding:1.5rem 1.5rem .6rem}
  .scroll>*{max-width:var(--shell); margin-left:auto; margin-right:auto}
  .answers{padding:.6rem 1.5rem 1.2rem; background:transparent}
  .answers>*{max-width:var(--shell); margin-left:auto; margin-right:auto}
  .answers.stuck{box-shadow:none; border-top-color:transparent}
  .answers.read .act{position:static; margin:.6rem auto 0; padding:0; border-top:0; box-shadow:none; background:transparent}
  .q{font-size:1.6rem; margin-bottom:1.2rem}
  .hint{display:flex}
  .opts{gap:.5rem}
  .opt{padding:.78rem .9rem}
  .act{margin-top:1.1rem}

  /* the sheet becomes a plain bottom bar again */
  .dock{
    position:fixed; left:var(--rail); right:0; bottom:0;
    transition:left .24s cubic-bezier(.22,.61,.36,1);
    height:auto; max-height:70dvh; border-radius:0; box-shadow:none;
    transform:none!important;
  }
  .grab{display:none}                  /* the legend says it; the numbers are the sheet's */
  .dock-in{padding:.55rem 1.5rem .75rem; max-width:calc(var(--shell) + 3rem); margin:0 auto}
  .stats{display:none}                 /* the numbers are a phone-sheet thing */
  .dock-body{overflow:visible}
  .dock-head{display:flex}
  .map{display:grid; grid-template-columns:repeat(auto-fill,minmax(10px,1fr)); gap:2px}
  .cell{min-height:9px; border-radius:2px}
  main{padding-bottom:var(--dockh,6rem)}

  /* the exam takes the whole window: no rail, and no empty app bar above
     the exam's own dark strip */
  body.exam{grid-template-columns:0 1fr}
  body.exam .nav{display:none}
  body.exam .bar{display:none}
  body.exam .dock{display:none}
  body.exam main{grid-column:1/-1; grid-row:1/3}
}

@media (prefers-reduced-motion: reduce){ *{transition:none!important; animation:none!important} }

/* ------------------------------------------------ hooks
   The recognition aid: a trigger word in the stem, a token in the right
   option. Two highlight colours carry the whole idea, so they are the only
   new hues here -- the trigger borrows the glossary's gold, the token the
   accent green that already means "this is the right answer". */
/* Do not set max-width here, and keep `auto` on the side margins: both would
   override the `.scroll>*` rule that gives the question and the options their
   shared column, and the card would stop lining up with them. */
.hook{
  background:var(--card); border:1px solid var(--rule); border-radius:10px;
  padding:.72rem .85rem; margin:0 auto .9rem;
}
.hookline{display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; font-size:1.05rem}
.hookline .hw{font-weight:600; letter-spacing:-.01em}
.hookline .trig{border-bottom:2px solid var(--gold)}
.hookline .tok{background:var(--okbg); color:var(--ok); border-radius:5px; padding:.05rem .3rem}
.hookline .tok.veiled{background:var(--sunk); color:var(--muted); font-weight:400; font-size:.86rem}
.hookline .hplus{font-size:.86rem; color:var(--muted)}
.hookline .harrow{color:var(--muted)}
.grade{
  flex:0 0 auto; width:1.45rem; height:1.45rem; border-radius:5px; display:grid; place-items:center;
  font-size:.8rem; font-weight:700; background:var(--sunk); color:var(--muted);
  border:1px solid var(--edge); cursor:help;
}
.grade.g-A{background:var(--ok); border-color:var(--ok); color:var(--card)}
.grade.g-B{background:var(--okbg); border-color:var(--ok); color:var(--ok)}
.grade.g-C{background:var(--goldbg); border-color:var(--gold); color:var(--gold)}
.grade.g-D{background:var(--nobg); border-color:var(--no); color:var(--no)}
.grade.g-V{background:var(--goldbg); border-color:var(--gold); color:var(--gold)}
.hooken{margin:.55rem 0 0; padding:.55rem 0 0; border-top:1px solid var(--soft); font-size:.82rem}
.hooken div{display:flex; gap:.45rem; margin:0 0 .22rem}
.hooken div:last-child{margin-bottom:0}
.hooken dt{flex:0 0 auto; font-weight:600; color:var(--ink)}
.hooken dd{margin:0; color:var(--muted); min-width:0}
.hookflag{margin:.5rem 0 0; font-size:.78rem; line-height:1.4; color:var(--gold)}
.hookflag b{font-weight:700}

/* the stem's trigger, and the token inside the right option */
.q mark.trig, .opt mark.tok{background:transparent; color:inherit}
.q mark.trig{border-bottom:2px solid var(--gold); font-weight:700}
.opt mark.tok{background:var(--gloss); border-radius:4px; padding:.02rem .18rem; font-weight:700}
/* Most triggers are glossary terms too, and the gloss nests with the mark. Its
   dotted line would sit on or under the trigger's solid one, so it gives way;
   the term still opens on a tap. */
.q mark.trig .gl, .q .gl:has(> mark.trig){border-bottom-color:transparent}

/* ------------------------------------------------ exam scope */
.scope{margin:0 0 1rem; max-width:30rem}
.scope .note{padding-top:.1rem}
.scope .note b{color:var(--ink)}
.rangerow{display:flex; gap:.6rem}
.rangerow .field{flex:1 1 0; min-width:0}
.rangerow[hidden]{display:none}
/* the number spinner carries no meaning here and crowds a narrow field */
.field input[type=number]{padding-right:12px; background-image:none; cursor:text}
.field input[type=number]::-webkit-outer-spin-button,
.field input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none; margin:0}
.field input[type=number]{-moz-appearance:textfield}
.next:disabled{opacity:.45; cursor:default}
