/* JLPT drill. Colors/type come from css/tokens.css — this file only adds
   the drill-specific layout (flip cards, match grid, session views). */
body{line-height:1.55;}
h1,h2,h3{font-family:var(--font-display);font-weight:700;text-wrap:balance;margin:0;}
.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}
.wrap{max-width:var(--page-width);margin:0 auto;padding:0 var(--page-gutter) 80px;}
button{font-family:inherit;cursor:pointer;}

/* header / tabs
   Scoped to .wrap: the shared site header is also a <header>, so a bare
   element selector here used to add 50px of padding to it and make this
   page's nav bar taller than every other page's. */
.wrap > header{padding:32px 0 18px;border-bottom:1px solid var(--line);}
.eyebrow{font-family:var(--font-mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);margin-bottom:8px;}
h1{font-size:26px;}
.tabs{display:flex;gap:6px;margin-top:22px;background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:4px;}
.tab-btn{flex:1;border:none;background:none;padding:9px 8px;border-radius:4px;font-size:13.5px;color:var(--ink-soft);font-weight:500;}
.tab-btn.active{background:var(--accent);color:var(--ink-inverse);}
.view{display:none;padding-top:28px;}
.view.active{display:block;}

/* today view */
.stat-row{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:24px;}
.stat{flex:1;min-width:110px;background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:14px 16px;}
.stat .num{font-family:var(--font-mono);font-size:26px;font-weight:500;color:var(--accent);line-height:1.1;}
.stat .label{font-size:11.5px;color:var(--ink-soft);margin-top:2px;letter-spacing:.02em;}
.stat.warn .num{color:var(--flag);}

.today-card{background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:20px 22px;margin-bottom:16px;}
.today-card .n{font-family:var(--font-mono);font-size:11px;color:var(--ink-soft);letter-spacing:.08em;text-transform:uppercase;}
.today-card h3,.today-card h2{font-size:18px;margin-top:6px;}
/* Links in the roadmap text took the browser's default blue, unreadable on the dark page. */
.today-card a{color:var(--accent);text-underline-offset:2px;}
.today-card p{color:var(--ink-soft);font-size:14px;margin-top:8px;}

.deck-card{display:flex;align-items:center;justify-content:space-between;gap:16px;background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:18px 20px;margin-bottom:12px;flex-wrap:wrap;transition:border-color .15s ease,box-shadow .15s ease;}
.deck-card:hover{border-color:var(--accent-line);box-shadow:var(--shadow);}
.deck-card .info{flex:1;min-width:140px;}
.deck-card h3,.deck-card h2{font-size:17px;}
.deck-card .counts{font-family:var(--font-mono);font-size:12.5px;color:var(--ink-soft);margin-top:6px;}
.deck-card .counts b{color:var(--accent);}
.deck-card .counts b.warn{color:var(--flag);}
.exam-card{background:var(--accent-soft);border-color:var(--accent-line);}
.exam-card .deck-jp{color:var(--accent);font-weight:700;}
.streak-note{font-size:13px;color:var(--ink-soft);margin-top:8px;}
.streak-note.risk{color:var(--flag);font-weight:600;}
/* Wraps: three buttons side by side ran 100 px past a 375 px phone, and the
   browser zoomed the whole page out to fit. */
.deck-actions{display:flex;flex-wrap:wrap;gap:8px;}
.go-btn{background:var(--accent);color:var(--ink-inverse);border:none;border-radius:999px;padding:11px 18px;font-size:13.5px;font-weight:700;white-space:nowrap;transition:filter .15s ease,transform .1s ease;}
.go-btn:not(:disabled):hover{filter:brightness(1.08);}
.go-btn:not(:disabled):active{transform:translateY(1px);}
.go-btn.secondary{background:var(--surface-2);color:var(--ink);border:1px solid var(--line);}
.go-btn:disabled{opacity:.4;cursor:default;}

details.settings{margin-top:24px;border:1px solid var(--line);border-radius:6px;background:var(--surface);}
details.settings summary{padding:12px 16px;font-size:13px;color:var(--ink-soft);cursor:pointer;list-style:none;font-family:var(--font-mono);}
details.settings summary::-webkit-details-marker{display:none;}
.settings-body{padding:4px 16px 16px;display:flex;gap:20px;flex-wrap:wrap;}
.field{display:flex;flex-direction:column;gap:4px;}
.field label,.field-label{font-size:12px;color:var(--ink-soft);}
.field input{width:70px;background:var(--bg);border:1px solid var(--line);border-radius:4px;padding:6px 8px;color:var(--ink);font-family:var(--font-mono);font-size:14px;}

/* session view */
.session-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;}
#sessionSave{margin-left:auto;margin-right:10px;}
.session-head .exit{background:none;border:1px solid var(--line);color:var(--ink-soft);border-radius:5px;padding:7px 12px;font-size:12.5px;}
.progress-bar{height:8px;background:var(--surface-2);border-radius:999px;overflow:hidden;margin-bottom:24px;}
.progress-bar .fill{height:100%;border-radius:999px;background:linear-gradient(90deg,var(--honey-1),var(--honey-2));transition:width .3s ease;}
@media (prefers-reduced-motion: reduce){.progress-bar .fill{transition:none;}}

.card-scene{perspective:1400px;}
/* The two faces are stacked in ONE grid cell rather than positioned
   absolutely. Absolute faces contribute no height, so the card was exactly
   its min-height and no taller — an N1 grammar note (some run past 700
   characters) was simply cut off at the bottom edge with nothing to say so.
   As grid items they size to their own content, so the card grows to fit
   the longer of the two faces, and only the genuinely long ones scroll. */
.card{display:grid;min-height:min(300px,42vh);border-radius:18px;background:var(--surface);transform-style:preserve-3d;transition:transform .45s cubic-bezier(.4,.2,.2,1);}
.card[data-shape="kanji"]{min-height:min(360px,46vh);}
.card[data-shape="grammar"]{min-height:min(380px,48vh);}
.card.flipped{transform:rotateY(180deg);}
@media (prefers-reduced-motion: reduce){.card{transition:none;}}
/* Capped against the viewport: a card tall enough to push the Chưa
   thuộc/Đã thuộc buttons off-screen makes the deck unusable on a laptop,
   so past that point the face scrolls instead of growing. */
/* Deliberately NOT overflow:auto on the face. Any overflow other than
   `visible` flattens it out of the card's 3D space and the flip then shows
   the front on both sides — .face-scroll inside it does the scrolling. */
