/* ==========================================================================
   base.css — reset + structural primitives, driven entirely by design tokens.
   The theme file (theme-editorial.css) supplies the token values (palette,
   fonts). This file and components.css are theme-agnostic and consume them.

   Token contract expected from the theme:
     Fonts   --font-body --font-display --tracking-display
     Type    --fs-base --fs-sm --fs-lg --fs-h1 --fs-h2 --fs-h3 --lh
     Ground  --page --surface --band --tint
     Text    --ink --body --muted --line
     Brand   --navy --navy-soft --accent --accent-ink --accent-hover
     Hero    --hero-bg --hero-ink --hero-sub --hero-eyebrow --skyline
     Footer  --footer-bg --footer-ink --footer-hover
     System  --maxw --gap --radius --space --shadow --shadow-lift --ease
   ========================================================================== */

/* Shared system tokens (theme-agnostic). Theme files override palette + fonts. */
:root {
  --maxw: 1160px;
  --gap: clamp(1rem, 0.6rem + 1.6vw, 2rem);
  --radius: 10px;
  --radius-lg: 16px;
  --space: clamp(2.75rem, 1.6rem + 3.4vw, 5rem);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
  --shadow: 0 10px 34px rgba(16, 24, 40, 0.10);
  --shadow-lift: 0 18px 48px rgba(16, 24, 40, 0.16);
  --line-strong: var(--line);

  --fs-base: 1rem;
  --fs-sm: 0.875rem;
  --fs-lg: 1.15rem;
  --fs-h1: clamp(1.85rem, 1.3rem + 2.2vw, 2.7rem);
  --fs-h2: clamp(1.35rem, 1.05rem + 1.3vw, 1.85rem);
  --fs-h3: 1.18rem;
  --fs-hero: clamp(2.3rem, 1.5rem + 3.4vw, 3.9rem);
  --lh: 1.72;
  --tracking-display: normal;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh);
  color: var(--body);
  background: var(--page);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--navy);
  line-height: 1.28;
  letter-spacing: var(--tracking-display);
  text-wrap: balance;
  margin: 0 0 0.5em;
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); margin-top: 0; }
h3 { font-size: var(--fs-h3); }
p { margin: 0 0 1em; text-wrap: pretty; }

a { color: var(--navy); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--accent); }

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

/* Editable fields honour manual line breaks: a newline stored in the content
   (added freely in the visual editor) renders as a line break, while ordinary
   wrapping is unchanged. */
[data-e] { white-space: pre-line; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

/* --- Layout primitives --- */
.container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gap); }
.section { padding-block: var(--space); }
.section-alt { background: var(--band); }

.lead {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  line-height: 1.7;
  color: var(--ink);
  /* Measure in `em`, not `ch`: `ch` is the width of a Latin "0", so a ch-based
     cap yields only ~half as many CJK characters per line and wraps Japanese/
     Chinese into cramped, ragged lines. `em` tracks the full-width glyph, giving
     a comfortable ~30 CJK / ~60 Latin characters across all three languages. */
  max-width: 32em;
  font-weight: 400;
}
.note { font-size: var(--fs-sm); color: var(--muted); }
/* A quiet secondary line set in the display serif — used for scope/aside notes
   that sit beneath a lead paragraph without competing with it. */
.aside-note {
  font-family: var(--font-display);
  color: var(--navy-soft);
  max-width: 56ch;
  margin-top: 1.2rem;
  font-size: 0.98rem;
  line-height: 1.65;
}
.prose { max-width: 66ch; }
/* When .prose IS the container (privacy, legal), the 66ch cap shrinks the
   centred box itself: `margin-inline: auto` then parks the whole text column in
   the middle of the page while the <h1> above it stays at the container's left
   edge. Keep the box at the normal container width and cap the measure on the
   children instead, so the copy runs flush left under the heading. */
.container.prose { max-width: var(--maxw); }
.container.prose > * { max-width: 66ch; }
.prose h2 { margin-top: 1.8em; }
.prose h3 { margin-top: 1.6em; }

/* --- Editorial primitives ------------------------------------------------ */
/* Brass eyebrow: a short label with a leading rule. Deliberately NOT the
   tracked-caps kicker stamped over every section — used sparingly, as voice. */
.eyebrow {
  display: flex; align-items: center; gap: 0.75rem;
  font-family: var(--font-body);
  font-size: var(--fs-sm); font-weight: 600;
  letter-spacing: 0.04em; color: var(--accent-strong);
  margin: 0 0 1rem;
}
.eyebrow::before {
  content: ""; width: 1.9rem; height: 1px; flex: 0 0 auto;
  background: var(--accent);
}

/* A section heading with the brass hairline flourish beneath it. */
.section-title { max-width: 24ch; }

/* Photographic frame — the standard way an image sits in the page. */
.frame {
  margin: 0; border-radius: var(--radius-lg); overflow: hidden;
  background: var(--band); box-shadow: var(--shadow);
  border: 1px solid var(--line);
}
.frame img { display: block; width: 100%; height: auto; }
.frame figcaption {
  padding: 0.7rem 1rem; font-size: var(--fs-sm); color: var(--muted);
  background: var(--surface); border-top: 1px solid var(--line);
}

/* Media split: prose beside a photograph, alternating sides without a grid
   framework. Collapses to a single column on narrow viewports. */
.media-split {
  display: grid; gap: clamp(1.5rem, 1rem + 3vw, 3.75rem);
  align-items: center; grid-template-columns: 1fr;
}
@media (min-width: 820px) {
  .media-split { grid-template-columns: 1.05fr 0.95fr; }
  .media-split.is-reversed .media-split-text { order: 2; }
  .media-split.is-reversed .media-split-media { order: 1; }
}
/* Aspect-ratio on the image itself gives it a definite height derived from its
   own width — no dependency on the grid track, so it always renders. */
.media-split-media .frame img { aspect-ratio: 4 / 5; object-fit: cover; }
@media (min-width: 820px) {
  .media-split-media .frame img { aspect-ratio: 5 / 6; }
}

/* Accessibility: skip link */
.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--navy); color: #fff; padding: 0.6em 1em; z-index: 100;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* Accessibility: text for assistive tech only (e.g. the "opens in a new tab"
   cue that the ↗ glyph carries visually). Not display:none — that would hide
   it from screen readers too. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* ==========================================================================
   Cross-document page transitions (View Transitions API).
   Pure CSS, no JS — the browser cross-fades navigations on supporting engines
   and simply hard-navigates elsewhere. Fully disabled under reduced-motion.
   ========================================================================== */
@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.42s;
  animation-timing-function: var(--ease);
}
::view-transition-old(root) { animation-name: vt-fade-out; }
::view-transition-new(root) { animation-name: vt-fade-in; }

@keyframes vt-fade-out { to { opacity: 0; transform: translateY(-6px); } }
@keyframes vt-fade-in { from { opacity: 0; transform: translateY(10px); } }

/* The sticky header should not slide with the page during a transition. */
.site-header { view-transition-name: site-header; }
::view-transition-group(site-header) { animation-duration: 0.28s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}
