/* =====================================================================
   eiken.css — the 英検® guide pages (/eiken/ and /eiken/<grade>/)
   ---------------------------------------------------------------------
   A module shared by the nine guide pages (like fee.css is shared by the
   fee tables), loaded after base.css → layout.css → components.css. The
   pages are long reference documents, so they are built on the .l-doc
   layout: a sticky 目次 rail beside one reading column. Everything here is
   composed from the tokens; the figures, tables and asides inside the
   column are the shared components (.facts, .table, .callout, .card,
   .faq-*, .note).

     1. Hero            .eiken-hero — the compact hero on cream, plus the
                        page's fact sheet
     2. Index           .eiken-toc — the 目次 in the rail; a sticky
                        chapter bar with a toggle below 1024px
     3. Chapter         .eiken-chapter — Caveat number + title, then prose
     4. Prose           .eiken-body — running text inside the column
     5. Grade scale     .eiken-scale — the eight grades as one line, the
                        page's own grade marked, CEFR bands under it
     6. Example         .eiken-example — a sample question card whose
                        answer opens in place under the question
     7. Pager / refs    .eiken-pager, .eiken-refs, .eiken-disclaimer
     8. Course PR       .eiken-pr — the matching course, labelled 「PR」,
                        inserted by the template after the study chapter

   Markup contract and authoring rules: docs/eiken-guide-authoring.md.
   ===================================================================== */


/* =====================================================================
   1. HERO
   The compact-hero family (legal pages, 404): breadcrumb, title, one
   lead, on cream with the legal hero's dotted gold ground. The fact
   sheet closes the hero, so the answer to "how hard / how many points /
   when" is on screen before the first scroll.
   ===================================================================== */