/* position:relative keeps .word-tag and .tap-hint anchored to the face —
   they were absolute against it back when the face itself was absolute. */
.face{position:relative;grid-area:1/1;backface-visibility:hidden;display:grid;border-radius:18px;border:1px solid var(--line);box-shadow:var(--shadow);background:var(--surface);max-height:min(66vh,640px);overflow:visible;}
/* "safe" centring: a plain `center` pushes overflowing content past the
   top of the scroll box, where it can never be scrolled back into view —
   which is exactly what happens on an answer with several examples. */
.face-scroll{min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:safe center;text-align:center;padding:30px 24px;border-radius:18px;overflow-y:auto;overscroll-behavior:contain;}
/* -webkit-appearance:none is what makes the bar permanent: macOS hides
   overlay scrollbars until you are already scrolling, so a card whose
   answer continues below the fold looked like a card whose answer simply
   ended there. */
.face-scroll::-webkit-scrollbar{-webkit-appearance:none;width:9px;}
.face-scroll::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:999px;border:2px solid var(--surface);}
.face-scroll::-webkit-scrollbar-track{background:transparent;}
.face-scroll{scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent;}
/* The hint promises a tap, so the whole card is the target. */
.card{cursor:pointer;}
/* The answer side is lifted with a honey edge rather than a flat fill, so
   revealing it reads as a reward instead of a colour change. */
.face.back{transform:rotateY(180deg);border-color:var(--accent-line);box-shadow:var(--shadow-lg);}
.face.back::before{content:"";position:absolute;inset:0 0 auto 0;height:4px;border-radius:18px 18px 0 0;background:linear-gradient(90deg,var(--honey-1),var(--honey-2));}
.tap-hint{position:absolute;bottom:16px;font-family:var(--font-mono);font-size:10.5px;color:var(--ink-faint);letter-spacing:.08em;text-transform:uppercase;}
.word-jp{font-family:var(--font-jp);font-size:52px;font-weight:700;line-height:1.15;}
/* A French or English word too long for the card even at its smallest
   (js/drill.js fitWords) breaks mid-word rather than running off the edge. */
.word-break{overflow-wrap:anywhere;}
.word-reading{margin-top:10px;font-size:15px;color:var(--ink-faint);letter-spacing:.02em;}
.word-tag{position:absolute;top:16px;left:20px;font-size:10.5px;font-weight:700;color:var(--accent);background:var(--accent-soft);border-radius:999px;padding:3px 10px;text-transform:uppercase;letter-spacing:.06em;}
.pattern-jp{font-family:var(--font-jp);font-size:26px;font-weight:600;line-height:1.4;}
.pattern-form{margin-top:10px;font-size:13.5px;color:var(--ink-soft);font-family:var(--font-mono);}
.meaning-vi{font-size:19px;font-weight:600;line-height:1.45;}
/* No max-height here on purpose. A scroll box inside a scroll box meant
   the grammar explanation had its own 120px window: you could scroll the
   card to the bottom and still be looking at a third of the note. The face
   is the only thing that scrolls now. */
.explain{margin-top:12px;font-size:13px;line-height:1.7;color:var(--ink-soft);text-align:left;white-space:pre-wrap;width:100%;}
.example{margin-top:14px;font-size:13.5px;line-height:1.75;text-align:left;white-space:pre-wrap;background:var(--surface-2);padding:10px 14px;border-radius:10px;width:100%;max-width:100%;}
.example .speak-btn{margin-left:8px;vertical-align:middle;}
/* Meanings on N1 vocab run to several numbered senses on their own lines;
   \n in the data has to survive or they read as one run-on sentence. A
   centred paragraph of that length is unreadable, so anything past a line
   or two is set left (drill.js tags it). */
.meaning-vi{white-space:pre-wrap;}
.meaning-vi.long{text-align:left;font-size:16px;width:100%;}

.speak-btn{-webkit-appearance:none;appearance:none;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:50%;border:1px solid var(--line);background:var(--bg);color:var(--accent);font-size:15px;line-height:1;position:relative;z-index:2;}
.speak-btn:active{background:var(--accent-soft);}
.speak-btn.small{width:26px;height:26px;font-size:12px;flex:none;}
.word-reading-row{display:flex;align-items:center;justify-content:center;gap:8px;margin-top:10px;}
.pattern-reading-row{display:flex;align-items:center;justify-content:center;gap:8px;margin-top:6px;}
.match-tile.jp{display:flex;align-items:center;justify-content:space-between;gap:8px;}
.match-tile.jp .lbl{flex:1;}

.answer-row{display:flex;gap:8px;margin-top:22px;}
.answer-row button{flex:1;min-width:0;border-radius:12px;padding:12px 6px;font-size:15px;font-weight:700;border:1px solid var(--line);transition:transform .1s ease,filter .15s ease;}
.answer-row .ivl{display:block;margin-top:3px;font-size:11.5px;font-weight:500;opacity:.8;font-variant-numeric:tabular-nums;min-height:1.2em;}
.answer-row button:active{transform:translateY(2px);}
.answer-row button:hover{filter:brightness(1.06);}
.btn-again{background:var(--flag-soft);color:var(--flag);border-color:color-mix(in srgb, var(--flag) 30%, transparent);}
.btn-good{background:var(--ok-soft);color:var(--ok);border-color:color-mix(in srgb, var(--ok) 30%, transparent);}
.btn-hard{background:var(--accent-soft);color:var(--accent);border-color:color-mix(in srgb, var(--accent) 30%, transparent);}
.btn-easy{background:var(--surface-2);color:var(--ink);border-color:var(--line);}
.flip-hint-row{margin-top:22px;text-align:center;}
.flip-btn{background:var(--accent);color:var(--ink-inverse);border:none;border-radius:999px;padding:14px 34px;font-size:14.5px;font-weight:700;box-shadow:var(--shadow);transition:transform .1s ease,filter .15s ease;}
.flip-btn:hover{filter:brightness(1.08);}
.flip-btn:active{transform:translateY(2px);}

/* match module */
.match-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
.match-col{display:flex;flex-direction:column;gap:8px;}
.match-tile{-webkit-appearance:none;appearance:none;width:100%;color:var(--ink);border:1px solid var(--line);background:var(--surface);border-radius:12px;padding:15px 14px;font-size:15px;text-align:left;cursor:pointer;transition:background .15s,border-color .15s,opacity .15s,transform .1s;}
.match-tile:not(.solved):hover{border-color:var(--accent-line);}
.match-tile:not(.solved):active{transform:translateY(1px);}
.match-tile.jp{font-family:var(--font-jp);font-size:16px;}
/* A long English word ("industrialization") would widen its column and
   push the other off screen; it breaks inside the tile instead. */
