/*
 * read.gonglogic.com — the library and the reading surface.
 *
 * Only what the library has that the theme does not. Everything structural (header,
 * family bar, hero, sections, buttons, footer) comes from the site's own stylesheet,
 * the same decision the studio subsite records: a subsite with its own type and
 * buttons looks like a different company, and a careful imitation is worse to maintain
 * than reuse.
 */

/* ── the catalogue ──────────────────────────────────────────────────────────── */

.library-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1rem;
  list-style: none;
  margin: 0 0 2.5rem;
  padding: 0;
}

.library-card__link {
  display: block;
  height: 100%;
  padding: 1.1rem 1.2rem;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 0.6rem;
  background: #fff;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.library-card__link:hover,
.library-card__link:focus-visible {
  border-color: rgba(0, 0, 0, 0.3);
  transform: translateY(-2px);
}

.library-card__kind {
  display: inline-block;
  margin-bottom: 0.4rem;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.6;
}

.library-card__title { margin: 0 0 0.25rem; font-size: 1.05rem; line-height: 1.3; }
.library-card__sub   { margin: 0 0 0.5rem; font-size: 0.88rem; opacity: 0.75; }
.library-card__meta  { margin: 0; font-size: 0.8rem; opacity: 0.65; }

.library-group__head {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin: 2rem 0 1rem;
}
.library-group__count { font-size: 0.85rem; opacity: 0.6; }

.library-note {
  padding: 0.9rem 1.1rem;
  border-radius: 0.5rem;
  background: rgba(0, 0, 0, 0.04);
  margin: 0 0 1.5rem;
}
.library-note--warn { background: rgba(200, 120, 0, 0.12); }
.library-fineprint { font-size: 0.85rem; opacity: 0.7; }
.library-empty { opacity: 0.7; }

/* ── plans ──────────────────────────────────────────────────────────────────── */

.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.2rem;
  list-style: none;
  margin: 0 0 2rem;
  padding: 0;
  max-width: 42rem;
}
.plan-card {
  padding: 1.5rem;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 0.6rem;
  background: #fff;
}
.plan-card__name  { margin: 0 0 0.6rem; font-size: 1.1rem; }
.plan-card__price { margin: 0 0 0.3rem; font-size: 1.6rem; }
.plan-card__price span { font-size: 0.9rem; opacity: 0.65; }
.plan-card__note  { margin: 0 0 1.2rem; font-size: 0.88rem; opacity: 0.75; }

.account-list { display: grid; grid-template-columns: auto 1fr; gap: 0.4rem 1.5rem; margin: 0 0 1.5rem; }
.account-list dt { opacity: 0.65; }
.account-list dd { margin: 0; }

/* ── chapters ───────────────────────────────────────────────────────────────── */

.chapter-list { list-style: none; margin: 0; padding: 0; }
.chapter-list__item { border-bottom: 1px solid rgba(0, 0, 0, 0.08); padding: 0.9rem 0; }
.chapter-list__link {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  text-decoration: none;
  color: inherit;
}
.chapter-list__link--locked { opacity: 0.45; cursor: default; }
.chapter-list__num { min-width: 2rem; font-variant-numeric: tabular-nums; opacity: 0.5; }
.chapter-list__name { font-size: 1.02rem; }
.chapter-list__en { font-size: 0.85rem; opacity: 0.6; }
.chapter-list__focus { margin: 0.35rem 0 0 2.9rem; font-size: 0.84rem; opacity: 0.65; }

/* ── the reader ─────────────────────────────────────────────────────────────── */

.reader-nav {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-bottom: 1rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}
.reader-nav__chapter { opacity: 0.6; font-size: 0.9rem; }
.reader-speak {
  margin-left: auto;
  padding: 0.4rem 0.9rem;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 2rem;
  background: #fff;
  cursor: pointer;
  font-size: 0.85rem;
}

.reader-pages { list-style: none; margin: 0; padding: 0; }
.reader-page { margin: 0 0 1.9rem; }
.reader-page__speaker {
  display: block;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.55;
  margin-bottom: 0.3rem;
}
.reader-page__source {
  margin: 0 0 0.45rem;
  font-size: 1.45rem;
  line-height: 2.5;   /* room for the reading above each token */
}
.reader-page__translation { margin: 0; opacity: 0.78; }

/*
 * A token. `ruby` puts the reading above it — furigana, pinyin, Jyutping — which is
 * the thing these readers exist for, and which the server decides: a reading equal to
 * the word itself is not rendered at all.
 */
.reader-word {
  position: relative;
  cursor: pointer;
  border-radius: 0.2rem;
  transition: background-color 0.12s ease;
}
.reader-word:hover { background: rgba(0, 0, 0, 0.06); }
.reader-word rt { font-size: 0.42em; opacity: 0.6; font-weight: 400; }

/* Tapped, and everything sharing its alignment. */
.reader-word--lit { background: rgba(255, 196, 0, 0.35); }
.reader-translation--lit { background: rgba(255, 196, 0, 0.35); border-radius: 0.2rem; }