.eiken-hero {
  position: relative;
  isolation: isolate;
  padding: calc(var(--header-h) + var(--sp-16)) 0 var(--sp-16);
  background-color: var(--bg-cream);
}
.eiken-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: radial-gradient(circle, rgba(245, 158, 11, 0.10) 1px, transparent 1.2px);
  background-size: 28px 28px;
  opacity: 0.55;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 85%);
          mask-image: linear-gradient(180deg, #000 0%, transparent 85%);
  pointer-events: none;
}
.eiken-hero-title {
  max-width: 22em;
  margin: 0 0 var(--sp-5);
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  font-weight: var(--fw-head);
  color: var(--text-main);
  word-break: auto-phrase;   /* 「準2級や2級」 never splits at 320 */
}
.eiken-hero-title sup,
.eiken-body sup,
.eiken-toc sup,
.eiken-hero .breadcrumb sup {
  font-size: 0.5em;
  vertical-align: baseline;
  position: relative;
  top: -0.8em;
  line-height: 0;
}
.eiken-body sup,
.eiken-toc sup,
.eiken-hero .breadcrumb sup { font-size: 0.6em; top: -0.45em; }
.eiken-hero-lead {
  max-width: var(--w-measure);
  margin: 0;
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  color: var(--text-light);
  /* two sentences, four or five lines on a phone: running text (§4) */
}
.eiken-hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-5);
  margin: var(--sp-5) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--ink-quiet);
}
.eiken-hero-meta li { display: inline-flex; gap: var(--sp-2); }
.eiken-hero-meta b { flex-shrink: 0; font-weight: var(--fw-bold); color: var(--text-light); }
.eiken-hero-meta a {
  color: var(--ink-sky);
  font-weight: var(--fw-bold);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.eiken-hero .facts { margin-top: var(--sp-12); }
@media (max-width: 767px) {
  .eiken-hero { padding: calc(var(--header-h) + var(--sp-10)) 0 var(--sp-10); }
  .eiken-hero .facts { margin-top: var(--sp-8); }
}


/* =====================================================================
   2. INDEX (目次)
   Printed as a static list under a plain title, which is what it stays
   without JS and at 1024px and up: the rail's card, numbered like the
   chapters, the chapter in view marked by a blue rule (js/eiken.js). The
   list scrolls inside the rail when the window is short, so the card is
   always whole.
   Below 1024px, with JS (.eiken-toc--js), the rail becomes a sticky
   chapter bar under the header: one full-width toggle — 「目次」, the
   chapter in view, ± — that opens the list as a panel under the bar.
   Open (.eiken-toc--open), the bar and the panel rise above the fixed
   bottom CTA (z 200, css/layout.css) to z 300 — still under the header
   (500, its menu drawer inside it) and the detail dialog (1000). The panel
   runs at most to the bottom of the screen (--eiken-toc-top: the bar's
   bottom edge, set by js/eiken.js) and scrolls inside itself, so every
   entry down to 参考資料 is reachable — on a phone too short for all of
   it, its rows close up and its foot fades while more is below
   (--dense, --more); a light scrim (the dialog
   backdrop's ink) covers the page under the header, and the page is held
   still (html.is-toc-open) until the panel closes. Anything linked to in
   the column (a chapter, 参考資料) lands clear of the bar by its own
   scroll-margin-top; the page's scroll padding stays the header's.
     <nav class="eiken-toc" aria-labelledby="eiken-toc-title">
       <p class="eiken-toc-title" id="eiken-toc-title">目次</p>
       <button class="eiken-toc-toggle" aria-expanded aria-controls hidden>…</button>
       <ol class="eiken-toc-list" id="eiken-toc-list">…</ol>
     </nav>
   ===================================================================== */
.eiken-toc {
  background: var(--bg-white);
  border: 1px solid var(--border-warm);
  border-radius: var(--r-md);
}
.eiken-toc-title {
  margin: 0;
  padding: var(--sp-4) var(--sp-5) var(--sp-3);
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  font-weight: var(--fw-bold);
  color: var(--text-main);
}
.eiken-toc-toggle { display: none; }
/* The ± of the toggle and of the example's answer (§6): two 2px bars,
   the upright one folding flat when open. */
.eiken-toc-icon,
.eiken-example-icon {
  position: relative;
  flex-shrink: 0;
  width: 12px;
  height: 12px;
}
.eiken-toc-icon::before,
.eiken-toc-icon::after,
.eiken-example-icon::before,
.eiken-example-icon::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 12px;
  height: 2px;
  border-radius: 1px;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: transform var(--transition);
}
.eiken-toc-icon::after,
.eiken-example-icon::after { transform: translate(-50%, -50%) rotate(90deg); }
.eiken-toc-toggle[aria-expanded="true"] .eiken-toc-icon::after,
.eiken-example-answer[open] .eiken-example-icon::after { transform: translate(-50%, -50%) rotate(0deg); }
.eiken-toc-list {
  margin: 0;
  padding: 0 var(--sp-3) var(--sp-3);
  list-style: none;
}
.eiken-toc-list[hidden] { display: none; }
.eiken-toc-list a {
  display: grid;
  grid-template-columns: 1.75rem minmax(0, 1fr);
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-3);
  border-left: 2px solid transparent;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--text-light);
  word-break: auto-phrase;
  transition: color var(--transition), background var(--transition), border-color var(--transition);
}
.eiken-toc-num {
  font-family: var(--font-en);
  font-size: var(--fs-caption);
  line-height: var(--lh-body-sm);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  color: var(--ink-amber);
}
.eiken-toc-list a:hover {
  opacity: 1;
  color: var(--text-main);
  background: var(--bg-cream);
}
.eiken-toc-list a[aria-current="true"] {
  color: var(--ink-sky);
  font-weight: var(--fw-bold);
  border-left-color: var(--primary);
  background: rgba(0, 174, 239, 0.06);
}
.eiken-toc-list a:focus-visible { outline-offset: -3px; }
/* Desktop: the rail's card is whole; the list scrolls inside it. */
@media (min-width: 1024px) {
  .eiken-doc .l-doc-aside { max-height: none; overflow: visible; }
  .eiken-toc-list {
    max-height: calc(100vh - var(--header-h) - var(--sp-12) - 3.5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}
@media (min-width: 1024px) and (max-height: 760px) {
  .eiken-toc-list a { padding-block: var(--sp-1); }
}
/* Below 1024px without JS: the list, open, above the column. */
@media (max-width: 1023px) {
  .eiken-toc-list { padding-top: var(--sp-1); border-top: 1px dashed var(--border-warm); }
  .eiken-toc-list a { padding-top: var(--sp-3); padding-bottom: var(--sp-3); }
}
/* Below 1024px with JS: the sticky chapter bar. */
@media (max-width: 1023px) {
  .eiken-doc .l-doc:has(.eiken-toc--js) { display: block; }
  .eiken-doc .l-doc-aside:has(.eiken-toc--js) {
    position: sticky;
    top: var(--header-h);
    z-index: 5;
    margin-inline: calc(-1 * var(--content-pad-x));
    margin-bottom: var(--sp-10);
  }
  .eiken-doc .l-doc-aside:has(.eiken-toc--open) { z-index: 300; }
  /* The bar's own surface, so the scrim (earlier in the aside) lies under it. */
  .eiken-toc--js { position: relative; border-width: 1px 0; border-radius: 0; }
  .eiken-toc--js .eiken-toc-title { display: none; }
  .eiken-toc--js .eiken-toc-toggle {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    width: 100%;
    min-height: 48px;
    padding: var(--sp-3) var(--content-pad-x);
    border: 0;
    background: none;
    font: inherit;
    text-align: left;
    color: var(--text-main);
    cursor: pointer;
  }
  .eiken-toc--js .eiken-toc-toggle:focus-visible { outline-offset: -3px; }
  .eiken-toc-toggle-label {
    flex-shrink: 0;
    font-size: var(--fs-h4);
    line-height: var(--lh-h4);
    font-weight: var(--fw-bold);
  }
  .eiken-toc-now {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    font-size: var(--fs-body-sm);
    line-height: var(--lh-body-sm);
    color: var(--ink-quiet);
    white-space: nowrap;
    text-overflow: ellipsis;
  }
  .eiken-toc--js .eiken-toc-icon { margin-left: auto; color: var(--primary); }
  .eiken-toc--js .eiken-toc-list {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    /* from the bar's bottom edge to the bottom of the visible screen */
    max-height: calc(100vh - var(--eiken-toc-top, calc(var(--header-h) + 3.5rem)) - env(safe-area-inset-bottom, 0px));
    max-height: calc(100dvh - var(--eiken-toc-top, calc(var(--header-h) + 3.5rem)) - env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
    overscroll-behavior: contain;
    margin-top: 1px;   /* under the bar's bottom rule */
    padding: var(--sp-1) var(--content-pad-x) var(--sp-3);
    background: var(--bg-white);
    border-top: 0;
    border-bottom: 1px solid var(--border-warm);
    box-shadow: var(--shadow-md);
  }
  /* A panel that must still scroll when open (a short phone; js/eiken.js):
     its rows close up (a 40px target), and while more of it is below, its
     foot fades into the panel's white — a list cut at an entry's edge
     never looks complete. The fade is a sticky layer inside the list, not
     a mask: a mask would make the foot see-through, and the fixed bottom
     CTA under the panel would show through it. */
  .eiken-toc--js .eiken-toc-list--dense a { padding-top: var(--sp-2); padding-bottom: var(--sp-2); }
  .eiken-toc--js .eiken-toc-list--more::after {
    content: '';
    position: sticky;
    bottom: calc(-1 * var(--sp-3));   /* over the list's bottom padding too */
    display: block;
    height: 3rem;
    margin-top: -3rem;
    background: linear-gradient(to bottom, transparent, var(--bg-white) 85%);
    pointer-events: none;
  }
  /* The scrim: the dialog backdrop's ink, lighter. It starts under the
     header (which stays as it is) and lies under the bar and the panel;
     a tap on it closes the list. */
  .eiken-toc-scrim {
    position: fixed;
    top: var(--header-h);
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(20, 18, 14, 0.32);
    cursor: pointer;
    touch-action: none;
    -webkit-tap-highlight-color: transparent;
  }
  @media (prefers-reduced-motion: no-preference) {
    .eiken-toc-scrim,
    .eiken-toc--open .eiken-toc-list { animation: eiken-toc-in 0.18s ease-out; }
  }
  /* The page stays where it is while the list is open. */
  html.is-toc-open { overflow: hidden; scrollbar-gutter: stable; }
  /* A chapter clears the bar through its own scroll margin, not the
     page's scroll padding: the padding stays the header's, so the bar
     itself (under the header) is inside the viewing area and focusing
     its toggle never scrolls the page. */
  html:has(.eiken-toc--js) { scroll-padding-top: var(--header-h); }
  .eiken-doc:has(.eiken-toc--js) .l-doc-main [id] { scroll-margin-top: 3.5rem; }
}
@keyframes eiken-toc-in { from { opacity: 0; } }


/* =====================================================================
   3. CHAPTER
   The legal article's head, reused: a handwritten Caveat number beside a
   section title. Chapters are divided by one hairline; the first sits
   straight under the top of the column. The course PR (§8) belongs to
   the end of the chapter it follows, so the chapter after it takes the
   same hairline and spacing as after a chapter.
   ===================================================================== */
.eiken-chapter { position: relative; }
.eiken-chapter + .eiken-chapter,
.eiken-pr + .eiken-chapter {
  margin-top: var(--sp-16);
  padding-top: var(--sp-16);
  border-top: 1px solid var(--border-warm);
}
.eiken-chapter-head {
  display: grid;
  grid-template-columns: 3.75rem minmax(0, 1fr);
  align-items: baseline;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-6);
}
.eiken-chapter-num {
  font-family: var(--font-deco);
  font-size: var(--fs-deco-lg);
  line-height: 0.85;
  font-weight: var(--fw-bold);
  color: var(--accent);
  transform: rotate(-4deg);
  transform-origin: left center;
}
.eiken-chapter-title {
  margin: 0;
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: var(--fw-head);
  color: var(--text-main);
  text-wrap: balance;
  word-break: auto-phrase;
}
.eiken-chapter--plain .eiken-chapter-head { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 520px) {
  .eiken-chapter-head { grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
  .eiken-chapter + .eiken-chapter,
  .eiken-pr + .eiken-chapter { margin-top: var(--sp-12); padding-top: var(--sp-12); }
}


/* =====================================================================
   4. PROSE
   Running text in the reading column. The column is the measure, so
   nothing here caps a width. Heading steps: chapter --fs-h1 (above) →
   h3 --fs-h2 → h4 --fs-h3. The chapter's first paragraph (.eiken-answer)
   answers the chapter's question in two or three sentences, at lead size.
   ===================================================================== */
/* Running text fills the measure: plain Japanese line breaking — wrap,
   word-break normal, line-break strict (kinsoku, from base.css) — flush
   left. Stated on the column because both properties inherit. Never
   text-wrap: pretty here: WebKit (Safari 26, iOS) applies it to every
   line of a paragraph and shortens each one to even out the rag, which in
   Japanese leaves every line two to four characters short (list items
   and dd take it in Chromium only, below .eiken-dl, where it touches just
   the last lines). Never word-break: auto-phrase: it breaks only between
   phrases and leaves a line up to a phrase short. Headings and short
   labels opt back in. The runs that must not break (dates, 約N分,
   第N回…) are kept whole by eiken_nb(). */
.eiken-body {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-main);
  text-wrap: wrap;
  word-break: normal;
}
.eiken-body :where(p) { margin: 0 0 var(--sp-4); }
.eiken-body > .eiken-chapter > .eiken-answer {
  margin-bottom: var(--sp-8);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
}
.eiken-body :where(h3:not([class])) {
  margin: var(--sp-12) 0 var(--sp-4);
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: var(--fw-head);
  color: var(--text-main);
  text-wrap: balance;
  word-break: auto-phrase;
}
.eiken-body :where(h4:not([class])) {
  margin: var(--sp-8) 0 var(--sp-3);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: var(--fw-bold);
  color: var(--text-main);
  word-break: auto-phrase;
}
.eiken-body :where(h3:not([class])) + :where(h4:not([class])) { margin-top: var(--sp-4); }
.eiken-chapter-head + h3:not([class]),
.eiken-answer + h3:not([class]) { margin-top: var(--sp-8); }
.eiken-body :where(strong, em) { font-style: normal; font-weight: var(--fw-bold); color: var(--text-main); }
.eiken-body :where(a:not([class])) {
  color: var(--ink-sky);
  font-weight: var(--fw-bold);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  overflow-wrap: anywhere;
}
.eiken-body :where(a:not([class])):hover { opacity: 1; color: var(--primary-dark); text-decoration-thickness: 2px; }
/* Lists: amber dots (the dialog-list recipe); steps done in order are
   numbered plainly 「1.」 in the text's own face, secondary ink. */
.eiken-body :where(ul:not([class]), ol:not([class])) {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-5);
  padding: 0;
  list-style: none;
}
.eiken-body :where(ul:not([class]), ol:not([class])) > li {
  position: relative;
  padding-left: 1.5em;
}
.eiken-body :where(ul:not([class])) > li::before {
  content: '';
  position: absolute;
  left: 0.35em;
  top: 0.72em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}
.eiken-body :where(ol:not([class])) { counter-reset: eiken-step; }
.eiken-body :where(ol:not([class])) > li { counter-increment: eiken-step; }
.eiken-body :where(ol:not([class])) > li::before {
  content: counter(eiken-step) '.';
  position: absolute;
  left: 0;
  top: 0;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: var(--fw-regular);
  font-variant-numeric: tabular-nums;
  color: var(--text-light);
}
.eiken-body :where(li > ul:not([class]), li > ol:not([class])) { margin: var(--sp-2) 0 0; }
/* A source line (.note) sits 12px under whatever block it cites — a
   table, a paragraph, a list, a term list, a callout, the grade scale. */
.eiken-body .eiken-chapter > :has(+ .note) { margin-bottom: 0; }
.eiken-body .note { max-width: none; margin-top: var(--sp-3); }
.eiken-body .table-wrap { margin-bottom: var(--sp-6); }
/* Citations are fine print: regular weight, the note's own ink. */
.eiken-body .note a {
  font-weight: var(--fw-regular);
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.eiken-body .note a:hover { opacity: 1; color: var(--ink-sky); }
/* Visually hidden, still read out (a table's caption, §4). */
.eiken-vh,
.table > caption.eiken-vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.eiken-body .l-grid,
.eiken-body .l-rows { margin: var(--sp-6) 0; }
.eiken-body .faq-list { margin-top: var(--sp-6); }
/* A term list for short "label → value" facts inside prose. */
.eiken-dl {
  display: grid;
  grid-template-columns: minmax(0, 10.5em) minmax(0, 1fr);   /* a 9-character bold label + its padding */
  margin: var(--sp-5) 0;
  border-top: 1px solid var(--border-warm);
}
.eiken-dl dt,
.eiken-dl dd {
  margin: 0;
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--border-warm);
}
.eiken-dl dt { padding-right: var(--sp-4); font-size: var(--fs-body-md); font-weight: var(--fw-bold); color: var(--text-light); word-break: auto-phrase; }
/* A list item or a dd is often one or two lines: Chromium's pretty (it
   rebalances only the last lines) keeps it from ending on one lone
   character (話｜す → 声で｜話す). WebKit — Safari, every iOS browser —
   matches the query and is left plain: it applies pretty to every line
   and shortens them all (§4). */
@supports not (font: -apple-system-body) {
  .eiken-body :where(ul:not([class]), ol:not([class])) > li,
  .eiken-dl dd { text-wrap: pretty; }
}
@media (max-width: 520px) {
  .eiken-dl { grid-template-columns: minmax(0, 1fr); }
  .eiken-dl dt { padding-bottom: 0; border-bottom: 0; }
  .eiken-dl dd { padding-top: var(--sp-1); }
}


/* =====================================================================
   5. GRADE SCALE
   The eight grades as one line, easiest to hardest, like a route map:
   every grade is a stop that links to its guide (the name underlined,
   like a link); the page's own grade is the filled stop, marked
   aria-current="page". Under the line, brackets group the stops by the
   CEFR level a passer is judged at; the CEFR is also in each stop for a
   screen reader. The level drops its 「程度」 on the line so every label
   fits one line (the caption says what the words are). Below 768px the
   line turns vertical: one row per stop, the full level, the CEFR as a
   pill and an arrow on every stop you can go to.
     <div class="eiken-scale">…built by eiken_scale() in partials/eiken/bootstrap.php…</div>
   In the reading column the frame is an inner panel (--r-md); on
   /level-guide/ it keeps the card radius.
   ===================================================================== */
.eiken-scale {
  --scale-cols: 8;
  margin: var(--sp-8) 0 var(--sp-6);
  padding: var(--sp-6) var(--sp-4) var(--sp-5);
  background: var(--bg-white);
  border: 1px solid var(--border-warm);
  border-radius: var(--r-lg);
}
.eiken-body .eiken-scale { border-radius: var(--r-md); }
.eiken-scale-stops,
.eiken-scale-bands {
  display: grid;
  grid-template-columns: repeat(var(--scale-cols), minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}
.eiken-scale-stops { position: relative; }
/* the line, from the first stop's centre to the last's */
.eiken-scale-stops::before {
  content: '';
  position: absolute;
  top: 9px;
  left: calc(100% / var(--scale-cols) / 2);
  right: calc(100% / var(--scale-cols) / 2);
  height: 2px;
  border-radius: 1px;
  background: linear-gradient(90deg, rgba(0, 174, 239, 0.25), var(--primary));
}
.eiken-scale-stop { position: relative; min-width: 0; }
.eiken-scale-stop > a {
  text-decoration: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-1);
  padding: 0 0 var(--sp-2);
  text-align: center;
  color: var(--text-main);
  border-radius: var(--r-sm);
}
.eiken-scale-stop.is-current > a { pointer-events: none; }
.eiken-scale-dot {
  position: relative;
  z-index: 1;
  display: block;
  width: 20px;
  height: 20px;
  margin-bottom: var(--sp-2);
  border-radius: 50%;
  background: var(--bg-white);
  border: 2px solid var(--primary);
  transition: transform var(--transition), background var(--transition);
}
.eiken-scale-dot::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: transparent;
  transition: background var(--transition);
}
.eiken-scale-name {
  font-size: var(--fs-body-md);
  line-height: var(--lh-body-md);
  font-weight: var(--fw-bold);
  white-space: nowrap;
}
.eiken-scale-level {
  font-size: var(--fs-caption);
  font-weight: var(--fw-regular);
  line-height: var(--lh-caption);
  color: var(--ink-quiet);
  word-break: auto-phrase;
}
@media (min-width: 768px) {
  .eiken-scale-level { white-space: nowrap; }
  .eiken-scale-level-suffix { display: none; }
  /* the CEFR is the brackets' job on the line; kept for a screen reader */
  .eiken-scale-cefr {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* a stop you can go to reads as a link: its name is underlined */
  .eiken-scale-stop:not(.is-current) > a .eiken-scale-name {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--text-muted);
    text-underline-offset: 4px;
  }
}
.eiken-scale-stop > a:hover { opacity: 1; }
.eiken-scale-stop > a:hover .eiken-scale-dot { transform: scale(1.12); }
.eiken-scale-stop > a:hover .eiken-scale-dot::after { background: rgba(0, 174, 239, 0.35); }
.eiken-scale-stop > a:hover .eiken-scale-name { color: var(--ink-sky); text-decoration-color: var(--ink-sky); }
/* Focus: the dot takes the ring, the name its underline. */
.eiken-scale-stop > a:focus-visible { outline: none; }
.eiken-scale-stop > a:focus-visible .eiken-scale-dot { box-shadow: 0 0 0 3px var(--bg-white), 0 0 0 6px var(--primary); }
.eiken-scale-stop > a:focus-visible .eiken-scale-name { text-decoration: underline; text-decoration-color: var(--ink-sky); }
/* the page's own grade */
.eiken-scale-stop.is-current .eiken-scale-dot {
  background: var(--primary);
  box-shadow: 0 0 0 5px rgba(0, 174, 239, 0.16);
}
.eiken-scale-stop.is-current .eiken-scale-dot::after { background: var(--bg-white); inset: 6px; }
.eiken-scale-stop.is-current .eiken-scale-name { color: var(--ink-sky); }
/* CEFR brackets under the stops: quiet rules, the page's own in amber */
.eiken-scale-bands { gap: 0 var(--sp-2); margin-top: var(--sp-4); padding: 0 var(--sp-1); }
.eiken-scale-band {
  position: relative;
  padding-top: var(--sp-3);
  text-align: center;
  font-family: var(--font-en);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-bold);
  letter-spacing: 0.06em;
  color: var(--text-light);
}
.eiken-scale-band::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  border: 1px solid var(--text-muted);
  border-bottom: 0;
  border-radius: 3px 3px 0 0;
  opacity: 0.45;
}
.eiken-scale-band.is-none { font-family: var(--font-ja); font-weight: var(--fw-regular); letter-spacing: 0; color: var(--ink-quiet); }
.eiken-scale-band.is-current { color: var(--ink-amber); }
.eiken-scale-band.is-current::before { border-color: var(--accent); opacity: 1; }
/* The rule spans the panel; the text keeps the reading measure. */
.eiken-scale-caption {
  margin: var(--sp-5) 0 0;
  padding: var(--sp-4) max(var(--sp-2), calc(100% - var(--w-measure) - var(--sp-2))) 0 var(--sp-2);
  border-top: 1px dashed var(--border-warm);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--ink-quiet);
  /* three sentences, five lines on a phone: running text (§4) */
}
/* Vertical below 768px: the line runs down the left, one row per stop:
   dot · name with its level under it · CEFR pill · arrow. The level has
   its own line, so 「高校上級程度」 never breaks, even at 320px; a row is
   70px tall, so the line starts and ends at the first and last dots'
   centres, 35px in. */