.match-tile{overflow-wrap:anywhere;}
.match-tile.selected{border-color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 2px var(--accent-soft);}
.match-tile.solved{opacity:.32;pointer-events:none;text-decoration:line-through;text-decoration-color:var(--ink-soft);}
.match-tile.wrong{border-color:var(--flag);background:var(--flag-soft);}
@media (prefers-reduced-motion: no-preference){.match-tile{transition:background .15s,border-color .15s,opacity .3s;}}
.match-meta{display:flex;align-items:center;justify-content:space-between;font-family:var(--font-mono);font-size:12px;color:var(--ink-soft);margin-bottom:14px;}
.match-meta .mistakes{color:var(--flag);}

.done-screen{text-align:center;padding:60px 20px;}
.done-screen h2{font-size:22px;}
.done-screen p{color:var(--ink-soft);margin-top:10px;font-size:14.5px;}
.reverse-prompt{font-size:21px;font-weight:700;line-height:1.4;margin:6px 0 4px;text-wrap:balance;}
.reverse-hint{margin-top:12px;font-size:13.5px;color:var(--ink-soft);}
.reverse-hint summary{cursor:pointer;color:var(--accent);font-weight:600;}
.reverse-answer{margin-top:16px;padding-top:14px;border-top:1px dashed var(--line);}
.reverse-word{font-size:34px;font-weight:700;display:flex;align-items:center;justify-content:center;gap:10px;}
.reverse-reading{margin-top:4px;color:var(--ink-soft);font-size:15px;}
.answer-row[hidden]{display:none;}
.line-text{font-size:24px;font-weight:700;line-height:1.55;text-align:center;overflow-wrap:anywhere;text-wrap:balance;}
.line-text[lang="ja"]{font-family:var(--font-jp);}
.line-text.small{font-size:19px;}
.cloze-opt .copt-m{display:block;margin-top:4px;font-family:var(--font-body,inherit);font-size:13px;font-weight:500;line-height:1.4;color:var(--ink-soft);}
.cloze-vi{margin-top:6px;}
.vid-ex{margin-top:16px;padding:14px 16px;border:1px solid var(--line);border-radius:12px;background:var(--surface);}
.vid-ex[hidden],.vx-player[hidden]{display:none;}
.vx-label{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent);}
.vx-sentence{margin:6px 0 0;font-size:17px;line-height:1.7;overflow-wrap:anywhere;}
.vx-sentence[lang="ja"]{font-family:var(--font-jp);}
.vx-sentence b{color:var(--accent);}
.vx-trans{margin:4px 0 0;font-size:13.5px;color:var(--ink-soft);}
.vx-trans b{color:var(--ink);font-weight:600;}
.vx-actions{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:10px;}
.vx-lesson{font-size:13px;color:var(--ink-soft);overflow-wrap:anywhere;}
.vx-player{margin-top:12px;aspect-ratio:16/9;width:100%;}
.vx-player iframe{width:100%;height:100%;border:0;border-radius:10px;}
.write-model{margin-top:12px;font-size:14px;color:var(--ink-soft);}
.write-model span[lang="ja"]{font-family:var(--font-jp);color:var(--ink);}
.write-label{display:block;margin:18px 0 6px;font-size:13px;font-weight:600;color:var(--ink-soft);}
.write-input{width:100%;box-sizing:border-box;padding:12px 14px;border:1px solid var(--line);border-radius:12px;background:var(--surface);color:var(--ink);font-size:17px;line-height:1.6;resize:vertical;}
.write-input[lang="ja"]{font-family:var(--font-jp);}
.write-input:focus{outline:2px solid var(--accent);outline-offset:1px;}
.write-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px;}
.write-result{margin-top:14px;}
.write-fix{margin-top:10px;font-size:17px;display:flex;flex-wrap:wrap;align-items:center;gap:6px;}
.write-fix span[lang="ja"]{font-family:var(--font-jp);}
.write-fix-label{font-size:13px;font-weight:600;color:var(--ink-soft);}
.write-why{margin:8px 0 0;font-size:14.5px;line-height:1.6;}
.write-error{color:var(--flag);font-size:14px;}
.write-result .muted{color:var(--ink-faint);font-size:13.5px;}
.write-left{margin-top:8px;font-size:12.5px;}
.reverse-note{text-align:center;color:var(--ink-soft);font-size:13.5px;margin:14px 0 0;}
.done-screen .done-tip{max-width:460px;margin:18px auto 0;padding:12px 16px;border-radius:10px;background:var(--surface);border:1px solid var(--line);color:var(--ink-soft);font-size:13.5px;line-height:1.55;text-align:left;}
.done-screen .back-btn{margin-top:26px;background:var(--accent);color:var(--ink-inverse);border:none;border-radius:6px;padding:12px 24px;font-size:14px;font-weight:600;}

.wrap > footer{padding:36px 0 8px;color:var(--ink-soft);font-size:11.5px;font-family:var(--font-mono);text-align:center;}

/* Sino-Vietnamese reading on a kanji card — deliberately the most
   prominent thing on the answer side, because for a Vietnamese learner it
   is the hook that makes the meaning stick. */
.hanviet{margin-top:10px;font-family:var(--font-display);font-size:26px;font-weight:700;color:var(--accent);text-transform:capitalize;}
.deck-jp{font-family:var(--font-jp);font-size:13px;font-weight:400;color:var(--ink-faint);margin-left:6px;}
.deck-card .counts b.warn{color:var(--flag);}
.match-tile .lbl{font-size:inherit;}

/* Per-deck progress bar on the Today view — seeing "34 of 107 learned"
   fill up is the main thing that makes a long deck feel finishable. */
.deck-progress{height:6px;background:var(--surface-2);border-radius:999px;overflow:hidden;margin-top:10px;}
.deck-progress .fill{height:100%;border-radius:999px;background:linear-gradient(90deg,var(--honey-1),var(--honey-2));transition:width .4s ease;}
.deck-card .info{min-width:200px;}
.done-screen h2{font-family:var(--font-display);}
.done-screen .back-btn{border-radius:999px;font-weight:700;padding:13px 28px;}

/* Focus mode. A study session has its own counter and exit button, so the
   page title and tab bar above it are just taking the vertical space the
   answer buttons need to stay on screen. */
