/* nihon.academy — base styles
   Latin text uses Figtree, self-hosted as one variable woff2 and
   preloaded; the system stack carries the page until it lands, and carries
   it permanently if the file is absent. Japanese glyphs always fall through
   to the OS Japanese font — no CJK webfont, those run to megabytes.
   Run `npm run fonts` once to fetch the file. */

:root {
  --ink: #16161a;
  --ink-soft: #55555f;
  --ink-faint: #8a8a96;
  --paper: #fbfaf7;
  --card: #ffffff;
  --line: #e6e3dc;
  --accent: #b4472f;        /* vermilion — torii red, muted */
  --accent-soft: #fceee9;
  --indigo: #2c3e64;        /* kon-iro */
  --ok: #2f7d52;
  --bad: #b4302f;
  --radius: 10px;
  --wrap: 1080px;
  --sans: Figtree, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --jp: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic",
        "Noto Sans JP", "Meiryo", sans-serif;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #edece8;
    --ink-soft: #b0aea8;
    --ink-faint: #7d7b76;
    --paper: #16161a;
    --card: #1e1e23;
    --line: #32323a;
    --accent: #e0745a;
    --accent-soft: #2e211d;
    --indigo: #8fa5cf;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  /* 16px / 1.7 — the roomier measure this class of learning site uses. */
  font: 400 16px/1.7 var(--sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Headings run heavy — 800 rather than the usual bold — which is most of
   what separates a friendly product voice from a document voice. */
h1, h2, h3, h4 { font-weight: 800; line-height: 1.2; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

.skip {
  position: absolute; left: -9999px;
  background: var(--accent); color: #fff; padding: 10px 16px;
}
.skip:focus { left: 12px; top: 12px; z-index: 100; }

/* --- header / footer --- */

.site-header { border-bottom: 1px solid var(--line); background: var(--card); }
.header-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; min-height: 62px; flex-wrap: wrap;
}
.brand { display: flex; align-items: baseline; gap: 10px; text-decoration: none; color: var(--ink); }
.brand-jp { font-family: var(--jp); font-size: 1.25rem; color: var(--accent); letter-spacing: .06em; }
.brand-en { font-weight: 800; letter-spacing: -.02em; }
/* Nav items are real targets, not bare inline text. They were 62x26, which
   is under the 44px a thumb needs, and nothing marked the current section. */
.site-nav { display: flex; gap: 2px; flex-wrap: wrap; align-items: center; margin: 0 -10px; }
.site-nav a, .site-nav .soon {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 9px 10px; min-height: 40px; border-radius: 9px;
  font-size: .95rem; text-decoration: none; color: var(--ink-soft);
}
.site-nav a:hover { color: var(--accent); background: var(--accent-soft); }
.site-nav a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Weight and an underline carry the current section as well as colour, so it
   survives a colour-blind reader and a greyscale print. */
.site-nav a[aria-current] { color: var(--accent); font-weight: 800; }
.site-nav a[aria-current]::after {
  content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px;
  background: var(--accent); border-radius: 2px;
}
.site-nav a { position: relative; }
/* Pending sections: a muted label plus a badge, never anything that looks or
   behaves like a link. */
.site-nav .soon { color: var(--ink-faint); cursor: default; }
.site-nav .soon b {
  font-size: .6rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 999px; border: 1px solid var(--line);
  background: none; color: var(--ink-faint);
}

/* --- section bar ---------------------------------------------------------
   The second level of navigation: the three pages every script has. It is
   sticky because the chart pages are long, and reaching practice from the
   bottom of 104 cells otherwise means scrolling all the way back up. */

.sectionbar {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--card) 97%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
.sectionbar-inner { display: flex; align-items: center; gap: 14px; min-height: 48px; }
.sectionbar-label {
  font-size: .7rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-faint); flex: none;
}
.sectionbar ul { display: flex; gap: 2px; list-style: none; margin: 0; padding: 0; min-width: 0; overflow-x: auto; }
.sectionbar li { flex: none; }
.sectionbar a {
  display: flex; align-items: center; min-height: 44px; padding: 0 14px;
  font-size: .92rem; font-weight: 700; color: var(--ink-soft); text-decoration: none;
  border-bottom: 2px solid transparent; white-space: nowrap;
}
.sectionbar a:hover { color: var(--accent); }
.sectionbar a[aria-current] { color: var(--accent); border-bottom-color: var(--accent); }
.sectionbar a:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.sectionbar-here {
  margin-left: auto; flex: none; font-family: var(--jp); font-size: 1.15rem;
  color: var(--accent); padding-left: 10px;
}

.site-footer {
  margin-top: 72px; padding: 32px 0 48px;
  border-top: 1px solid var(--line); background: var(--card);
  font-size: .84rem; color: var(--ink-faint);
}
.footer-tagline { margin: 0 0 8px; color: var(--ink-soft); }
.credit { margin: 0; max-width: 70ch; line-height: 1.6; }
.credit a { color: var(--ink-soft); }

/* --- page furniture --- */

.hero { padding: 56px 0 8px; }
.hero h1 { font-size: clamp(2rem, 5vw, 2.9rem); line-height: 1.12; margin: 0 0 14px; letter-spacing: -.025em; }
.hero .lede { font-size: 1.12rem; color: var(--ink-soft); max-width: 62ch; margin: 0; }

.section { padding: 40px 0 0; }
.section h2 { font-size: 1.45rem; margin: 0 0 6px; letter-spacing: -.018em; }
.section .sub { color: var(--ink-soft); margin: 0 0 20px; max-width: 66ch; }

.crumbs { padding: 20px 0 0; font-size: .85rem; color: var(--ink-faint); }
.crumbs a { color: var(--ink-soft); }

.pillbar { display: flex; gap: 10px; flex-wrap: wrap; margin: 20px 0 0; }
.pill {
  display: inline-block; padding: 9px 16px; border: 1px solid var(--line);
  border-radius: 999px; background: var(--card); color: var(--ink);
  text-decoration: none; font-size: .92rem; font-weight: 700; letter-spacing: .01em;
}
.pill:hover { border-color: var(--accent); color: var(--accent); }
.pill.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.pill.primary:hover { color: #fff; opacity: .9; }

/* --- home cluster cards --- */

.cards { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.card {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card); padding: 20px; text-decoration: none; color: inherit;
  display: block;
}
.card:hover { border-color: var(--accent); }
.card .card-jp { font-family: var(--jp); font-size: 1.8rem; color: var(--accent); line-height: 1; }
.card h3 { margin: 12px 0 4px; font-size: 1.05rem; }
.card p { margin: 0; color: var(--ink-soft); font-size: .9rem; }
.card[aria-disabled="true"] { opacity: .55; }

/* --- kana chart --- */

.chart { margin: 8px 0 0; }
.chart-grid { display: grid; gap: 6px; grid-template-columns: 64px repeat(5, 1fr); }
.chart-grid.yoon { grid-template-columns: 64px repeat(3, 1fr); }
.chart-head, .chart-rowlabel {
  display: flex; align-items: center; justify-content: center;
  font-size: .72rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-faint); font-weight: 600;
}
.chart-rowlabel { justify-content: flex-end; padding-right: 10px; }

.kana-cell {
  display: flex; border: 1px solid var(--line); border-radius: 8px;
  background: var(--card); color: var(--ink);
}
.kana-cell:has(a.kana-cell-link):hover { border-color: var(--accent); background: var(--accent-soft); }
.kana-cell.empty { border-style: dashed; opacity: .3; }
.kana-cell .glyph { font-family: var(--jp); font-size: 1.7rem; line-height: 1.1; }
.kana-cell .roma { font-size: .74rem; color: var(--ink-faint); letter-spacing: .04em; }

/* --- individual kana page --- */

.kana-hero { display: grid; gap: 28px; grid-template-columns: minmax(0, 240px) minmax(0, 1fr); align-items: start; padding: 28px 0 0; }
.glyph-box {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--card);
  padding: 18px; text-align: center;
}
.glyph-box .big { font-family: var(--jp); font-size: 6rem; line-height: 1; margin: 0; }
.kana-visuals { display: grid; gap: 12px; }
.glyph-box .roma-big { font-size: 1.1rem; color: var(--ink-faint); letter-spacing: .12em; text-transform: uppercase; margin: 8px 0 0; }
.stroke { margin: 0 auto; max-width: 200px; }
.stroke svg { width: 100%; height: auto; }
.stroke svg text { font-size: 6px; fill: var(--accent); font-family: inherit; }
.stroke svg [style*="stroke"] { stroke: var(--ink) !important; }
.stroke-caption { font-size: .78rem; color: var(--ink-faint); margin: 6px 0 0; }

