/* ── Font (self-hosted, NFR-2) ─────────────────────────────── */
@font-face { font-family: 'Roboto'; src: url('/fonts/roboto-latin-400-normal.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Roboto'; src: url('/fonts/roboto-latin-700-normal.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'Roboto'; src: url('/fonts/roboto-latin-900-normal.woff2') format('woff2'); font-weight: 900; font-style: normal; font-display: swap; }

/* ── Tokens (spec §4.4) ─────────────────────────────────────── */
:root {
  --color-accent: #ea5a0b;
  --color-accent-dark: #c94c08;
  --color-sand: #e0ded8;
  --color-ink: #1a1a1a;
  --color-muted: #5f5b55;
  --color-placeholder: #9a9a9a;
  --color-white: #ffffff;

  --font-base: 'Roboto', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;

  --content-width: 1060px;
  --gutter: 24px;
  --header-height: 80px;
  /* Height of the home hero; layout.css reuses it for the header's scroll animation. */
  --home-hero-height: clamp(480px, 100svh, 800px);

  --shadow-card: 0 4px 14px rgba(0, 0, 0, 0.18);
  --transition: 0.2s ease;
}

/* ── Reset ──────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* Always show the vertical scrollbar so the centred content - and with it the menu -
   sits in the same place on pages that scroll and pages that do not. scrollbar-gutter
   would leave an empty white strip beside the full-width orange bars, and Safari does
   not support it. Browsers with overlay scrollbars (Safari, mobile) reserve no space
   and never shifted to begin with. */
html { font-size: 16px; -webkit-text-size-adjust: 100%; overflow-y: scroll; }
/* Column layout so the footer sits at the bottom of the viewport on short pages. */
body { font-family: var(--font-base); font-size: 16px; line-height: 28px; color: var(--color-ink); background: var(--color-white); display: flex; flex-direction: column; min-height: 100svh; }
/* No rubber-band overscroll or pull-to-refresh: it fights the scroll corrections of zoom-font.js. */
html, body {
    overscroll-behavior: none;
}
body > main { flex: 1 0 auto; }
/* ZoomFont (zoom-font.js): a pinch sets the user's font scale instead of zooming
   the page. touch-action blocks the native pinch zoom; panning stays. The preference
   scales paragraphs, and all text inside an element with .zoom-font (opt-in, e.g. the
   project facts): zoom keeps each element's own sizes and line heights in proportion, and
   an auto-width block still fills its container, so the text reflows instead of widening
   the page. Zoom multiplies with an ancestor's, so nested ones stay at 1. */
html { touch-action: pan-x pan-y; }
p, .zoom-font { zoom: var(--zoom-font-scale, 1); overflow-wrap: break-word; }
.zoom-font p, .zoom-font .zoom-font { zoom: 1; }
/* Opt-out: the text in a .no-zoom-font element (the project hero) keeps its designed size. */
.no-zoom-font p { zoom: 1; }
/* Small and normal sized labels, headings and buttons follow the font scale too: section titles, buttons, the project
   filter, news card labels, dates and titles, the slider counter and headings in article text. The hero title,
   the header menu and the text on the project cards (which sit on a photo of fixed size) do not. Inside a
   scaled paragraph or .zoom-font container they stay at 1. Keep this list in sync with SCALED_TEXT in zoom-font.js. */
.section-title, .button, .project-filter__toggle, .project-filter__legend, .filter-chip span, .news-card__label, .news-card__date, .news-card__title, .slider-counter, .prose h2 { zoom: var(--zoom-font-scale, 1); }
.zoom-font :is(.section-title, .button, .project-filter__toggle, .project-filter__legend, .filter-chip span, .news-card__label, .news-card__date, .news-card__title, .slider-counter, .prose h2), p :is(.section-title, .button, .project-filter__toggle, .project-filter__legend, .filter-chip span, .news-card__label, .news-card__date, .news-card__title, .slider-counter, .prose h2) { zoom: 1; }

/* Photos (not logos, cards or icons) carry .pinch-zoom: a pinch lifts a copy onto this
   overlay, on top of the page, where it zooms and pans over the whole screen. The heroes do not
   carry it: the home hero is a .zoom-font container that follows the font scale as a whole, the project hero opts out
   of the font scale (.no-zoom-font). The overlay takes all
   touches while open, so the page underneath does not scroll; the copy itself is inert. */
.pinch-zoom-overlay { position: fixed; inset: 0; z-index: 40; touch-action: none; background-color: rgba(0, 0, 0, 0); }
.pinch-zoom-overlay > * { position: absolute; margin: 0; min-height: 0; max-width: none; transform-origin: 0 0; pointer-events: none; }
.pinch-zoom-overlay.is-settling, .pinch-zoom-overlay.is-settling > * { transition: transform 0.25s ease, background-color 0.25s ease; }

/* Text size controls: built by zoom-font.js, shown after a pinch on text, then fade out. */
.zoom-font-controls { position: fixed; z-index: 30; left: 50%; bottom: calc(16px + env(safe-area-inset-bottom)); transform: translateX(-50%); display: flex; align-items: center; gap: 4px; padding: 4px; background: rgba(26, 26, 26, 0.85); color: var(--color-white); font-size: 14px; line-height: 1; opacity: 0; visibility: hidden; transition: opacity 0.4s ease, visibility 0s linear 0.4s; }
.zoom-font-controls.is-visible { opacity: 1; visibility: visible; transition: opacity 0.2s ease; }
.zoom-font-controls button { width: 40px; height: 40px; border: 0; background: rgba(255, 255, 255, 0.15); color: inherit; font-size: 20px; cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.zoom-font-controls button:active { background: rgba(255, 255, 255, 0.35); }
.zoom-font-controls output { align-self: stretch; display: flex; align-items: center; justify-content: center; min-width: 52px; font-variant-numeric: tabular-nums; cursor: pointer; user-select: none; -webkit-user-select: none; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
@media (prefers-reduced-motion: reduce) {
  .zoom-font-controls, .zoom-font-controls.is-visible, .pinch-zoom-overlay.is-settling, .pinch-zoom-overlay.is-settling > * { transition: none; }
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; }
ul[class], ol[class] { list-style: none; }
[hidden] { display: none !important; }
:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 3px; }

/* ── Utilities ──────────────────────────────────────────────── */
.container { width: 100%; max-width: calc(var(--content-width) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* ── Section heading: lowercase text, 2px accent underline under the text ── */
.section-title { display: inline-block; font-size: 28px; font-weight: 700; line-height: 1.2; padding-bottom: 4px; border-bottom: 2px solid var(--color-accent); }

/* ── Buttons ────────────────────────────────────────────────── */
.button { user-select: none; display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: 0 20px; background: var(--color-accent); color: var(--color-white); font-size: 18px; font-weight: 700; line-height: 1.25; border: 0; cursor: pointer; transition: background var(--transition); }
.button:hover { background: var(--color-accent-dark); }
.icon-button { user-select: none; display: inline-grid; place-items: center; width: 32px; height: 32px; border: 1px solid var(--color-accent); background: var(--color-white); color: var(--color-accent); font-size: 14px; line-height: 1; cursor: pointer; transition: background var(--transition), color var(--transition); }
.icon-button:hover:not(:disabled) { background: var(--color-accent); color: var(--color-white); }
.icon-button:disabled { opacity: 0.35; cursor: default; }

/* ── Text pages ─────────────────────────────────────────────── */
.page { padding-block: 56px 80px; }
.page__header { margin-bottom: 40px; }
.prose { max-width: 70ch; }
.prose > * + * { margin-top: 1em; }
.prose h2 { font-size: 20px; font-weight: 700; line-height: 1.3; margin-top: 2em; }
.prose ul, .prose ol { padding-left: 1.25em; }
.prose a { color: var(--color-accent); text-decoration: underline; }

@media (max-width: 600px) {
  :root { --gutter: 16px; --header-height: 64px; }
  .section-title { font-size: 24px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

/* ── News article ───────────────────────────────────────────── */
.page__lead { margin-block: 16px 32px; }
.news-article__header { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin-bottom: 32px; }
.news-article__label { position: static; }
.news-article__title { max-width: 26ch; font-size: 32px; font-weight: 900; line-height: 1.2; color: var(--color-accent); }
.news-article__image { width: 100%; max-width: 720px; aspect-ratio: 1.4; object-fit: cover; margin-bottom: 32px; }
.news-article__source { margin-top: 24px; }
.news-article__source a { color: var(--color-accent); text-decoration: underline; }
.news-article__actions { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 40px; }
