/*
 * read.gonglogic.com — the library and its reading surface.
 *
 * ═════════════════════════════════════════════════════════════════════════════
 * REWRITTEN 2026-10-25, AS ONE SYSTEM
 * ═════════════════════════════════════════════════════════════════════════════
 * This file had grown to 2,700 lines by patching the main site's marketing theme
 * one page at a time: dark hero bands made smaller, section padding taken back, a
 * second definition of the pager under the first, and a third of the comments
 * explaining an override that lost to load order. Every fault it fixed was real,
 * and the lessons are kept below beside the rule they produced — but the page
 * underneath was still a marketing site wearing a library's clothes.
 *
 * So the library now owns its look:
 *
 *   - its own TOKENS (paper, ink, one amber accent), light and dark, so a whole
 *     colour scheme is a dozen values and not a hunt through six hundred rules;
 *   - a BOOK FACE (Newsreader) for titles and for reading Latin-script text, with
 *     Inter kept for everything that is interface — the split a printed book makes
 *     between its text and its running heads;
 *   - its own HEADER, PAGE HEADS and FOOTER, instead of the theme's dark `.hero`,
 *     whose `min-height: 78vh` this file spent five rules taking back.
 *
 * ── HOW IT WINS AGAINST THE THEME, WITHOUT !important
 *
 * library.css is printed BEFORE main.css (controller requirements come first), so
 * any tie goes to the theme. The theme styles bare elements — `h1`, `p`, `a`,
 * `a:hover` — and so:
 *
 *   1. Element resets come first and are written `[data-area="library"] :where(h1)`:
 *      specificity (0,1,0), which beats the theme's (0,0,1) and TIES with a single
 *      component class — and a tie inside this file goes to the later rule, so
 *      every component below overrides the reset as it should.
 *   2. The theme's `a:hover` is (0,1,1) and beats a single class, so every link
 *      component states its own colour for :hover. `.x, .x:hover { color: … }` is
 *      the pattern; a link component without it turns amber when pointed at.
 *
 * ── `hidden` MEANS HIDDEN
 *
 * Three separate faults on this site were an author `display` beating the
 * user-agent's `[hidden] { display: none }` — the definition panel's resting text
 * sat above every card, the dictionary's empty "Recently looked up" row showed on
 * a fresh visit. One rule, at the end of this file, ends that class of fault.
 */

/* ═══ 1. TOKENS ════════════════════════════════════════════════════════════════ */

body[data-area="library"] {
  --paper: #f7f2e8;          /* the page */
  --paper-2: #efe7d6;        /* a band, one step down */
  --surface: #fffdf8;        /* anything that sits ON the page: cards, the sheet */
  --surface-2: #f4eee2;      /* a fill inside a surface */
  --ink: #1d1b17;
  --ink-2: #4a453c;          /* secondary text */
  --ink-3: #6b6558;          /* tertiary text — 4.9:1 on paper, the floor */
  --rule: rgba(29, 27, 23, 0.11);
  --rule-2: rgba(29, 27, 23, 0.2);
  --accent: #c8962f;         /* the brand amber: fills, marks, rules */
  --accent-strong: #b3831f;
  --accent-ink: #8a5e0d;     /* amber that has to be READ: 5.6:1 on paper */
  --accent-wash: rgba(200, 150, 47, 0.13);
  --on-accent: #1d1b17;      /* ink on amber is 7:1; the white it had was 2.6:1 */
  --lit: rgba(236, 184, 58, 0.36);
  --ok: #2d7444;
  --ok-wash: rgba(45, 116, 68, 0.12);
  --bad: #ad2b22;
  --bad-wash: rgba(173, 43, 34, 0.1);
  --panel: #1f1d19;          /* the dark definition card on a phone */
  --on-panel: #f4eee2;

  --shadow-1: 0 1px 2px rgba(29, 27, 23, 0.06);
  --shadow-2: 0 1px 2px rgba(29, 27, 23, 0.05), 0 10px 28px -14px rgba(29, 27, 23, 0.28);
  --shadow-3: 0 2px 4px rgba(29, 27, 23, 0.06), 0 22px 48px -18px rgba(29, 27, 23, 0.4);

  --r-s: 0.5rem;
  --r: 0.75rem;
  --r-l: 1.1rem;

  --serif: 'Newsreader', 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
  --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
    'PingFang SC', 'Hiragino Sans', 'Noto Sans CJK SC', 'Microsoft YaHei', sans-serif;

  color-scheme: light;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
}

/*
 * DARK, FOR THE WHOLE PAGE OR NOT AT ALL.
 *
 * This file once carried six `prefers-color-scheme: dark` blocks that darkened a
 * surface each and set no text colour, on a theme with no dark mode — black text on
 * near-black cards. The lesson was not "no dark mode"; it was that a dark mode is a
 * set of TOKENS, page and ink and surfaces together. Now that every colour here is a
 * token, it is exactly that: the values change and nothing else does. Reading at
 * night is most of the reading anybody does.
 */
@media (prefers-color-scheme: dark) {
  body[data-area="library"] {
    --paper: #151411;
    --paper-2: #1b1916;
    --surface: #201e1a;
    --surface-2: #2a2722;
    --ink: #ede6d7;
    --ink-2: #c6bdab;
    --ink-3: #9d947f;
    --rule: rgba(237, 230, 215, 0.11);
    --rule-2: rgba(237, 230, 215, 0.22);
    --accent: #d6a646;
    --accent-strong: #e3b65a;
    --accent-ink: #e4b95e;
    --accent-wash: rgba(214, 166, 70, 0.15);
    --on-accent: #17150f;
    --lit: rgba(214, 166, 70, 0.34);
    --ok: #74c38c;
    --ok-wash: rgba(116, 195, 140, 0.14);
    --bad: #f0877c;
    --bad-wash: rgba(240, 135, 124, 0.13);
    --panel: #2a2722;
    --on-panel: #f1eadb;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 30px -14px rgba(0, 0, 0, 0.7);
    --shadow-3: 0 2px 4px rgba(0, 0, 0, 0.35), 0 24px 50px -18px rgba(0, 0, 0, 0.8);
    color-scheme: dark;
  }
}

/* ═══ 2. RESETS — specificity (0,1,0), see the header ══════════════════════════ */

[data-area="library"] :where(.layout, .lh, .lf) :where(h1, h2, h3, h4, h5, h6) {
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;
  font-size: inherit;
  line-height: 1.2;
  letter-spacing: -0.005em;
  color: inherit;
}
[data-area="library"] :where(.layout, .lh, .lf) :where(p) {
  margin: 0;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
}
/* Scoped to the library's own regions: the family bar above the header is the
   theme's, and an unscoped `a` here turned its links amber. */
[data-area="library"] :where(.layout, .lh, .lf) :where(a) { color: var(--accent-ink); }
/* Hovered, a plain link goes to INK and underlines. It went to --accent-strong, which
   is a FILL colour: 2.9:1 on the page as text (check:read-hover, CONTRAST). */
[data-area="library"] :where(.layout, .lh, .lf) :where(a:not([class])):hover { color: var(--ink); text-decoration: underline; }
[data-area="library"] :where(.layout, .lh, .lf) :where(ul, ol) { list-style: none; margin: 0; padding: 0; }
[data-area="library"] :where(.layout, .lh, .lf) :where(button, input, select, textarea) { font: inherit; color: inherit; }
[data-area="library"] ::selection { background: var(--lit); color: var(--ink); }
[data-area="library"] :where(:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 0.3rem;
}
/* The theme paints `.layout` its own grey-cream; here the page is the paper. And
   the page is at least a screen tall, so a short one (the dictionary before a
   search) ends in its footer rather than in a band of bare paper under it. */
body[data-area="library"] { display: flex; flex-direction: column; min-height: 100vh; }
[data-area="library"] .layout { flex: 1 0 auto; background: transparent; }

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.ic { display: block; width: 1.1em; height: 1.1em; flex: none; }

/* ═══ 3. LAYOUT ════════════════════════════════════════════════════════════════
   Three widths: the catalogue (76rem), the reader with its panel (72rem), and a
   column of prose (46rem). A 16px gutter on a phone, where every pixel of width
   is a character of a line. */

.lib-wrap {
  width: 100%;
  max-width: 76rem;
  margin-inline: auto;
  padding-inline: 1rem;
}
.lib-wrap--read { max-width: 72rem; }
.lib-wrap--text { max-width: 48rem; }
/* A column of reading width that keeps the page's LEFT edge — for a list under a
   wide header, where a centred column would leave the two misaligned. */
.lib-measure { max-width: 46rem; }
@media (min-width: 48rem) {
  .lib-wrap { padding-inline: 2rem; }
}

.lib-section { padding-block: 2.25rem; }
@media (min-width: 48rem) {
  .lib-section { padding-block: 3rem; }
}
/* Two plain sections meeting pay for the gap twice; the join is one gap. A band
   keeps its padding, because there the colour change is the separation and the
   text must not clamp onto it. */
.lib-section:not(.lib-section--band) + .lib-section:not(.lib-section--band) { padding-top: 0; }
.lib-section--band {
  background: var(--paper-2);
  border-block: 1px solid var(--rule);
}
.lib-section--tight { padding-top: 1.25rem; }

/* A section's own heading: the title, and one line of what is in it. */
.section-head { margin: 0 0 1.25rem; }
.section-head--row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
}
.section-head__title {
  font-family: var(--serif);
  font-size: clamp(1.4rem, 2.6vw, 1.75rem);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.section-head__note {
  margin-top: 0.35rem;
  max-width: 62ch;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--ink-2);
}

.kicker {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

/* ═══ 4. BUTTONS AND MARKS ═════════════════════════════════════════════════════
   `.button` was used 22 times across the theme and defined nowhere, so every call
   to action rendered as a text link until it was found in a screenshot. It lives
   here because every use is a library template. */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  min-height: 2.6rem;
  padding: 0.55rem 1.15rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--sans);
  font-size: 0.94rem;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.button:hover { text-decoration: none; }
.button:active { transform: translateY(1px); }
.button--large { min-height: 3rem; padding: 0.7rem 1.45rem; font-size: 1rem; }

.button--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.button--primary:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.button--primary:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  box-shadow: var(--shadow-1);
}

/* An outline knows what it sits on only through the tokens, which is why it can
   no longer go invisible: the one that did inherited a colour meant for a light
   page and was drawn on the old dark hero. */
.button--ghost {
  background: transparent;
  border-color: var(--rule-2);
  color: var(--ink);
}
.button--ghost:hover { background: transparent; border-color: var(--rule-2); color: var(--ink); }
.button--ghost:hover { background: var(--surface); border-color: var(--ink-3); }

/* For the thing somebody might want and the site would rather they did not:
   plain and legible, not disguised as a link. */
.button--quiet {
  background: transparent;
  border-color: var(--rule);
  color: var(--ink-2);
  font-weight: 500;
}
.button--quiet:hover { background: transparent; border-color: var(--rule); color: var(--ink-2); }
.button--quiet:hover { border-color: var(--rule-2); color: var(--ink); }