.factlist { list-style: none; padding: 0; margin: 0 0 20px; display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.factlist li { border: 1px solid var(--line); border-radius: 8px; background: var(--card); padding: 10px 12px; }
.factlist .k { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint); }
.factlist .v { font-weight: 600; }
.factlist .v .jp { font-family: var(--jp); }

.mnemonic {
  border-left: 3px solid var(--accent); background: var(--accent-soft);
  padding: 14px 18px; border-radius: 0 8px 8px 0; margin: 0 0 20px;
}
.mnemonic h2 { font-size: .74rem; text-transform: uppercase; letter-spacing: .09em; color: var(--accent); margin: 0 0 4px; }
.mnemonic p { margin: 0; font-size: 1.02rem; }

/* The word list now sits above this, so it needs its own top margin rather
   than relying on whatever preceded it. */
.confuse { margin: 26px 0 0; }
.confuse h2 { font-size: .74rem; text-transform: uppercase; letter-spacing: .09em; color: var(--ink-faint); margin: 0 0 8px; }
.confuse .row { display: flex; gap: 10px; flex-wrap: wrap; }
.confuse .row a { min-width: 66px; }

/* Walking the chart in order is the main way these pages get read, so
   prev/next are cards, not footnotes. */

/* --- quiz --- */

.quiz { max-width: 1120px; margin: 24px 0 0; }
.opts { display: flex; gap: 8px; flex-wrap: wrap; }
.opt { position: relative; }
.opt input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.opt span {
  display: inline-block; padding: 7px 14px; border: 1px solid var(--line);
  border-radius: 999px; font-size: .88rem; background: var(--paper); cursor: pointer;
}
.opt input:checked + span { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.opt input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.btn {
  display: inline-block; padding: 12px 24px; border: 0; border-radius: 999px;
  background: var(--accent); color: #fff; font: inherit; font-weight: 700;
  letter-spacing: .01em; cursor: pointer;
}
.btn:hover { opacity: .9; }
.btn.ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); }

.quiz-play { border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); padding: 28px 20px; text-align: center; }
.quiz-progress { font-size: .78rem; color: var(--ink-faint); letter-spacing: .06em; }
.quiz-prompt { font-family: var(--jp); font-size: 5rem; line-height: 1.1; margin: 12px 0 20px; }
.quiz-prompt.roma { font-family: inherit; font-size: 3rem; letter-spacing: .06em; }
.quiz-answers { display: grid; gap: 10px; grid-template-columns: repeat(2, 1fr); max-width: 420px; margin: 0 auto; }
.quiz-answers button {
  padding: 14px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--paper); font: inherit; font-size: 1.15rem; cursor: pointer; color: var(--ink);
}
.quiz-answers button .jp { font-family: var(--jp); font-size: 1.6rem; }
.quiz-answers button:hover:not(:disabled) { border-color: var(--accent); }
.quiz-answers button.correct { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent); }
.quiz-answers button.wrong { border-color: var(--bad); background: color-mix(in srgb, var(--bad) 12%, transparent); }
.quiz-score { margin: 18px 0 0; font-size: .9rem; color: var(--ink-soft); }

.quiz-done { text-align: center; padding: 28px 20px; }
.quiz-done .big-score { font-size: 3rem; font-weight: 700; margin: 0; }
.quiz-done .missed { margin: 20px auto 0; max-width: 420px; text-align: left; }
.quiz-done .missed h3 { font-size: .8rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint); }

