/* styles.css — old-school (late-90s / early-2000s) author site.
   Deliberately plain and basic: system serif, square corners, hairline rules,
   classic underlined links, content centered in a narrow column.
   Look-and-feel only; book content lives in books.js. */

/* ---------- Web fonts (self-hosted, subset) ----------
   EB Garamond carries the Latin text; LXGW WenKai GB (霞鹜文楷 GB) carries Chinese.
   Both are self-hosted from assets/fonts/, so the site still works fully offline
   (file://). The WenKai files are SUBSETS — only the characters the site uses —
   rebuilt by refresh-fonts.py whenever Chinese text changes (see CLAUDE.md).
   font-display: swap shows text immediately in a fallback, then swaps in the web
   font once it loads. */

@font-face {
  font-family: "EB Garamond";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/eb-garamond-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "EB Garamond";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/fonts/eb-garamond-latin-700-normal.woff2") format("woff2");
}
@font-face {
  font-family: "EB Garamond";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/eb-garamond-latin-400-italic.woff2") format("woff2");
}

/* EB Garamond — Latin Extended-A/B subset. Carries the accented Latin the base
   "latin" subset omits, including the pīnyīn macron vowels (ā ē ī ō ū ǖ …). The
   unicode-range scopes these faces to those characters, so the browser only
   fetches a latin-ext file when such a glyph actually appears (and, declared
   after the latin faces, wins for the overlapping range). Without this, pīnyīn
   fell through the font stack to a system CJK font and rendered mismatched. */
@font-face {
  font-family: "EB Garamond";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/eb-garamond-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1AB0-1AFF, U+1DC0-1DFF,
    U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "EB Garamond";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/fonts/eb-garamond-latin-ext-700-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1AB0-1AFF, U+1DC0-1DFF,
    U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "EB Garamond";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/eb-garamond-latin-ext-400-italic.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1AB0-1AFF, U+1DC0-1DFF,
    U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "LXGW WenKai GB";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/lxgwwenkaigb-400.subset.woff2") format("woff2");
}
@font-face {
  font-family: "LXGW WenKai GB";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/fonts/lxgwwenkaigb-700.subset.woff2") format("woff2");
}

:root {
  --bg: #f2e4ba;           /* 毛边纸 — maobian paper-yellow (original) */
  --ink: #1b1b1b;          /* near-black text */
  --muted: #555a5e;        /* secondary text */
  --line: #c9ccce;         /* hairline rules */
  --link: #0b3d91;         /* deep, austere blue */
  --link-visited: #551a8b; /* classic visited purple */

  --container: 42rem;      /* narrow, old-school column */
  /* EB Garamond sets the Latin text; Chinese falls through to LXGW WenKai GB,
     then to a system CJK serif if a glyph isn't in our subset; Georgia/Times are
     the Latin fallback if EB Garamond fails to load. */
  --serif: "EB Garamond", "LXGW WenKai GB", "Noto Serif CJK SC", "Songti SC",
           SimSun, Georgia, "Times New Roman", Times, serif;
}

* { box-sizing: border-box; }

/* The nav below bleeds to the full window width (negative margins). Clip the
   sub-pixel horizontal overflow that trick creates when a scrollbar is present,
   so it never produces a stray horizontal scrollbar. */
html { overflow-x: hidden; }

body {
  margin: 0 auto;
  max-width: var(--container);
  padding: 1.5rem clamp(1rem, 5vw, 2rem) 2.5rem;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.6;
}

/* ---------- Links (classic underlined) ---------- */

a {
  color: var(--link);
  text-decoration: underline;
}
a:visited { color: var(--link-visited); }
a:hover { color: var(--ink); }
a:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 2px;
}

/* ---------- Hairline rules ---------- */

.rule {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 1.25rem 0;
}

/* ---------- Navigation ---------- */