.tag {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink-2);
}
.tag--course { background: var(--accent); color: var(--on-accent); }
.is-free { color: var(--accent-ink); font-weight: 600; }

.ticks li {
  position: relative;
  margin-bottom: 0.55rem;
  padding-left: 1.5rem;
  font-size: 0.94rem;
  line-height: 1.55;
}
.ticks li::before {
  content: '';
  position: absolute;
  left: 0.15rem;
  top: 0.45em;
  width: 0.7rem;
  height: 0.38rem;
  border-left: 2px solid var(--ink-3);
  border-bottom: 2px solid var(--ink-3);
  transform: rotate(-45deg);
}
.ticks--paid li::before { border-color: var(--accent); }
/* What does NOT change: the same shape, making no claim. */
.ticks--plain li::before {
  top: 0.62em;
  width: 0.55rem;
  height: 0;
  border-left: 0;
  transform: none;
  border-color: var(--rule-2);
}

.library-note {
  margin: 0 0 1.25rem;
  padding: 0.85rem 1.05rem;
  border-radius: var(--r-s);
  background: var(--surface-2);
  font-size: 0.95rem;
  line-height: 1.55;
}
.library-note--warn { background: var(--accent-wash); }
.library-fineprint { margin-top: 1rem; font-size: 0.86rem; line-height: 1.55; color: var(--ink-3); }
.library-empty { color: var(--ink-2); }

/* ═══ 5. THE HEADER ════════════════════════════════════════════════════════════
   One bar: the library, its two places, and you. The family bar above it is the
   theme's and stays the theme's. */