@media (max-width: 767px) {
  .eiken-scale { padding: var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-3); }
  .eiken-scale-stops { grid-template-columns: minmax(0, 1fr); }
  .eiken-scale-stops::before {
    top: 35px;
    bottom: 35px;
    left: calc(var(--sp-3) + 9px);
    right: auto;
    width: 2px;
    height: auto;
    background: linear-gradient(180deg, rgba(0, 174, 239, 0.25), var(--primary));
  }
  .eiken-scale-stop > a {
    display: grid;
    grid-template-columns: 20px minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 0 var(--sp-3);
    padding: var(--sp-3);
    text-align: left;
  }
  .eiken-scale-dot { grid-column: 1; grid-row: 1 / span 2; margin: 0; }
  .eiken-scale-name { grid-column: 2; grid-row: 1; }
  .eiken-scale-level { grid-column: 2; grid-row: 2; white-space: nowrap; }
  .eiken-scale-cefr {
    grid-column: 3;
    grid-row: 1 / span 2;
    display: inline-block;
    padding: 0 var(--sp-2);
    border-radius: var(--r-full);
    background: rgba(0, 174, 239, 0.10);
    font-family: var(--font-en);
    font-size: var(--fs-caption);
    line-height: var(--lh-caption);
    font-weight: var(--fw-bold);
    color: var(--ink-sky);
  }
  .eiken-scale-cefr:empty { display: none; }
  /* the arrow says "this row goes somewhere"; the current row keeps its
     width, so the pills line up */
  .eiken-scale-stop > a::after {
    content: '→';
    grid-column: 4;
    grid-row: 1 / span 2;
    font-weight: var(--fw-bold);
    color: var(--ink-sky);
  }
  .eiken-scale-stop.is-current > a::after { visibility: hidden; }
  .eiken-scale-stop.is-current > a { background: rgba(0, 174, 239, 0.06); }
  .eiken-scale-bands { display: none; }
}