/* The nav is a single CENTRED row of items at its natural ("reasonable") width —
   not spread to the window edges. It still bleeds out of the narrow reading column
   (negative margins cancel the body's centring + padding) so a long row has the
   room to stay on one line, but the items are centred as a group rather than
   justified edge-to-edge. On narrow screens they wrap, and each wrapped row stays
   centred. Generous gaps divide the items, in place of the old "pipe" separators.
   The language switch is the one exception: on wide screens it's lifted out of the
   centred row and pinned to the far right (see .nav-lang), so the main items stay
   centred across the whole window while the switch sits at the right edge. */
.site-nav {
  position: relative;            /* anchors the far-right language switch */
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding: 0 clamp(1rem, 5vw, 2.5rem);
}

.nav-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0.4rem 1.5rem;
}

.nav-list a {
  text-decoration: none;
}
.nav-list a:hover {
  text-decoration: underline;
}

/* The current page's own nav entry: plain, muted text instead of a link, so
   "you are here" is clear and there's nothing to click back to itself. */
.nav-current {
  color: var(--muted);
}

/* The language switch is pulled out of the centred nav row and pinned to the far
   right of the full-bleed nav: the main items (in .nav-list) then centre across the
   whole window, while the switch sits at the right edge, aligned to the nav's own
   horizontal padding. Below 68rem — comfortably before the centred row could grow
   wide enough to reach it — it drops back into the flow and wraps, centred, with the
   rest of the nav (the layout the site shipped with). */
.nav-lang {
  position: absolute;
  top: 0;
  right: clamp(1rem, 5vw, 2.5rem);
}
@media (max-width: 68rem) {
  .nav-lang { position: static; }
}

/* Language switch — injected into the nav by lang.js. The two labels are fixed:
   "English" and "汉文" never translate or swap places; only which one is marked
   active changes. Styled to match the nav: link-blue when clickable, muted (like
   the current page) when active, the two labels joined by a single pipe. */
.lang-btn {
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  color: var(--link);
  text-decoration: none;
  cursor: pointer;
}
.lang-btn:hover { text-decoration: underline; }
.lang-btn:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 2px;
}
/* The active language reads as plain muted text, like the current-page entry. */
.lang-btn.is-active {
  color: var(--muted);
  cursor: default;
  text-decoration: none;
}
/* Pipe between the two language labels, keeping them a tight pair at the
   end of the nav row. */
.lang-btn + .lang-btn {
  border-left: 1px solid var(--muted);
  margin-left: 0.6em;
  padding-left: 0.6em;
}

/* English-only annotations (e.g. the link-page glosses with no Chinese
   counterpart) — shown in the English default, hidden when 汉文 is active so the
   Chinese reading stays clean. The mirror case would use [data-lang="en"]
   .zh-only, added only if/when it's ever needed. */
html[data-lang="zh"] .en-only { display: none; }

/* ---------- Masthead (home page only) ----------
   The welcome hero, used once on index.html. Inner pages deliberately do NOT
   repeat the studio name as a running header — they return home via the nav. */

.masthead {
  text-align: center;
  padding: clamp(2.5rem, 12vw, 6rem) 0;
}

.studio-name {
  font-weight: 700;
  font-size: clamp(2.2rem, 8vw, 3.6rem);
  line-height: 1.1;
  letter-spacing: 0.01em;
  margin: 0;
}

/* ---------- Footer ---------- */

.site-footer {
  text-align: center;
}

.footer-note {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
}

/* A little air between stacked footer lines (contact, copyright). */
.footer-note + .footer-note {
  margin-top: 0.35rem;
}

/* ---------- Publications ---------- */

.section-heading {
  text-align: center;
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0 0 1.25rem;
}

/* Quiet status label ("Coming soon"). */
.book-group-heading {
  font-style: italic;
  font-weight: 400;
  font-size: 1rem;
  color: var(--muted);
  margin: 1.75rem 0 0.75rem;
}
.book-group-heading:first-child {
  margin-top: 0;
}

.book-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.book {
  display: flex;
  gap: 1rem;
  margin: 0 0 1.5rem;
}

.book-cover {
  flex: 0 0 auto;
  width: 84px;
  height: auto;
  border: 1px solid var(--line); /* hairline frame, square corners */
}