/* In a session the page title steps aside, but the h1 stays for a screen
   reader: clipped rather than display:none. Tabs and the rest go. */
body.in-session .wrap > header{padding:0;border:0;}
body.in-session .wrap > header > :not(.page-title){display:none;}
body.in-session .wrap > header .page-title{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}
body.in-session .site-header{display:none;}
body.in-session .wrap{padding-top:18px;}

/* A tab that leaves the page (the N5 mock exam) rather than switching
   views — looks like a tab, behaves like a link. */
.tab-link{flex:1;display:flex;align-items:center;justify-content:center;padding:9px 8px;border-radius:4px;font-size:13.5px;font-weight:500;color:var(--ink-soft);text-decoration:none;}
.tab-link:hover{background:var(--surface-2);color:var(--ink);}

/* Roadmap card that is itself the call to action. */
a.cta-card{display:block;text-decoration:none;color:inherit;border-color:var(--accent-line);background:var(--accent-soft);transition:border-color .15s ease,box-shadow .15s ease;}
a.cta-card:hover{border-color:var(--accent);box-shadow:var(--shadow);}
a.cta-card .n{color:var(--accent);}
.cta-go{display:inline-block;margin-top:12px;font-size:13.5px;font-weight:600;color:var(--accent);}

/* YouGlish — the word on this card, said by real people (js/youglish.js). */
.usage-btn{margin-top:14px;width:100%;font-size:13px;font-weight:600;color:var(--accent);background:var(--accent-soft);border:1px solid var(--accent-line);border-radius:999px;padding:9px 14px;position:relative;z-index:2;}
.usage-btn:hover{filter:brightness(1.05);}
.yg-panel{margin-top:18px;background:var(--surface);border:1px solid var(--accent-line);border-radius:14px;padding:16px;}
.yg-panel[hidden]{display:none;}
.yg-head{display:flex;align-items:baseline;gap:12px;margin-bottom:10px;}
.yg-term{font-family:var(--font-jp);font-size:18px;font-weight:700;color:var(--accent);word-break:break-word;}
.yg-count{font-size:12px;color:var(--ink-faint);}
.yg-close{margin-left:auto;background:none;border:none;font-size:16px;color:var(--ink-faint);padding:2px 6px;}
.yg-close:hover{color:var(--ink);}
.yg-status:not(:empty){font-size:13px;color:var(--ink-soft);margin:0 0 10px;}
#ygWidget{width:100%;overflow:hidden;}
#ygWidget iframe{max-width:100%;}
.yg-actions{display:flex;gap:8px;margin-top:12px;}
.yg-actions .go-btn{flex:1;}

/* ---------- day-by-day roadmap (js/drill.js, course.plan) ---------- */
.plan-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap;}
.plan-eyebrow{font-family:var(--font-mono);font-size:11px;color:var(--accent);letter-spacing:.08em;text-transform:uppercase;}
.plan-title{font-family:var(--font-display);font-size:24px;margin-top:4px;text-wrap:balance;display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.plan-sub{color:var(--ink-soft);font-size:14px;margin-top:6px;max-width:60ch;}
.plan-progress{margin-top:16px;}
.plan-progress-label{font-size:12px;color:var(--ink-soft);margin:6px 0 18px;}
.plan-notes-title{font-family:var(--font-display);font-size:18px;margin:34px 0 14px;}

.plan-month{background:var(--surface);border:1px solid var(--line);border-radius:14px;margin-bottom:10px;}
.plan-month[open]{border-color:var(--accent-line);}
.plan-month summary{display:flex;align-items:baseline;gap:12px;padding:15px 18px;cursor:pointer;list-style:none;}
.plan-month summary::-webkit-details-marker{display:none;}
.plan-month summary::before{content:"›";color:var(--ink-faint);font-weight:700;transition:transform .15s ease;display:inline-block;}
.plan-month[open] summary::before{transform:rotate(90deg);}
.plan-month summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:14px;}
.plan-month-name{font-weight:700;font-size:16px;}
.plan-month-range{font-size:12px;color:var(--ink-soft);}
.plan-month-count{margin-left:auto;font-size:12.5px;color:var(--ink-soft);}
.plan-month.is-done .plan-month-count{color:var(--ok);font-weight:600;}

.plan-days{display:grid;grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:8px;padding:0 14px 14px;}
.plan-day{display:grid;grid-template-columns:1fr auto;align-items:center;gap:2px 6px;text-align:left;background:var(--surface-2);border:1px solid var(--line);border-radius:10px;padding:9px 11px;color:var(--ink);font:inherit;cursor:pointer;}
.plan-day:not(:disabled):hover{border-color:var(--accent-line);}
.plan-day:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
.plan-day-n{font-weight:700;font-size:13.5px;}
.plan-day-mark{font-size:12px;}
.plan-day-sub{grid-column:1 / -1;font-size:11px;color:var(--ink-soft);line-height:1.35;}
.plan-day.is-done{background:var(--ok-soft);border-color:transparent;}
.plan-day.is-done .plan-day-mark{color:var(--ok);font-weight:700;}
.plan-day.is-next{background:var(--accent-soft);border-color:var(--accent);}
.plan-day.is-locked{background:var(--surface-2);cursor:not-allowed;}

.plan-back{background:none;border:none;color:var(--accent);font:inherit;font-size:13.5px;font-weight:600;padding:0;margin-bottom:14px;cursor:pointer;}
.plan-pill{font-family:var(--font-body);font-size:12px;font-weight:700;border-radius:999px;padding:3px 10px;}
.plan-pill.ok{background:var(--ok-soft);color:var(--ok);}
.plan-note{margin-top:14px;background:var(--accent-soft);border-radius:10px;padding:10px 14px;font-size:13.5px;}
.plan-steps{margin-top:18px;}
.plan-next{margin:4px 0 8px;}
.plan-list{margin-top:14px;background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:12px 16px;}
.plan-list summary{cursor:pointer;font-weight:600;font-size:14px;}
.plan-list ul{list-style:none;padding:0;margin-top:10px;display:grid;gap:6px;}
.plan-list li{display:grid;grid-template-columns:minmax(90px,30%) 1fr;gap:12px;font-size:13.5px;border-top:1px solid var(--line);padding-top:6px;}
.plan-list .jp,.quiz-reveal .jp{font-family:var(--font-jp);}