.lh {
  position: relative;
  z-index: 20;
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
}
.lh__inner {
  display: flex;
  align-items: center;
  gap: 0.75rem 1.5rem;
  min-height: 3.6rem;
}
.lh__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink);
  text-decoration: none;
}
.lh__brand:hover { color: var(--ink); text-decoration: none; }
.lh__brand svg {
  width: 2rem;
  height: 2rem;
  flex: none;
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--rule);
}
.lh__name {
  font-family: var(--serif);
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.lh__nav { display: flex; align-items: center; gap: 0.25rem; }
.lh__link {
  padding: 0.45rem 0.7rem;
  border-radius: 999px;
  color: var(--ink-2);
  font-size: 0.94rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.lh__link:hover { color: var(--ink-2); text-decoration: none; }
.lh__link:hover { background: var(--surface-2); color: var(--ink); }
.lh__link[aria-current="page"] { color: var(--ink); background: var(--surface-2); }
@media (max-width: 40rem) {
  .lh__link--wide { display: none; }
}
.lh__you { margin-left: auto; display: flex; align-items: center; }
.lh__join {
  display: inline-flex;
  align-items: center;
  min-height: 2.25rem;
  padding: 0.4rem 0.95rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.88rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.lh__join:hover { background: var(--accent); color: var(--on-accent); text-decoration: none; }
.lh__join:hover { background: var(--accent-strong); }
.lh__account {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  color: var(--ink);
  font-size: 0.88rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.lh__account:hover { color: var(--ink); text-decoration: none; }
.lh__account:hover { background: var(--surface-2); }
.lh__signin {
  margin-right: 0.35rem;
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  color: var(--ink-2);
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.lh__signin:hover { color: var(--ink-2); text-decoration: none; }
.lh__signin:hover { background: var(--surface-2); color: var(--ink); }
.lh__signin { display: inline-flex; align-items: center; gap: 0.4rem; }
.lh__signin .ic { display: none; }
@media (max-width: 40rem) {
  /* An icon on a phone: as words it pushed the header 13px past the screen. */
  .lh__signin { margin-right: 0.15rem; padding: 0.45rem; }
  .lh__signin .ic { display: block; }
  .lh__signin span { display: none; }
}
.lh__short { display: none; }

/* ON A PHONE. Four links beside a logo in 390px once wrapped into a three-line
   stack 106px tall. One line: the mark, the two places, and the short form of the
   ask. The library's name is in the family bar above, so the mark carries it. */
@media (max-width: 40rem) {
  .lh__inner { gap: 0.5rem; min-height: 3.25rem; }
  .lh__name { display: none; }
  .lh__nav { gap: 0; }
  .lh__link { padding: 0.4rem 0.55rem; font-size: 0.9rem; }
  .lh__long { display: none; }
  .lh__short { display: inline; }
  .lh__join { padding: 0.35rem 0.8rem; font-size: 0.84rem; }
  .lh__account span { display: none; }
  .lh__account { padding: 0.45rem; }
}

/* ── the reader's row: where you were, and your languages ────────────────────
   Chrome, so quiet — but the "Continue" is the one thing on it somebody may be
   looking for, so it comes first and it is the one thing with a colour. */
.shelf {
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
  font-size: 0.86rem;
}
.shelf__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.25rem;
  padding-block: 0.5rem;
}
.shelf__carry {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  min-width: 0;
  max-width: 100%;
  padding: 0.35rem 0.85rem;
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  border-radius: 999px;
  background: var(--accent-wash);
  color: var(--ink);
  text-decoration: none;
}
.shelf__carry:hover { background: var(--accent-wash); color: var(--ink); text-decoration: none; }
.shelf__carry:hover { border-color: var(--accent); }
.shelf__carry-what {
  flex: none;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
/* The title is the part that can be long, so it is the part that truncates. */
.shelf__carry-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.shelf__carry-where { flex: none; color: var(--ink-2); font-size: 0.8rem; }
.shelf__carry-go { flex: none; color: var(--accent-ink); }
.shelf__langs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; min-width: 0; }
.shelf__label {
  margin-right: 0.2rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.shelf__lang {
  padding: 0.18rem 0.65rem;
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.shelf__lang:hover { color: var(--ink); text-decoration: none; }
.shelf__lang:hover { border-color: var(--accent); }
@media (min-width: 48rem) {
  .shelf__langs { margin-left: auto; }
}
@media (max-width: 40rem) {
  /* ONE ROW on a phone. Two rows — the carry-on, then a single language chip on a
     line of its own — was 70px of chrome before the page began. The title is the
     part that gives way. */
  .shelf__inner {
    flex-wrap: nowrap;
    gap: 0.5rem;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .shelf__inner::-webkit-scrollbar { display: none; }
  /* The carry-on never shrinks below readable: with four languages beside it, a
     shrinkable pill was crushed to "CON…". The row scrolls instead, and the
     languages are what scroll off — the carry-on is what this row is for. */
  .shelf__carry { flex: 0 0 auto; max-width: 78vw; padding-inline: 0.7rem; }
  .shelf__carry-where { display: none; }
  .shelf__langs { flex: none; flex-wrap: nowrap; }
  .shelf__label { display: none; }
}

/* ── the previewer's banner and the closed library ─────────────────────────── */

/* Loud on purpose. A preview that looks like the real thing gets sent to somebody
   who then sees the coming-soon page; this is cheaper than that mistake. */
.preview-banner {
  padding: 0.5rem 0;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.85rem;
}
.preview-banner .container { max-width: 76rem; }
.preview-banner code { padding: 0.05rem 0.3rem; border-radius: 3px; background: rgba(0, 0, 0, 0.12); }

.soon-page { padding: clamp(3rem, 10vh, 6rem) 0 clamp(3rem, 12vh, 7rem); }
.soon-page__eyebrow {
  margin-bottom: 0.8rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.soon-page__title {
  margin-bottom: 1rem;
  font-family: var(--serif);
  font-size: clamp(2.4rem, 7vw, 3.6rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.soon-page__lede { margin-bottom: 1.75rem; max-width: 44ch; font-size: 1.12rem; line-height: 1.6; color: var(--ink-2); }
.soon-page__list { margin-bottom: 1.75rem; }
.soon-page__list li { position: relative; margin-bottom: 0.55rem; padding-left: 1.4rem; line-height: 1.55; }
.soon-page__list li::before { content: '—'; position: absolute; left: 0; color: var(--accent); }
.soon-page__note { margin-bottom: 2rem; font-size: 0.92rem; color: var(--ink-3); }
.soon-page__links { display: flex; flex-wrap: wrap; gap: 1.25rem; }

/* ═══ 6. THE PAGE HEAD ═════════════════════════════════════════════════════════
   What every page opens with, on the paper. It replaced the theme's dark `.hero`,
   which was built as a marketing splash: it reserved three quarters of a screen,
   every custom element on it needed its own colour or vanished, and on a title
   page it pushed the chapters — the thing the page is for — below the fold. */

.masthead {
  padding-block: 2rem 1.75rem;
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 48rem) {
  .masthead { padding-block: 3rem 2.5rem; }
}
.masthead__eyebrow {
  margin-bottom: 0.6rem;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.masthead__eyebrow a { color: inherit; text-decoration: none; }
.masthead__eyebrow a:hover { color: inherit; text-decoration: none; }

/* The way up, as a row of links: on a Chinese story every word on the screen is
   Chinese, and this is the part that says where you are in English. */
.masthead__trail {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.5rem;
  margin-bottom: 0.7rem;
  font-size: 0.88rem;
}
.masthead__trail a { color: var(--ink-2); text-decoration: none; }
.masthead__trail a:hover { color: var(--ink-2); text-decoration: none; }
.masthead__trail a:hover { color: var(--accent-ink); text-decoration: underline; }
.masthead__trail a:not(:last-child)::after { content: '/'; margin-left: 0.5rem; color: var(--ink-3); opacity: 0.6; }

.masthead__title {
  font-family: var(--serif);
  font-size: clamp(2.05rem, 5vw, 3.3rem);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.masthead__native {
  display: inline-block;
  margin-left: 0.15em;
  font-weight: 400;
  color: var(--ink-3);
}
.masthead__sub { margin-top: 0.45rem; font-size: 1.1rem; color: var(--ink-2); }
.masthead__lede {
  margin-top: 0.8rem;
  max-width: 58ch;
  font-size: 1.08rem;
  line-height: 1.6;
  color: var(--ink-2);
}
.masthead__actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.5rem; }
.masthead__terms { margin-top: 1rem; font-size: 0.92rem; line-height: 1.55; color: var(--ink-3); }
.masthead__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.25rem;
  margin-top: 1.5rem;
  font-size: 0.88rem;
  color: var(--ink-3);
}
.masthead__facts strong { font-family: var(--serif); font-size: 1.15rem; font-weight: 600; color: var(--ink); }

/* A grid child defaults to its content's min width, and a long unbroken title
   in a column would push the cover off the side. */
.masthead__say { min-width: 0; }

.masthead--slim { padding-block: 1.75rem 1.25rem; }
.masthead--slim .masthead__title { font-size: clamp(1.9rem, 4vw, 2.6rem); }
.masthead--slim .masthead__lede { margin-top: 0.4rem; }

/* ── the front page: one sentence, one action, and the proof beside them ────── */
.masthead--home { padding-block: 2.25rem 2.5rem; }
@media (min-width: 48rem) {
  .masthead--home { padding-block: 3.75rem 4rem; }
}
.masthead__split {
  display: grid;
  gap: 2rem;
  align-items: center;
}
@media (min-width: 60rem) {
  .masthead__split { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: 3.5rem; }
}
.masthead--home .masthead__title { font-size: clamp(2.3rem, 5.6vw, 3.9rem); max-width: 14ch; }
.masthead--home .masthead__lede { font-size: 1.15rem; max-width: 46ch; }

/* ── a title: the cover beside the name, as a bookshop shows a book ────────── */
.masthead__book { display: grid; gap: 1.25rem; align-items: start; }
@media (min-width: 48rem) {
  .masthead__book { grid-template-columns: 15rem minmax(0, 1fr); gap: 2.5rem; align-items: center; }
}
.book-cover {
  overflow: hidden;
  border-radius: var(--r);
  aspect-ratio: 16 / 9;
  box-shadow: var(--shadow-2);
  background: var(--surface-2);
}
@media (min-width: 48rem) {
  .book-cover { aspect-ratio: 3 / 4; }
}
@media (max-width: 47.99rem) {
  /* On a phone the cover is a band, not a block: a 3:4 cover at full width would
     be a whole screen before the title. */
  .book-cover { max-height: 9.5rem; }
  /* And a cover with no art is not drawn at all: a typeset board repeating the title
     was the whole first screen of the course page on a phone, the title and its
     button below the fold. */
  .book-cover--typeset { display: none; }
}
.book-cover img { display: block; width: 100%; height: 100%; object-fit: cover; }
.book-cover .story__cover { height: 100%; aspect-ratio: auto; border-radius: 0; }
.book-cover .story__cover-title { font-size: clamp(1.15rem, 2.4vw, 1.6rem); -webkit-line-clamp: 5; }

/* ═══ 7. THE FRONT PAGE ════════════════════════════════════════════════════════ */

/* THE DEMONSTRATION. A real sentence from a real story, in the reader's own
   markup, with one word showing its definition — the front page used to describe
   all of this in a line of text and show none of it. A page on the page. */
.demo {
  margin: 0;
  padding: 1.4rem 1.5rem 1.25rem;
  border: 1px solid var(--rule);
  border-radius: var(--r-l);
  background: var(--surface);
  box-shadow: var(--shadow-3);
}
.demo__cap {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.6rem;
  margin-bottom: 0.9rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.demo__cap span + span::before { content: '·'; margin-right: 0.6rem; }
/* THE READER, AT HOME. The demonstration is the real reading surface run by
   reader.js, so it needs only the sheet's own frame taken off (the figure is the
   frame) and the panel put inline: a column needs room the hero has not got, and
   a sheet docked to the foot of a phone would cover the page under the hero. */
.demo .reader-controls { position: static; gap: 0.35rem; margin: 0 0 0.6rem; padding: 0; background: none; }
.demo .reader-ctl { min-height: 2rem; padding: 0.25rem 0.7rem; font-size: 0.8rem; }
.demo .reader-pages { padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
.demo .reader-page { padding-block: 0.45rem; }
.demo .reader-page + .reader-page { margin-top: 0.35rem; }
.demo .reader-page__source { font-size: clamp(1.2rem, 2.4vw, 1.45rem); }
.demo .reader-page__translation { font-size: 0.94rem; }
.demo .word-panel {
  position: static;
  z-index: auto;
  margin-top: 0.9rem;
  border: 0;
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r-s) var(--r-s) 0;
  background: var(--surface-2);
  color: var(--ink);
  box-shadow: none;
  animation: none;
}
.demo .word-panel::before { display: none; }
.demo .word-panel:not(.word-panel--open) { display: block; }
.demo .word-panel__rest { display: block; }
/* A card can carry its characters and related words; capped, so tapping one does
   not push the rest of the front page a screen down. */
.demo .word-panel__inner { max-width: none; max-height: 15rem; padding: 0.75rem 2.6rem 0.8rem 0.9rem; }
.demo .word-panel__close { top: 0.4rem; right: 0.4rem; width: 1.9rem; height: 1.9rem; font-size: 1.1rem; }
.demo .reader-tip__head { font-size: 1.2rem; }
.demo .reader-tip__def { font-size: 0.92rem; }
/* The word, its reading, its meaning and its characters: what a tap is FOR. The
   further senses and the related-word chips doubled the card's height and pushed
   the hero past the fold; a story shows them, and the demonstration links there. */
.demo :is(.reader-tip__more, .reader-tip__rel) { display: none; }
.demo__hint { margin-right: 0.6rem; font-weight: 400; color: var(--ink-3); }
.demo__try { margin-top: 1rem; font-size: 0.9rem; font-weight: 600; }
.demo__try a { color: var(--accent-ink); text-decoration: none; }
.demo__try a:hover { color: var(--accent-ink); text-decoration: none; }
.demo__try a:hover { text-decoration: underline; }

/* ── where you got to ──────────────────────────────────────────────────────── */
.resume-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 0.9rem;
}
.resume-grid--list { grid-template-columns: 1fr; }
.resume__link {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  height: 100%;
  padding: 1rem 1.1rem;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.resume__link:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
.resume__link:hover { border-color: var(--accent); box-shadow: var(--shadow-2); }
.resume__kind { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
.resume__title { font-family: var(--serif); font-size: 1.15rem; font-weight: 500; line-height: 1.3; }
/* The bar is the only decoration on this card that carries information. */
.resume__bar { height: 4px; border-radius: 2px; background: var(--surface-2); overflow: hidden; }
.resume__fill { display: block; height: 100%; background: var(--accent); }
.resume__meta { font-size: 0.82rem; color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* ── the languages that teach: named in their own script ───────────────────
   The eight a beginner should be weighing, apart from the rest, with the name a
   speaker writes on the spine — 日本語, 한국어 — because a learner scanning for
   their language finds it faster as the thing they came for. */
.lang-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15.5rem), 1fr));
  gap: 0.9rem;
}
.lang-tile { display: flex; }
.lang-tile__link {
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0.2rem;
  padding: 1.15rem 1.25rem 1.2rem;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  box-shadow: var(--shadow-1);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
/* NO LIFT. It rose 2px on hover, so a pointer resting on its bottom edge un-hovered
   it, it dropped back, re-hovered — a flicker loop (check:read-hover, SLIP). The
   shadow and the border say "this is live" without moving the target. */
.lang-tile__link:hover { background: var(--surface); color: var(--ink); text-decoration: none; box-shadow: var(--shadow-1); }
.lang-tile__link:hover { border-color: var(--accent); box-shadow: var(--shadow-2); }
.lang-tile__native {
  font-family: var(--serif);
  font-size: 1.85rem;
  font-weight: 500;
  line-height: 1.2;
  color: var(--accent-ink);
}
.lang-tile__name { font-size: 1.02rem; font-weight: 600; }
.lang-tile__holdings { margin-top: 0.25rem; font-size: 0.85rem; line-height: 1.45; color: var(--ink-2); }
@media (max-width: 40rem) {
  /* Two across on a phone: eight full-width tiles were a screen of scrolling to
     reach the rest of the languages. The name in its own script and in English
     is what a phone has room for. */
  .lang-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; }
  .lang-tile__link { padding: 0.85rem 0.9rem 0.9rem; }
  .lang-tile__native { font-size: 1.45rem; }
  .lang-tile__name { font-size: 0.92rem; }
  .lang-tile__holdings { display: none; }
}

/* ── every other language: a list of names, which is how people actually choose */
.lang-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
  gap: 0 1.5rem;
}
.lang__link {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.7rem 0.15rem;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  text-decoration: none;
}
.lang__link:hover { color: var(--ink); text-decoration: none; }
.lang__link:hover .lang__name { color: var(--accent-ink); }
.lang__name { flex: none; font-weight: 600; white-space: nowrap; }
.lang__native { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-3); font-size: 0.92rem; }
/* How many stories: a number, not a sentence, read down the right edge. */
.lang__count {
  margin-left: auto;
  flex: none;
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}
.lang__count::after { content: ' stories'; }

.lang-filter { display: block; min-width: min(100%, 16rem); }
.lang-filter__input {
  width: 100%;
  min-height: 2.6rem;
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 0.95rem;
}
.lang-filter__input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.lang-filter__none { margin-top: 1rem; color: var(--ink-2); }
@media (max-width: 40rem) {
  .lang-filter { width: 100%; }
}

/* ── how it works, and what costs what ───────────────────────────────────── */
.portal-explain { display: grid; gap: 2rem; align-items: start; }
@media (min-width: 52rem) {
  .portal-explain { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 3rem; }
}
.howto { display: grid; gap: 1.1rem; margin-top: 1.1rem; }
.howto__step { display: flex; gap: 0.9rem; align-items: flex-start; }
.howto__num {
  flex: none;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-family: var(--serif);
  font-size: 1.05rem;
  font-weight: 600;
}
.howto__title { font-family: var(--serif); font-size: 1.15rem; font-weight: 500; }
.howto__body { margin-top: 0.2rem; font-size: 0.95rem; line-height: 1.6; color: var(--ink-2); }
.portal-price {
  padding: 1.3rem 1.4rem;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
}
.portal-price__title { margin-bottom: 0.8rem; font-family: var(--serif); font-size: 1.25rem; }
.portal-price p { margin-bottom: 0.7rem; font-size: 0.92rem; line-height: 1.55; color: var(--ink-2); }
.portal-price p strong { color: var(--ink); }
.portal-price__act { margin: 1rem 0 0; }

/* ═══ 8. A LANGUAGE ════════════════════════════════════════════════════════════
   Weight is the whole design: the course is a panel, the words are two tiles,
   the stories are a shelf. "Where do I start" is answered by the layout. */

.course-panel {
  display: grid;
  gap: 1.5rem;
  padding: 1.4rem 1.3rem;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--rule));
  border-radius: var(--r-l);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}
@media (min-width: 52rem) {
  .course-panel { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: 2.5rem; padding: 2rem 2.1rem; }
}
.course-panel__title {
  margin-top: 0.4rem;
  font-family: var(--serif);
  font-size: clamp(1.55rem, 3vw, 2.1rem);
  font-weight: 500;
  line-height: 1.15;
}
.course-panel__sub { margin-top: 0.3rem; color: var(--ink-2); }
.course-panel__terms { margin-top: 0.8rem; font-size: 0.95rem; line-height: 1.55; color: var(--ink-2); }
.course-panel__actions { display: flex; flex-wrap: wrap; gap: 0.55rem; margin-top: 1.25rem; }

/* The free chapters, named: the scenes say what taking a course is like. */
.course-peek { border-top: 1px solid var(--rule); }
@media (min-width: 52rem) {
  .course-peek { border-top: 0; border-left: 1px solid var(--rule); padding-left: 1.5rem; }
}
.course-peek__link {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  padding: 0.75rem 0.25rem;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  text-decoration: none;
}
.course-peek__link:hover { color: var(--ink); text-decoration: none; }
.course-peek__item:last-child .course-peek__link { border-bottom: 0; }
.course-peek__link:hover .course-peek__name { color: var(--accent-ink); }
.course-peek__num { min-width: 1.4rem; font-family: var(--serif); font-size: 1.05rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.course-peek__body { display: flex; flex: 1; flex-direction: column; gap: 0.1rem; min-width: 0; }
.course-peek__name { font-weight: 500; }
.course-peek__focus { font-size: 0.82rem; line-height: 1.45; color: var(--ink-3); }
.course-peek__free { flex: none; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent-ink); }

.word-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); gap: 0.9rem; }
.word-tile {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.word-tile:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
.word-tile:hover { border-color: var(--accent); box-shadow: var(--shadow-2); }
.word-tile__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-size: 1.15rem;
}
.word-tile__body { display: flex; flex-direction: column; gap: 0.1rem; }
.word-tile__title { font-family: var(--serif); font-size: 1.15rem; font-weight: 500; }
.word-tile__meta { font-size: 0.85rem; color: var(--ink-2); }

/* ── the stories: a shelf of books ─────────────────────────────────────────
   They were twenty-five identical white boxes. Now each is a cover — the artwork
   where the pipeline has drawn one, a typeset board where it has not — and the
   grid reads as a shelf whichever it is. */
.story-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 10.5rem), 1fr));
  gap: 1.4rem 1rem;
}
@media (max-width: 40rem) {
  .story-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1rem 0.75rem; }
}
.story { display: flex; }
.story__link {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0.55rem;
  color: var(--ink);
  text-decoration: none;
}
.story__link:hover { color: var(--ink); text-decoration: none; }
.story__art,
.story__cover {
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-s);
  box-shadow: var(--shadow-2);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.story__link:hover .story__art,