/* =====================================================================
   6. EXAMPLE QUESTION
   A plain card (it is not a control, so no .card--link): the title, the
   question in English at body size, its numbered choices, and a
   <details> under them. Its summary — 「正解と解説を見る」 — is the one
   control; it opens the answer and the explanation in place, under a
   dashed rule, right below the question they refer to. Built by
   eiken_example() in partials/eiken/bootstrap.php.
   ===================================================================== */
.eiken-example-q {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-main);
  overflow-wrap: anywhere;
}
.eiken-example-q p { margin: 0 0 var(--sp-2); }
.eiken-example-q > :last-child { margin-bottom: 0; }   /* a paragraph or a list of topics */
/* No choices (a writing or speaking task): the summary's own 16px is the gap. */
.eiken-example-q:has(+ .eiken-example-answer) { margin-bottom: 0; }
.eiken-choices {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2) var(--sp-6);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: choice;
}
.eiken-choices li {
  display: flex;
  gap: var(--sp-2);
  font-size: var(--fs-body-md);
  line-height: var(--lh-body-md);
  color: var(--text-main);
  counter-increment: choice;
}
.eiken-choices li::before {
  content: counter(choice);
  flex-shrink: 0;
  width: 1.5em;
  font-family: var(--font-en);
  font-weight: var(--fw-bold);
  color: var(--text-light);
}
.eiken-choices--stack { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 520px) {
  .eiken-choices { grid-template-columns: minmax(0, 1fr); }
}
/* The answer: a quiet ink-sky control, 44px tall, ± at its end. */
.eiken-example-summary {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 44px;
  margin-top: var(--sp-4);
  list-style: none;
  cursor: pointer;
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  font-weight: var(--fw-bold);
  color: var(--ink-sky);
  /* a little room inside the focus ring; the text stays on the card's edge */
  padding-inline: var(--sp-2);
  margin-inline: calc(-1 * var(--sp-2));
  border-radius: var(--r-sm);
}
.eiken-example-summary::-webkit-details-marker { display: none; }
.eiken-example-summary:hover > span:first-child {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.eiken-example-answer-body {
  margin-top: var(--sp-3);
  padding-top: var(--sp-4);
  border-top: 1px dashed var(--border-warm);
}
.eiken-example-answer-body > :last-child { margin-bottom: 0; }
/* 「正解 1 abandon」: a quiet label, the number in Montserrat, the choice. */
.eiken-example-key {
  margin-bottom: var(--sp-3);
  font-size: var(--fs-body-md);
  line-height: var(--lh-body-md);
  color: var(--text-main);
}
.eiken-example-key-label {
  margin-right: var(--sp-2);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  font-weight: var(--fw-bold);
  color: var(--text-light);
}
.eiken-example-key-num { margin-right: var(--sp-2); font-family: var(--font-en); font-weight: var(--fw-bold); }
/* a model answer in English, set off like a quotation */
.eiken-example-answer-body p[lang="en"] {
  padding-left: var(--sp-4);
  border-left: 3px solid var(--border-warm);
  color: var(--text-main);
}


/* =====================================================================
   7. PAGER, REFERENCES, DISCLAIMER
   The pager: two cards, 「← ひとつ下の級」 / 「ひとつ上の級 →」 over the
   grade's name and its level (at the ends of the set, the hub). The
   references: a plain list between hairlines, publisher in quiet ink,
   the title a regular-weight link. The disclaimer: fine print under a
   hairline.
   ===================================================================== */
.eiken-pager-dir {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--ink-quiet);
}
.eiken-pager .card-title { margin-bottom: var(--sp-1); }
.eiken-pager .card-text { margin: 0; }
.eiken-pager-next { text-align: right; }
@media (max-width: 767px) {
  .eiken-pager-next { text-align: left; }
}
.eiken-refs {
  margin: 0 0 var(--sp-6);
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--border-warm);
}
.eiken-refs li {
  padding: var(--sp-2) 0;
  border-top: 1px solid var(--border-warm);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--text-light);
  word-break: normal;   /* a citation runs to 2–3 lines: fill them (auto-phrase left 18em gaps) */
}
.eiken-refs a {
  font-weight: var(--fw-regular);
  color: var(--text-main);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  overflow-wrap: anywhere;
}
.eiken-refs a:hover { opacity: 1; color: var(--ink-sky); }
.eiken-refs-org { color: var(--ink-quiet); }
.eiken-refs-group {
  margin: var(--sp-6) 0 var(--sp-3);
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  font-weight: var(--fw-bold);
  color: var(--text-main);
}
.eiken-disclaimer {
  margin: var(--sp-8) 0 0;
  padding: var(--sp-5) 0 0;
  background: none;
  border-top: 1px solid var(--border-warm);
  border-radius: 0;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--ink-quiet);
}
.eiken-disclaimer p { margin: 0; }
.eiken-disclaimer p + p { margin-top: var(--sp-2); }

