/* ==========================================================================
   BASE — reset, document defaults, typography primitives, motion primitives
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--t-body);
  font-weight: 300;
  line-height: var(--lh-body);
  letter-spacing: var(--tr-normal);
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

input,
textarea {
  font: inherit;
  color: inherit;
}

:lang(zh) {
  font-family: var(--font-cn);
  font-weight: 200;
}

/* ------------------------------------------------------------- LANGUAGE
   Both languages ship in the document. The switch reveals one and hides
   the other — no reload, no second page, no loss of markup. */

html[data-lang="en"] [data-lang="zh"],
html[data-lang="zh"] [data-lang="en"] {
  display: none !important;
}

/* Chinese sets differently: a serif with no negative tracking, looser
   leading, and no balance heuristics designed for Latin word spacing. */
html[data-lang="zh"] .t-display,
html[data-lang="zh"] .t-h1,
html[data-lang="zh"] .t-h2,
html[data-lang="zh"] .t-h3,
html[data-lang="zh"] .quote {
  font-family: var(--font-cn-display);
  font-weight: 400;
  letter-spacing: 0.02em;
  text-wrap: initial;
  /* ch is measured on a Latin glyph, so the Latin measure strands Chinese
     lines a few characters short. em gives a true count: fifteen per line. */
  max-width: 15em;
}

html[data-lang="zh"] .t-display { line-height: 1.15; font-size: clamp(2.5rem, 7vw, 6rem); }
html[data-lang="zh"] .t-h1      { line-height: 1.25; }
html[data-lang="zh"] .t-h2      { line-height: 1.3; }
html[data-lang="zh"] .t-h3      { line-height: 1.5; }

html[data-lang="zh"] .t-body,
html[data-lang="zh"] .t-lead,
html[data-lang="zh"] .prose p {
  line-height: 1.95;
  letter-spacing: 0.01em;
}

html[data-lang="zh"] .t-label {
  letter-spacing: 0.3em;
}

/* ------------------------------------------------------------- TYPOGRAPHY */

.t-display,
.t-h1,
.t-h2,
.t-h3 {
  font-family: var(--font-display);
  font-weight: 400;
  margin: 0;
  text-wrap: balance;
}

.t-display {
  font-size: var(--t-display);
  line-height: var(--lh-display);
  letter-spacing: var(--tr-display);
}

.t-h1 {
  font-size: var(--t-h1);
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-display);
}

.t-h2 {
  font-size: var(--t-h2);
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-tight);
}

.t-h3 {
  font-size: var(--t-h3);
  line-height: var(--lh-snug);
  letter-spacing: var(--tr-tight);
}

.t-lead {
  font-size: var(--t-lead);
  line-height: 1.55;
  font-weight: 300;
  color: var(--fg-muted);
  margin: 0;
}

.t-body {
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--fg-muted);
  margin: 0;
}

.t-caption {
  font-size: var(--t-caption);
  line-height: 1.5;
  color: var(--fg-faint);
  margin: 0;
}

/* The one recurring editorial device: a small tracked-out label */
.t-label {
  display: block;
  margin: 0;
  font-size: var(--t-label);
  font-weight: 500;
  line-height: 1;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--fg-faint);
}

/* Label accents. Which one a chapter wears is not decorative: cool belongs to
   ice and meltwater, warm to sun and harvest, clay to earth and wall. */
.t-label--accent { color: var(--accent); }
.t-label--cool   { color: var(--accent-cool); }
.t-label--warm   { color: var(--accent-warm); }
.t-label--clay   { color: var(--accent-clay); }

.t-cn {
  font-family: var(--font-cn);
  font-weight: 200;
  letter-spacing: 0.18em;
  color: var(--fg-faint);
}

.t-measure {
  max-width: var(--measure);
}

.t-measure-narrow {
  max-width: var(--measure-narrow);
}

/* Body copy inside prose blocks */
.prose > * + * {
  margin-top: var(--s-5);
}

.prose p {
  margin: 0;
  max-width: var(--measure);
  color: var(--fg-muted);
}

/* ------------------------------------------------------------------ LINKS */

a {
  color: inherit;
  text-decoration: none;
}

.link {
  display: inline-block;
  position: relative;
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--fg);
  padding-bottom: var(--s-2);
}

.link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  opacity: 0.35;
  transform-origin: left;
  transition: opacity var(--d-base) var(--ease);
}

.link:hover::after {
  opacity: 1;
}

.link--accent {
  color: var(--accent);
}

/* ------------------------------------------------------------------ LAYOUT */

.container {
  width: var(--container);
  margin-inline: auto;
}

.container-narrow {
  width: var(--container-narrow);
  margin-inline: auto;
}

.section {
  padding-block: var(--section-y);
}

.section--tall {
  padding-block: var(--section-y-tall);
}

.section--flush-top {
  padding-top: 0;
}

/* ------------------------------------------------------------ ACCESSIBILITY */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: -100%;
  left: var(--s-4);
  z-index: 9999;
  padding: var(--s-3) var(--s-5);
  font-size: var(--t-caption);
  background: var(--c-paper);
  color: var(--c-ink);
}

.skip-link:focus-visible {
  top: var(--s-4);
}

:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 4px;
}

/* --------------------------------------------------------------- MOTION
   Every reveal in the site uses these two primitives and nothing else. */

[data-reveal] {
  will-change: opacity, transform;
}

[data-reveal="fade"] {
  opacity: 0;
  transform: translateY(1.5rem);
  transition:
    opacity var(--d-reveal) var(--ease),
    transform var(--d-reveal) var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

/* The clip goes on the photograph, never on the figure the observer is
   watching. Clipping the observed element to zero height makes
   IntersectionObserver report it as not intersecting, so it is never told to
   open — and it can only open by being told. The reveal deadlocks and the
   image never appears at all. */
[data-reveal="mask"] {
  overflow: hidden;
}

[data-reveal="mask"] > img {
  clip-path: inset(0 0 100% 0);
  transform: scale(1.08);
  transition:
    clip-path var(--d-reveal) var(--ease),
    transform calc(var(--d-reveal) * 1.4) var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

[data-reveal="mask"].is-revealed > img {
  clip-path: inset(0 0 0 0);
  transform: scale(1);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }

  [data-reveal="mask"] > img {
    clip-path: none !important;
    transform: none !important;
  }
}
