/* Lock horizontal overflow using `overflow-x: clip` — critically
   DIFFERENT from `overflow-x: hidden`:
   - `hidden` turns the element into a scroll container, which on iOS
     Safari breaks `position: sticky` descendants AND has been observed
     to prevent vertical scroll entirely on some pages.
   - `clip` clips overflow WITHOUT creating a scroll container, so it
     is transparent to sticky / scroll behavior.
   Apply to both <html> and <body> so neither can host horizontal scroll.
   Supported in all evergreen browsers since 2022. */

html {
  overflow-x: clip;
}

body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-regular);
  line-height: var(--leading-normal);
  color: var(--color-text);
  background-color: var(--color-bg);
  /* Ambient atmosphere — the SOLE source of "lit room" depth on the
     site. Three soft radial glows anchored to the viewport via
     background-attachment: fixed, so they stay in place as you scroll
     and the cream pages slide under them. Default `.section` elements
     are transparent and let this backdrop show through unbroken —
     so the ambient flows continuously, with no section-boundary seams.
     Sections that want a clean opaque elevated panel use `--alt`
     (cream-0) and intentionally cover the ambient.
       · Lavender top-left (cool, anchor)
       · Slate centre-right (cool, anchor — adds mid-page depth)
       · Mauve bottom-right (warm, anchor)
     All three are pure brand anchors at modest alpha. */
  background-image:
    radial-gradient(
      ellipse 80% 65% at 0% 0%,
      hsla(251, 13%, 82%, 0.55) 0%,
      hsla(251, 13%, 82%, 0) 60%
    ),
    radial-gradient(
      ellipse 50% 60% at 110% 50%,
      hsla(207, 27%, 58%, 0.22) 0%,
      hsla(207, 27%, 58%, 0) 60%
    ),
    radial-gradient(
      ellipse 70% 55% at 100% 100%,
      hsla(317, 11%, 43%, 0.22) 0%,
      hsla(317, 11%, 43%, 0) 65%
    );
  background-attachment: fixed;
  background-repeat: no-repeat;
  font-feature-settings: 'ss01', 'cv11';
  overflow-x: clip;
  /* overscroll-behavior on body kills pull-to-refresh / rubber-band
     without affecting the document scroller. */
  overscroll-behavior-y: none;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  /* Headings resolve to ink anchor (#32292f) per brand discipline.
     Use color: var(--color-heading-em) on individual elements that
     need the slate-accent treatment. */
  color: var(--color-heading);
}

h1 {
  font-size: var(--text-6xl);
  letter-spacing: var(--tracking-tightest);
  font-weight: var(--weight-medium);
}
h2 { font-size: var(--text-4xl); font-weight: var(--weight-medium); }
h3 { font-size: var(--text-2xl); font-weight: var(--weight-medium); }
h4 { font-size: var(--text-xl); }
h5 { font-size: var(--text-lg); }
h6 { font-size: var(--text-base); }

p {
  max-width: 62ch;
  /* Body paragraphs resolve to ink anchor. Use class .text-soft (or set
     color: var(--color-text-soft) inline) only for genuine secondary
     hierarchy (meta lines, captions) — NOT just because it "looks softer". */
  color: var(--color-text);
  line-height: var(--leading-relaxed);
}

em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
}

a {
  /* Anchor links resolve to slate anchor (#7698b1) per brand. */
  color: var(--color-primary);
  transition: color var(--duration-fast) var(--ease-default);
}
/* Hover = slate darkened 8% — functional derivative for hover state. */
a:hover { color: var(--color-primary-hover); }

/* Chinese-language blocks */
:lang(zh), .lang-zh {
  font-family: var(--font-body-zh);
}
:lang(zh) h1, :lang(zh) h2, :lang(zh) h3,
.lang-zh h1, .lang-zh h2, .lang-zh h3 {
  font-family: var(--font-display-zh);
  letter-spacing: 0;
}

/* Eyebrow labels — small uppercase kickers above headlines. Slate anchor
   gives them subtle brand differentiation from body text without using a
   derived shade. */
.eyebrow {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--color-heading-em);   /* anchor slate */
}

/* Variants — all resolve to anchors. */
.eyebrow--plum { color: var(--color-heading-em); }    /* slate anchor */
.eyebrow--jade { color: var(--color-heading-em); }    /* slate anchor (jade collapsed) */
.eyebrow--cream { color: var(--color-text-on-dark); } /* white — for dark surfaces */

/* Lead — editorial intro paragraph that sits right under a headline.
   Uses the display serif so it reads as a continuation of the headline
   rather than an abrupt switch into sans-serif body type. Carries its
   own top margin so it always breathes from the heading above it. */
.lead {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  line-height: var(--leading-snug);
  letter-spacing: -0.005em;
  /* Lead = continuation of headline. Stays on ink anchor for full brand
     weight; the larger size + display serif provides the hierarchy. */
  color: var(--color-text);
  max-width: 54ch;
  font-weight: var(--weight-regular);
  margin-top: var(--space-5);
}
/* Inside dark sections, lead reads in cream */
.section--dark .lead,
.section--deep .lead { color: hsla(0, 0%, 100%, 0.85); }

/* On dark surfaces — text resolves to white (permitted on ink/slate/mauve bg). */
.text-invert { color: var(--color-text-on-dark); }
.text-invert p { color: hsla(0, 0%, 100%, 0.78); }          /* white @ 78% — on dark */
.text-invert h1, .text-invert h2,
.text-invert h3, .text-invert h4 { color: var(--color-text-on-dark); }

/* ═══════════════════════════════════════════
   LANGUAGE TOGGLE — English-first by default
   The site ships with html[lang="en"]. All Chinese
   content is tagged with lang="zh" and hidden by
   the rule below. When the toggle is implemented,
   JS swaps html[lang] to "zh" and the second rule
   takes over (showing Chinese, hiding English).
   ═══════════════════════════════════════════ */
html[lang="en"] [lang="zh"] {
  display: none;
}
/* Inline CJK runs in headings/text — hide cleanly so adjacent English
   doesn't carry trailing whitespace from the hidden span. */
html[lang="en"] span[lang="zh"],
html[lang="en"] em[lang="zh"] {
  display: none;
}

/* Inverse rule for the future ZH mode (kept here so the toggle
   doesn't need to ship CSS). When html[lang="zh"], hide English-only
   markers. Author-marked English-only blocks should use lang="en"
   on the element (rare — most copy is implicit English). */
html[lang="zh"] [lang="en"] {
  display: none;
}

/* Selection handles on dark sections — lavender bg + ink text (anchors). */
.section--dark ::selection,
.section--deep ::selection {
  background: var(--color-accent);   /* anchor lavender */
  color: var(--color-text);          /* anchor ink */
}