/* quiz */
.quiz-card{position:relative;background:var(--surface);border:1px solid var(--line);border-radius:16px;padding:44px 22px 24px;text-align:center;}
.quiz-ask{font-size:13px;color:var(--ink-soft);}
.quiz-show{margin-top:10px;overflow-wrap:anywhere;}
.quiz-show.jp{font-family:var(--font-jp);font-size:34px;font-weight:500;}
.quiz-show.vi{font-size:17px;font-weight:600;line-height:1.5;}
.quiz-sub{margin-top:12px;font-size:14px;color:var(--ink-soft);line-height:1.7;}
.quiz-hear{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px;margin-top:14px;}
.quiz-hear .usage-btn{width:auto;margin-top:0;}
.quiz-options{display:grid;gap:10px;margin-top:16px;}
@media (min-width:640px){.quiz-options{grid-template-columns:1fr 1fr;}}
.quiz-opt{background:var(--surface);border:1.5px solid var(--line-strong);border-radius:12px;padding:13px 16px;text-align:left;font:inherit;font-size:14.5px;color:var(--ink);line-height:1.45;cursor:pointer;overflow-wrap:anywhere;}
.quiz-opt.jp{font-family:var(--font-jp);font-size:17px;}
.quiz-opt:not(:disabled):hover{border-color:var(--accent);}
.quiz-opt:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
.quiz-opt:disabled{cursor:default;}
.quiz-opt.is-right{background:var(--ok-soft);border-color:var(--ok);}
.quiz-opt.is-wrong{background:var(--flag-soft);border-color:var(--flag);}
.quiz-feedback{margin-top:16px;display:grid;gap:10px;justify-items:start;}
.quiz-feedback:empty{display:none;}
.quiz-verdict{font-weight:700;font-size:14px;}
.quiz-verdict.ok{color:var(--ok);}
.quiz-verdict.no{color:var(--flag);}
.quiz-verdict.warn{color:var(--accent);}
.quiz-reveal{font-size:14px;color:var(--ink-soft);display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
/* "Điền câu": the example sentence with its grammar pattern blanked out */
.cloze-sentence{margin-top:14px;font-family:var(--font-jp);font-size:22px;line-height:1.8;overflow-wrap:anywhere;}
.cloze-gap{display:inline-block;min-width:3em;margin:0 .15em;border-bottom:2px solid var(--accent);color:var(--accent);font-weight:700;}
.cloze-full{font-family:var(--font-jp);font-size:17px;line-height:1.8;display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.cloze-full mark{background:var(--accent-soft);color:var(--ink);border-radius:4px;padding:0 3px;font-weight:700;}
.cloze-opt .mono{font-size:12px;color:var(--ink-faint);margin-right:4px;}

/* account tiers + upgrade request */
.plan-link{background:none;border:none;padding:0;font:inherit;color:var(--accent);font-weight:600;text-decoration:underline;text-underline-offset:2px;cursor:pointer;}
.plan-tomorrow{font-size:12.5px;color:var(--ink-soft);align-self:center;}
.plan-day.is-locked{cursor:pointer;}
.upgrade-dialog{width:min(480px,calc(100vw - 32px));border:1px solid var(--line);border-radius:16px;background:var(--surface);color:var(--ink);padding:22px 24px 24px;box-shadow:var(--shadow-lg);}
.upgrade-dialog::backdrop{background:var(--backdrop);}
.upgrade-close-row{display:flex;justify-content:flex-end;margin:-8px -10px 0 0;}
.upgrade-x{background:none;border:none;color:var(--ink-soft);font-size:18px;padding:4px 8px;cursor:pointer;}
.upgrade-why{margin-top:10px;background:var(--accent-soft);border-radius:10px;padding:10px 14px;font-size:13.5px;}
.upgrade-form{display:grid;gap:12px;margin-top:16px;justify-items:start;}
.upgrade-label{display:grid;gap:6px;width:100%;font-size:13px;font-weight:600;}
.upgrade-label em{font-style:normal;font-weight:400;color:var(--ink-soft);}
.upgrade-label input,.upgrade-label textarea{width:100%;font:inherit;font-size:14px;font-weight:400;color:var(--ink);background:var(--surface-2);border:1px solid var(--line);border-radius:10px;padding:10px 12px;}
.upgrade-label input[readonly]{color:var(--ink-soft);}
.upgrade-label textarea{resize:vertical;}
.upgrade-label input:focus-visible,.upgrade-label textarea:focus-visible{outline:2px solid var(--accent);outline-offset:1px;}
.upgrade-status{font-size:13px;color:var(--ink-soft);min-height:1em;}
.upgrade-status:empty{display:none;}
/* "Giải thích bằng · Explain in" (js/drill.js) */
.lang-switch{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:14px;font-size:13px;}
.lang-switch .lang-label{color:var(--ink-soft);}
.lang-switch button{border:1px solid var(--line);background:var(--surface);color:var(--ink-soft);border-radius:999px;padding:6px 14px;font-size:13px;font-weight:600;cursor:pointer;}
.lang-switch button[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:var(--ink-inverse);}
.lang-switch button:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
.lang-switch .lang-note{flex-basis:100%;color:var(--ink-faint);font-size:12px;}
.lang-switch .lang-note:empty{display:none;}

/* JLPT level colour (GUI plan 1.3): the page's <body class="lv-nX"> sets
   --lv (css/tokens.css). It marks where you are — the level badge, the
   tabs, the numbers, the progress — while actions stay honey, the brand. */
.eyebrow,.plan-eyebrow{color:var(--lv);}
.tab-btn.active{background:var(--lv);}
.stat .num,.deck-card .counts b{color:var(--lv);}
.progress-bar .fill,.deck-progress .fill{background:var(--lv);}
.word-tag{color:var(--lv);background:var(--lv-soft);}

/* Depth (GUI plan 1.4): cards rest on a soft shadow and lift on hover;
   buttons press down. Values from css/tokens.css. */
.stat,.today-card,.deck-card,.plan-month{border-radius:var(--radius-card);box-shadow:var(--shadow-card);}
.deck-card:hover{box-shadow:var(--shadow-lift);transform:translateY(-1px);}
.deck-card{transition:border-color .15s ease,box-shadow .15s ease,transform .15s ease;}
.go-btn,.flip-btn{box-shadow:var(--shadow-btn);}
.go-btn:active,.flip-btn:active,.answer-row button:active{transform:translateY(2px);box-shadow:none;}
.tabs{border-radius:12px;box-shadow:var(--shadow-card);}
.tab-btn,.tab-link{border-radius:9px;}
@media (prefers-reduced-motion: reduce){.deck-card:hover{transform:none;}}

/* ---------- GUI plan 3.1: page header ----------
   Level badge, then the title with its level in the level colour and a
   plain subtitle under it (the old monospace eyebrow line is gone). On a
   wide screen the language toggle sits on the title's row. */
.wrap > header{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;}
.wrap > header .tabs{margin-top:0;}
.page-title{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:12px;align-items:center;}
.page-title h1{font-size:26px;line-height:1.15;}
.page-sub{grid-column:2;margin:3px 0 0;font-size:13.5px;line-height:1.4;color:var(--ink-soft);}
.lvt{color:var(--lv);}
.page-title::before{grid-row:1 / span 2;display:grid;place-items:center;width:46px;height:46px;border-radius:13px;
  background:var(--lv);color:var(--ink-inverse);font-family:var(--font-body);font-size:17px;font-weight:800;}
.lv-n5 .page-title::before{content:"N5";}
.lv-n4 .page-title::before{content:"N4";}
.lv-n3 .page-title::before{content:"N3";}
.lv-n2 .page-title::before{content:"N2";}
.lv-n1 .page-title::before{content:"N1";}
/* Language toggle: one pill with two halves, never wrapping. */
.lang-switch{margin-top:0;gap:10px;}
.lang-switch .lang-seg{display:inline-flex;flex:none;padding:3px;border-radius:999px;background:var(--surface-2);border:1px solid var(--line);}
.lang-switch .lang-seg button{border:0;background:none;padding:5px 13px;white-space:nowrap;color:var(--ink-soft);}
.lang-switch .lang-seg button[aria-pressed="true"]{background:var(--surface);border:0;color:var(--ink);box-shadow:var(--shadow-sm);}
.lang-switch .lang-label{white-space:nowrap;}
.lang-switch{flex-wrap:wrap;}
.lang-switch .lang-seg button{font-size:13px;}
@media (min-width:720px){
  .wrap > header{grid-template-columns:minmax(0,1fr) auto;align-items:center;}
  .wrap > header .tabs{grid-column:1 / -1;}
  .wrap > header .lang-switch{grid-column:2;grid-row:1;justify-content:flex-end;}
  .lang-switch .lang-note{text-align:right;}
}

/* ---------- The "Hôm nay" block (redesign story 1) ----------
   Counts, one big "Bắt đầu học", and beside it the streak and the extra
   practice modes. Built by renderTodayPanel() in js/drill.js. */
.wrap{max-width:1040px;}
#view-today.active{display:grid;grid-template-columns:minmax(0,1fr);gap:20px;align-items:start;}
.today-panel{display:flex;flex-direction:column;gap:22px;margin:0;padding:clamp(20px,3vw,32px);background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-card);}
.tp-title{font-size:24px;}
.tp-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:12px;}
.tp-tile{display:flex;flex-direction:column;gap:2px;padding:14px 16px;border-radius:var(--radius);}
.tp-tile span{font-size:13.5px;color:var(--ink-soft);}
.tp-tile b{font-size:34px;font-weight:800;line-height:1.1;font-variant-numeric:tabular-nums;color:var(--ink);}
.tp-tile small{font-size:12.5px;color:var(--ink-soft);font-variant-numeric:tabular-nums;}
.t-new{background:var(--accent-soft);}
.t-due{background:var(--lv-soft);}
.t-done{background:var(--ok-soft);}
.tp-warn{display:flex;align-items:center;gap:10px;padding:8px 8px 8px 10px;border-radius:12px;background:var(--flag-soft);font-size:14px;color:var(--ink-soft);}
.tp-warn i{width:32px;height:32px;flex:none;border-radius:10px;display:grid;place-items:center;background:var(--flag);color:var(--ink-inverse);}
.tp-warn svg{width:19px;height:19px;}
.tp-warn b{color:var(--flag);font-size:18px;font-weight:700;font-variant-numeric:tabular-nums;margin-right:2px;}
.tp-go{margin-left:auto;flex:none;border:0;border-radius:999px;padding:7px 14px;background:var(--flag);color:var(--ink-inverse);
  font-size:13px;font-weight:700;white-space:nowrap;box-shadow:var(--shadow-btn);}