[hidden] { display: none !important; }

/* --- print --- */

@media print {
  .site-header, .site-footer, .pillbar, .site-nav, .sectionbar, .crumbs, .quiz, .kana-bar { display: none; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .kana-cell { border: 1px solid #bbb; break-inside: avoid; }
  .chart-grid { gap: 3px; }
  .hero { padding: 0 0 8px; }
  .section { padding: 16px 0 0; }
  a { color: #000; text-decoration: none; }
}



/* --- stroke order diagram --- */
.kvg { display: block; width: 100%; height: auto; }
.kvg .kvg-guide line { stroke: var(--line); stroke-width: 1; stroke-dasharray: 4 4; }
.kvg .kvg-strokes path {
  fill: none;
  stroke: var(--ink);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
[data-stroke].playing .kvg-strokes path { stroke: var(--accent); }

/* --- pronunciation buttons --- */

.speak {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--ink-soft);
  cursor: pointer; transition: color .12s, border-color .12s, background-color .12s;
}
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.speak svg { width: 15px; height: 15px; }
/* <use> puts the paths in a shadow tree, so these are set on the symbol's
   own classes and inherited through currentColor. */
#ico-speak path { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
#ico-speak .cone { fill: currentColor; }
#ico-speak .w2 { opacity: .55; }
.speak:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.speak:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.speak.speaking { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.speak.speaking svg { animation: speakPulse .45s ease-out; }
@keyframes speakPulse {
  0%   { transform: scale(.82); opacity: .5; }
  60%  { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .speak.speaking svg { animation: none; } }

/* Big one, next to the glyph on a kana page */
.speak-lg { width: 40px; height: 40px; margin-top: 10px; }
.speak-lg svg { width: 20px; height: 20px; }

/* Chart cells: the link fills the cell, the speaker floats over its corner. */
.kana-cell { position: relative; padding: 0; }
.kana-cell-link {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; width: 100%; min-height: 76px; padding: 14px 4px 10px;
  text-decoration: none; color: var(--ink); border-radius: 8px;
}
/* Always visible, and tinted rather than grey. The chart's own copy promises
   that every cell plays; a control that only appears on hover contradicts
   that, and is invisible on touch besides. */
.kana-cell .speak {
  position: absolute; top: 4px; right: 4px;
  width: 24px; height: 24px;
  background: var(--accent-soft); border-color: transparent;
  color: var(--accent);
}
.kana-cell .speak svg { width: 13px; height: 13px; }
.kana-cell:hover .speak { background: var(--accent); color: #fff; }
.kana-cell .speak:hover,
.kana-cell .speak:focus-visible { background: var(--accent); color: #fff; transform: scale(1.12); }
.kana-cell .speak.speaking { background: var(--accent); color: #fff; }

/* Touch needs a large target, but the disc itself must stay smaller than the
   glyph it belongs to — at 390px the cell is only ~58px wide, and a 30px
   button read as bigger than the kana. So grow the HIT AREA with a
   pseudo-element and leave the visible disc alone; ergonomics and visual
   weight are then independent. */
@media (hover: none), (pointer: coarse) {
  .kana-cell .speak { width: 22px; height: 22px; }
  .kana-cell .speak svg { width: 12px; height: 12px; }
  .kana-cell .speak::after {
    content: ""; position: absolute;
    top: -10px; right: -8px; bottom: -10px; left: -10px;
  }
}

/* No audio available anywhere: the buttons are removed by audio.js, but hide
   them up front so they never flash in. */
html:not(.has-audio) .speak { display: none; }

@media print { .speak { display: none !important; } }

.quiz-listen { margin: -8px 0 18px; min-height: 28px; }
.quiz-listen .speak { width: 34px; height: 34px; }
.quiz-listen .speak svg { width: 17px; height: 17px; }

/* --- footer ---------------------------------------------------------
   Topic columns carry the weight; brand, social and legal collect into a
   bottom bar. Denser than a single row of links, and the column headings
   give each group of pages a reason to be there.
   ------------------------------------------------------------------- */

.foot-cols {
  display: grid; gap: 30px 24px; padding: 4px 0 30px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.foot-col h2 {
  font-size: .74rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink); margin: 0 0 14px;
}
.foot-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.foot-col a { color: var(--ink-soft); text-decoration: none; font-size: .89rem; line-height: 1.35; }
.foot-col a:hover { color: var(--accent); text-decoration: underline; }
.foot-soon { color: var(--ink-faint); font-size: .89rem; }

.foot-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  padding: 20px 0 0; border-top: 1px solid var(--line);
}
.foot-bar-left { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.foot-bar-right { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.foot-copy { margin: 0; font-size: .82rem; color: var(--ink-faint); }

.foot-social { display: flex; gap: 6px; list-style: none; margin: 0; padding: 0; }
.foot-social a {
  display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 999px; color: var(--ink-faint);
}
.foot-social svg { width: 18px; height: 18px; fill: currentColor; }
.foot-social a:hover { color: var(--accent); background: var(--accent-soft); }

.foot-legal { display: flex; gap: 18px; list-style: none; margin: 0; padding: 0; }
.foot-legal a { color: var(--ink-faint); font-size: .82rem; text-decoration: none; }
.foot-legal a:hover { color: var(--accent); text-decoration: underline; }

@media (max-width: 860px) {
  .foot-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px 20px; }
}
@media (max-width: 520px) {
  .foot-bar { flex-direction: column; align-items: flex-start; gap: 16px; }
  .foot-bar-right { width: 100%; justify-content: space-between; }
}

/* --- legal and contact pages --- */

.legal { max-width: 720px; }
.legal .hero { padding: 44px 0 8px; }
.legal h2 { font-size: 1.12rem; margin: 34px 0 8px; }
.legal p, .legal li { color: var(--ink-soft); line-height: 1.7; }
.legal ul { padding-left: 20px; }
.legal li { margin: 0 0 6px; }
.legal code {
  font-size: .88em; background: var(--card); border: 1px solid var(--line);
  border-radius: 5px; padding: 1px 5px;
}
.legal-date { font-size: .82rem; color: var(--ink-faint); margin: 14px 0 0; }

.contact-grid {
  display: grid; gap: 40px; margin: 28px 0 0;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
}
.contact-aside h2 { font-size: .78rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint); margin: 0 0 6px; }
.contact-aside h2 + p { margin: 0 0 22px; font-size: .9rem; }

.contact-form { display: grid; gap: 18px; }
.contact-form .btn { justify-self: start; }
.field { display: grid; gap: 6px; }
.field label { font-size: .82rem; font-weight: 600; }
.field input, .field textarea, .field select {
  font: inherit; color: var(--ink); background: var(--card);
  border: 1px solid var(--line); border-radius: 10px; padding: 11px 13px;
  width: 100%;
}
.field textarea { resize: vertical; min-height: 130px; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
.field input:user-invalid, .field textarea:user-invalid { border-color: var(--bad, #b4302f); }
.field-note { font-size: .76rem; color: var(--ink-faint); }
.field-opt {
  font-weight: 400; font-size: .74rem; color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: .07em; margin-left: 4px;
}

/* Off-screen rather than display:none — bots skip hidden fields. */
.trap {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden; margin: 0;
}

.form-status { margin: 4px 0 0; font-size: .88rem; min-height: 1.2em; color: var(--ink-soft); }
.form-status.is-ok { color: var(--ok, #2f7d52); font-weight: 600; }
.form-status.is-bad { color: var(--bad, #b4302f); font-weight: 600; }
.form-status.is-warn { color: var(--ink-faint); }

@media (max-width: 760px) {
  .contact-grid { grid-template-columns: 1fr; gap: 30px; }
}

@media print { .site-footer { display: none; } }

/* --- narrow screens -------------------------------------------------
   Kept last: these override the chart and cell rules above, and at equal
   specificity the later rule wins. Moving this block earlier silently
   disables it. */
@media (max-width: 640px) {
  .kana-hero { grid-template-columns: 1fr; }
  .chart-grid { grid-template-columns: 40px repeat(5, 1fr); gap: 4px; }
  .chart-grid.yoon { grid-template-columns: 40px repeat(3, 1fr); }
  .kana-cell-link { min-height: 58px; padding: 11px 2px 6px; }
  .kana-cell .glyph { font-size: 1.35rem; }
  .quiz-prompt { font-size: 3.6rem; }
  .kana-cell .speak { width: 20px; height: 20px; top: 3px; right: 3px; }
  .kana-cell .speak svg { width: 11px; height: 11px; }

  /* Stacked, these two boxes filled most of a phone screen before any
     content appeared. Side by side they read as one unit — the glyph and
     how to write it — and the facts start above the fold. */
  .kana-hero { gap: 18px; padding-top: 20px; }
  .kana-hero h1 { margin-top: 0; font-size: 1.5rem; }
  .kana-visuals { grid-template-columns: 1fr 1fr; gap: 10px; align-items: stretch; }
  .kana-visuals .glyph-box { padding: 12px 8px; display: flex; flex-direction: column;
    align-items: center; justify-content: center; }
  .glyph-box .big { font-size: 3.6rem; }
  .glyph-box .roma-big { font-size: .9rem; letter-spacing: .1em; margin-top: 4px; }
  .speak-lg { width: 34px; height: 34px; margin-top: 8px; }
  .speak-lg svg { width: 17px; height: 17px; }
  .glyph-box-stroke .stroke { max-width: 118px; }
  .stroke-caption { margin-top: 8px; }
  .stroke-caption .pill { padding: 6px 12px; font-size: .78rem; }
}

/* ======================================================================
   Practice setup. Two columns on a wide screen, one on a narrow one; the
   preview follows the controls rather than competing with them.
   ====================================================================== */

.setup { max-width: 1120px; margin: 0 auto; }
.setup-grid { display: grid; gap: 20px; grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr); align-items: start; }
.setup-main, .setup-side { min-width: 0; }

.panel { border: 1px solid var(--line); border-radius: 16px; background: var(--card); padding: 22px; }
/* A quiet band of the brand colour gives the panel a top edge without a
   heavy header bar. */
.setup-main { position: relative; overflow: hidden; }
.setup-main::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 4px;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 40%, var(--paper)));
}

.setup-head { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 6px 0 22px; }
.setup-head h2 { font-size: 1.2rem; margin: 0 0 4px; }
.setup-head .hint { margin: 0; max-width: 46ch; }
.jp-note { font-family: var(--jp); font-size: .78em; font-weight: 400; color: var(--ink-faint); }

.setup-actions { display: flex; align-items: center; gap: 10px; flex: none; }
.linkish {
  border: 0; background: none; cursor: pointer; font: inherit;
  font-size: .84rem; font-weight: 700; color: var(--accent);
  padding: 6px 2px; min-height: 30px;
}
.linkish:hover { text-decoration: underline; }
.dot { width: 4px; height: 4px; border-radius: 50%; background: var(--line); display: inline-block; }
.dot-base { background: var(--accent); }
.dot-voiced { background: var(--ink-faint); }

.fieldrow { margin: 0 0 22px; }
.fieldhead { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin: 0 0 10px; flex-wrap: wrap; }
.fieldhead .label { font-size: .72rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-faint); }
.fieldnote { font-size: .78rem; color: var(--ink-faint); }
.fieldnote b { color: var(--accent); }

.segmented { display: inline-flex; padding: 4px; gap: 4px; border: 1px solid var(--line); border-radius: 999px; background: var(--paper); flex-wrap: wrap; }
.seg { position: relative; }
.seg input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.seg span { display: block; padding: 9px 18px; border-radius: 999px; cursor: pointer; font-size: .9rem; font-weight: 700; color: var(--ink-soft); white-space: nowrap; }
.seg span i { font-style: normal; color: var(--ink-faint); margin: 0 2px; }
.seg input:checked + span { background: var(--card); color: var(--accent); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.seg input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.preset-grid { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(216px, 1fr)); }
.preset { display: flex; align-items: center; gap: 9px; min-height: 46px; text-align: left; padding: 11px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--paper); cursor: pointer; font: inherit; }
.preset:hover { border-color: var(--accent); }
.preset-tick { width: 16px; height: 16px; flex: none; border-radius: 4px; border: 1.5px solid var(--line); display: grid; place-items: center; }
.preset-tick svg { width: 11px; height: 11px; opacity: 0; }
.preset-tick svg path { fill: none; stroke: #fff; stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; }
.preset-name { font-size: .88rem; font-weight: 700; color: var(--ink); line-height: 1.25; }
.preset-name i { font-style: normal; font-family: var(--jp); font-weight: 400; color: var(--ink-faint); }
.preset-count { margin-left: auto; font-size: .72rem; color: var(--ink-faint); white-space: nowrap; }
.preset.is-on { border-color: var(--accent); background: var(--accent-soft); }
.preset.is-on .preset-tick { background: var(--accent); border-color: var(--accent); }
.preset.is-on .preset-tick svg { opacity: 1; }
.preset.is-on .preset-count { color: var(--accent); }

.rowbox { border: 1px solid var(--line); border-radius: 12px; padding: 16px; background: var(--paper); }
.rowgroup + .rowgroup { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.rowgroup-title { display: flex; align-items: center; gap: 7px; margin: 0 0 10px; font-size: .68rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); }
.row-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip-row { position: relative; }
.chip-row input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.chip-row span { display: inline-flex; align-items: baseline; gap: 5px; padding: 7px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); cursor: pointer; font-size: .82rem; color: var(--ink-soft); }
.chip-row b { font-weight: 700; }
.chip-row i { font-style: normal; font-family: var(--jp); font-size: .92em; color: var(--ink-faint); }
.chip-row input:checked + span { background: var(--accent); border-color: var(--accent); color: #fff; }
.chip-row input:checked + span i { color: rgba(255,255,255,.75); }
.chip-row input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.setup-go { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin: 26px 0 0; }
.setup-go .hint { margin: 0; }
.btn-lg { font-size: 1rem; padding: 14px 26px; }
.btn i { font-style: normal; margin-left: 4px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
kbd { display: inline-block; margin-left: 10px; padding: 2px 7px; border-radius: 5px; background: rgba(255,255,255,.22); font: inherit; font-size: .74rem; font-weight: 700; }
.hint kbd { background: var(--card); border: 1px solid var(--line); color: var(--ink-soft); margin: 0 2px; }

.setup-side { display: grid; gap: 16px; grid-template-columns: minmax(0, 1fr); }
.side-card { min-width: 0; }
.side-card { padding: 18px; }
.side-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 0 14px; flex-wrap: wrap; }
.side-head h2 { min-width: 0; }
.side-head h2 { font-size: .98rem; margin: 0; }
.pill-badge { font-size: .7rem; font-weight: 800; letter-spacing: .04em; padding: 3px 9px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); white-space: nowrap; flex: none; }
.pill-badge.is-off { background: var(--line); color: var(--ink-faint); }
.side-label { font-size: .68rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); margin: 0 0 7px; }
.side-sub { font-size: .78rem; color: var(--ink-faint); margin: 7px 0 0; }
.side-sub b { color: var(--ink-soft); }

.meter { height: 7px; border-radius: 999px; background: var(--line); overflow: hidden; }
.meter span { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 999px; transition: width .25s; }

.glyph-sample { margin: 18px 0 0; padding: 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--paper); }
.sample-grid { display: grid; gap: 5px; grid-template-columns: repeat(5, minmax(0, 1fr)); }
.sample-cell { display: grid; place-items: center; aspect-ratio: 1; border: 1px solid var(--line); border-radius: 7px; background: var(--card); font-family: var(--jp); font-size: 1.05rem; }
.est { margin: 18px 0 0; }
.est-time { margin: 0; font-size: 1.5rem; font-weight: 800; }

.streak-n { margin: 0 0 14px; display: flex; align-items: baseline; gap: 8px; }
.streak-n b { font-size: 2.2rem; font-weight: 800; line-height: 1; color: var(--accent); }
.streak-n span { font-size: .84rem; color: var(--ink-soft); }
.week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 5px; min-width: 0; list-style: none; margin: 0; padding: 0; }
.week li { display: grid; gap: 4px; justify-items: center; position: relative; }
.week-d { font-size: .66rem; font-weight: 700; color: var(--ink-faint); }
.week-m { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line); background: var(--paper); font-size: .76rem; font-weight: 800; color: transparent; }
.week li.done .week-m { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.week li.is-today .week-m { box-shadow: 0 0 0 2px var(--accent-soft); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.tip-card { background: var(--accent-soft); border-color: transparent; }
.tip-text { margin: 0; font-size: .86rem; line-height: 1.6; color: var(--ink); }
.tip-text span[lang="ja"] { font-family: var(--jp); font-weight: 700; }

@media (max-width: 960px) {
  .setup-grid { grid-template-columns: minmax(0, 1fr); }
  .setup-side { grid-template-columns: repeat(auto-fit, minmax(min(255px, 100%), 1fr)); }
}
@media (max-width: 620px) {
  .panel { padding: 18px 16px; }
  .setup-head { margin-bottom: 18px; }
  .segmented { width: 100%; }
  .seg { flex: 1; }
  .seg span { text-align: center; padding: 10px 8px; }
  .preset-grid { grid-template-columns: minmax(0, 1fr); }
  .sample-grid { gap: 4px; }
  .rowbox { padding: 13px; }
  .setup-go { flex-direction: column; align-items: stretch; }
  .setup-go .btn { width: 100%; }
  .setup-go .hint { text-align: center; }
  .setup-side { grid-template-columns: minmax(0, 1fr); }
  .sample-grid { grid-template-columns: repeat(8, minmax(0, 1fr)); }
}

/* ======================================================================
   Vertical density. Two separate paddings sat between the breadcrumb and
   the heading (20px under the crumb, 56px over the hero), so on a phone
   roughly 40% of the first screen was spent before the first control.
   The gap is collapsed to one value here, and tightened again on small
   screens.
   ====================================================================== */

.crumbs + .hero { padding-top: 26px; }

/* The row chips are the fine-grained control; the set buttons above cover
   the common case. On a narrow screen they are folded away so the start
   button is reachable without scrolling past 27 checkboxes. setup.js
   closes this on load below 620px, which means it stays open without JS. */
.rowsfield > summary {
  cursor: pointer; list-style: none; min-height: 34px; align-items: center;
}
.rowsfield > summary::-webkit-details-marker { display: none; }
.rowsfield > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
.chev {
  display: none; width: 8px; height: 8px; margin-left: 6px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg); transition: transform .15s;
}
.rowsfield[open] > summary .chev { transform: translateY(1px) rotate(225deg); }

@media (max-width: 640px) {
  .crumbs { padding-top: 12px; }
  .crumbs + .hero { padding-top: 14px; }
  .hero { padding: 26px 0 6px; }
  .hero h1 { font-size: 1.7rem; margin-bottom: 8px; }
  .hero .lede { font-size: 1rem; line-height: 1.55; }
  .section { padding-top: 28px; }
}

@media (max-width: 620px) {
  .chev { display: inline-block; }
  .rowsfield > summary { min-height: 44px; }
  .setup-head { margin-bottom: 14px; gap: 8px; }
  .setup-head h2 { font-size: 1.1rem; }
  .fieldrow { margin-bottom: 18px; }
  .setup-go { margin-top: 20px; }
  .glyph-sample, .est { margin-top: 14px; }
}

/* The section bar replaced the breadcrumb on the pages where the crumb only
   repeated it, so the hero needs the same collapsed gap the crumb had. */
.sectionbar + main .hero { padding-top: 26px; }
.sectionbar + main .kana-hero { padding-top: 22px; }

@media (max-width: 640px) {
  .sectionbar-inner { gap: 10px; min-height: 46px; }
  .sectionbar a { padding: 0 11px; font-size: .88rem; }
  .sectionbar + main .hero { padding-top: 16px; }
  .sectionbar + main .kana-hero { padding-top: 14px; }
  /* The four items have to clear 44px vertically and still fit one row on a
     360px phone, so the horizontal padding and the pending badge shrink
     rather than the tap height. */
  .site-nav { gap: 0; margin: 0 -7px; }
  .site-nav a, .site-nav .soon { padding: 10px 7px; min-height: 44px; font-size: .88rem; gap: 4px; }
  .site-nav a[aria-current]::after { left: 7px; right: 7px; }
  .site-nav .soon b { font-size: .54rem; padding: 1px 4px; letter-spacing: .04em; }
}

/* Below 360px the four items cannot fit and cannot shrink further without
   dropping under 44px, so the row scrolls instead of stacking. The clipped
   last item is the affordance; nothing is hidden from a keyboard, which
   scrolls the row into view on focus. */
@media (max-width: 359px) {
  .site-nav { flex-wrap: nowrap; overflow-x: auto; min-width: 0; scrollbar-width: none; }
  .site-nav::-webkit-scrollbar { display: none; }
}

/* ======================================================================
   Home page. The hero carries a working demo rather than a description of
   one, so it is two columns on a wide screen: copy on the left, the strip
   on the right where the page used to be empty.
   ====================================================================== */

.home-hero {
  display: grid; gap: 40px; align-items: center;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  padding: 48px 0 8px;
}
.home-copy h1 { font-size: clamp(2rem, 5vw, 2.9rem); line-height: 1.12; margin: 0 0 14px; letter-spacing: -.025em; }
.home-copy .lede { font-size: 1.12rem; color: var(--ink-soft); max-width: 46ch; margin: 0; }
.home-copy .pillbar { margin-top: 24px; }

/* Capped and pushed right: at full column width the stroke card was mostly
   empty paper around a small glyph. */
.demo { min-width: 0; max-width: 420px; margin-left: auto; width: 100%; }
.demo-stage {
  border: 1px solid var(--line); border-radius: 18px; background: var(--card);
  padding: 14px; display: grid; place-items: center;
}
.demo-svg { width: 100%; max-width: 230px; }
.demo-svg .kvg { width: 100%; height: auto; display: block; }

.demo-keys { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; margin: 12px 0 0; }
.demo-key {
  display: grid; gap: 2px; justify-items: center; align-content: center;
  min-height: 60px; padding: 8px 4px; cursor: pointer; font: inherit;
  border: 1px solid var(--line); border-radius: 12px; background: var(--card);
}
.demo-key:hover { border-color: var(--accent); }
.demo-key:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dk-char { font-family: var(--jp); font-size: 1.5rem; line-height: 1.1; color: var(--ink); }
.dk-roma { font-size: .7rem; color: var(--ink-faint); }
.demo-key[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); }
.demo-key[aria-pressed="true"] .dk-char,
.demo-key[aria-pressed="true"] .dk-roma { color: var(--accent); }

.demo-note {
  display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline;
  margin: 10px 0 0; font-size: .82rem; color: var(--ink-faint);
}
.demo-note a { color: var(--accent); font-weight: 700; text-decoration: none; }
.demo-note a:hover { text-decoration: underline; }

/* Resume. Present only for a browser that has practised, so it is styled as
   a returning-visitor shortcut rather than as part of the pitch. */
.resume {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin: 28px 0 0;
  padding: 16px 20px; border-radius: 14px;
  background: var(--accent-soft); border: 1px solid transparent;
}
.resume-main { min-width: 0; }
.resume-line { margin: 0; font-weight: 700; color: var(--ink); }
.resume-sub { margin: 4px 0 0; font-size: .86rem; color: var(--ink-soft); }
.resume-sub span[lang="ja"] { font-family: var(--jp); font-weight: 700; color: var(--accent); }

.cards-2 { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }

/* One honest line where two dead cards used to sit. */
.inbuild {
  display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: baseline;
  margin: 20px 0 0; font-size: .86rem; color: var(--ink-faint);
}
.inbuild b { color: var(--ink-soft); font-weight: 800; letter-spacing: .02em; }
.inbuild span { position: relative; padding-left: 14px; }
.inbuild span::before {
  content: ""; position: absolute; left: 0; top: .5em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--line);
}

@media (max-width: 860px) {
  .home-hero { grid-template-columns: minmax(0, 1fr); gap: 28px; padding-top: 32px; }
  .demo { max-width: none; margin-left: 0; }
  .demo-stage { padding: 10px; }
  .demo-svg { max-width: 190px; }
}
@media (max-width: 640px) {
  .home-hero { padding-top: 24px; gap: 22px; }
  .home-copy h1 { font-size: 1.7rem; margin-bottom: 8px; }
  .home-copy .lede { font-size: 1rem; line-height: 1.55; }
  .home-copy .pillbar { margin-top: 18px; }
  .demo-svg { max-width: 150px; }
  .demo-key { min-height: 56px; }
  .dk-char { font-size: 1.3rem; }
  .resume { padding: 14px 16px; }
  .resume .pill { width: 100%; text-align: center; }
}

/* The chart page's own content: how to read the grid, and how to print it.
   Without this the page was a copy of the pillar with the prose removed. */
.chart-notes { max-width: 72ch; }
.chart-notes ul { margin: 0; padding-left: 20px; }
.chart-notes li { margin: 0 0 12px; line-height: 1.65; color: var(--ink-soft); }
.chart-notes li strong { color: var(--ink); }
.chart-notes li span[lang="ja"] { font-family: var(--jp); }
.chart-notes kbd { background: var(--card); border: 1px solid var(--line); color: var(--ink-soft); margin: 0 1px; }
.chart-more { margin: 18px 0 0; font-size: .92rem; color: var(--ink-faint); }
.chart-more a { color: var(--accent); font-weight: 700; text-decoration: none; }
.chart-more a:hover { text-decoration: underline; }
@media print { .chart-notes { display: none; } }

/* Example words and the written notes on a kana page. Each block is absent
   rather than empty when there is nothing true to put in it, so page length
   varies between kana. */
.wordlist { margin: 26px 0 0; }
.wordlist h2, .pitfall h2 { font-size: .72rem; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-faint); margin: 0 0 10px; }
.wordlist ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.wordlist li {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px;
  padding: 11px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--card);
}
.w-kana { font-family: var(--jp); font-size: 1.25rem; color: var(--ink); line-height: 1.3; }
.w-read { font-size: .84rem; color: var(--accent); font-weight: 700; letter-spacing: .02em; }
.w-en { font-size: .92rem; color: var(--ink-soft); }
.w-kanji {
  margin-left: auto; font-family: var(--jp); font-size: .95rem; color: var(--ink-faint);
  border: 1px solid var(--line); border-radius: 7px; padding: 2px 8px; flex: none;
}
.confuse-note { margin: 12px 0 0; font-size: .92rem; line-height: 1.65; color: var(--ink-soft); max-width: 62ch; }
.pitfall { margin: 26px 0 0; padding: 16px 18px; border-radius: 12px;
  background: var(--paper); border: 1px solid var(--line); }
.pitfall p { margin: 0; font-size: .95rem; line-height: 1.65; color: var(--ink-soft); max-width: 62ch; }
.pitfall p span[lang="ja"], .confuse-note span[lang="ja"] { font-family: var(--jp); }

@media (max-width: 640px) {
  .confuse { margin-top: 20px; }
  .wordlist { margin-top: 20px; }
  .wordlist li { padding: 10px 12px; gap: 3px 10px; }
  .w-kanji { margin-left: 0; }
  .pitfall { margin-top: 20px; padding: 14px 15px; }
}

/* ======================================================================
   The words page: an index of everything the site teaches, plus a drill.
   ====================================================================== */

.words { max-width: 1120px; margin: 0 auto; }
.words-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 8px 0 18px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--card);
}
.wfind { flex: 1 1 240px; min-width: 0; display: block; }
.sr-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.wfind input {
  width: 100%; font: inherit; font-size: .95rem; padding: 10px 12px; min-height: 44px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--paper); color: var(--ink);
}
.wfind input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.wcount { margin: 0; font-size: .82rem; color: var(--ink-faint); flex: none; }
.wcount b { color: var(--accent); }
.words-bar .pill { flex: none; }