/* ---- Motion ---- */
@media (prefers-reduced-motion: reduce) {
  .eiken-toc-icon::before,
  .eiken-toc-icon::after,
  .eiken-example-icon::before,
  .eiken-example-icon::after,
  .eiken-toc-list a,
  .eiken-scale-dot,
  .eiken-scale-dot::after { transition: none; }
  .eiken-scale-stop > a:hover .eiken-scale-dot { transform: none; }
}

/* The pager card is one link: its title's hit area covers the card. */
.eiken-pager { margin-top: var(--sp-16); }
.eiken-pager + .eiken-chapter {
  margin-top: var(--sp-16);
  padding-top: var(--sp-16);
  border-top: 1px solid var(--border-warm);
}
.eiken-pager .l-grid { margin: 0; }
.eiken-pager a.card-title { color: var(--text-main); }
.eiken-pager a.card-title::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: var(--r-lg);
}
.eiken-pager a.card-title:focus-visible { outline: none; }
.eiken-pager a.card-title:focus-visible::after { outline: var(--focus-ring); outline-offset: 2px; }

/* The PR's course cards (§8): one link per card, its title stretched over it. */
.eiken-pr-course .card-title { color: var(--text-main); }
.eiken-pr-course a.card-title::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: var(--r-lg);
}
.eiken-pr-course a.card-title:focus-visible { outline: none; }
/* The card's ring is the hover; the global link dim would grey the title. */
.eiken-pager a.card-title:hover,
.eiken-pr-course a.card-title:hover { opacity: 1; }
.eiken-pr-course a.card-title:focus-visible::after { outline: var(--focus-ring); outline-offset: 2px; }