.reader-tip {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: calc(100% + 0.5rem);
  z-index: 20;
  min-width: 13rem;
  max-width: 21rem;
  padding: 0.8rem 0.95rem;
  border-radius: 0.5rem;
  background: #1d1d1f;
  color: #fff;
  font-size: 0.9rem;
  line-height: 1.45;
  text-align: left;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);
  cursor: default;
}
.reader-tip__head { margin: 0 0 0.2rem; font-weight: 600; }
.reader-tip__pos  { margin: 0 0 0.35rem; font-size: 0.78rem; opacity: 0.6; }
.reader-tip__def  { margin: 0; }
.reader-tip__more { margin: 0.4rem 0 0; font-size: 0.84rem; opacity: 0.75; }
.reader-tip__say {
  margin-top: 0.6rem;
  padding: 0.25rem 0.6rem;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 1rem;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.reader-foot {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(0, 0, 0, 0.08);
}

/* ── study material: the words, the phrases, the check ───────────────────────── */

.study { margin-top: 3rem; padding-top: 2rem; border-top: 1px solid rgba(0, 0, 0, 0.08); }
.study__head { margin: 2rem 0 0.9rem; font-size: 1.15rem; }

.vocab-list { list-style: none; margin: 0; padding: 0; }
.vocab-list__item {
  display: grid;
  grid-template-columns: minmax(6rem, auto) minmax(0, auto) 1fr;
  gap: 0.3rem 1rem;
  align-items: baseline;
  padding: 0.5rem 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.vocab-list--phrases .vocab-list__item { grid-template-columns: minmax(10rem, 1.2fr) 1fr; }
.vocab-list__word    { font-size: 1.08rem; }
.vocab-list__reading { font-size: 0.85rem; opacity: 0.6; }
.vocab-list__meaning { opacity: 0.8; }

.quiz { list-style: none; margin: 0; padding: 0; counter-reset: q; }
.quiz__q {
  padding: 1.1rem 0 1.3rem;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.quiz__vocab  { margin: 0 0 0.4rem; font-size: 1.1rem; }
.quiz__prompt { margin: 0 0 0.8rem; font-weight: 500; }
.quiz__options { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.45rem; }
.quiz__option {
  width: 100%;
  text-align: left;
  padding: 0.6rem 0.9rem;
  border: 1px solid rgba(0, 0, 0, 0.18);
  border-radius: 0.45rem;
  background: #fff;
  cursor: pointer;
  font: inherit;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}
.quiz__option:hover:not(:disabled) { border-color: rgba(0, 0, 0, 0.4); }
.quiz__option:disabled { cursor: default; }
.quiz__option--right { background: rgba(40, 160, 90, 0.16); border-color: rgba(40, 160, 90, 0.5); }
.quiz__option--wrong { background: rgba(200, 60, 60, 0.14); border-color: rgba(200, 60, 60, 0.45); }
.quiz__feedback { margin: 0.7rem 0 0; font-size: 0.9rem; opacity: 0.85; }

/* ── flashcards ─────────────────────────────────────────────────────────────── */

.deck-native { margin: 0 0 0.3rem; font-size: 1.15rem; }
.deck-about  { margin: 0 0 1.8rem; opacity: 0.72; }

.deck-progress { margin: 0 0 1rem; font-size: 0.85rem; opacity: 0.6; font-variant-numeric: tabular-nums; }
.deck-cards { list-style: none; margin: 0 0 1.5rem; padding: 0; }

.deck-card__face {
  display: block;
  width: 100%;
  min-height: 11rem;
  padding: 2.2rem 1.5rem;
  border: 1px solid rgba(0, 0, 0, 0.14);
  border-radius: 0.75rem;
  background: #fff;
  cursor: pointer;
  font: inherit;
  text-align: center;
  transition: border-color 0.15s ease;
}
.deck-card__face:hover { border-color: rgba(0, 0, 0, 0.32); }
.deck-card__word { display: block; font-size: 2rem; line-height: 1.3; }
.deck-card__pos  { display: block; margin-top: 0.5rem; font-size: 0.82rem; opacity: 0.55; }

.deck-card__back {
  margin-top: 0.9rem;
  padding: 1.2rem 1.4rem;
  border-radius: 0.6rem;
  background: rgba(0, 0, 0, 0.045);
}
.deck-card__translation { margin: 0 0 0.5rem; font-size: 1.2rem; }
.deck-card__definition  { margin: 0 0 0.8rem; opacity: 0.8; }
.deck-card__example     { margin: 0 0 0.2rem; font-size: 1.05rem; }
.deck-card__example-en  { margin: 0; opacity: 0.7; font-size: 0.92rem; }

.deck-controls { display: flex; gap: 0.8rem; }
.deck-controls .button { flex: 1; }
.deck--done .deck-controls { display: none; }
.deck-score { margin-top: 1.2rem; font-size: 0.95rem; }

/* ── dictionary ─────────────────────────────────────────────────────────────── */

.dict-langs { display: flex; flex-wrap: wrap; gap: 0.45rem; list-style: none; margin: 0 0 1.5rem; padding: 0; }
.dict-lang {
  display: inline-block;
  padding: 0.3rem 0.75rem;
  border: 1px solid rgba(0, 0, 0, 0.16);
  border-radius: 2rem;
  font-size: 0.85rem;
  text-decoration: none;
  color: inherit;
}
.dict-lang span { opacity: 0.5; margin-left: 0.3rem; font-variant-numeric: tabular-nums; }
.dict-lang--on { background: #1d1d1f; color: #fff; border-color: #1d1d1f; }

.dict-search { display: block; margin: 0 0 1.6rem; }
.dict-search__label { display: block; margin-bottom: 0.4rem; font-size: 0.85rem; opacity: 0.65; }
.dict-search__input {
  width: 100%;
  padding: 0.75rem 1rem;
  font: inherit;
  font-size: 1.1rem;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 0.5rem;
  background: #fff;
}

.dict-results { list-style: none; margin: 0 0 2rem; padding: 0; }
.dict-entry { padding: 0.9rem 0; border-bottom: 1px solid rgba(0, 0, 0, 0.07); }
.dict-entry__head { margin: 0 0 0.3rem; display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; }
.dict-entry__word { font-size: 1.25rem; }
.dict-entry__reading { opacity: 0.6; font-size: 0.9rem; }
.dict-entry__pos { font-size: 0.78rem; opacity: 0.5; }
.dict-entry__def { margin: 0; }
.dict-entry__more { margin: 0.3rem 0 0; font-size: 0.88rem; opacity: 0.72; }
.dict-none { opacity: 0.6; padding: 0.9rem 0; }
.dict-note { font-size: 0.85rem; opacity: 0.62; }

/* ───────────────────────────────────────────────────────────────────────────────
   THE PLATFORM SURFACES
   Added when the library stopped being a catalogue behind a paywall and became the
   only place this project exists: Apple terminated the developer account on
   2026-10-24 and Play is blocked, so every visitor arrives knowing nothing. These
   are the pieces that have to introduce it — the language grid, the free/paid
   split, the end of a preview, and where you got to.

   Tokens only, from the site's own palette (warm paper, ink, amber accent). A
   subsite with its own colours looks like a different company.
   ─────────────────────────────────────────────────────────────────────────────── */

.lib-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 1.5rem 0 0;
}
.lib-hero__terms {
  margin: 1.25rem 0 0;
  font-size: 0.92rem;
  opacity: 0.75;
}

/* ── the numbers that matter, and only those ─────────────────────────────────── */

.lib-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 1.75rem 2.5rem;
  margin: 2rem 0 0;
  padding: 0;
  list-style: none;
}
.lib-stat { display: flex; flex-direction: column; line-height: 1.2; }
.lib-stat strong {
  font-family: var(--font-heading, inherit);
  font-size: 1.9rem;
  font-weight: var(--weight-medium, 500);
}
.lib-stat span { font-size: 0.82rem; letter-spacing: 0.04em; opacity: 0.65; }

/* ── section headings ────────────────────────────────────────────────────────── */

.lib-section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1rem;
  margin-bottom: 1.25rem;
}
.lib-section__title {
  margin: 0 0 1.25rem;
  font-family: var(--font-heading, inherit);
  font-size: 1.5rem;
}
.lib-section__head .lib-section__title { margin-bottom: 0; }
.lib-section__note { margin: 0; font-size: 0.9rem; opacity: 0.65; }

/* ── where you got to ────────────────────────────────────────────────────────── */

.resume-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.resume-grid--list { grid-template-columns: 1fr; }
.resume__link {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  height: 100%;
  padding: 1rem 1.1rem;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 0.6rem;
  background: var(--color-white, #fff);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.resume__link:hover,
.resume__link:focus-visible {
  border-color: var(--color-accent, #c8962f);
  transform: translateY(-2px);
}
.resume__kind {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.6;
}
.resume__title { font-size: 1.05rem; line-height: 1.3; }
/* The bar is the only decoration here that carries information, so it is the only
   thing with the accent colour on this card. */
.resume__bar {
  height: 4px;
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.1);
  overflow: hidden;
}
.resume__fill {
  display: block;
  height: 100%;
  background: var(--color-accent, #c8962f);
}
.resume__meta { font-size: 0.82rem; opacity: 0.7; font-variant-numeric: tabular-nums; }

/* ── how it works ────────────────────────────────────────────────────────────── */

.howto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}
.howto__step { display: flex; flex-direction: column; gap: 0.5rem; }
.howto__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--color-ink, #15151b);
  color: var(--color-paper, #f8f4ea);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}
.howto__title { margin: 0; font-family: var(--font-heading, inherit); font-size: 1.12rem; }
.howto__body { margin: 0; font-size: 0.93rem; line-height: 1.6; opacity: 0.8; }

/* ── the languages: the platform's unit ──────────────────────────────────────── */

.lang-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr));
  gap: 0.9rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.lang__link {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  height: 100%;
  padding: 1rem 1.1rem 1.1rem;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 0.6rem;
  background: var(--color-white, #fff);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.lang__link:hover,
.lang__link:focus-visible {
  border-color: var(--color-accent, #c8962f);
  transform: translateY(-2px);
}
.lang__code {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
}
.lang__name { margin: 0; font-family: var(--font-heading, inherit); font-size: 1.15rem; }
.lang__holdings { margin: 0; font-size: 0.84rem; opacity: 0.7; line-height: 1.45; }
.lang__tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.5rem; }

.tag {
  display: inline-block;
  padding: 0.14rem 0.5rem;
  border-radius: 1rem;
  background: rgba(0, 0, 0, 0.06);
  font-size: 0.7rem;
  letter-spacing: 0.03em;
}
/* A course is the thing worth paying for and the thing a learner is looking for, so
   it is the one tag that carries the accent. */
.tag--course { background: var(--color-accent, #c8962f); color: #fff; }
.tag--free { background: rgba(0, 0, 0, 0.06); }
.is-free { color: var(--color-accent-hover, #ac7d1f); }

/* ── what is free and what is not ────────────────────────────────────────────── */

.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1.25rem;
}
.split--tight { margin-top: 3rem; }
.split__side {
  padding: 1.5rem 1.6rem;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 0.7rem;
  background: var(--color-white, #fff);
}
.split__side--paid { border-color: var(--color-accent, #c8962f); }
.split__title { margin: 0 0 0.9rem; font-family: var(--font-heading, inherit); font-size: 1.15rem; }
.ticks { margin: 0; padding: 0; list-style: none; }
.ticks li {
  position: relative;
  padding-left: 1.4rem;
  margin-bottom: 0.5rem;
  font-size: 0.93rem;
  line-height: 1.55;
}
.ticks li::before {
  content: "✓";
  position: absolute;
  left: 0;
  opacity: 0.55;
}
.ticks--paid li::before { color: var(--color-accent, #c8962f); opacity: 1; }
.split__note { margin: 1rem 0 0; font-size: 0.86rem; opacity: 0.7; line-height: 1.55; }
.split__cta { margin: 1.25rem 0 0; }

/* ── a nudge, where it is relevant rather than everywhere ────────────────────── */

.promo {
  padding: 1.75rem 1.8rem;
  border: 1px solid var(--color-accent, #c8962f);
  border-radius: 0.7rem;
  background: var(--color-white, #fff);
}
.promo__title { margin: 0 0 0.5rem; font-family: var(--font-heading, inherit); font-size: 1.25rem; }
.promo__body { margin: 0 0 1.1rem; font-size: 0.95rem; line-height: 1.6; opacity: 0.82; }

/* ── the boundary, stated once ───────────────────────────────────────────────── */

.chapter-gate {
  margin: 1.25rem 0;
  padding: 1.4rem 1.5rem;
  border: 1px dashed var(--color-accent, #c8962f);
  border-radius: 0.7rem;
  background: rgba(200, 150, 47, 0.07);
}
.chapter-gate__title {
  margin: 0 0 0.4rem;
  font-family: var(--font-heading, inherit);
  font-size: 1.1rem;
}
.chapter-gate__body { margin: 0 0 1rem; font-size: 0.92rem; line-height: 1.6; opacity: 0.85; }

.chapter-list__body { display: flex; flex-direction: column; gap: 0.1rem; flex: 1; }
/* Dimmed, not hidden: a locked row still tells a reader what the course covers, and
   that is most of what persuades them it is worth having. */
.chapter-list__item--locked { opacity: 0.6; }
.chapter-list__flag {
  flex-shrink: 0;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent-hover, #ac7d1f);
}

/* ── the end of a preview, inside the reader ──────────────────────────────────── */

.preview-end {
  margin-top: 2.5rem;
  padding: 1.75rem 1.8rem;
  border: 1px solid var(--color-accent, #c8962f);
  border-radius: 0.7rem;
  background: rgba(200, 150, 47, 0.07);
}
.preview-end__eyebrow {
  margin: 0 0 0.3rem;
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.6;
}
.preview-end__title { margin: 0 0 0.6rem; font-family: var(--font-heading, inherit); font-size: 1.3rem; }
.preview-end__body { margin: 0 0 1.2rem; font-size: 0.95rem; line-height: 1.6; opacity: 0.85; }
.preview-end__actions { display: flex; flex-wrap: wrap; gap: 0.7rem; margin: 0; }
.preview-end__note { margin: 1rem 0 0; font-size: 0.86rem; opacity: 0.7; }

.account-heading {
  margin: 2.5rem 0 1rem;
  font-family: var(--font-heading, inherit);
  font-size: 1.25rem;
}

/* ── the reading surface must wrap, whatever the script ─────────────────────────
   Chinese, Japanese, Cantonese and Thai are written WITHOUT spaces, so a line of
   them is one long word as far as a browser is concerned and runs straight off the
   right edge. The same thing happened to spaced languages while the renderer was
   dropping its separators. `anywhere` rather than `break-word` because the latter
   only breaks when a word cannot fit a line ON ITS OWN, which a 300-character
   unspaced sentence technically can on a wide screen.                           */
.reader-page__source,
.reader-page__translation {
  overflow-wrap: anywhere;
}
/* …but a span is the tap target, so breaking INSIDE one would split a word across
   two lines and give it two hit areas. Words break between, never within. */
.reader-word {
  overflow-wrap: normal;
  word-break: keep-all;
}

/* ── BUTTONS, WHICH THIS SITE HAS NEVER ACTUALLY HAD ───────────────────────────
   `class="button button--primary"` appears 22 times across the theme and is
   defined nowhere — not in main.css, not in any .scss. Every call to action in
   the library has therefore rendered as a plain blue-ish text link, including
   "Pick a language" on the front page and "Choose Monthly" on the pricing page.
   Found by screenshotting the pages rather than by any check, because to HTTP
   and to the DOM an unstyled link is a perfectly good link.

   Defined here rather than in the theme because a grep says every use is in a
   library template: this fixes all of them and changes nothing else.           */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.62rem 1.25rem;
  border: 1px solid transparent;
  border-radius: 0.4rem;
  font-family: var(--font-heading, inherit);
  font-size: 0.95rem;
  font-weight: var(--weight-medium, 500);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.button:active { transform: translateY(1px); }
.button:focus-visible {
  outline: 2px solid var(--color-accent, #c8962f);
  outline-offset: 2px;
}

.button--primary {
  background: var(--color-accent, #c8962f);
  border-color: var(--color-accent, #c8962f);
  color: #fff;
}
.button--primary:hover {
  background: var(--color-accent-hover, #ac7d1f);
  border-color: var(--color-accent-hover, #ac7d1f);
  color: #fff;
}

/* A ghost button is an outline, so it has to know what it is sitting ON.
   `color: inherit` was the first attempt and it rendered "Look a word up"
   INVISIBLE on the hero: the link was in the markup, the button was the right
   size, and it inherited a colour close enough to the dark background to vanish.
   A screenshot was the only thing that could have shown that — the page was
   correct to curl, to the DOM and to every check.

   So the default is for a light surface, and the dark hero states its own. */
.button--ghost {
  background: transparent;
  border-color: rgba(0, 0, 0, 0.28);
  color: var(--color-grey-800, #232220);
}
.button--ghost:hover {
  border-color: var(--color-ink, #15151b);
  background: rgba(0, 0, 0, 0.05);
  color: var(--color-ink, #15151b);
}

.lib-hero .button--ghost {
  border-color: rgba(248, 244, 234, 0.45);
  color: var(--color-paper, #f8f4ea);
}
.lib-hero .button--ghost:hover {
  border-color: var(--color-paper, #f8f4ea);
  background: rgba(248, 244, 234, 0.12);
  color: var(--color-paper, #f8f4ea);
}

/* ── the hero was eating the whole screen ──────────────────────────────────────
   The headline alone filled the viewport, so the four numbers and both calls to
   action were below the fold on a laptop — a front page whose entire job is to
   say what this is and let someone start. Tightened here rather than in the
   theme's `.hero--compact`, which other sections use. */
.hero.lib-hero .hero__title {
  font-size: clamp(2rem, 4.2vw, 3.4rem);
  line-height: 1.08;
  margin-bottom: 0.75rem;
}
.hero.lib-hero .hero__subtitle { max-width: 46ch; margin-left: auto; margin-right: auto; }
.lib-hero .lib-stats { justify-content: center; }
.lib-hero .lib-hero__actions { justify-content: center; }

/* ── EVERY CUSTOM ELEMENT ON THE DARK HERO NEEDS ITS OWN COLOUR ────────────────
   Three separate things were rendered invisible on it before this was traced to
   one cause: the ghost button, the terms line ("The first 3 chapters are free…")
   and the four statistics. All three were present in the markup, correctly sized
   and positioned, and coloured close enough to the near-black hero to vanish.

   The theme's own hero classes (hero__title, hero__subtitle, hero__eyebrow) each
   set a colour, so they were fine; every class added here did not, and inherited
   one meant for a light page. Declared explicitly, once, for all of them —
   inheritance across a light/dark boundary is the bug, not the individual values.

   Nothing but a screenshot could have found any of it. The pages were correct to
   curl, correct in the DOM, and passed all 38 checks.                          */

.lib-hero,
.lib-hero .hero__inner { color: var(--color-paper, #f8f4ea); }
.lib-hero .lib-hero__terms { color: rgba(248, 244, 234, 0.72); }
.lib-hero .lib-stat strong { color: var(--color-paper, #f8f4ea); }
.lib-hero .lib-stat span { color: rgba(248, 244, 234, 0.6); }
.lib-hero .hero__eyebrow a { color: inherit; }

/* ── and the hero must not eat the screen ──────────────────────────────────────
   On a title page it was a name and a button filling the whole viewport, with
   the terms line and all 24 chapters below the fold — on the page whose job is
   to show someone what a course contains. */
.hero.lib-hero .hero__inner { padding-top: 2.5rem; padding-bottom: 2.5rem; }
.lib-hero .lib-hero__actions { margin-top: 1.25rem; }
.lib-hero .lib-stats { margin-top: 1.5rem; }

/* The theme's `.hero` reserves `min-height: min(78vh, 720px)`, which is right for a
   marketing splash and wrong for every page here: a title page's hero is a name, a
   button and one line saying what is free, and that was reserving three quarters of
   the screen to say it — pushing all 24 chapters, the thing the page exists to show,
   below the fold. Overridden only for the library's own heroes; `.hero--compact`
   keeps its padding. */
.hero.lib-hero { min-height: 0; }
/* `.hero.lib-hero`, not `.lib-hero`. Both are one class, so they have EQUAL
   specificity and the winner is whichever stylesheet loads last — which is not
   something this file gets to decide. Written the short way it lost silently, and
   the only symptom was a hero that stayed exactly as tall as before. */

/* ───────────────────────────────────────────────────────────────────────────────
   THE PORTAL
   The front page stopped being a landing page. It was a full screen of hero, then
   three paragraphs about how reading works, then — two screens down — the 36
   languages, which are the only thing on the page anyone came to use. Right for a
   product nobody has heard of; wrong for the place its readers return to daily,
   and this site is now both.

   So the hero is a BAR, not a splash: the same words, one screen-sixth of the
   height, with the numbers and the two actions on the same line.
   ─────────────────────────────────────────────────────────────────────────────── */

.portal-bar {
  background: var(--gradient-hero, var(--color-ink, #15151b));
  color: var(--color-paper, #f8f4ea);
  padding: 1.6rem 0;
}
.portal-bar__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
}
.portal-bar__say { flex: 1 1 18rem; min-width: 0; }
.portal-bar__title {
  margin: 0;
  font-family: var(--font-heading, inherit);
  font-size: clamp(1.25rem, 2.1vw, 1.6rem);
  line-height: 1.15;
  color: var(--color-paper, #f8f4ea);
}
.portal-bar__lede {
  margin: 0.25rem 0 0;
  font-size: 0.9rem;
  color: rgba(248, 244, 234, 0.7);
}
.portal-bar__actions { display: flex; gap: 0.5rem; margin: 0; flex-wrap: wrap; }

/* The numbers, inline. They were a row of four large figures that pushed everything
   else below the fold; here they are a fact about the bar they sit in. */
.portal-stats {
  display: flex;
  gap: 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.portal-stats li { display: flex; flex-direction: column; line-height: 1.1; }
.portal-stats strong {
  font-family: var(--font-heading, inherit);
  font-size: 1.3rem;
  color: var(--color-paper, #f8f4ea);
}
.portal-stats span {
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: rgba(248, 244, 234, 0.55);
}
.portal-bar .button--ghost {
  border-color: rgba(248, 244, 234, 0.4);
  color: var(--color-paper, #f8f4ea);
  padding: 0.45rem 0.9rem;
  font-size: 0.88rem;
}
.portal-bar .button--ghost:hover {
  border-color: var(--color-paper, #f8f4ea);
  background: rgba(248, 244, 234, 0.12);
  color: var(--color-paper, #f8f4ea);
}
.portal-bar .button--primary { padding: 0.45rem 0.9rem; font-size: 0.88rem; }

/* ── sections, tightened ─────────────────────────────────────────────────────── */

/* `.section.portal-section`, not `.portal-section`. The theme's `.section` sets
   `padding: 4.5rem 0` and both are a single class, so specificity ties and the
   winner is load order — which this file does not control. Written the short way it
   lost, and the symptom was 72px of empty beige between the bar and the first
   heading on the portal. This is the second override in this file to be bitten by
   exactly that; `.hero.lib-hero` was the first. */
.section.portal-section { padding-top: 2.25rem; padding-bottom: 2.25rem; }
.portal-h {
  margin: 0 0 1rem;
  font-family: var(--font-heading, inherit);
  font-size: 1.3rem;
}
.portal-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin-bottom: 1.1rem;
}
.portal-head .portal-h { margin-bottom: 0; }

/* ── the filter ──────────────────────────────────────────────────────────────── */

/* Hidden until portal.js reveals it: a control that does nothing is worse than no
   control, and without the script this page is still the whole catalogue. */
.lang-filter { display: flex; align-items: center; gap: 0.5rem; }
.lang-filter__label {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.6;
}
.lang-filter__input {
  width: 15rem;
  max-width: 100%;
  padding: 0.45rem 0.7rem;
  border: 1px solid rgba(0, 0, 0, 0.18);
  border-radius: 0.4rem;
  background: var(--color-white, #fff);
  font: inherit;
  font-size: 0.92rem;
  color: inherit;
}
.lang-filter__input:focus-visible {
  outline: 2px solid var(--color-accent, #c8962f);
  outline-offset: 1px;
}
.lang-filter__none { margin: 1rem 0 0; opacity: 0.7; }

/* ── cards of an even height ─────────────────────────────────────────────────── */

/* The rows were ragged: a language with one tag sat shorter than its neighbours and
   the grid looked broken rather than sparse. */
.lang-grid { align-items: stretch; }
.lang { display: flex; }
.lang__link { flex: 1; }
.lang__tags { margin-top: auto; padding-top: 0.5rem; }

/* ── the explaining, underneath ──────────────────────────────────────────────── */

.portal-explain {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 2.5rem;
  align-items: start;
}
.howto--compact { gap: 1rem; grid-template-columns: 1fr; }
.howto--compact .howto__step { flex-direction: row; gap: 0.85rem; align-items: flex-start; }
.howto--compact .howto__num { flex: 0 0 auto; width: 1.6rem; height: 1.6rem; font-size: 0.8rem; }
.howto--compact .howto__title { font-size: 1rem; margin-bottom: 0.15rem; }
.howto--compact .howto__body { font-size: 0.89rem; }

.portal-price {
  padding: 1.25rem 1.4rem;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 0.6rem;
  background: var(--color-white, #fff);
}
.portal-price p { margin: 0 0 0.8rem; font-size: 0.9rem; line-height: 1.55; }
.portal-price__paid { padding-top: 0.8rem; border-top: 1px solid rgba(0, 0, 0, 0.08); }

@media (max-width: 760px) {
  .portal-explain { grid-template-columns: 1fr; gap: 1.75rem; }
  .portal-bar__inner { flex-direction: column; align-items: flex-start; }
  /* `flex: 1 1 18rem` is a WIDTH basis in a row and a HEIGHT basis in a column, and
     this container becomes a column here — so the heading block claimed 288px of
     height and the bar opened a band of empty black between the sentence and the
     numbers. Reset rather than restated: in a column it should be its own height. */
  .portal-bar__say { flex: 0 0 auto; }
  .portal-stats { gap: 1.1rem; }
  .lang-filter__input { width: 100%; }
  .lang-filter { width: 100%; }
}

/* ── THERE IS NO DARK MODE HERE, AND THAT IS NOW DELIBERATE ────────────────────
   This file used to carry six `prefers-color-scheme: dark` blocks. Every one of
   them darkened a SURFACE — card backgrounds, inputs, quiz options, deck faces —
   and not one of them set a text colour.

   The theme has no dark mode at all: `main.css` contains zero
   `prefers-color-scheme` rules, so with a dark system the page background stays
   warm paper and the body text stays dark ink. The blocks therefore turned every
   card into a near-black box, on a white page, with black text on it. The
   language grid was 36 unreadable rectangles.

   Four of those blocks were here before this work and two were added by copying
   the convention, which is how a pre-existing bug got propagated into the new
   pages rather than noticed.

   A partial dark mode is strictly worse than none: it changes half the surfaces
   and leaves the colours that have to contrast with them alone. If this site ever
   wants dark mode it belongs in the theme, where the page, the header, the footer
   and the body text live — and then this file can follow it. Until then, nothing
   here responds to the colour scheme.                                          */

/* ── the reader's controls ──────────────────────────────────────────────────── */

.reader-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1.5rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}
.reader-ctl {
  padding: 0.35rem 0.8rem;
  border: 1px solid rgba(0, 0, 0, 0.22);
  border-radius: 1rem;
  background: transparent;
  font: inherit;
  font-size: 0.84rem;
  color: inherit;
  cursor: pointer;
}
/* Pressed is a filled pill, not a tint: these are toggles whose state has to be
   readable at a glance from across the page, mid-sentence. */
.reader-ctl[aria-pressed="true"] {
  background: var(--color-ink, #15151b);
  border-color: var(--color-ink, #15151b);
  color: var(--color-paper, #f8f4ea);
}

/* ── romanisation under each word ───────────────────────────────────────────── */

/* Only while the toggle is on, and only on words that have one. `inline-block` so
   the pseudo-element can sit on its own line under the word; the baseline is kept
   by `vertical-align: top` or the line would ride up around every annotated word. */
.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-size: 0.62em;
  line-height: 1.3;
  letter-spacing: 0.01em;
  opacity: 0.6;
}

/* ── hiding the English ─────────────────────────────────────────────────────── */

/* Blurred rather than removed: the shape of the sentence stays, so a reader can see
   there IS a translation and how long it is, which is the difference between a tool
   that covers an answer and a page that looks broken. */
.reader-pages--blur .reader-page__translation {
  filter: blur(5px);
  cursor: pointer;
  transition: filter 0.15s ease;
  user-select: none;
}
.reader-pages--blur .reader-page__translation:hover { filter: blur(3px); }
.reader-pages--blur .reader-page__translation--shown {
  filter: none;
  cursor: auto;
  user-select: auto;
}

/* ── the coming-soon page, and the previewer's banner ───────────────────────── */

.soon-page {
  padding: 5rem 0 6rem;
  background: var(--gradient-hero, var(--color-ink, #15151b));
  color: var(--color-paper, #f8f4ea);
  min-height: 70vh;
}
.soon-page__eyebrow {
  margin: 0 0 0.6rem;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent, #c8962f);
}
.soon-page__title {
  margin: 0 0 1rem;
  font-family: var(--font-heading, inherit);
  font-size: clamp(2.2rem, 6vw, 3.4rem);
  line-height: 1.05;
  color: var(--color-paper, #f8f4ea);
}
.soon-page__lede {
  margin: 0 0 1.75rem;
  max-width: 44ch;
  font-size: 1.05rem;
  line-height: 1.6;
  color: rgba(248, 244, 234, 0.78);
}
.soon-page__list { margin: 0 0 1.75rem; padding: 0; list-style: none; }
.soon-page__list li {
  position: relative;
  padding-left: 1.3rem;
  margin-bottom: 0.5rem;
  color: rgba(248, 244, 234, 0.78);
}
.soon-page__list li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--color-accent, #c8962f);
}
.soon-page__note { margin: 0 0 2rem; font-size: 0.9rem; color: rgba(248, 244, 234, 0.55); }
.soon-page__links { display: flex; flex-wrap: wrap; gap: 1.25rem; margin: 0; }
.soon-page__links a { color: var(--color-accent, #c8962f); }

/* 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(--color-accent, #c8962f);
  color: #fff;
  font-size: 0.85rem;
}
.preview-banner code {
  padding: 0.05rem 0.3rem;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.18);
}

/* ── the subscribe page's coming-soon panel ─────────────────────────────────── */

.soon {
  padding: 1.5rem 1.6rem;
  border: 1px solid var(--color-accent, #c8962f);
  border-radius: 0.7rem;
  background: rgba(200, 150, 47, 0.07);
}
.soon__lead { margin: 0 0 0.9rem; font-size: 1.02rem; }
.soon__what { margin: 0 0 1.2rem; opacity: 0.8; }

/* ───────────────────────────────────────────────────────────────────────────────
   A LANGUAGE HUB
   It was three identical grids of identical cards, so the course — the one thing
   that teaches this language in a sequence — looked exactly like the fiftieth folk
   tale. Weight is the whole fix: the course is a panel, the words are tiles, the
   stories are a quiet grid. A learner asking "where do I start" gets an answer
   from the layout before reading a word of it.
   ─────────────────────────────────────────────────────────────────────────────── */

.hero.lang-hero .hero__inner { padding-top: 2rem; padding-bottom: 2rem; }

/* ── the course ─────────────────────────────────────────────────────────────── */

.course-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 2rem;
  padding: 1.75rem 1.9rem;
  border: 1px solid var(--color-accent, #c8962f);
  border-radius: 0.8rem;
  background: var(--color-white, #fff);
}
.course-panel__kind {
  display: inline-block;
  margin-bottom: 0.5rem;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent-hover, #ac7d1f);
}
.course-panel__title {
  margin: 0 0 0.3rem;
  font-family: var(--font-heading, inherit);
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  line-height: 1.15;
}
.course-panel__sub { margin: 0 0 0.75rem; opacity: 0.75; }
.course-panel__terms { margin: 0 0 1.25rem; font-size: 0.93rem; line-height: 1.55; }
.course-panel__actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin: 0; }

/* The free chapters, named. "Chapter 1, 2, 3" says nothing about a course; the
   scenes say what taking one is like, which is the only honest advertisement. */
.course-peek { margin: 0; padding: 0; list-style: none; }
.course-peek__link {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.6rem 0.7rem;
  border-radius: 0.45rem;
  color: inherit;
  text-decoration: none;
}
.course-peek__link:hover { background: rgba(200, 150, 47, 0.1); }
.course-peek__num {
  min-width: 1.4rem;
  font-variant-numeric: tabular-nums;
  opacity: 0.45;
}
.course-peek__body { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.course-peek__name { font-size: 0.97rem; }
.course-peek__focus { font-size: 0.8rem; opacity: 0.6; }
.course-peek__free {
  flex-shrink: 0;
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent-hover, #ac7d1f);
}

/* ── the words ──────────────────────────────────────────────────────────────── */

.word-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1rem;
}
.word-tile {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1.1rem 1.2rem;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 0.6rem;
  background: var(--color-white, #fff);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.word-tile:hover { border-color: var(--color-accent, #c8962f); transform: translateY(-2px); }
.word-tile__kind {
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.55;
}
.word-tile__title { font-family: var(--font-heading, inherit); font-size: 1.1rem; }
.word-tile__meta { font-size: 0.84rem; opacity: 0.72; }

/* ── the stories ────────────────────────────────────────────────────────────── */

/* Deliberately quieter than the course panel. There are up to twenty-five of them
   and they are the thing you do once you have some grammar, not the thing to start
   with — so they read as a shelf, not as twenty-five competing offers. */
.story-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.story { display: flex; }
.story__link {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 0.2rem;
  padding: 0.9rem 1rem;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 0.5rem;
  background: var(--color-white, #fff);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease;
}
.story__link:hover { border-color: rgba(0, 0, 0, 0.35); }
.story__title { margin: 0; font-size: 0.98rem; line-height: 1.3; font-weight: 500; }
.story__sub { margin: 0; font-size: 0.82rem; opacity: 0.65; }
.story__meta { margin-top: auto; padding-top: 0.4rem; font-size: 0.78rem; opacity: 0.55; }

@media (max-width: 760px) {
  .course-panel { grid-template-columns: 1fr; gap: 1.25rem; padding: 1.25rem 1.3rem; }
}
