/* ==========================================================================
   Base: reset, typography defaults, layout primitives
   ========================================================================== */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-weight: var(--weight-medium);
  font-synthesis: none; /* never fake bold/italic on the single-weight serif */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.main { flex: 1; overflow-x: clip; } /* trims full-bleed sliders' 100vw by the scrollbar width */

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

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

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

ul[class], ol[class] { list-style: none; padding: 0; }

h1, h2, h3, h4, h5, h6 { font-weight: inherit; font-size: inherit; }

/* Keyboard focus: a dotted accent outline that follows the element's shape
   (pill, rounded image, text link). main.js adds the hover label under it.
   Text links in the header and footer have no corners of their own: an
   invisible pill radius gives their outline round ends, like the buttons'. */
:focus-visible {
  outline: 2px dotted var(--color-accent);
  outline-offset: 4px;
}
:is(.site-header, .site-footer) a:not(.button) { border-radius: var(--radius-pill); }

::selection { background: var(--color-accent); color: var(--color-on-accent); }

/* Layout primitives ------------------------------------------------------ */

/* Page width without the scrollbar (main.js keeps it current; 100vw until
   then), for blocks that break out of the content column */
:root { --page-w: 100vw; }

.container {
  width: 100%;
  max-width: calc(var(--width-wide) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}
/* Full width: the header and footer on every page, and the home templates.
   Case-study content keeps its reading layout inside that frame. */
.site-header,
.site-footer,
:is(.template-home, .template-home-stepped, .template-home-masthead) .main {
  --gutter: var(--gutter-full);
  --width-wide: var(--width-full);
}

.container--content { max-width: calc(var(--width-content) + 2 * var(--gutter)); }
.container--text    { max-width: calc(var(--width-text) + 2 * var(--gutter)); }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -100px;
  z-index: 10;
  padding: var(--space-2) var(--space-4);
  background: var(--color-primary);
  color: var(--color-inverse);
  border-radius: var(--radius-pill);
}
.skip-link:focus { top: var(--space-4); }

/* Text styles ------------------------------------------------------------ */

.prose > * + * { margin-top: 0; }
.prose--spaced > * + *,

/* Long-form prose: larger size, looser leading, near-black.
   `--color-text-muted` stays for labels and captions — it isn't a body colour. */
.reading {
  font-size: var(--text-reading);
  line-height: var(--leading-reading);
  color: var(--color-text-body);
}
/* Paragraph rhythm — one line of leading. Without this, multi-paragraph
   blocks render as one undifferentiated slab. */
.reading p + p,
.reading > * + * { margin-top: var(--space-paragraph); }
.prose a { text-decoration: underline; text-underline-offset: 0.15em; }
.prose a:hover { color: var(--color-text); }
.prose strong, .prose b { font-weight: var(--weight-semibold); color: var(--color-text); }
.prose ul, .prose ol { padding-left: 1.5em; }
.prose--muted { color: var(--color-text-muted); }

.caption {
  margin-top: var(--space-3);
  font-size: var(--text-caption);
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* Shared: disclosure reveals (home intro, project switcher) */
@keyframes fade-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* Scroll motion (see assets/js/motion.js) ---------------------------------
   Hide animated elements until GSAP reveals them, to avoid a flash.
   Only applies when <html> has the `motion` class. */

.motion :is(
  .intro__text, .project-hero__title-text, .project-hero__subtitle, .project-facts,
  .chapter__label, .chapter__title, .chapter__meta, .chapter__index,
  .block--heading h1, .block--heading h2, .quote__text, .metric__value, .media-text__heading,
  .project-row__title,
  .intro__portrait, .intro__actions, .project-nav, .work__heading, .next-project__label,
  .project-row__chevron, .project-row__aside, .project-row__thumb,
  .statement__text, .intro .availability, .recap,
  .masthead__name, .masthead__statement,
  .project-live, .block--text, .block--list, .block--h3, .block--h4, .block--h5, .block--h6,
  .caption, .media-text__body .prose,
  .project .media .picture, .project .fullwidth .picture, .project .media-text__media .picture,
  .about-lead, .principle__title, .clients--main, .about-prose, .about-label, .principle__num,
  .principle__text, .client-group__label, .clients--list, .timeline li, .about-languages, .about-portrait .picture
) {
  visibility: hidden;
}

/* Blueprint (assets/js/blueprint.js): parts are traced on one canvas over
   the page, then appear through a 4px dot grid whose dots grow until they
   merge. The mask is removed once they have. Lite tier: a short flicker. */
@property --dot { syntax: "<length>"; inherits: false; initial-value: 0px; }
.bp-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 800; /* under the hover label and the page transition */
  pointer-events: none;
}
.bp-dots {
  -webkit-mask: radial-gradient(circle, #000 var(--dot), transparent calc(var(--dot) + 0.5px)) 0 0 / 4px 4px;
          mask: radial-gradient(circle, #000 var(--dot), transparent calc(var(--dot) + 0.5px)) 0 0 / 4px 4px;
}
.bp-dots.is-on { --dot: 3px; transition: --dot 0.6s cubic-bezier(0.5, 0, 0.75, 0); }
.bp-dots--fast.is-on { transition-duration: 0.45s; } /* reading text */
.bp-flicker { animation: bp-flicker 0.32s steps(1, end); }
@keyframes bp-flicker {
  0%  { opacity: 0.55; }
  20% { opacity: 0.1; }
  40% { opacity: 0.85; }
  60% { opacity: 0.35; }
  80% { opacity: 1; }
}

/* Lenis smooth scroll (full motion tier only) — from lenis/dist/lenis.css */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-smooth iframe { pointer-events: none; }