.book-info {
  flex: 1 1 auto;
  min-width: 0; /* let long titles/blurbs wrap instead of overflowing the row */
}

.book-title {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0 0 0.25rem;
}

.book-blurb {
  margin: 0 0 0.4rem;
}

.book-links {
  margin: 0;
  font-size: 0.95rem;
}

/* Pipe separators between a book's links — same idiom as the top nav. */
.book-links a + a {
  border-left: 1px solid var(--muted);
  margin-left: 0.6em;
  padding-left: 0.6em;
}

.book-empty {
  color: var(--muted);
  font-style: italic;
}

/* Quiet fine-print notes under the catalog (the buying note, the returns
   policy) — not headlines. */
.policy-note {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
}

/* A little air between stacked notes, same idiom as the footer lines. */
.policy-note + .policy-note {
  margin-top: 0.6rem;
}

/* ---------- Announcements ---------- */

.news-item {
  margin: 0 0 1.5rem;
}

/* Quiet, italic dateline above each item's headline. */
.news-date {
  margin: 0 0 0.15rem;
  color: var(--muted);
  font-size: 0.85rem;
  font-style: italic;
}

.news-title {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0 0 0.3rem;
}

.news-body {
  margin: 0 0 0.4rem;
}

.news-links {
  margin: 0;
  font-size: 0.95rem;
}

/* Pipe separators between links — same idiom as the top nav and book links. */
.news-links a + a {
  border-left: 1px solid var(--muted);
  margin-left: 0.6em;
  padding-left: 0.6em;
}

/* ---------- Reading List ---------- */

/* Lead-in paragraph under a section heading (the Reading List preamble). */
.section-intro {
  margin: 0 0 1.25rem;
}

/* Contact line on the About page — the studio email + patience note, migrated off
   the footer. Normal body register (not footer fine-print), set off below the bio. */
.contact-line {
  margin: 1.25rem 0 0;
}

.reading-item {
  margin: 0 0 1.75rem;
}

.reading-title {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0 0 0.2rem;
}

/* Citation line under the title — quiet, like fine print. */
.reading-biblio {
  margin: 0 0 0.3rem;
  color: var(--muted);
  font-size: 0.95rem;
}

/* Genre line — quiet italic, same register as the "Coming soon" label. */
.reading-genres {
  margin: 0 0 0.4rem;
  color: var(--muted);
  font-size: 0.9rem;
  font-style: italic;
}

/* Mini-heading above the "Why read it" / "Caveats" notes. */
.reading-label {
  margin: 0.5rem 0 0.15rem;
  color: var(--muted);
  font-style: italic;
  font-size: 0.95rem;
}

/* A single note rendered as a paragraph (when there's only one). */
.reading-text {
  margin: 0 0 0.3rem;
}

/* Several notes rendered as a list. */
.reading-points {
  margin: 0 0 0.3rem;
  padding-left: 1.2rem;
}
.reading-points li {
  margin: 0 0 0.2rem;
}

/* ---------- Links ---------- */

/* An annotated link: a "kind" lead-in label, the link, then the operator's note(s). */
.link-entry {
  margin: 0 0 1.5rem;
}

.link-head {
  margin: 0 0 0.3rem;
}

/* Quiet lead-in before an annotated link ("Print-on-Demand (POD) Publisher:"). */
.link-kind {
  color: var(--muted);
}

.link-note {
  margin: 0 0 0.4rem;
  font-size: 0.95rem;
}

/* Italic lead-in for a note ("Note:", "Biases:", "Pros:"). */
.link-note-label {
  color: var(--muted);
  font-style: italic;
}

/* Numbered further-reading links. */
.link-list {
  margin: 0;
  padding-left: 1.4rem;
}
.link-list li {
  margin: 0 0 0.4rem;
}

/* ---------- Upcoming Projects ---------- */

/* A short, quiet list of forthcoming titles — same title register as the other
   sections (book / news / reading-list titles), just the titles, no apparatus. */
.upcoming-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.upcoming-item {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0 0 1rem;
}
.upcoming-item:last-child {
  margin-bottom: 0;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}