.story__link:hover .story__cover { transform: translateY(-3px); box-shadow: var(--shadow-3); }
.story__art { background: var(--surface-2); }
.story__art img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center; }

/* A typeset cover: the title on a cloth board inside a ruled frame. The six
   boards rotate by position; they carry no meaning and only keep neighbours
   apart, the way a real shelf is never one colour. */
.story__cover {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.95rem 0.9rem 1rem;
  color: #f6efe0;
  background: #6f3a33;
}
.story__cover::before {
  content: '';
  position: absolute;
  inset: 0.4rem;
  border: 1px solid rgba(246, 239, 224, 0.28);
  border-radius: 0.3rem;
  pointer-events: none;
}
.story__cover--t0 { background: #6f3a33; }   /* oxblood */
.story__cover--t1 { background: #2f5546; }   /* forest */
.story__cover--t2 { background: #2d3f61; }   /* navy */
.story__cover--t3 { background: #8a6420; }   /* ochre */
.story__cover--t4 { background: #573a59; }   /* plum */
.story__cover--t5 { background: #2c5b5f; }   /* teal */
.story__cover-lang {
  position: relative;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.75;
}
.story__cover-title {
  position: relative;
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  font-family: var(--serif);
  font-size: 1.12rem;
  font-weight: 500;
  line-height: 1.18;
  overflow-wrap: anywhere;
}
.story__body { display: flex; flex-direction: column; gap: 0.15rem; }
.story__title { font-family: var(--serif); font-size: 1.02rem; font-weight: 500; line-height: 1.3; }
.story__link:hover .story__title { color: var(--accent-ink); }
/* The board already says the title; under it, the card says only what it is. */
.story--typeset .story__title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.story__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; font-size: 0.8rem; color: var(--ink-3); }
.story__tier {
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--ink-2);
}
.story__tier--paid { background: var(--accent-wash); color: var(--accent-ink); }
/* The gentlest story on the shelf, which is where a beginner should begin. */
.story__start {
  padding: 0.05rem 0.5rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* ── a nudge, where it is relevant rather than everywhere ──────────────────── */
.promo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding: 1.4rem 1.5rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: var(--r);
  background: var(--surface);
}
.promo > div { flex: 1 1 24rem; }
.promo__title { font-family: var(--serif); font-size: 1.3rem; font-weight: 500; }
.promo__body { margin-top: 0.35rem; font-size: 0.95rem; line-height: 1.6; color: var(--ink-2); }
.promo__act { flex: none; }

/* ═══ 9. A TITLE'S CONTENTS ════════════════════════════════════════════════════
   A table of contents: the number as a mark, the name, its English, a mark for
   what is free. Locked rows keep their shape and lose their surface, so the
   boundary is visible down the page and not only at the gate that explains it. */

.chapter-list { display: grid; gap: 0.5rem; }
.chapter-list__link {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.chapter-list__link:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
a.chapter-list__link:hover { border-color: var(--accent); box-shadow: var(--shadow-2); }
.chapter-list__link--locked { background: transparent; border-style: dashed; cursor: default; }
.chapter-list__link--locked .chapter-list__name { color: var(--ink-2); }
.chapter-list__num {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: var(--surface-2);
  font-family: var(--serif);
  font-size: 1rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}
.chapter-list__link--locked .chapter-list__num { background: transparent; box-shadow: inset 0 0 0 1px var(--rule-2); }
.chapter-list__body { display: flex; flex: 1; flex-direction: column; gap: 0.1rem; min-width: 0; }
.chapter-list__name { font-size: 1.05rem; font-weight: 500; }
.chapter-list__en { font-size: 0.88rem; color: var(--ink-2); }
.chapter-list__focus { font-size: 0.8rem; line-height: 1.45; color: var(--ink-3); }
.chapter-list__flag {
  flex: none;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.chapter-list__flag--locked { color: var(--ink-3); font-size: 1rem; }
/* The arrow is the affordance and arrives on hover: 24 arrows down a page is noise. */
.chapter-list__go { flex: none; color: var(--accent-ink); opacity: 0; transform: translateX(-3px); transition: opacity 0.15s ease, transform 0.15s ease; }
a.chapter-list__link:hover .chapter-list__go,
a.chapter-list__link:focus-visible .chapter-list__go { opacity: 1; transform: none; }

/* The boundary, stated once, the width of the list. */
.chapter-gate {
  margin: 0.75rem 0;
  padding: 1.25rem 1.35rem;
  border: 1px dashed var(--accent);
  border-radius: var(--r);
  background: var(--accent-wash);
}
.chapter-gate__title { font-family: var(--serif); font-size: 1.2rem; font-weight: 500; }
.chapter-gate__body { margin: 0.35rem 0 1rem; font-size: 0.94rem; line-height: 1.6; color: var(--ink-2); }

/* ═══ 10. READING ══════════════════════════════════════════════════════════════ */

.lib-reading { padding-block: 1.1rem 2.5rem; }
@media (min-width: 48rem) {
  .lib-reading { padding-block: 1.5rem 3rem; }
}

/* ── the trail, in place of a back button ─────────────────────────────────────
   One "← <title>" link told you nothing about where you were, and on a
   single-chapter story it pointed at a page that redirects straight back. Each
   step named, ending where you are. The separator TRAILS its step, so a trail
   that wraps never starts a line with "›". */
.reader-nav { margin-bottom: 1rem; }
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.5rem;
  font-size: 0.88rem;
  min-width: 0;
}
.crumbs__step { display: flex; align-items: baseline; gap: 0.5rem; color: var(--ink-2); }
.crumbs__step:not(:last-child)::after { content: '›'; color: var(--ink-3); }
.crumbs__step a { color: inherit; text-decoration: none; }
.crumbs__step a:hover { color: inherit; text-decoration: none; }
.crumbs__step a:hover { color: var(--accent-ink); text-decoration: underline; }
/* The first step gets an arrow, so the trail also reads as the way back. */
.crumbs__step:first-child a::before { content: '←'; margin-right: 0.35rem; color: var(--ink-3); }
.crumbs__step--here { color: var(--ink); font-weight: 600; }
@media (max-width: 40rem) {
  .crumbs { font-size: 0.82rem; }
}

/* ── two columns: the text, and the panel beside it ───────────────────────────
   The panel was once `float: right` on an element AFTER the text, so it landed
   below the chapter. A grid puts two things side by side. */
@media (min-width: 64rem) {
  .reader-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20rem;
    gap: 2.25rem;
    align-items: start;
  }
}
.reader-layout__main { min-width: 0; }

/* ── the toolbar: the voice, the text, the selection ──────────────────────── */
.reader-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.1rem;
  margin: 0 0 1rem;
}
@media (min-width: 64rem) {
  /* Stays where you left it while the chapter moves underneath. */
  .reader-controls {
    position: sticky;
    top: 0;
    z-index: 5;
    padding: 0.65rem 0;
    margin-bottom: 0.4rem;
    background: linear-gradient(180deg, var(--paper) 75%, transparent);
  }
}
.reader-controls__group { display: flex; align-items: center; gap: 0.35rem; }
.reader-controls__group--step { margin-left: auto; }
.reader-ctl {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.25rem;
  padding: 0.35rem 0.85rem;
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}
.reader-ctl:hover { border-color: var(--ink-3); }
/* Pressed is filled: a toggle's state has to read at a glance, mid-sentence. */
.reader-ctl[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.reader-ctl--icon { padding: 0.35rem 0.55rem; }
.reader-ctl__hint { margin-right: 0.15rem; font-size: 0.68rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
/* Listen starts something rather than changing a setting, so it is the one that
   looks like a button and not a switch. */
.reader-ctl--go { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600; }
.reader-ctl--go:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
.reader-ctl--go[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
@media (max-width: 40rem) {
  /* On a phone the stepper sits inline with the rest: there is no room to be apart. */
  .reader-controls { gap: 0.4rem 0.6rem; }
  .reader-controls__group--step { margin-left: 0; }
  .reader-ctl { padding: 0.3rem 0.7rem; font-size: 0.82rem; }
}

/* ── the sheet ──────────────────────────────────────────────────────────────
   A page on the page. Each source line and its English are a unit, grouped by a
   rule down the left — the one mark that says "these two lines are the same
   sentence twice". */
.reader-pages {
  padding: 1.6rem 1.8rem 1.3rem;
  border: 1px solid var(--rule);
  border-radius: var(--r-l);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}
@media (max-width: 40rem) {
  .reader-pages { padding: 1rem 0.95rem 0.8rem; border-radius: var(--r); }
}
.reader-page {
  position: relative;
  padding: 0.85rem 0 0.85rem 1.1rem;
  border-left: 2px solid var(--rule);
  transition: border-color 0.15s ease;
}
@media (max-width: 40rem) {
  .reader-page { padding-left: 0.8rem; }
}
/* A GAP, or the rules touch and the column reads as one long line. */
.reader-page + .reader-page { margin-top: 0.8rem; }
.reader-page:hover { border-left-color: color-mix(in srgb, var(--accent) 50%, transparent); }
.reader-page__speaker {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
/* The source in the book face where the book face has the letters — Latin, Greek,
   Cyrillic — and the system's own face for every script it does not, which is the
   fallback order a font stack already gives. */
.reader-page__source {
  margin-bottom: 0.35rem;
  font-family: var(--serif);
  font-size: 1.42rem;
  line-height: 1.6;
  color: var(--ink);
}
/* Room for a reading ABOVE each word — furigana, pinyin, Jyutping — and only in the
   scripts that carry one. Set everywhere, it opened a full blank line between the
   lines of a German tale. */
:is([lang="ja"], [lang="zh"], [lang="hk"]).reader-page__source { line-height: 2.25; }
.reader-page__translation { font-size: 0.98rem; line-height: 1.6; color: var(--ink-2); }
/* EXCEPT the scripts the book face has no letters for. Falling back from a serif,
   the system picks a Mincho or a Song — thin horizontals that blur at phone size
   under a row of furigana, and on Windows a bitmap-era SimSun. A learner reads
   these in the clean sans every phone ships. */
[lang="ja"].reader-page__source,
[lang="zh"].reader-page__source,
[lang="hk"].reader-page__source,
[lang="ko"].reader-page__source,
[lang="th"].reader-page__source,
:is([lang="ja"], [lang="zh"], [lang="hk"], [lang="ko"], [lang="th"]):is(.deck-card__word, .vocab-list__word, .wordlist__word, .quiz__vocab, .dict-entry__word, .deck-card__example) { font-family: var(--sans); }
@media (max-width: 40rem) {
  .reader-page__source { font-size: 1.28rem; }
  :is([lang="ja"], [lang="zh"], [lang="hk"]).reader-page__source { line-height: 2.1; }
}

/* RIGHT TO LEFT. Arabic and Hebrew were laid out left to right, so every line sat
   against the wrong margin and its full stop ended up at the start. The template
   already marks each line with its language; the direction follows from that, and
   `isolate` keeps a right-to-left word inside an English list from reordering the
   words around it. */
[data-area="library"] :is([lang="ar"], [lang="he"], [lang="fa"], [lang="ur"], [lang="yi"]) {
  direction: rtl;
  unicode-bidi: isolate;
}

/* ── the reading surface must wrap, whatever the script ─────────────────────
   Chinese, Japanese, Cantonese and Thai are written without spaces, so a line is
   one long word to a browser. `anywhere` breaks it; a word span keeps its own
   letters together (one tap target, never two) — except in those scripts, where
   breaking between characters is how the writing works and `keep-all` removed
   every break the line had (measured: a Japanese line ran to 438px at 390). */
.reader-page__source,
.reader-page__translation { overflow-wrap: anywhere; }
.reader-word { overflow-wrap: normal; word-break: keep-all; }
[lang="ja"] .reader-word,
[lang="zh"] .reader-word,
[lang="hk"] .reader-word,
[lang="th"] .reader-word { word-break: normal; overflow-wrap: anywhere; }

/* A token: tappable, with its reading above it in a <ruby> when the server
   decided it has one worth showing. */
.reader-word {
  position: relative;
  border-radius: 0.2rem;
  cursor: pointer;
  transition: background-color 0.12s ease;
}
.reader-word:hover { background: var(--surface-2); }
/* Punctuation: no pointer, no wash — it opens nothing (reader.js marks it). */
.reader-word--mute { cursor: auto; }
.reader-word--mute:hover { background: none; }
.reader-word rt { font-family: var(--sans); font-size: 0.4em; font-weight: 400; color: var(--ink-3); }
/* Chinese pinyin is wider than the character under it ("chuáng" over 床), and a ruby
   row wider than its base widens the base: the line opened gaps — "叫到 床 前". Set
   smaller and tighter, the gaps close to a hair. */
[lang="zh"] .reader-word rt,
[lang="hk"] .reader-word rt { font-size: 0.34em; letter-spacing: -0.02em; }
/* "Hide pinyin": the row keeps its height, so the lines do not jump when it is
   switched, and the word that is tapped or stepped onto still shows its own. */
.reader-pages--noread .reader-word rt { visibility: hidden; }
.reader-pages--noread .reader-word--lit rt,
.reader-pages--noread .reader-word--here rt { visibility: visible; }
/* Tapped, and everything sharing its alignment. */
.reader-word--lit { background: var(--lit); }
.reader-word--lit:hover { background: var(--lit); }
.reader-translation--lit { border-radius: 0.2rem; background: var(--lit); color: var(--ink); }
/* The word the stepper stands on — distinct from `--lit`, which marks what the
   definition covers; the two are not always the same word. */
.reader-word--here { box-shadow: inset 0 -2px 0 var(--accent); }

/* Romanisation under each word, while the toggle is on. */
.reader-pages--roman .reader-word[data-roman] { display: inline-block; vertical-align: top; text-align: center; }
.reader-pages--roman .reader-word[data-roman]::after {
  content: attr(data-roman);
  display: block;
  font-family: var(--sans);
  font-size: 0.55em;
  line-height: 1.35;
  color: var(--ink-3);
}

/* Hiding the English: blurred rather than removed, so the shape of the sentence
   stays and a reader can see there IS a translation and how long it is. */
.reader-pages--blur .reader-page__translation { filter: blur(5px); cursor: pointer; user-select: none; transition: filter 0.15s ease; }
.reader-pages--blur .reader-page__translation:hover { filter: blur(3px); }
.reader-pages--blur .reader-page__translation--shown { filter: none; cursor: auto; user-select: auto; }

/* Simplified or Traditional: both are in the markup and CSS chooses, because
   swapping the text node under a <ruby> is how a reading gets lost. */
.reader-word__alt { display: none; }
.reader-pages--alt .reader-word__is { display: none; }
.reader-pages--alt .reader-word__alt { display: inline; }

/* The line being read aloud — the one time the reader is not choosing where to look. */
.reader-page--speaking { border-left-color: var(--accent); }
.reader-page--speaking .reader-page__source { border-radius: 0.3rem; background: var(--accent-wash); }

/* ── the definition panel ─────────────────────────────────────────────────────
   It was a popup inside the tapped word: it covered the sentence the word came
   from and appeared somewhere different every time. Now it is a place — beside
   the text where there is room, a sheet at the foot of a phone where there is not,
   and the same place every time. reader.js brings the tapped line up when the
   sheet would have covered it. */
.word-panel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  border-radius: var(--r-l) var(--r-l) 0 0;
  background: var(--panel);
  color: var(--on-panel);
  box-shadow: 0 -10px 32px rgba(0, 0, 0, 0.3);
  animation: word-panel-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
/* A grabber, so the sheet reads as a sheet. */
.word-panel::before {
  content: '';
  display: block;
  width: 2.4rem;
  height: 4px;
  margin: 0.5rem auto 0;
  border-radius: 2px;
  background: currentColor;
  opacity: 0.25;
}
@keyframes word-panel-in {
  from { transform: translateY(100%); }
  to { transform: none; }
}
.word-panel:not(.word-panel--open) { display: none; }
.word-panel__inner {
  position: relative;
  max-width: 44rem;
  max-height: 45vh;
  margin: 0 auto;
  padding: 0.6rem 3.2rem calc(1rem + env(safe-area-inset-bottom, 0px)) 1.2rem;
  overflow-y: auto;
}
.word-panel__close {
  position: absolute;
  top: 0.35rem;
  right: 0.7rem;
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 2.2rem;
  border: 0;
  border-radius: 50%;
  background: color-mix(in srgb, currentColor 14%, transparent);
  color: inherit;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}
.word-panel__close:hover { background: color-mix(in srgb, currentColor 24%, transparent); }
.word-panel__rest { display: none; }
.word-panel__rest-head { margin-bottom: 0.35rem; font-family: var(--serif); font-size: 1.1rem; font-weight: 500; }
.word-panel__rest-body { font-size: 0.9rem; line-height: 1.6; color: var(--ink-2); }

@media (min-width: 64rem) {
  /* Beside the text, as a margin note on the paper: the dark card it was beside a
     white sheet was the loudest thing on the page, louder than the reading. */
  .word-panel {
    position: sticky;
    top: 4.25rem;
    left: auto;
    right: auto;
    bottom: auto;
    display: block;
    border: 1px solid var(--rule);
    border-top: 3px solid var(--accent);
    border-radius: var(--r);
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-2);
    animation: none;
  }
  .word-panel::before { display: none; }
  /* Always present on a wide screen, so closing a card does not collapse the
     column and shift the whole chapter sideways. */
  .word-panel:not(.word-panel--open) { display: block; }
  .word-panel__rest { display: block; }
  .word-panel__inner { max-height: calc(100vh - 6rem); padding: 1.1rem 1.25rem 1.2rem; }
  .word-panel--open .word-panel__inner { padding-right: 2.8rem; }
}

/* The card inside the panel: the panel is the surface, so the card has none. */
.reader-tip {
  position: static;
  font-size: 0.95rem;
  line-height: 1.5;
  text-align: left;
  cursor: default;
}
.reader-tip__head { margin-bottom: 0.15rem; font-family: var(--serif); font-size: 1.45rem; font-weight: 500; line-height: 1.25; }
.reader-tip__pos { margin-bottom: 0.4rem; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.6; }
.reader-tip__def { font-size: 1rem; }
.reader-tip__more { margin-top: 0.4rem; font-size: 0.86rem; opacity: 0.75; }
.reader-tip__again { margin-top: 0.55rem; padding-top: 0.45rem; border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent); font-size: 0.76rem; opacity: 0.6; }
/* The characters a word is built from, for a multi-character CJK word. */
.reader-tip__parts {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-top: 0.6rem;
  padding-top: 0.55rem;
  border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);
}
.reader-tip__part { display: flex; align-items: baseline; gap: 0.5rem; font-size: 0.86rem; }
.reader-tip__part b { font-size: 1.15em; font-weight: 500; }
.reader-tip__part i { font-style: normal; opacity: 0.6; }
.reader-tip__part span { opacity: 0.85; }
.reader-tip__rel { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.3rem; margin-top: 0.55rem; font-size: 0.84rem; }
.reader-tip__rel-label { font-size: 0.68rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.55; }
/* Buttons, because following one is an action. */
.reader-tip__rel-word {
  padding: 0.12rem 0.5rem;
  border: 1px solid color-mix(in srgb, currentColor 25%, transparent);
  border-radius: 999px;
  background: transparent;
  font-size: 0.86rem;
  cursor: pointer;
}
.reader-tip__rel-word:hover { border-color: var(--accent); }
.reader-tip__say {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.85rem;
  padding: 0.35rem 0.85rem;
  border: 1px solid color-mix(in srgb, currentColor 25%, transparent);
  border-radius: 999px;
  background: transparent;
  font-size: 0.85rem;
  cursor: pointer;
}
.reader-tip__say:hover { border-color: var(--accent); }

/* ── page by page ─────────────────────────────────────────────────────────────
   A chapter was 44,845px tall on a phone. A page is a unit you finish, somewhere
   to stop, and a number that goes up. paging.js builds the bar. */
.pager__track { height: 3px; margin: 0 0 1.1rem; border-radius: 2px; background: var(--rule); overflow: hidden; }
.pager__fill { height: 100%; width: 0; border-radius: 2px; background: var(--accent); transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1); }
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.2rem;
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}
@media (min-width: 64rem) {
  .pager {
    position: sticky;
    bottom: 0;
    z-index: 5;
    padding-bottom: 0.6rem;
    background: linear-gradient(0deg, var(--paper) 75%, transparent);
  }
}
.pager__group { display: flex; align-items: center; gap: 0.4rem; }
.pager__group--page { margin-left: auto; }
.pager__label { margin-right: 0.15rem; font-size: 0.68rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.pager__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 2.4rem;
  padding: 0.45rem 1rem;
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
}
.pager__btn--icon { padding: 0.45rem 0.6rem; }
/* Forward is the way through a chapter, so it is the button with weight. */
.pager__btn[data-go="page-next"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.pager__btn:hover:not(:disabled) { border-color: var(--accent); }
/* Disabled rather than removed: a button that vanishes makes the other jump. */
.pager__btn:disabled { opacity: 0.35; cursor: default; }
.pager__where { font-size: 0.85rem; font-variant-numeric: tabular-nums; color: var(--ink-3); }

/* ── the foot of a chapter ─────────────────────────────────────────────────── */
.reader-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
}
.reader-layout + .reader-foot { margin-top: 1rem; }

/* The end of a preview: what chapter 4 is, and what opens it. A Next button that
   lands on /subscribe with no warning is a trick; this is the warning. */
.preview-end {
  margin-top: 2rem;
  padding: 1.5rem 1.6rem;
  border: 1px solid var(--rule);
  border-top: 3px solid var(--accent);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}
.preview-end__eyebrow { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent-ink); }
.preview-end__title { margin-top: 0.3rem; font-family: var(--serif); font-size: 1.45rem; font-weight: 500; }
.preview-end__body { margin: 0.5rem 0 1.15rem; max-width: 62ch; font-size: 0.97rem; line-height: 1.6; color: var(--ink-2); }
.preview-end__actions { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.preview-end__note { margin-top: 1rem; font-size: 0.88rem; color: var(--ink-3); }

/* ═══ 11. A COURSE CHAPTER ═════════════════════════════════════════════════════
   Four activities done at different times — the dialogue, the words, the grammar,
   the quiz — so an overview with links, as the app has, not one long scroll. */

.chapter-head { margin: 0.75rem 0 1.6rem; }
.chapter-head__num { font-size: 0.74rem; font-weight: 600; letter-spacing: 0.13em; text-transform: uppercase; color: var(--accent-ink); }
.chapter-head__title {
  margin-top: 0.4rem;
  font-family: var(--serif);
  font-size: clamp(1.9rem, 4.5vw, 2.6rem);
  font-weight: 500;
  line-height: 1.12;
  letter-spacing: -0.015em;
}
.chapter-head__en { margin-top: 0.3rem; font-size: 1.1rem; color: var(--ink-2); }
.chapter-head__focus { margin-top: 0.8rem; max-width: 56ch; line-height: 1.6; color: var(--ink-2); }

.parts { display: grid; gap: 0.6rem; }
.part__link {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.part__link:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
.part__link:hover { border-color: var(--accent); box-shadow: var(--shadow-2); }
.part:first-child .part__link { border-color: color-mix(in srgb, var(--accent) 50%, var(--rule)); }
.part__num {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-family: var(--serif);
  font-size: 1.05rem;
  font-weight: 600;
}
.part__body { display: flex; flex: 1; flex-direction: column; gap: 0.1rem; min-width: 0; }
.part__name { font-family: var(--serif); font-size: 1.15rem; font-weight: 500; }
.part__blurb { font-size: 0.86rem; color: var(--ink-2); }
/* The count says what you are committing to — the question an overview answers. */
.part__count { flex: none; font-size: 0.8rem; font-variant-numeric: tabular-nums; color: var(--ink-3); white-space: nowrap; }
.parts__go { margin-top: 1.4rem; }

/* The strip that stays on all four parts: changing activity is one tap. */
.parts-strip {
  display: flex;
  gap: 0.35rem;
  margin: 0 0 1.4rem;
  padding: 0.3rem;
  overflow-x: auto;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--surface);
  scrollbar-width: none;
}
.parts-strip::-webkit-scrollbar { display: none; }
.parts-strip__item {
  flex: 1 0 auto;
  padding: 0.45rem 0.9rem;
  border-radius: 999px;
  color: var(--ink-2);
  font-size: 0.88rem;
  font-weight: 500;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
}
.parts-strip__item:hover { color: var(--ink-2); text-decoration: none; }
.parts-strip__item:hover { background: var(--surface-2); color: var(--ink); }
.parts-strip__item--here { background: var(--ink); color: var(--paper); }
.parts-strip__item--here:hover { background: var(--ink); color: var(--paper); }

.part-head {
  margin-bottom: 1.1rem;
  font-family: var(--serif);
  font-size: clamp(1.6rem, 3.4vw, 2.05rem);
  font-weight: 500;
  line-height: 1.15;
}
.part-head--second { margin-top: 2.2rem; }
.part-next { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 2rem; padding-top: 1.25rem; border-top: 1px solid var(--rule); }

/* The grammar reference: the longest prose on the site, and the one thing read
   start to finish, so a measured column in the book face. */
.reference { max-width: 44rem; }
.reference__intro { margin-bottom: 1.6rem; font-family: var(--serif); font-size: 1.18rem; line-height: 1.65; color: var(--ink-2); }
.reference__section { margin-bottom: 1.8rem; }
.reference__head { margin-bottom: 0.55rem; font-family: var(--serif); font-size: 1.3rem; font-weight: 500; line-height: 1.3; }
.reference__p { margin-bottom: 0.9rem; font-size: 1.02rem; line-height: 1.75; }
/* What the chapter's grammar is ABOUT, in a quiet line: the generated title is long
   and themed ("Unlocking the Xiaoqu: …"), so it sits under a plain heading. */
.reference__theme { margin: -0.5rem 0 1.25rem; font-family: var(--serif); font-size: 1.1rem; font-style: italic; color: var(--ink-2); }
/* The sections, listed and linked, so the rules can be seen before the prose. */
.reference__toc {
  margin: 0 0 1.5rem;
  padding: 1rem 1.2rem;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
}
.reference__toc-head { margin-bottom: 0.5rem; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.reference__toc ol { display: grid; gap: 0.35rem; padding-left: 1.2rem !important; list-style: decimal !important; }
.reference__toc a,
.reference__toc a:hover { color: var(--ink); text-decoration: none; }
.reference__toc a:hover { color: var(--accent-ink); text-decoration: underline; }
/* The essay's opening, kept but quiet: background, not the lesson. */
.reference .reference__intro { font-family: var(--sans); font-size: 0.95rem; line-height: 1.6; color: var(--ink-3); }
.reference__section { scroll-margin-top: 1rem; padding-top: 0.5rem; }
.reference__sub { margin: 1.2rem 0 0; padding-left: 1rem; border-left: 2px solid var(--rule); }
.reference__subhead { margin-bottom: 0.5rem; font-family: var(--serif); font-size: 1.12rem; font-weight: 500; }

/* Worked examples, before the prose: the sentence, how it is said, what it means. */
.ref-examples { display: grid; gap: 0.5rem; margin: 0 0 1rem; }
.ref-example {
  display: grid;
  gap: 0.1rem;
  padding: 0.7rem 0.95rem;
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r-s) var(--r-s) 0;
  background: var(--surface);
}
.ref-example__phrase { font-family: var(--serif); font-size: 1.25rem; }
:is([lang="ja"], [lang="zh"], [lang="hk"], [lang="ko"], [lang="th"]).ref-example__phrase { font-family: var(--sans); }
.ref-example__reading { font-size: 0.9rem; color: var(--accent-ink); }
.ref-example__en { font-size: 0.92rem; color: var(--ink-2); }

/* ── the words, in columns ─────────────────────────────────────────────────── */
.study { margin-top: 2.5rem; padding-top: 1.75rem; border-top: 1px solid var(--rule); }
.study__head { margin: 2rem 0 0.9rem; font-family: var(--serif); font-size: 1.35rem; font-weight: 500; }
.vocab-list { display: grid; gap: 0 2.5rem; }
@media (min-width: 52rem) {
  .vocab-list { grid-template-columns: 1fr 1fr; }
}
.vocab-list__item {
  display: grid;
  grid-template-columns: minmax(6rem, auto) minmax(0, auto) 1fr;
  gap: 0.25rem 1rem;
  align-items: baseline;
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--rule);
}
/* A phrase is a sentence: two columns of phrases is two columns of wrapping. */
.vocab-list--phrases { grid-template-columns: 1fr; }
.vocab-list--phrases .vocab-list__item { grid-template-columns: minmax(8rem, 1fr) minmax(0, 0.9fr) minmax(0, 1.2fr); }
.vocab-list__word { font-family: var(--serif); font-size: 1.2rem; }
.vocab-list__reading { font-size: 0.86rem; color: var(--ink-3); }
.vocab-list__meaning { color: var(--ink-2); }
@media (max-width: 36rem) {
  .vocab-list__item,
  .vocab-list--phrases .vocab-list__item { grid-template-columns: 1fr auto; }
  .vocab-list__meaning { grid-column: 1 / -1; }
}

/* ── check yourself ─────────────────────────────────────────────────────────── */
.quiz { display: grid; gap: 1rem; }
.quiz__q {
  padding: 1.15rem 1.25rem 1.25rem;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
}
.quiz__vocab { margin-bottom: 0.35rem; font-family: var(--serif); font-size: 1.3rem; }
.quiz__prompt { margin-bottom: 0.85rem; font-weight: 600; line-height: 1.5; }
.quiz__options { display: grid; gap: 0.45rem; }
.quiz__option {
  width: 100%;
  min-height: 2.75rem;
  padding: 0.6rem 0.95rem;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-s);
  background: var(--paper);
  text-align: left;
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}
.quiz__option:hover:not(:disabled) { border-color: var(--accent); }
.quiz__option:disabled { cursor: default; }
.quiz__option--right { background: var(--ok-wash); border-color: var(--ok); }
.quiz__option--wrong { background: var(--bad-wash); border-color: var(--bad); }
.quiz__feedback { margin-top: 0.75rem; font-size: 0.92rem; line-height: 1.55; color: var(--ink-2); }