.wgrid {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
}
.wcard {
  min-width: 0; padding: 14px 16px; border: 1px solid var(--line);
  border-radius: 14px; background: var(--card);
}
.wcard-main { display: flex; align-items: center; gap: 8px; }
.wcard .w-kana { font-family: var(--jp); font-size: 1.4rem; line-height: 1.25; min-width: 0; }
/* Visual size and tap size are separate: a 26px speaker beside a 1.4rem
   word looks right, but a thumb needs more than that, so the hit area is
   grown with a pseudo-element the same way the chart cells do it. */
.wcard .speak { position: relative; width: 26px; height: 26px; flex: none; }
.wcard .speak svg { width: 13px; height: 13px; }
.wcard .speak::after {
  content: ""; position: absolute; top: -9px; right: -9px; bottom: -9px; left: -9px;
}
.wcard-read { margin: 4px 0 0; font-size: .82rem; font-weight: 700; color: var(--accent); letter-spacing: .02em; }
.wcard-en { margin: 6px 0 0; font-size: .95rem; color: var(--ink-soft); }
.wcard-kanji { font-family: var(--jp); color: var(--ink-faint); font-size: .9em; }
.wcard-via { margin: 10px 0 0; display: flex; gap: 6px; }
.wcard-via a {
  font-family: var(--jp); font-size: .92rem; text-decoration: none;
  color: var(--ink-soft); border: 1px solid var(--line); border-radius: 7px;
  min-width: 30px; min-height: 30px; display: inline-flex; align-items: center; justify-content: center;
}
.wcard-via a:hover { border-color: var(--accent); color: var(--accent); }
.wempty { margin: 20px 0 0; color: var(--ink-faint); font-size: .92rem; }