/* A row header's second line wraps instead of widening the first column. */
.table tbody th .table-sub { white-space: normal; max-width: 14em; }

/* A quoted official sentence (e.g. the 協会's 6割／7割 guideline): set off
   by a hairline rule and the quiet ink, never italic in Japanese. */
.eiken-body :where(blockquote) {
  margin: var(--sp-6) 0;
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-5);
  border-left: 3px solid var(--border-warm);
  color: var(--text-light);
}
.eiken-body :where(blockquote) p:last-child { margin-bottom: 0; }
.eiken-body :where(blockquote) cite {
  display: block;
  margin-top: var(--sp-2);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-style: normal;
  color: var(--ink-quiet);
}


/* =====================================================================
   8. COURSE PR
   The one promotion inside the reading column: the Jumpstart English
   course that matches the page. The template prints it — never a page —
   after the `study` chapter (the hub: after `choose`); built by
   eiken_course_pr() in partials/eiken/bootstrap.php from
   config/courses.php. It is advertising and says so: an <aside> with a
   「PR」 tag and an aria-label that starts 「PR：」, and no heading, so
   the outline and the 目次 are untouched. It closes the chapter it
   follows (a block's distance under it), and the next chapter opens
   with the usual hairline (§3).

     grade page  .eiken-pr-card — one course on a cream panel: the photo
                 (2/5) beside the text (3/5): name, the course's own
                 headline with its one .keyword, a line of framing for
                 this page, a three-row spec list, one primary button
                 and a quiet arrow link. Stacks, photo on top, ≤600px.
     hub         .eiken-pr--lineup — the four courses as compact link
                 cards (.card--link, title stretched over the card) two
                 to a row, on the same cream panel.
   ===================================================================== */