/* ═══ 12. FLASHCARDS ═══════════════════════════════════════════════════════════
   The owner's note was "messy, padding and layout issues, hard to read". One
   column, one card, centred and no wider than the word needs — the heading, the
   bar, the card and the two answers all on the same 34rem axis. */

.deck-head { margin: 0.5rem 0 1.5rem; }
.deck-head__title {
  font-family: var(--serif);
  font-size: clamp(1.75rem, 4vw, 2.3rem);
  font-weight: 500;
  line-height: 1.15;
}
.deck-head__native { margin-top: 0.25rem; font-size: 1.1rem; color: var(--ink-2); }
.deck-head__about { margin-top: 0.7rem; max-width: 56ch; font-size: 0.97rem; line-height: 1.6; color: var(--ink-2); }

/* On the page's left edge, under its heading: centred in a wider column, the
   card and the title above it had two different left edges — the "layout
   issues" half of the owner's note. */
.deck { max-width: 34rem; }
.deck-progress { display: flex; align-items: center; gap: 0.75rem; margin: 0 0 1.25rem; font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.deck-progress__count { flex: none; color: var(--ink-3); }
.deck-progress__bar { flex: 1; height: 5px; border-radius: 3px; background: var(--rule); overflow: hidden; }
.deck-progress__fill { display: block; height: 100%; width: 0; border-radius: 3px; background: var(--accent); transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1); }