/* While a round is running the list is hidden: the answer to the question
   on screen is sitting in it. */
.words.drilling .wgrid, .words.drilling .words-bar, .words.drilling .wempty { display: none; }

.wdrill { padding: 26px 22px; border: 1px solid var(--line); border-radius: 16px; background: var(--card); }
.wdrill-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.wdrill-progress { margin: 0; font-size: .8rem; color: var(--ink-faint); }
.wdrill-progress b { color: var(--ink-soft); }
.wdrill-q { font-family: var(--jp); font-size: clamp(2.6rem, 9vw, 4rem); text-align: center; margin: 26px 0 0; line-height: 1.2; }
.wdrill-r { text-align: center; margin: 8px 0 0; font-size: 1rem; color: var(--accent); font-weight: 700; letter-spacing: .04em; }
.wdrill-opts { display: grid; gap: 8px; margin: 26px 0 0; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
.wopt {
  font: inherit; font-size: .98rem; padding: 14px 16px; min-height: 52px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 12px; background: var(--paper); color: var(--ink);
}
.wopt:hover:not(:disabled) { border-color: var(--accent); }
.wopt:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wopt.correct { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 700; }
.wopt.wrong { background: var(--line); border-color: var(--ink-faint); color: var(--ink-faint); text-decoration: line-through; }
.wopt:disabled { cursor: default; }

.wdrill-done { text-align: center; margin: 26px 0 0; }
.wdrill-score { margin: 0; font-size: 2.2rem; font-weight: 800; }
.wdrill-note { margin: 8px auto 0; max-width: 54ch; font-size: .92rem; color: var(--ink-soft); line-height: 1.7; }
.wdrill-note span[lang="ja"] { font-family: var(--jp); font-weight: 700; color: var(--ink); }
.wdrill-done .pillbar { justify-content: center; margin-top: 20px; }

@media (max-width: 640px) {
  .words-bar { padding: 10px 12px; gap: 10px; }
  .words-bar .pill { width: 100%; text-align: center; }
  .wgrid { grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); gap: 8px; }
  .wcard { padding: 12px 13px; }
  .wdrill { padding: 20px 15px; }
  .wdrill-opts { grid-template-columns: minmax(0, 1fr); }
}
@media print { .words-bar, .wdrill, .wcard-via { display: none; } }