.eiken-body > .eiken-pr { margin-top: var(--sp-12); }
.eiken-pr-label {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--ink-quiet);
}
.eiken-pr-tag {
  flex-shrink: 0;
  padding: 0 var(--sp-2);
  border: 1px solid currentColor;
  border-radius: var(--r-full);
  font-family: var(--font-en);
  font-size: var(--fs-eyebrow);
  line-height: var(--lh-eyebrow);
  font-weight: var(--fw-bold);
  letter-spacing: 0.08em;
}
/* The one surface: a cream panel with the warm hairline. */
.eiken-pr-card,
.eiken-pr-tray {
  background: var(--bg-cream);
  border: 1px solid var(--border-warm);
  border-radius: var(--r-lg);
}
.eiken-pr-card {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  overflow: hidden;
}
.eiken-pr-media {
  position: relative;
  min-height: 100%;
  background: var(--bg-warm);
}
.eiken-pr-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 35%;
}
.eiken-pr-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--sp-8);
}
.eiken-pr-name {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  font-weight: var(--fw-bold);
  color: var(--ink-sky);
}
.eiken-pr-pitch {
  margin: 0;
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: var(--fw-head);
  color: var(--text-main);
  text-wrap: balance;
  word-break: auto-phrase;
}
/* .eiken-body's plain-ink emphasis must not flatten the keyword. */
.eiken-pr-pitch .keyword { color: var(--primary); }
.eiken-pr-lead {   /* running text (§4): the pitch above keeps its phrase breaks */
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-body-md);
  line-height: var(--lh-body-md);
  color: var(--text-light);
}
.eiken-pr-facts { margin: var(--sp-5) 0 0; }
.eiken-pr-facts > div {
  display: grid;
  grid-template-columns: 5em minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: baseline;
  padding: var(--sp-2) 0;
  border-top: 1px solid var(--border-warm);
}
.eiken-pr-facts > div:last-child { border-bottom: 1px solid var(--border-warm); }
.eiken-pr-facts dt {
  font-size: var(--fs-caption);
  line-height: var(--lh-body-md);
  font-weight: var(--fw-bold);
  color: var(--ink-quiet);
}
.eiken-pr-facts dd {
  margin: 0;
  font-size: var(--fs-body-md);
  line-height: var(--lh-body-md);
  color: var(--text-main);
  word-break: auto-phrase;
}
.eiken-pr-num {
  margin: 0 0.1em;
  font-family: var(--font-en);
  font-size: var(--fs-body-lg);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--ls-num);
}
.eiken-pr-facts dd > .eiken-pr-num:first-child { margin-inline-start: 0; }
.eiken-pr-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-6);
  margin-top: var(--sp-6);
}
@media (max-width: 600px) {
  .eiken-pr-card { grid-template-columns: minmax(0, 1fr); }
  .eiken-pr-media { min-height: 0; aspect-ratio: 16 / 9; }
  .eiken-pr-body { padding: var(--sp-6) var(--sp-5); }
  .eiken-pr-actions .btn { flex: 1 1 100%; }
}