/* Room under the card for the stack to show in. */
.deck-cards { margin: 0 0 1.4rem; padding-bottom: 1.4rem; }
/* It looks like a card off a stack: two boards behind it, offset down and
   narrower, say "one of many" and "more after it". Drawn on the <li> because a
   pseudo-element inside the button would sit on the word. */
.deck-card { position: relative; isolation: isolate; }
.deck-card::before,
.deck-card::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  width: 100%;
  height: min(100%, 15rem);
  border: 1px solid var(--rule);
  border-radius: var(--r-l);
  background: var(--surface);
  z-index: -1;
}
.deck-card::before { transform: translateX(-50%) translateY(9px) scale(0.955); }
.deck-card::after { transform: translateX(-50%) translateY(18px) scale(0.91); opacity: 0.6; }
/* The last card has nothing behind it: a stack that never runs out undoes the point. */
.deck--done .deck-card::before,
.deck--done .deck-card::after { display: none; }
.deck-card__face {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  width: 100%;
  min-height: 15rem;
  padding: 2rem 1.5rem;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-l);
  background: var(--surface);
  box-shadow: var(--shadow-2);
  color: var(--ink);
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.deck-card__face:hover { border-color: var(--accent); box-shadow: var(--shadow-3); }
.deck-card__word { display: block; font-family: var(--serif); font-size: clamp(2.4rem, 8vw, 3.4rem); line-height: 1.2; overflow-wrap: anywhere; }
.deck-card__pos { display: block; font-size: 0.8rem; letter-spacing: 0.04em; color: var(--ink-3); }
.deck-card__hint { margin-top: 0.9rem; font-size: 0.78rem; color: var(--ink-3); }
.deck-card:has(.deck-card__back:not([hidden])) .deck-card__hint { display: none; }
.deck-card__back {
  margin-top: 0.8rem;
  padding: 1.15rem 1.3rem;
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r) var(--r) 0;
  background: var(--surface);
  box-shadow: var(--shadow-1);
}
.deck-card__reading { margin-bottom: 0.25rem; font-size: 1.15rem; font-weight: 500; letter-spacing: 0.01em; color: var(--accent-ink); }
.deck-card__translation { font-family: var(--serif); font-size: 1.4rem; font-weight: 500; line-height: 1.3; }
.deck-card__example-reading { margin-top: 0.15rem; font-size: 0.88rem; color: var(--ink-3); }
.deck-card__definition { margin-top: 0.4rem; line-height: 1.55; color: var(--ink-2); }
.deck-card__example { margin-top: 0.85rem; padding-top: 0.75rem; border-top: 1px solid var(--rule); font-family: var(--serif); font-size: 1.12rem; }
.deck-card__example-en { margin-top: 0.15rem; font-size: 0.92rem; color: var(--ink-2); }