.tp-go:active{transform:translateY(2px);box-shadow:none;}
.tp-go:focus-visible{outline:2px solid var(--flag);outline-offset:2px;}
.tp-actions{display:flex;flex-wrap:wrap;gap:12px;}
.tp-actions .bh-btn{min-height:48px;padding:0 22px;font-size:15px;}
.tp-start{min-height:52px;padding:0 28px;font-size:17px;}
.tp-start svg,.tp-actions .bh-btn svg{width:18px;height:18px;flex:none;}
.today-side{display:flex;flex-direction:column;gap:16px;}
.tp-streak{padding:20px 22px;border-radius:var(--radius-lg);background:var(--accent-soft);border:1px solid var(--accent-line);}
.tp-streak-n{display:flex;align-items:center;gap:10px;font-weight:700;color:var(--ink);}
.tp-streak-n i{width:32px;height:32px;border-radius:10px;display:grid;place-items:center;background:var(--fire-soft);color:var(--fire);}
.tp-streak-n svg{width:19px;height:19px;}
.tp-streak-n b{font-size:24px;font-variant-numeric:tabular-nums;margin-right:2px;}
.tp-streak p{margin:8px 0 0;font-size:14px;color:var(--ink-soft);}
.tp-more{padding:20px 22px;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:var(--shadow-card);}
.tp-more h3{font-size:18px;margin:0 0 6px;}
.more-row{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;min-height:48px;padding:0;background:none;border:0;
  border-bottom:1px solid var(--line);color:var(--ink);font:inherit;font-weight:600;text-align:left;}
.more-row:last-child{border-bottom:0;}
.more-row svg{width:18px;height:18px;flex:none;color:var(--ink-soft);}
.more-row:disabled{opacity:.4;cursor:default;}
.more-row:not(:disabled):hover{color:var(--accent);}
.today-decks,.today-settings{min-width:0;}
@media (min-width:900px){
  #view-today.active{grid-template-columns:minmax(0,1fr) 320px;}
  .today-panel{grid-column:1;grid-row:1;}
  .today-side{grid-column:2;grid-row:1;}
  .today-decks,.today-settings{grid-column:1 / -1;}
}

