/* jlpt.css - the JLPT screens (X track): the hub, practice, mock tests, results and the placement test. Colours and
   radii only through the tokens in app.css (light and dark both follow); every control 44 px or more; text 14 px or
   more; nothing wider than the screen at 320 px (wide tables scroll inside their own box). Japanese is set a little
   larger than English, with room for furigana. Phone first (docs/mobile-plan.md J6 to J10): the hub is a title with
   the level chip, one main action and rows; practice keeps Check at the foot of the screen and turns it into the
   feedback sheet; a running mock lends its time and Exit to the bar ("upright phone" below is the bar's own query,
   (max-width: 720px) and (min-height: 501px)). */

/* Japanese as the booklet prints it */
.jl-item [lang=ja], .jl-passage, .jl-kana [lang=ja] { line-height: 1.9; }
.jl-item ruby rt, .jl-passage ruby rt { font-size: .55em; color: var(--mute); }
.jl-u { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: .28em; text-decoration-color: var(--fg); }
.jl-gap { display: inline-block; min-width: 3.4em; height: 1.4em; vertical-align: -.25em; margin: 0 .2em; border-bottom: 2px solid var(--fg); }
.jl-box { display: inline-grid; place-items: center; min-width: 1.8em; height: 1.6em; margin: 0 .2em; padding: 0 .3em; border: 1.5px solid var(--fg); border-radius: 3px; font-size: .9em; font-weight: 700; vertical-align: .05em; line-height: 1; }
.jl-box.now { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

/* The hub's head: the title and the level chip on one line, then the one main action */
.jl-titlerow { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2) var(--s-3); }
.jl-titlerow h1 { margin: 0; }
.jl-head p { margin: var(--s-1) 0 0; }
.jl-first { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-4); margin: 0 0 var(--s-5); }
/* Practise next: a primary button like every other, its words centred, the plain name over its Japanese in a small
   line */
.page .jl-first .btn.jl-next { display: inline-flex; flex-wrap: nowrap; align-items: center; justify-content: center; padding: var(--s-2) var(--s-5); text-align: center; white-space: normal; line-height: 1.25; }
.jl-nextwords { flex: 0 1 auto; display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 2px; min-width: 0; }
.jl-nextwords small { font-size: var(--fs-14); font-weight: 400; opacity: .85; }
.jl-banner { display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; padding: 12px 16px; margin-bottom: 18px; border-radius: var(--r); background: var(--accent-soft); color: var(--fg); }