/* EQUAL HALVES. `flex: 1` sizes by content, so "Again" and "I knew it" came out
   different widths on the one screen where two choices should look like two. */
.deck-controls { display: flex; gap: 0.75rem; }
.deck-controls .button { flex: 1 1 0; min-width: 0; min-height: 3rem; }
.deck--done .deck-controls { display: none; }
.deck-score { margin-top: 1.1rem; font-size: 1rem; text-align: center; }

/* ═══ 13. THE DICTIONARY ═══════════════════════════════════════════════════════ */

.dict-box {
  border: 1px solid var(--rule-2);
  border-radius: var(--r-l);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}
.dict-box:focus-within { border-color: var(--accent); }
.dict-picker { border-bottom: 1px solid var(--rule); }
.dict-picker__current {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.7rem 1.1rem;
  font-size: 0.92rem;
  cursor: pointer;
  list-style: none;
}
.dict-picker__current::-webkit-details-marker { display: none; }
.dict-picker__label { font-size: 0.7rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.dict-picker__change { margin-left: auto; font-size: 0.85rem; font-weight: 600; color: var(--accent-ink); }
.dict-picker__change::after { content: ' ▾'; }
.dict-picker[open] .dict-picker__change::after { content: ' ▴'; }
.dict-langs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr));
  gap: 0.15rem 1rem;
  max-height: 22rem;
  padding: 0.3rem 1.1rem 0.9rem;
  overflow-y: auto;
}
.dict-lang {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  padding: 0.45rem 0.4rem;
  border-radius: var(--r-s);
  color: var(--ink);
  text-decoration: none;
  font-size: 0.92rem;
}
.dict-lang:hover { color: var(--ink); text-decoration: none; }
.dict-lang:hover { background: var(--surface-2); }
.dict-lang--on { background: var(--accent-wash); font-weight: 600; }
.dict-lang--on:hover { background: var(--accent-wash); }
.dict-lang__name { font-weight: 500; }
.dict-lang__native { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-3); font-size: 0.85rem; }
.dict-lang__count { margin-left: auto; font-size: 0.75rem; font-variant-numeric: tabular-nums; color: var(--ink-3); }

.dict-search { position: relative; display: block; }
.dict-search__icon { position: absolute; left: 1.1rem; top: 50%; transform: translateY(-50%); color: var(--ink-3); font-size: 1.15rem; pointer-events: none; }
.dict-search__input {
  width: 100%;
  min-height: 3.6rem;
  padding: 0.85rem 1.1rem 0.85rem 2.9rem;
  border: 0;
  border-radius: 0 0 var(--r-l) var(--r-l);
  background: transparent;
  color: var(--ink);
  font-size: 1.2rem;
}
.dict-search__input:focus,
.dict-search__input:focus-visible { outline: none; }

/* What this reader has looked up, as the words themselves at reading size. */
.dict-history { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem; margin: 1rem 0 0; }
.dict-history__label { font-size: 0.7rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.dict-history__chips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.dict-history__chip {
  padding: 0.22rem 0.7rem;
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  background: var(--surface);
  font-size: 0.95rem;
  cursor: pointer;
}
.dict-history__chip:hover { border-color: var(--accent); }
.dict-history__clear { margin-left: auto; padding: 0; border: 0; background: none; font-size: 0.8rem; color: var(--ink-3); text-decoration: underline; cursor: pointer; }
.dict-history__clear:hover { color: var(--ink); }

.dict-results { margin: 1.25rem 0 1.5rem; }
.dict-entry { padding: 1rem 0.1rem; border-bottom: 1px solid var(--rule); }
.dict-entry__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.6rem; margin-bottom: 0.3rem; }
.dict-entry__word { font-family: var(--serif); font-size: 1.45rem; font-weight: 500; }
.dict-entry__reading { font-size: 0.92rem; color: var(--ink-3); }
.dict-entry__pos { font-size: 0.7rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.dict-entry__def { line-height: 1.55; }
.dict-entry__more { margin-top: 0.3rem; font-size: 0.88rem; color: var(--ink-2); }
.dict-none { padding: 1rem 0; color: var(--ink-2); }
.dict-note { font-size: 0.86rem; line-height: 1.55; color: var(--ink-3); }

/* ═══ 14. A COURSE'S WHOLE VOCABULARY ══════════════════════════════════════════
   430 words broken at the chapter that teaches each — the same data shows the
   shape of the course. */

.wordgroup { margin: 0 0 2rem; }
.wordgroup__head {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  margin-bottom: 0.4rem;
  padding-bottom: 0.45rem;
  border-bottom: 2px solid var(--rule-2);
  font-family: var(--serif);
  font-size: 1.2rem;
  font-weight: 500;
}
.wordgroup__num {
  display: grid;
  place-items: center;
  flex: none;
  width: 1.8rem;
  height: 1.8rem;
  border-radius: 50%;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-size: 0.9rem;
  font-weight: 600;
}
.wordgroup__name { color: inherit; text-decoration: none; }
.wordgroup__name:hover { color: inherit; text-decoration: none; }
.wordgroup__name:hover { color: var(--accent-ink); }
.wordgroup__count { margin-left: auto; font-family: var(--sans); font-size: 0.78rem; font-weight: 400; color: var(--ink-3); }
.wordlist__item {
  display: grid;
  grid-template-columns: minmax(6rem, 1fr) minmax(0, 1fr) minmax(0, 2.2fr);
  gap: 0.75rem;
  align-items: baseline;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--rule);
}
.wordlist__word { font-family: var(--serif); font-size: 1.15rem; }
.wordlist__reading { font-size: 0.86rem; color: var(--ink-3); }
.wordlist__meaning { font-size: 0.94rem; color: var(--ink-2); }
.wordlist__locked {
  margin-top: 1.5rem;
  padding: 0.9rem 1.1rem;
  border: 1px dashed var(--accent);
  border-radius: var(--r-s);
  background: var(--accent-wash);
  font-size: 0.92rem;
}
@media (max-width: 38rem) {
  .wordlist__item { grid-template-columns: 1fr auto; gap: 0.15rem 0.6rem; }
  .wordlist__reading { grid-column: 2; text-align: right; }
  .wordlist__meaning { grid-column: 1 / -1; }
}

/* ═══ 15. YOU: JOINING, YOUR LIBRARY, AND WHAT IT COSTS ════════════════════════ */

/* NOT A CARD IN A CARD. The theme draws a bare <form> as a 34rem bordered panel;
   here the form is the card, and what it changes sits beside it. */
.join-split { display: grid; gap: 2rem; }
@media (min-width: 60rem) {
  .join-split { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: 3rem; align-items: start; }
}
.join { min-width: 0; }
[data-area="library"] .join form {
  max-width: none;
  margin: 0;
  padding: 1.75rem;
  border: 1px solid var(--rule);
  border-radius: var(--r-l);
  background: var(--surface);
  box-shadow: var(--shadow-2);
  color: var(--ink);
}
[data-area="library"] .join form fieldset { border: 0; }
[data-area="library"] .join form .field { margin-bottom: 1.1rem; }
[data-area="library"] .join form .field label { margin-bottom: 0.35rem; font-size: 0.9rem; font-weight: 600; color: var(--ink); }
[data-area="library"] .join form .field :is(input[type='text'], input[type='email'], input[type='password']) {
  width: 100%;
  padding: 0.75rem 0.95rem;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-s);
  background: var(--paper);
  color: var(--ink);
}
[data-area="library"] .join form .field :is(input[type='text'], input[type='email'], input[type='password']):focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
  outline: none;
}
[data-area="library"] .join form :is(button[type='submit'], input[type='submit']) {
  min-height: 3rem;
  padding: 0.7rem 1.4rem;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
}
[data-area="library"] .join form :is(button[type='submit'], input[type='submit']):hover { background: var(--accent-strong); }
.join .description { margin-top: 0.25rem; font-size: 0.82rem; color: var(--ink-3); }
.join .btn-toolbar,
.join .Actions { margin-top: 1.25rem; }
/* A failed submission's message has to read as a problem, not more instructions. */
.join .message { margin: 0 0 1rem; padding: 0.65rem 0.85rem; border-left: 3px solid var(--bad); border-radius: 0.3rem; background: var(--bad-wash); font-size: 0.92rem; }
.join .message.good { border-left-color: var(--ok); background: var(--ok-wash); }
.join__alt { margin-top: 1rem; font-size: 0.92rem; color: var(--ink-2); }
.join__aside { padding-top: 0.25rem; }
.join__aside .section-head__title { margin-bottom: 0.9rem; font-size: 1.35rem; }
.join__aside-h--first { margin-top: 0 !important; }
/* The login form's own extras: "keep me signed in" and its help bubble, and the
   framework's forgotten-password link, which is also offered under the form. */