/* ---- Hub: the four courses ---- */
.eiken-pr-tray { padding: var(--sp-6); }
.eiken-pr-intro {   /* running text (§4) */
  margin: 0 0 var(--sp-5);
  font-size: var(--fs-body-md);
  line-height: var(--lh-body-md);
  color: var(--text-light);
}
.eiken-body .eiken-pr-tray .l-grid { margin: 0; }
.eiken-pr-course .card-body { position: static; }   /* the title's hit area spans the card, photo included */
.eiken-pr-course .card-media { aspect-ratio: 5 / 2; }
.eiken-pr-course .card-media img { object-position: 50% 28%; }
.eiken-pr-course .card-title { margin-bottom: var(--sp-1); }
.eiken-pr-course .card-text { margin: 0 0 var(--sp-4); text-wrap: balance; }   /* not the prose paragraph's margin; balanced, it breaks after 「、」 like the course page's headline */
.eiken-pr-course .card-foot { align-items: flex-end; }
.eiken-pr-course-meta {
  margin: 0;
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--text-light);
}
.eiken-pr-course-meta > span { display: inline-block; margin-right: var(--sp-3); }   /* each fact wraps whole */
.eiken-pr-course-meta .eiken-pr-num { font-size: var(--fs-body-md); color: var(--text-main); }
.eiken-pr-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-6);
  margin: var(--sp-5) 0 0;
}
/* One card to a row (≤767, where .l-grid--2 collapses): the photo strip
   would grow as tall as a hero, so each course becomes a compact row — a
   square thumbnail beside the name, the fee and 詳細 under the name; the
   pitch is left to the course page. */
@media (max-width: 767px) {
  .eiken-pr-course {
    display: grid;
    grid-template-columns: 4.5rem minmax(0, 1fr);
    column-gap: var(--sp-4);
    row-gap: var(--sp-1);
    align-items: center;
  }
  .eiken-pr-course .card-body { display: contents; }
  .eiken-pr-course .card-media {
    grid-row: 1 / span 2;
    grid-column: 1;
    margin: 0;
    aspect-ratio: 1;
    border-radius: var(--r-md);
  }
  .eiken-pr-course .card-media::before { content: none; }
  .eiken-pr-course .card-title { grid-column: 2; grid-row: 1; align-self: end; margin-bottom: 0; }
  .eiken-pr-course .card-text { display: none; }
  /* the row itself is the link (its frame and ring), like the pager: no 詳細 */
  .eiken-pr-course .card-foot { grid-column: 2; grid-row: 2; align-self: start; margin-top: 0; padding-top: 0; border-top: 0; }
  .eiken-pr-course .card-foot .link-arrow { display: none; }
}
@media (max-width: 520px) {
  .eiken-body > .eiken-pr { margin-top: var(--sp-10); }
  .eiken-pr-tray { padding: var(--sp-4); }
  .eiken-pr-course .card-title { word-break: auto-phrase; }
}
@media (max-width: 400px) {
  .eiken-pr-course { grid-template-columns: 3.5rem minmax(0, 1fr); column-gap: var(--sp-3); }
}