/* Breadcrumb, level chips and underline tabs (redesign story 1). */
.course-top{display:flex;flex-direction:column;gap:14px;}
.crumbs{display:flex;flex-wrap:wrap;gap:8px;font-size:14px;color:var(--ink-soft);}
.crumbs a{color:var(--ink-soft);}
.crumbs b{color:var(--ink);font-weight:600;}
.level-chips{display:flex;flex-wrap:wrap;gap:8px;}
.level-chip{min-width:56px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;padding:0 14px;border-radius:12px;
  border:1px solid var(--line);background:var(--surface);color:var(--ink);font-weight:800;text-decoration:none;}
.level-chip:hover{border-color:var(--lv);}
.level-chip[aria-current]{background:var(--lv);border-color:var(--lv);color:var(--ink-inverse);}
.wrap > header .tabs{background:none;border:0;border-bottom:1px solid var(--line);border-radius:0;box-shadow:none;padding:0;gap:4px;
  overflow-x:auto;white-space:nowrap;}
.wrap > header .tab-btn,.wrap > header .tab-link{flex:0 0 auto;border-radius:0;padding:12px 18px;font-size:15px;font-weight:600;
  border-bottom:3px solid transparent;margin-bottom:-1px;background:none;color:var(--ink-soft);}
.wrap > header .tab-btn.active{background:none;color:var(--ink);font-weight:700;border-bottom-color:var(--lv);}
.wrap > header .tab-link:hover{background:none;color:var(--ink);}

/* Roadmap: the notes in a grid, the mock-exam card as a banner. */
#view-roadmap.active:has(> .today-card){display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:16px;align-items:stretch;}
#view-roadmap > .today-card{margin:0;}
/* The day plan and the notes heading are added by drill.js into the same grid; they take the full row. */
#view-roadmap > #planBox, #view-roadmap > .plan-notes-title{grid-column:1 / -1;}
#view-roadmap > .plan-notes-title{margin:18px 0 0;}
#view-roadmap > a.cta-card{grid-column:1 / -1;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:16px;padding:24px 28px;}
#view-roadmap > a.cta-card .cta-go{margin-top:0;padding:12px 24px;border-radius:var(--radius-pill);background:var(--accent);color:var(--ink-inverse);font-size:15px;font-weight:700;}

/* Each deck carries its card-kind colour (3.3) as a small square. */
.k-kana,.k-kanji{--k:var(--accent);--k-soft:var(--accent-soft);}
.k-vocab{--k:var(--teal);--k-soft:var(--teal-soft);}
.k-grammar{--k:var(--tier2);--k-soft:var(--tier2-soft);}
.deck-card h3,.deck-card h2{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;}
.deck-card .kind-dot{flex:none;align-self:center;width:10px;height:10px;border-radius:3px;background:var(--k);}

/* ---------- GUI plan 3.3: flashcards ----------
   The card's edge and tag take the colour of what is being studied
   (kanji honey, vocabulary teal, grammar plum), the same on every level,
   so a mixed roadmap pass still says what each card is at a glance. */
.card[data-shape="kana"],.card[data-shape="kanji"]{--k:var(--accent);--k-soft:var(--accent-soft);}
.card[data-shape="vocab"]{--k:var(--teal);--k-soft:var(--teal-soft);}
.card[data-shape="grammar"]{--k:var(--tier2);--k-soft:var(--tier2-soft);}
.card .face{border:2px solid color-mix(in srgb,var(--k,var(--accent)) 45%,var(--line));}
/* The card's colour is its border; the 5px stripe across the top read as a heavy bar. */
.card .face::before{content:none;}
.card .face.back{border-color:color-mix(in srgb,var(--k,var(--accent)) 65%,var(--line));}
.card .word-tag{color:var(--k,var(--lv));background:var(--k-soft,var(--lv-soft));}
/* The turn. Text must never show mirrored, and backface-visibility alone
   cannot promise that: a filter or opacity on the card, or a scrolling box
   inside a face (Safari), makes the face behind show through backwards. So
   each face is also shown or hidden outright at the half-way point, when
   the card is edge-on (ease-in-out: 90 degrees is exactly half the time)
   and nothing can be seen to jump. Keep filter/opacity off .card. */
.card{transition:transform .5s ease-in-out;}
.face,.face-scroll{-webkit-backface-visibility:hidden;backface-visibility:hidden;}
.card .face{transition:visibility 0s linear .25s;}
.card .face.front{visibility:visible;}
.card .face.back{visibility:hidden;}
.card.flipped .face.front{visibility:hidden;}
.card.flipped .face.back{visibility:visible;}
.card.no-turn,.card.no-turn .face{transition:none;}
@media (prefers-reduced-motion:reduce){.card,.card .face{transition:none;}}
/* Keyboard hints: only where there is a keyboard and a mouse. */
.key{display:none;min-width:22px;margin-right:8px;padding:0 6px;border:1px solid currentColor;border-bottom-width:2px;border-radius:6px;
  font:600 11.5px/1.6 var(--font-mono);text-align:center;}
.tap-hint .on-keys{display:none;}
@media (hover:hover) and (pointer:fine){
  .key{display:inline-block;}
  .tap-hint .on-touch{display:none;}
  .tap-hint .on-keys{display:inline;}
}

/* Hán-Việt of each kanji under a vocabulary card (js/drill.js hanVietHint) */
.hv-hint{margin-top:10px;display:flex;flex-wrap:wrap;justify-content:center;gap:2px 4px;font-size:14px;color:var(--ink-soft);}
.hv-hint span[lang="ja"]{font-family:var(--font-jp);font-size:16px;color:var(--ink);}
.hv-hint b{color:var(--accent);font-weight:700;letter-spacing:.02em;}
.hv-sep{color:var(--ink-faint);}
/* The note on a reading under a vocabulary card (data/so-dem.json `note`) */
.word-note{margin-top:6px;font-size:14px;color:var(--ink-soft);text-align:center;}

/* "Đoán trước khi lật": pick the meaning before the card turns (js/drill.js) */
.guess-row{margin-top:14px;display:grid;gap:10px;}
.guess-row[hidden]{display:none;}
.guess-ask{margin:0;text-align:center;font-size:13.5px;font-weight:600;color:var(--ink-soft);}
.guess-options{display:grid;gap:8px;}
@media (min-width:640px){.guess-options{grid-template-columns:1fr 1fr;}}
.guess-opt{background:var(--surface);border:1.5px solid var(--line-strong);border-radius:12px;padding:12px 14px;min-height:48px;text-align:left;font:inherit;font-size:14.5px;color:var(--ink);line-height:1.45;cursor:pointer;overflow-wrap:anywhere;}
.guess-opt .mono{font-size:12px;color:var(--ink-faint);margin-right:4px;}
.guess-opt:not(:disabled):hover{border-color:var(--accent);}
.guess-opt:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
.guess-opt:disabled{cursor:default;}
.guess-opt.is-right{background:var(--ok-soft);border-color:var(--ok);}
.guess-opt.is-wrong{background:var(--flag-soft);border-color:var(--flag);}
.guess-next{justify-self:center;}
.field-check label{display:flex;align-items:center;gap:8px;cursor:pointer;}
.field-check input{width:18px;height:18px;}