/* ======================================================================
   The bar at the foot of a kana page: previous, the call to action with
   its keyboard hints, and next. These were three separate things spread
   down the page; walking the chart in order is the main way these pages
   get read, so they belong together.
   ====================================================================== */

.kana-bar {
  display: grid; align-items: center; gap: 16px;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  margin: 40px 0 0; padding: 14px 18px;
  border: 1px solid var(--line); border-radius: 16px; background: var(--card);
}
.kbar-side { min-width: 0; }
.kbar-next { justify-self: end; }

.kbar-move {
  display: flex; align-items: center; gap: 12px; min-width: 0;
  text-decoration: none; color: inherit; border-radius: 12px;
  padding: 6px 8px; margin: -6px -8px;
}
a.kbar-move:hover { background: var(--paper); }
a.kbar-move:hover .kbar-name { color: var(--accent); }
a.kbar-move:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The ends of the chart are links like any other slot in this bar, not
   controls dressed as unavailable. They go to the chart itself, which is
   what "beginning of the chart" refers to, so they get the same arrow,
   tile, hover and focus treatment as a real previous or next kana. */
.kbar-grid { width: 20px; height: 20px; fill: var(--ink-faint); }
a.kbar-move:hover .kbar-grid { fill: var(--accent); }

.kbar-arrow {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--paper);
  display: grid; place-items: center; font-size: 1rem; color: var(--ink-soft);
}
a.kbar-move:hover .kbar-arrow { border-color: var(--accent); color: var(--accent); }
.kbar-text { display: grid; gap: 1px; min-width: 0; }
.kbar-label {
  font-size: .64rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint);
}
.kbar-name { font-size: .95rem; font-weight: 700; color: var(--ink-soft); }
.kbar-name span[lang="ja"] { font-family: var(--jp); }
.kbar-next .kbar-text { text-align: right; justify-items: end; }
.kbar-tile {
  flex: none; width: 46px; height: 46px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--paper);
  display: grid; place-items: center; font-family: var(--jp); font-size: 1.5rem;
}
a.kbar-move:hover .kbar-tile { border-color: var(--accent); }