/* The hub: readiness and the mock on one side, the test's parts (the data) on the wider side */
.jl-hub { display: grid; gap: 18px; align-items: start; }
.jl-hub .stack { display: grid; gap: 18px; align-content: start; min-width: 0; }
.jl-hub .panel h2 { margin-top: 0; }
/* No estimate yet: one quiet line under Practise next, no card */
.jl-ready-none { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--s-2); margin: 0 0 var(--s-5); }
.jl-first:has(+ .jl-ready-none) { margin-bottom: var(--s-3); }
.jl-ready-none h2 { margin: 0; font-size: var(--fs-16); }
.jl-ready-none p { margin: 0; }
/* The test, part by part: flat, the parts one hairline apart (no card around folds and rows) */
.jl-sections > h2 { margin: 0 0 var(--s-2); }
.jl-sections > details.how { margin-top: 0; }
.jl-sections > details.how:last-of-type { border-bottom: 1px solid var(--line); }
.jl-line1 { margin: 0; font-size: var(--fs-18); }
.jl-line1 b { font-size: var(--fs-24); }
.jl-line2 { margin: var(--s-1) 0 0; }
.jl-readymore { margin-top: var(--s-4); }
.jl-readymore > summary { color: var(--accent-text); }
.jl-mock { padding-top: var(--s-2); padding-bottom: var(--s-2); }
.jl-rowoff { display: flex; align-items: center; gap: var(--s-3); min-height: 56px; padding: var(--s-2) 2px; }
.jl-rowoff small { white-space: normal !important; }
.jl-recent-h { margin: var(--s-3) 0 0; font-size: var(--fs-16); }
/* each part of the test folds: its plain name, its Japanese and minutes under it, how many types are tried */
.jl-secfold { margin-top: 0; }
.jl-secfold:first-of-type { border-top: 1px solid var(--line); }
.jl-secfold > summary { min-height: 64px; gap: var(--s-3); padding: var(--s-2) 2px; }
.jl-sumname { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; flex: 1; min-width: 0; }
.jl-sumname b { font-size: var(--fs-18); color: var(--ink); }
.jl-sumname small { font-size: var(--fs-14); font-weight: 400; color: var(--ink-3); overflow-wrap: anywhere; }
.jl-summeta { flex: none; font-size: var(--fs-14); font-weight: 400; color: var(--ink-3); white-space: nowrap; }
.jl-secfold > .jl-types { margin: 0 0 var(--s-2); }
.jl-later > p { margin: 0 0 var(--s-2); }
.jl-later-list small { display: inline; }
@media (min-width: 1000px) { .jl-hub { grid-template-columns: minmax(340px, 5fr) minmax(0, 7fr); } }
.jl-sec { padding: 12px 0; border-top: 1px solid var(--line); }
.jl-sec:first-of-type { border-top: 0; }
.jl-sechead { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; flex-wrap: wrap; margin-bottom: 8px; }
.jl-sechead .num b { font-size: 22px; }
.jl-need { margin: 0; padding: 10px 12px; border-radius: var(--r-sm); background: var(--sunk); color: var(--mute); font-size: 14px; }
.jl-bar { position: relative; height: 14px; border-radius: 999px; background: var(--sunk); overflow: visible; margin: 6px 0 4px; }
.jl-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 999px; background: var(--accent-2); }
.jl-fill.low { background: var(--bad); }
.jl-mark { position: absolute; top: -5px; bottom: -5px; width: 3px; margin-left: -1.5px; border-radius: 2px; }
.jl-mark.min { background: var(--bad); }
.jl-mark.pace { background: var(--fg); }
.jl-legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 14px; color: var(--mute); }
.jl-legend i { display: inline-block; width: 3px; height: 14px; border-radius: 2px; margin-right: 6px; vertical-align: -2px; }
.jl-legend i.min { background: var(--bad); }
.jl-legend i.pace { background: var(--fg); }
.jl-low { margin: 8px 0 0; padding: 8px 12px; border-radius: var(--r-sm); background: var(--bad-soft); color: var(--bad); font-size: 14px; font-weight: 600; }
.jl-total { padding-top: 12px; border-top: 2px solid var(--line2); }
.jl-verdict { margin: 10px 0 0; padding: 10px 12px; border-radius: var(--r-sm); font-weight: 600; }
.jl-verdict.good { background: var(--good-soft); color: var(--good); }
.jl-verdict.warn { background: var(--warn-soft); color: var(--warn); }
.jl-note { margin: 12px 0 0; }
.jl-partlist { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 2px; counter-reset: part; }
.jl-partlist li { display: flex; justify-content: space-between; gap: 12px; align-items: center; padding: 10px 0; border-top: 1px solid var(--line); }
.jl-partlist li:first-child { border-top: 0; }
.jl-partlist li > span { display: grid; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.jl-partlist li > b { white-space: nowrap; }
.jl-partlist.big li { padding: 12px 0; }
.jl-notready { padding: 12px 14px; border-radius: var(--r-sm); background: var(--sunk); color: var(--mute); }
.jl-source { margin: var(--s-6) 0 0; }
.jl-about blockquote { margin: 4px 0 6px; padding: 10px 14px; border-left: 3px solid var(--line2); color: var(--mute); }
.jl-types { list-style: none; margin: 0; padding: 0; }

/* One question */
.jl-practice { max-width: 860px; margin: 0 auto; }
.jl-phead { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 12px; }
.jl-phead h1 { margin: 2px 0 4px; }
.jl-phead p { margin: 0; }
.jl-item { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: 20px; box-shadow: var(--shadow); min-width: 0; }
.jl-how { margin-bottom: 14px; padding-bottom: 10px; border-bottom: 1px dashed var(--line2); }
.jl-how p { margin: 0 0 2px; }
.jl-how p[lang=ja] { font-weight: 600; }
.jl-stem { font-size: 19px; margin: 6px 0 14px; overflow-wrap: anywhere; }
.jl-usehead { font-size: var(--fs-26); font-weight: 700; }
.jl-n { display: inline-grid; place-items: center; min-width: 30px; height: 28px; margin-right: 10px; padding: 0 6px; border: 1.5px solid var(--fg); border-radius: 4px; font: 700 15px/1 var(--font); vertical-align: .15em; }
.jl-item { container-type: inline-size; }
.jl-opts { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.jl-opts.long, .jl-opts.mid { grid-template-columns: minmax(0, 1fr); }
/* short options sit in one row of four when the question has the room, as the booklet prints them; middling ones
   two by two, then four; long ones one under another */
@container (min-width: 520px) { .jl-opts.mid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@container (min-width: 560px) { .jl-opts:not(.long):not(.mid) { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@container (min-width: 820px) { .jl-opts.mid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* a very narrow question (a 320 px phone) takes even the shortest answers one under another */
@container (max-width: 279px) { .jl-opts { grid-template-columns: minmax(0, 1fr); } }
/* a phone: one layout for every kind of question, the answers one under another (the thumb runs down one column) */
@media (max-width: 720px) { .jl-opts, .jl-opts.mid, .jl-opts:not(.long):not(.mid) { grid-template-columns: minmax(0, 1fr); } }
.jl-opt { min-height: 54px; gap: var(--s-2); padding-inline: var(--s-3); }
/* An answer is never broken inside a word: kana and kanji keep together (keep-all) and break only where they
   would not fit at all; a long answer (a sentence) breaks between phrases. */
.jl-opt .jl-ot { flex: 1; min-width: 0; font-size: 18px; word-break: keep-all; line-break: strict; overflow-wrap: anywhere; }
.jl-opts.long .jl-opt .jl-ot { word-break: normal; }
@supports (word-break: auto-phrase) { .jl-opts.long .jl-opt .jl-ot:lang(ja) { word-break: auto-phrase; } }
.jl-on { display: inline-grid; place-items: center; width: 26px; height: 26px; flex: none; border-radius: 50%; border: 2px solid var(--field); font: 700 14px/1 var(--font); color: var(--mute); }
.jl-opt[aria-checked=true] { border-color: var(--accent); background: var(--accent-soft); }
.jl-opt[aria-checked=true] .jl-on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.jl-opt.right { border-color: var(--good); background: var(--good-soft); }
.jl-opt.wrong { border-color: var(--bad); background: var(--bad-soft); }
.jl-opt.right .jl-on { background: var(--good); border-color: var(--good); color: var(--good-soft); }
.jl-opt.wrong .jl-on { background: var(--bad); border-color: var(--bad); color: var(--bad-soft); }
.jl-pics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.jl-pics .jl-opt { flex-direction: column; align-items: center; padding: 10px; gap: 8px; }
.jl-pics img { width: 100%; max-width: 220px; height: auto; border-radius: var(--r-sm); }
.jl-spoken { display: flex; gap: 12px; flex-wrap: wrap; }
.jl-spoken .jl-opt { width: auto; min-width: 72px; justify-content: center; }
.jl-figure { margin: 0 0 14px; text-align: center; }
.jl-figure img { max-width: min(100%, 360px); height: auto; border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--panel); }
.jl-audio { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; min-height: 44px; }
.jl-now { font-weight: 600; color: var(--accent-2); }
/* Check, then the feedback sheet, the full width at the foot of the question (sticky on a phone, below) */
/* one column that never grows past the page (a long verdict wraps; it never widens the dock past the gutters) */
.jl-acts { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-3); margin-top: var(--s-4); min-width: 0; }
.jl-acts > * { min-width: 0; max-width: 100%; box-sizing: border-box; }
.jl-acts > .primary { width: 100%; min-height: 52px; }
/* Practice's verdict: two fixed lines, bold "Right." / "Not quite." over "The answer is 3: はんぶん". Neither line
   wraps (jlpt.js names a too-long answer by its number alone), so the dock is the same height for every answer. */
.jl-said-box .verdict.jl-v { display: grid; grid-template-columns: minmax(0, 1fr); line-height: var(--lh-body); }
.jl-v-head, .jl-v-ans { display: block; min-width: 0; white-space: nowrap; overflow: hidden; }
.jl-v-ans { font-weight: 400; }
/* On the narrowest phones (320) the answer line ("The answer is 4, marked above.") is a little wide for one line: the
   smallest size the site allows keeps it whole. */
@media (max-width: 340px) { .jl-v-ans { font-size: var(--fs-14); } }
.jl-acts.answer-sheet .jl-after { margin-top: 0; }
.jl-acts .verdict { margin-top: 0; }
.jl-whynot { margin-top: var(--s-2); }
.jl-whynot .jl-mistakes { margin-bottom: var(--s-2); }
.jl-score { margin: -4px 0 10px; }
.jl-pkind { margin: 0; }
.jl-after:empty { display: none; }
.jl-after { margin-top: 14px; }
.jl-why { margin: 10px 0 6px; }
.jl-mistakes { margin: 6px 0 0; padding-left: 0; list-style: none; display: grid; gap: 6px; }
.jl-mistakes li { padding: 8px 12px; border-radius: var(--r-sm); background: var(--sunk); overflow-wrap: anywhere; }
.jl-mistakes li.mine { background: var(--bad-soft); }
.jl-mistakes b { display: inline-grid; place-items: center; min-width: 24px; height: 24px; margin-right: 6px; border-radius: 50%; border: 1.5px solid var(--field); font-size: 14px; }
.jl-said { margin: 8px 0; padding-left: 28px; }
.jl-said li.good { color: var(--good); font-weight: 700; }
.jl-script { margin-top: 10px; }
.jl-script summary, .jl-pfold summary { cursor: pointer; min-height: 44px; display: flex; align-items: center; font-weight: 600; color: var(--accent); }
.jl-script dl { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 12px; margin: 4px 0 0; }
.jl-script dt { color: var(--mute); font-size: 14px; padding-top: .35em; }
.jl-script dd { margin: 0; overflow-wrap: anywhere; }
.jl-full { padding: 10px 12px; border-radius: var(--r-sm); background: var(--good-soft); overflow-wrap: anywhere; }
.jl-full b { padding: 0 .15em; }
.jl-full .jl-onstar { text-decoration: underline; text-decoration-color: var(--good); text-decoration-thickness: 2px; }

/* The ★ question */
.jl-slot { display: inline-flex; align-items: center; justify-content: center; min-width: 4.2em; min-height: 44px; margin: 2px .2em; padding: 0 8px; vertical-align: middle;
  border: 0; border-bottom: 2px solid var(--fg); border-radius: 6px 6px 0 0; background: var(--sunk); color: var(--fg); font: inherit; font-weight: 600; white-space: normal; }
.jl-slot.star { color: var(--accent); }
.jl-slot.full { background: var(--accent-soft); }
.jl-starmark { margin-left: 4px; color: var(--accent); font-size: .8em; }
.jl-parts { display: flex; flex-wrap: wrap; gap: 10px; }
.jl-part { min-height: 48px; font-size: 18px; font-weight: 500; white-space: normal; }
.jl-part:disabled { opacity: .35; }
.jl-hint { margin: -6px 0 10px; }

/* Passages, notices and tables */
.jl-passage { margin: 0 0 16px; padding: 16px 18px; border-radius: var(--r-sm); background: var(--bg); border: 1px solid var(--line); font-size: 17px; overflow-wrap: anywhere; }
.jl-passage p { margin: 0 0 .4em; }
.jl-ph { text-align: center; font-size: 18px; margin: 0 0 10px; }
.jl-frame-notice { border: 2px solid var(--line2); background: var(--panel); }
.jl-frame-memo, .jl-frame-email, .jl-frame-letter { border-style: dashed; }
.jl-tablewrap { overflow-x: auto; margin: 8px 0; border-radius: var(--r-sm); border: 1px solid var(--line2); }
.jl-table { min-width: 100%; width: auto; font-size: 16px; }
.jl-table th, .jl-table td { padding: 8px 10px; white-space: nowrap; }
.jl-table th { position: static; }

/* A mock test */
.jl-coverwrap { display: grid; gap: 18px; align-items: start; }
@media (min-width: 1000px) { .jl-coverwrap { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); } }
.jl-how2 ul { margin: 0; padding-left: 20px; display: grid; gap: 8px; }
.jl-mockbar { position: sticky; top: calc(var(--bar-h) + env(safe-area-inset-top)); z-index: 20; display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; padding: 10px 14px; margin: -8px 0 16px; border-radius: var(--r); background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow); }
.jl-mb-name { display: grid; gap: 2px; flex: 1 1 200px; min-width: 0; overflow-wrap: anywhere; }
.jl-clock { font: 700 22px/1 var(--mono); font-variant-numeric: tabular-nums; padding: 8px 12px; border-radius: var(--r-sm); background: var(--sunk); }
.jl-clock.low { background: var(--warn-soft); color: var(--warn); }
.jl-exit { color: var(--bad); }
.jl-mockbody { display: grid; gap: 16px; align-items: start; }
/* on a phone the question comes first and the palette under it; beside it on a computer */
.jl-palette { order: 2; }
@media (min-width: 1000px) { .jl-mockbody { grid-template-columns: 250px minmax(0, 1fr); } .jl-palette { order: 0; position: sticky; top: calc(var(--bar-h) + 110px); } }
.jl-palette { padding: 14px; border-radius: var(--r); background: var(--panel); border: 1px solid var(--line); min-width: 0; }
.jl-paltop { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; margin-bottom: 10px; flex-wrap: wrap; }
.jl-palgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 6px; }
.jl-pb { min-height: 44px; padding: 0; border-radius: 10px; font-size: 15px; position: relative; }
.jl-pb.a { background: var(--accent-2-soft); border-color: var(--accent-2); color: var(--accent-2); }
.jl-pb.f::after { content: ''; position: absolute; top: 4px; right: 4px; width: 8px; height: 8px; border-radius: 50%; background: var(--warn); }
.jl-pb[aria-current=true] { outline: 2px solid var(--accent); outline-offset: 1px; }
/* An answer not saved yet (no connection): a dashed edge and a small ! on its number (the button's name says it in
   words), and a line under the question with Try again. */
.jl-pb.u { border-style: dashed; border-color: var(--warn); }
.jl-pb.u::before { content: '!'; position: absolute; top: 3px; left: 5px; font-size: var(--fs-14); font-weight: 700; line-height: 1; color: var(--warn-text); }
.jl-unsaved { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); margin: var(--s-3) 0 0; padding: var(--s-1) var(--s-3); border-radius: var(--r-2); background: var(--warn-soft); color: var(--warn-text); }
.jl-unsaved[hidden] { display: none; }
.jl-unsaved .link { min-height: var(--tap); color: inherit; font-weight: 700; text-decoration: underline; }
.jl-unsaved-mark { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--warn); color: var(--surface); font-weight: 700; }
/* the part's chip and Flag on one line: a long chip gives way (an ellipsis; its full words in its title), never Flag */
.jl-qhead .chip { display: block; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; line-height: 24px; }
.jl-palkey { display: flex; gap: 14px; margin-top: 10px; flex-wrap: wrap; }
.jl-palkey i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; }
.jl-palkey i.a { background: var(--accent-2); }
.jl-palkey i.f { background: var(--warn); border-radius: 50%; }
.jl-qwrap, .jl-listen { min-width: 0; }
.jl-listen { max-width: 860px; margin: 0 auto; }
.jl-qhead { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: nowrap; min-width: 0; }
.jl-qhead > :not(.chip) { flex: none; }
.jl-qhead .jl-flag { margin-left: auto; }
.jl-flag { gap: var(--s-2); padding: 0 var(--s-3); color: var(--ink-2); }
.jl-flag svg { width: 20px; height: 20px; }
.jl-flag[aria-pressed=true] { background: var(--warn-soft); color: var(--warn-text); }
.jl-flag[aria-pressed=true] svg { fill: currentColor; }
.jl-nav { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-top: 14px; }
.jl-pos { min-width: 88px; padding: 0 var(--s-3); color: var(--ink-2); font-weight: 400; }
.jl-sheetsum { margin: 0 0 var(--s-3); }
/* only on an upright phone (where the bar holds the time and Exit) / everywhere else */
.jl-onphone { display: none; }
.jl-finishrow { display: flex; justify-content: flex-end; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.jl-break { max-width: 640px; margin: 6vh auto; text-align: left; }
.jl-nextpart { display: grid; gap: 4px; padding: 14px 16px; margin: 12px 0; border-radius: var(--r-sm); background: var(--sunk); }
.jl-cover h2 { margin-bottom: 12px; }
/* the pass mark as a small table of three rows (the part, the least it needs), and Start the full width at the foot
   of the cover */
.jl-passtable { width: 100%; margin: var(--s-4) 0; border-collapse: collapse; font-size: var(--fs-16); }
.jl-passtable caption { caption-side: top; text-align: left; padding-bottom: var(--s-1); font-weight: 700; }
.jl-passtable caption .mute { font-size: var(--fs-14); font-weight: 400; }
.jl-passtable th, .jl-passtable td { padding: var(--s-1) 0; border-top: 1px solid var(--line); vertical-align: baseline; }
.jl-passtable th { font-weight: 400; color: var(--ink-2); text-align: left; padding-right: var(--s-3); }
.jl-passtable td { text-align: right; white-space: nowrap; color: var(--ink-2); }
.jl-passtable td b { color: var(--ink); }
.jl-startbar .primary { width: 100%; }
.jl-coverside { display: grid; min-width: 0; }
.jl-coverside > details.how { margin-top: 0; }
.jl-coverside > details.how:last-child { border-bottom: 1px solid var(--line); }
.jl-passfold .jl-passtable { margin: 0 0 var(--s-2); }
.jl-passfold p { margin: 0 0 var(--s-3); }

/* A result */
.jl-score .jl-big { font-size: 28px; font-weight: 800; margin: 0 0 4px; letter-spacing: -.01em; }
.jl-big.good { color: var(--good); }
.jl-big.warn { color: var(--warn); }
.jl-totalline { margin: 0 0 6px; }
.jl-totalline b { font-size: 34px; }
.jl-letters { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.jl-letters li { display: grid; gap: 2px; padding: 12px; border-radius: var(--r-sm); background: var(--sunk); }
.jl-letter { font-size: 28px; }
.jl-letter.A { color: var(--good); }
.jl-letter.B { color: var(--warn); }
.jl-letter.C { color: var(--bad); }
.jl-review .seg { margin-bottom: 12px; }
.jl-review h3 { margin: 18px 0 8px; }
.jl-rv { margin-bottom: 14px; }
.jl-rvhead { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 6px; }
.jl-rv .jl-item { box-shadow: none; }
.jl-rv.no .jl-item { border-color: color-mix(in srgb, var(--bad) 40%, var(--line)); }

/* The placement test */
.jl-placement .jl-pl { max-width: 720px; margin: 0 auto; }
.jl-pl .lead { font-size: 18px; color: var(--mute); }
.jl-pl .link { display: inline-flex; align-items: center; min-height: var(--tap); }
.jl-plgo { gap: var(--s-2) var(--s-5); }
.jl-plcover .jl-plgo { margin-top: var(--s-4); }
.jl-pl details.how { margin-top: var(--s-5); }
.jl-steps { padding-left: 22px; display: grid; gap: 8px; margin: 0 0 18px; }
.jl-plwhat { margin: var(--s-5) 0 var(--s-2); font-size: var(--fs-16); color: var(--ink-2); }
.jl-plcover .jl-steps { margin-bottom: 0; color: var(--ink-2); }
.jl-plhead { display: flex; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.jl-kana { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: 22px; box-shadow: var(--shadow); text-align: center; }
.jl-kanabig { font-size: clamp(44px, 14vw, 72px); font-weight: 500; margin: 6px 0 18px; letter-spacing: .06em; }
.jl-kana .jl-opts { text-align: left; }
.jl-plfoot { justify-content: center; margin-top: 14px; }
.jl-plbig { font-size: 64px; font-weight: 800; margin: 0; color: var(--accent); letter-spacing: -.02em; }
.jl-pllevels { list-style: none; padding: 0; margin: 0 0 18px; display: flex; flex-wrap: wrap; gap: 10px; }
.jl-pllevels li { display: grid; gap: 2px; padding: 10px 14px; border-radius: var(--r-sm); background: var(--sunk); }
#pl-choose { margin-top: 14px; }

@media (max-width: 720px) {
  .jl-item { padding: 16px 14px; }
  .jl-stem { font-size: 18px; }
  .jl-passage { padding: 14px; font-size: 16px; }
  .jl-mockbar { top: calc(var(--bar-h) + env(safe-area-inset-top)); padding: 8px 10px; flex-wrap: nowrap; gap: 8px; }
  .jl-mb-name { flex: 1 1 auto; }
  .jl-mb-name b { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .jl-mb-name .jl-en { display: none; }
  .jl-exit { padding: 0 12px; }
  .jl-clock { font-size: 19px; }
  .jl-next { flex: 1 1 100%; }
  .jl-pkind { display: none; }
  .jl-startbar { position: sticky; z-index: 5; bottom: calc(var(--tab-h) + env(safe-area-inset-bottom)); padding: var(--s-2) 0; margin-bottom: calc(-1 * var(--s-2)); background: var(--surface); }
  .jl-hub .panel { padding: var(--s-4); }
  .jl-mock { padding-top: var(--s-1); padding-bottom: var(--s-1); }
}
/* Practice on a phone on its side: Check (and then the sheet with the verdict and Next) holds to the foot of the
   screen, above the home indicator, so the thumb finds it and the verdict and Next are in sight together. */
@media (max-width: 720px) { .jl-phead h1 { font-size: var(--fs-24); } }
@media (max-height: 500px) {
  .jl-practice .jl-acts { position: sticky; z-index: 5; bottom: calc(var(--tab-h) + env(safe-area-inset-bottom)); margin-top: var(--s-2); padding: var(--s-2) 0; background: var(--bg); }
  .jl-practice .jl-acts.answer-sheet { margin-top: var(--s-3); padding: var(--s-3) var(--s-4) var(--s-4); background: var(--surface); box-shadow: var(--shadow-lg);
    max-height: calc(100dvh - var(--bar-h) - env(safe-area-inset-top) - var(--tab-h) - env(safe-area-inset-bottom) - var(--s-7)); overflow-y: auto; overscroll-behavior: contain; }
  html:has(#main .jl-practice .jl-acts) { scroll-padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + 88px); }
  html:has(#main .jl-practice .jl-acts.answer-sheet) { scroll-padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + min(46vh, 340px)); }
}
/* An upright phone: Check, and after it the verdict (two fixed lines) over Next, are the dock at the foot of the screen
   (study.css, as in every session); the question's card grows to meet it, its answers at its foot in the thumb's
   reach, and the why comes to rest just above the dock (jlpt.js). */
@media (max-width: 720px) and (min-height: 501px) {
  .jl-practice .jl-item.dock-grow { display: flex; flex-direction: column; }
  .jl-practice .jl-item.dock-grow > :is(.jl-opts, .jl-pics, .jl-spoken) { margin-top: auto; }
  .jl-practice .jl-acts.dock { gap: var(--s-2); }
  /* the verdict's two lines, snug (each one line: see .jl-v) */
  .jl-acts .jl-said-box .verdict { min-height: 0; padding-block: var(--s-2); line-height: var(--lh-body); }
  .jl-acts .jl-said-box .verdict::before { top: calc(var(--s-2) + 2px); }
  html:has(#main .jl-practice .jl-acts.dock.answer-sheet) { scroll-padding-bottom: calc(var(--dock-at) + 132px); }
}
/* Placement on an upright phone: the cover's Start (and Not now under it) and a question's answers sit in the lower
   half of the screen, in reach of the thumb; the cover is not boxed. The page's height less the bar, the tab bar
   (none in a session) and the page's own padding. */
@media (max-width: 720px) and (min-height: 501px) {
  .jl-pl.jl-plcover, .jl-pl.jl-plq { display: flex; flex-direction: column;
    min-height: calc(100dvh - var(--bar-h) - env(safe-area-inset-top) - var(--tab-h) - env(safe-area-inset-bottom) - var(--s-4) - var(--s-7)); }
  .jl-pl.jl-plcover { padding: 0; border: 0; background: transparent; box-shadow: none; }
  .jl-plcover .jl-plgo { margin-top: auto; padding-top: var(--s-5); flex-direction: column; align-items: stretch; gap: var(--s-1); }
  .jl-plcover .jl-plgo .primary { width: 100%; }
  .jl-plcover .jl-notnow { justify-content: center; }
  .jl-plq #pl-q { flex: 1; display: flex; flex-direction: column; }
  .jl-plq #pl-q > :is(.jl-item, .jl-kana) { flex: 1; display: flex; flex-direction: column; }
  .jl-plq :is(.jl-opts, .jl-pics, .jl-parts) { margin-top: auto; }
  .jl-plq .jl-kanabig { flex: 1; display: grid; place-items: center; margin: var(--s-2) 0; }
  /* the kana question has no box of its own: its answers take the page's width, as in Practice and the mock */
  .jl-plq .jl-kana { padding: var(--s-2) 0 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
  .jl-plq .jl-kana .jl-opts { gap: var(--s-2); }
  .jl-plq .jl-plfoot .btn { width: 100%; }
}
/* A running mock on an upright phone: the head card is the part's name (its time and Exit are in the bar), the
   chip and Flag share one line, Finish this part is a row in the site's ⋯ (and Next's place on the last question:
   nothing in the middle of the page), the palette opens from the question's number as a sheet, and Previous and
   Next hold to the foot of the screen. */
@media (max-width: 720px) and (min-height: 501px) {
  .jl-onphone { display: inline-flex; }
  .jl-chip-ja { display: none; }
  .jl-offphone { display: none !important; }
  /* the part's name as a plain label (no box that could be taken for a field) */
  .jl-mockbar { position: static; margin: 0 0 var(--s-3); padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
  .jl-mockbar .jl-mb-name b { font-size: var(--fs-16); color: var(--ink-2); }
  .jl-mockbar .jl-mb-part { display: none; }
  .jl-mockbody .jl-palette { display: none; }
  .jl-flagword { display: none; }
  .jl-flag { width: var(--tap); padding: 0; justify-content: center; }
  /* Previous, the question's number and Next: a thumb bar fixed to the foot of the screen through the whole part */
  .jl-qwrap .jl-nav { position: fixed; z-index: 25; left: 0; right: 0; bottom: calc(var(--tab-h) + env(safe-area-inset-bottom)); margin: 0;
    padding: var(--s-2) var(--gut-r) var(--s-2) var(--gut-l); background: var(--surface); border-top: 1px solid var(--line); }
  html:not(:has(#tabbar:not([hidden]))) .jl-qwrap .jl-nav { bottom: 0; padding-bottom: calc(var(--s-2) + env(safe-area-inset-bottom)); }
  .jl-qwrap .jl-nav .btn { flex: 1 1 0; min-height: 52px; }
  .jl-qwrap { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
  html:has(#main .jl-qwrap .jl-nav) { scroll-padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + 80px); }
}