/* "Ôn trộn" on the Today tab (js/drill.js) */
.mix-card{border-color:var(--accent);background:var(--accent-soft);}
.mix-card .kind-dot{background:var(--accent);}

/* Touch targets (GUI plan 2.2). On a touch screen, or a narrow one,
   everything tapped is at least 44 px in each direction (WCAG 2.5.5, Apple
   HIG), with at least 8 px between neighbours. With a mouse the sizes above
   stay as they are. tests/test_touch_targets.py keeps these blocks. */
@media (pointer: coarse), (max-width: 720px) {
  .session-head .exit, .tab-btn, .tab-link, .go-btn, .lang-switch button, .flip-btn, .say-btn { min-height: 44px; }
  .level-chip, .tp-go, .more-row { min-height: 44px; }
  .tp-actions .bh-btn { min-height: 48px; }
  .speak-btn { width: 44px; height: 44px; }
  .speak-btn.small { width: 44px; height: 44px; }
  .field input { height: 44px; }
  .field-check label { min-height: 44px; }
  .field-check input { width: 22px; height: 22px; }
  .deck-actions { gap: 8px; }
  .vx-lesson { display: inline-flex; align-items: center; min-height: 44px; }
}
/* Within the thumb's reach (GUI plan 2.2): on a phone the session's main
   buttons, "Xem đáp án" and the four grades, stay at the bottom of the
   screen, however tall the card. */
@media (max-width: 720px) {
  #view-session .flip-hint-row, #view-session .answer-row {
    position: sticky; bottom: 0; z-index: 3;
    padding: 10px 0 calc(10px + env(safe-area-inset-bottom));
    background: linear-gradient(to top, var(--bg) 78%, transparent);
  }
}
/* "Đọc to" under the card (js/drill.js sayRow): record a try, play it back. */
.say-row{margin-top:14px;display:flex;flex-wrap:wrap;justify-content:center;gap:8px;}
.say-row[hidden]{display:none;}
.say-btn{font:inherit;font-size:13px;padding:6px 14px;border-radius:999px;border:1px solid var(--line-strong);background:var(--surface);color:var(--ink);cursor:pointer;}
.say-btn:hover,.say-btn:focus-visible{border-color:var(--accent);}
.say-btn.is-rec{border-color:var(--flag);color:var(--flag);}
.say-note{font-size:13px;color:var(--ink-soft);}

/* ---------- Flashcard session, Ghép thẻ, end screen (redesign stories 2-3) ----------
   A focus bar (Thoát, progress, counter), a card at most 560 px wide, one
   wide "Xem đáp án", then four grade buttons in a row. */
#view-session,#view-match{max-width:560px;margin:0 auto;}
.focus-bar{gap:14px;margin-bottom:20px;}
.focus-bar .progress-bar{flex:1;margin:0;height:12px;}
.focus-bar .exit{order:0;display:inline-flex;align-items:center;min-height:44px;padding:0 14px;border-radius:12px;color:var(--ink);font-weight:600;}
.focus-bar .progress-bar{order:1;}
.focus-bar #sessionSave{order:2;margin:0;}
.focus-bar #sessionCounter,.focus-bar #matchMistakes{order:3;min-width:56px;text-align:right;font-size:14px;font-weight:700;color:var(--ink);}
.focus-bar #matchMistakes{color:var(--flag);}
#view-session .flip-hint-row{margin-top:20px;}
#view-session .flip-btn{display:block;width:100%;min-height:56px;border-radius:16px;font-size:17px;}
#view-session .answer-row{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin-top:20px;}
#view-session .answer-row[hidden],#view-session .answer-row[style*="display: none"],#view-session .answer-row[style*="display:none"]{display:none;}
.answer-row button{min-height:56px;border-radius:14px;}
.btn-hard{background:var(--accent-soft);color:var(--accent);border-color:var(--accent-line);}
.btn-easy{background:var(--n3-soft);color:var(--n3);border-color:color-mix(in srgb, var(--n3) 30%, transparent);}
.card[data-shape="kanji"] .word-jp,.card[data-shape="kana"] .word-jp{font-size:clamp(72px,16vw,112px);line-height:1.05;}
.card .face{border-radius:28px;}
.card .face-scroll{border-radius:28px;}

/* Ghép thẻ: tall tiles, four states. */
.match-meta{margin-bottom:16px;}
.match-tile{min-height:64px;border:2px solid var(--line);border-radius:16px;font-weight:700;}
.match-tile.selected{border-color:var(--ink);background:var(--accent-soft);box-shadow:none;}
.match-tile.solved{opacity:1;background:var(--ok-soft);border-color:var(--ok-soft);color:var(--ok);text-decoration:none;pointer-events:none;}
.match-tile.wrong{border-color:var(--flag);background:var(--surface);color:var(--flag);}
.match-tile.jp{font-size:22px;}

/* End screen: one count per grade. */
.done-counts{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;max-width:420px;margin:20px auto 0;}
.done-counts[hidden]{display:none;}
.dc{display:flex;flex-direction:column;padding:12px 4px;border-radius:14px;}
.dc b{font-size:22px;font-variant-numeric:tabular-nums;}
.dc span{font-size:13px;}
.dc-again{background:var(--flag-soft);color:var(--flag);}
.dc-hard{background:var(--accent-soft);color:var(--accent);}
.dc-good{background:var(--ok-soft);color:var(--ok);}
.dc-easy{background:var(--n3-soft);color:var(--n3);}
.done-screen{border:1px solid var(--line);background:var(--surface);border-radius:28px;max-width:520px;margin:20px auto 0;box-shadow:var(--shadow-card);}
.done-screen .back-btn{min-height:52px;border-radius:14px;}
.focus-bar #sessionCounter{white-space:nowrap;min-width:0;font-size:13px;}
.focus-bar .progress-bar{min-width:48px;}
.card .face::before{border-radius:26px 26px 0 0;}
@media (max-width:480px){.focus-bar{gap:10px;}.focus-bar #sessionCounter{font-size:12px;}}