.kbar-mid { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: center; }
.kbar-cta { white-space: nowrap; }
.kbar-row { font-family: var(--jp); font-weight: 400; opacity: .8; }
.kbar-keys { display: flex; gap: 10px; margin: 0; flex-wrap: wrap; }
.kbar-key {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .74rem; color: var(--ink-faint); white-space: nowrap;
}
.kbar-key kbd {
  margin: 0; background: var(--paper); border: 1px solid var(--line);
  color: var(--ink-soft); font-size: .7rem; padding: 2px 6px;
}

/* Below the three-column width the bar stacks: the call to action first,
   because it is the reason the bar exists, then the two moves side by side. */
@media (max-width: 820px) {
  .kana-bar { grid-template-columns: 1fr 1fr; gap: 14px; padding: 14px; }
  .kbar-mid { grid-column: 1 / -1; order: -1; }
  .kbar-next { justify-self: end; }
  .kbar-cta { width: 100%; text-align: center; }
}
@media (max-width: 480px) {
  .kana-bar { margin-top: 28px; }
  .kbar-arrow { width: 30px; height: 30px; }
  .kbar-tile { width: 40px; height: 40px; font-size: 1.3rem; }
  .kbar-name { font-size: .88rem; }
  .kbar-label { font-size: .6rem; }
}

/* A phone has no Space bar and no arrow keys, so the hints are noise there. */
@media (hover: none), (pointer: coarse) {
  .kbar-keys { display: none; }
}