[data-area="library"] .signin form .field.checkbox { display: flex; align-items: center; gap: 0.5rem; }
[data-area="library"] .signin form .field.checkbox label { margin: 0; font-weight: 500; }
[data-area="library"] .signin form #ForgotPassword,
[data-area="library"] .signin form .cms-security__container__help { display: none; }
.join__aside-h { margin: 1.75rem 0 0.9rem; font-family: var(--serif); font-size: 1.35rem; font-weight: 500; }
.split__note { margin-top: 1rem; font-size: 0.88rem; line-height: 1.55; color: var(--ink-3); }

.account-heading { margin: 2.5rem 0 1rem; font-family: var(--serif); font-size: 1.4rem; font-weight: 500; }
.lib-section > .lib-wrap > .account-heading:first-child { margin-top: 0; }
.account-list { display: grid; grid-template-columns: auto 1fr; gap: 0.5rem 1.5rem; margin: 0 0 1.25rem; }
.account-list dt { color: var(--ink-3); }
.account-list dd { margin: 0; }
.account-links { display: flex; flex-wrap: wrap; gap: 1.25rem; font-size: 0.94rem; }
.account-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1rem; }
[data-area="library"] .lib-wrap--text > p:not([class]) { margin-bottom: 1rem; line-height: 1.6; }

/* THREE TIERS, each saying what it ADDS. The middle one — free, and what most
   people should take — is the marked one. */
.tiers__head { margin: 2.5rem 0 1.25rem; }
.lib-section .lib-wrap > .tiers__head:first-child { margin-top: 0; }
.tiers { display: grid; gap: 1rem; }
@media (min-width: 58rem) {
  .tiers { grid-template-columns: repeat(3, 1fr); align-items: start; }
}
.tier {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 1.45rem 1.5rem 1.5rem;
  border: 1px solid var(--rule);
  border-radius: var(--r-l);
  background: var(--surface);
}
.tier--pick { border-color: var(--accent); box-shadow: var(--shadow-3); }
@media (min-width: 58rem) {
  .tier--pick { margin-top: -0.6rem; padding-bottom: 2rem; }
}
.tier__flag {
  position: absolute;
  top: 0;
  left: 1.5rem;
  transform: translateY(-50%);
  padding: 0.2rem 0.75rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.tier__name { font-family: var(--serif); font-size: 1.35rem; font-weight: 500; }
.tier__price { margin: 0.35rem 0 1rem; color: var(--ink-3); font-size: 0.88rem; }
.tier__price strong { margin-right: 0.3rem; font-family: var(--serif); font-size: 1.75rem; font-weight: 600; color: var(--ink); }
.tier__adds { margin-bottom: 0.7rem; font-size: 0.82rem; color: var(--ink-3); }
.tier .ticks { flex: 1; }
.tier__act { margin-top: 1.1rem; }
.tier__note { margin-top: 1rem; font-size: 0.84rem; line-height: 1.55; color: var(--ink-3); }

.plan-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: 1rem; max-width: 42rem; margin: 0 0 1.5rem; }
.plan-card { padding: 1.5rem; border: 1px solid var(--rule); border-radius: var(--r-l); background: var(--surface); }
.plan-card__name { font-family: var(--serif); font-size: 1.3rem; font-weight: 500; }
.plan-card__price { margin: 0.4rem 0 0.3rem; color: var(--ink-3); }
.plan-card__price strong { font-family: var(--serif); font-size: 1.8rem; color: var(--ink); }
.plan-card__note { margin-bottom: 1.2rem; font-size: 0.9rem; color: var(--ink-2); }

/* Nothing to buy yet: said as plainly as a price would be. */
.soon {
  padding: 1.5rem 1.6rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: var(--r);
  background: var(--surface);
}
.soon p { margin-bottom: 0.9rem; line-height: 1.6; }
.soon__lead { font-family: var(--serif); font-size: 1.25rem; line-height: 1.45 !important; }
.soon__what { color: var(--ink-2); }

/* ── the notice row: the launch month, and "still being built" ───────────── */
.notice-row {
  background: var(--accent-wash);
  border-bottom: 1px solid var(--rule);
  font-size: 0.84rem;
  line-height: 1.45;
}
.notice-row__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.25rem 1.25rem;
  padding-block: 0.45rem;
}
.notice-row__offer { color: var(--ink); }
.notice-row__dev { margin-left: auto; color: var(--ink-2); white-space: nowrap; }
.notice-row a { color: var(--accent-ink); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.notice-row a:hover { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 40rem) {
  .notice-row__dev { margin-left: 0; }
}

/* ── a language chip you can take off ───────────────────────────────────── */
.shelf__chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  background: var(--surface);
}
.shelf__chip .shelf__lang { border: 0; padding: 0.18rem 0.15rem 0.18rem 0.65rem; }
.shelf__chip:hover { border-color: var(--accent); }
.shelf__x {
  display: grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  margin-right: 0.1rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-3);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.shelf__x:hover { background: var(--surface-2); color: var(--bad); }

/* ── on or off "your languages", on a language's own page ─────────────────── */
.mylang__mark {
  width: 0.95rem;
  height: 0.95rem;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  position: relative;
}
.mylang__mark::before { content: '+'; position: absolute; inset: -0.2rem 0 0; display: grid; place-items: center; font-size: 0.8rem; font-weight: 700; }
.mylang[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-wash); }
.mylang[aria-pressed="true"]:hover { border-color: var(--accent); background: var(--accent-wash); }
.mylang[aria-pressed="true"] .mylang__mark { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.mylang[aria-pressed="true"] .mylang__mark::before { content: '✓'; font-size: 0.65rem; inset: 0; }

/* ── the account page's new parts ─────────────────────────────────────────── */
.library-note--done { background: var(--ok-wash); border-left: 3px solid var(--ok); }
.verify-card {
  margin-bottom: 2rem;
  padding: 1.35rem 1.45rem;
  border: 1px solid var(--rule);
  border-top: 3px solid var(--accent);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}
.verify-card__title { font-family: var(--serif); font-size: 1.4rem; font-weight: 500; }
.verify-card__body { margin: 0.45rem 0 1rem; line-height: 1.6; color: var(--ink-2); }
.verify-card__form { margin: 0; padding: 0; border: 0; background: none; box-shadow: none; }

.mylangs { border-top: 1px solid var(--rule); }
.mylangs__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--rule);
}
.mylangs__name { color: var(--ink); font-weight: 600; text-decoration: none; }
.mylangs__name:hover { color: var(--ink); text-decoration: none; }
.mylangs__name span { margin-left: 0.35rem; font-weight: 400; color: var(--ink-3); }
.mylangs__name:hover { color: var(--accent-ink); }
.mylangs__form { margin: 0; padding: 0; border: 0; background: none; box-shadow: none; }
.mylangs__remove { min-height: 2.1rem; padding: 0.3rem 0.85rem; font-size: 0.85rem; }
.mylangs__add { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 1rem 0 0; padding: 0; border: 0; background: none; box-shadow: none; max-width: none; }
.mylangs__select {
  min-height: 2.6rem;
  min-width: 12rem;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-s);
  background: var(--surface);
  color: var(--ink);
}

/* The profile form: the theme draws a bare <form> as a centred 34rem panel. */
[data-area="library"] .profile-form form {
  max-width: 28rem;
  margin: 0;
  padding: 1.2rem 1.3rem;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: none;
}
[data-area="library"] .profile-form form fieldset { border: 0; }
[data-area="library"] .profile-form form .field { margin-bottom: 0.8rem; }
[data-area="library"] .profile-form form .field label { margin-bottom: 0.3rem; font-size: 0.88rem; font-weight: 600; color: var(--ink); }
[data-area="library"] .profile-form form .field input[type='text'] {
  width: 100%;
  padding: 0.6rem 0.85rem;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-s);
  background: var(--paper);
  color: var(--ink);
}
[data-area="library"] .profile-form form :is(button, input)[type='submit'] {
  width: auto;
  min-height: 2.5rem;
  padding: 0.5rem 1.2rem;
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  box-shadow: none;
  cursor: pointer;
}
[data-area="library"] .profile-form form :is(button, input)[type='submit']:hover { background: var(--surface-2); border-color: var(--ink-3); }

/* ═══ 16. THE FOOTER ═══════════════════════════════════════════════════════════ */

.lf {
  margin-top: 1rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--rule);
  background: var(--paper-2);
  font-size: 0.9rem;
  color: var(--ink-2);
}
.lf__inner { display: grid; gap: 2rem; }
@media (min-width: 52rem) {
  .lf__inner { grid-template-columns: minmax(0, 1.2fr) minmax(0, 2fr); gap: 3rem; }
}
.lf__mark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.15rem;
  font-weight: 600;
  text-decoration: none;
}
.lf__mark:hover { color: var(--ink); text-decoration: none; }
.lf__mark svg { width: 1.8rem; height: 1.8rem; border-radius: 50%; box-shadow: 0 0 0 1px var(--rule); }
.lf__line { margin-top: 0.6rem; max-width: 34ch; line-height: 1.55; }
.lf__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 1.5rem; }
.lf__col { display: flex; flex-direction: column; gap: 0.45rem; }
.lf__head { margin-bottom: 0.2rem; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); }
.lf__col a { color: var(--ink-2); text-decoration: none; }
.lf__col a:hover { color: var(--ink-2); text-decoration: none; }
.lf__col a:hover { color: var(--accent-ink); text-decoration: underline; }
.lf__base { margin-top: 2rem; padding-block: 1.1rem 1.4rem; border-top: 1px solid var(--rule); font-size: 0.8rem; color: var(--ink-3); }

/* ═══ 17. LAST, AND ON PURPOSE ═════════════════════════════════════════════════
   `hidden` means hidden. An author `display` beats the user-agent's own
   `[hidden] { display: none }`, and on this site that showed the definition
   panel's resting text above every card and an empty "Recently looked up" row on
   every fresh visit. Every script here hides and shows things with the attribute,
   so the attribute wins. */
[data-area="library"] [hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  [data-area="library"] *,
  [data-area="library"] *::before,
  [data-area="library"] *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
