/* ==========================================================================
   Meridian — Base styles & layout primitives
   Consumes semantic tokens only. Logical properties exclusively (spec A5):
   physical left/right properties are forbidden in this system.
   ========================================================================== */

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

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

body {
  background: var(--surface-primary);
  color: var(--text-primary);
  font-family: var(--font-body-latin);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

/* ------------------------------------------------------------------
   Typography — serif for display/h2 and pull-quotes only (spec A3);
   everything functional is the sans. Fraunces axes locked, binding.
   ------------------------------------------------------------------ */

h1, h2, .u-display-xl, .u-display {
  font-family: var(--font-display-latin);
  font-weight: 400;
  font-variation-settings: var(--display-axes);
  font-optical-sizing: none;
  text-wrap: balance;
}

h1, .u-display-xl { font-size: var(--text-display-xl); line-height: var(--leading-display-xl); }
.u-display { font-size: var(--text-display); line-height: var(--leading-display); }
h2 { font-size: var(--text-h2); line-height: var(--leading-h2); }

h3, h4 {
  font-family: var(--font-body-latin);
  font-weight: 600;
}
h3 { font-size: var(--text-h3); line-height: var(--leading-h3); }
h4 { font-size: var(--text-h4); line-height: var(--leading-h4); }

p { max-inline-size: 70ch; }
.u-body-lg { font-size: var(--text-body-lg); }
.u-small { font-size: var(--text-small); line-height: var(--leading-small); }
.u-caption {
  font-size: var(--text-caption);
  line-height: var(--leading-caption);
  font-weight: 500;
  letter-spacing: var(--tracking-caption);
}
.u-secondary { color: var(--text-secondary); }

/* Text lockup — interim logo per IMPLEMENTATION_ASSETS.md §A:
   display serif, tracked +4%, offwhite-on-charcoal or charcoal-on-offwhite only. */
.lockup {
  font-family: var(--font-display-latin);
  font-variation-settings: var(--display-axes);
  font-optical-sizing: none;
  font-weight: 400;
  letter-spacing: var(--tracking-lockup);
  text-transform: uppercase;
  color: var(--text-primary);
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

strong { font-weight: 600; }

:lang(ar) { letter-spacing: 0; font-style: normal; } /* no faux-slanted Arabic ever */

/* ------------------------------------------------------------------
   Focus — one semantic token; components may not restyle focus (A7).
   ------------------------------------------------------------------ */

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

/* ------------------------------------------------------------------
   Layout primitives (spec A5)
   ------------------------------------------------------------------ */

.container,
.container--content,
.container--wide {
  inline-size: 100%;
  max-inline-size: var(--container-standard);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--content { max-inline-size: var(--container-content); }
.container--wide { max-inline-size: var(--container-wide); }

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gutter);
}
@media (min-width: 768px) {
  .grid { grid-template-columns: repeat(12, 1fr); }
}

.stack > * + * { margin-block-start: var(--space-4); }
.stack--loose > * + * { margin-block-start: var(--space-8); }

/* Spacing utilities — the three most recurring inline margin-block-start
   values across the copy (paragraphs stacked under a heading). Token-only,
   no arbitrary values; replaces one-off style="margin-block-start:…"
   attributes so rhythm stays swappable from one place. */
.u-mt-4 { margin-block-start: var(--space-4); }
.u-mt-6 { margin-block-start: var(--space-6); }
.u-mt-8 { margin-block-start: var(--space-8); }
.u-mb-8 { margin-block-end: var(--space-8); }
.u-mb-12 { margin-block-end: var(--space-12); }

.visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Skip link — hidden until keyboard focus, then a real button above the header */
.skip-link {
  position: absolute;
  inset-block-start: var(--space-2);
  inset-inline-start: var(--space-2);
  z-index: 20;
  background: var(--surface-inverse);
  color: var(--text-inverse);
  padding: var(--space-3) var(--space-6);
  border-radius: 2px;
  font-size: var(--text-small);
  font-weight: 500;
  text-decoration: none;
  translate: 0 calc(-100% - var(--space-4));
}
.skip-link:focus-visible { translate: 0 0; }

/* ------------------------------------------------------------------
   Motion — restraint is the signature (spec A8). Global reduced-motion
   collapse; loading indicators are exempt (they're information).
   ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .is-loading::after {
    animation-duration: 800ms !important;   /* spinner remains — information */
    animation-iteration-count: infinite !important;
  }
}

/* Reveal-on-scroll (js/reveal.js) — section fade + rise, once, on entry.
   Opt-in only: [data-reveal] and .js-reveal are set by JS itself, and only
   after it has confirmed prefers-reduced-motion is off and
   IntersectionObserver exists. With no JS, an old browser, or reduced
   motion, neither is ever present — sections render exactly as authored,
   fully visible, nothing to undo. The prefers-reduced-motion block above
   is a second, redundant guard (collapses any transition to 0.01ms) in
   case a user's preference changes between page loads without a reload. */
.js-reveal [data-reveal] {
  opacity: 1;
  translate: 0 8px;
  transition: translate var(--duration-large) var(--ease-enter);
}
.js-reveal [data-reveal].is-revealed {
  opacity: 1;
  translate: 0 0;
}

/* Staggered child reveal — grid/gallery/list items enter in reading order
   once their section reveals, so motion *guides the eye down the page*
   rather than decorating it. reveal.js tags the children of the first
   stagger group in each section and sets --reveal-index in source order;
   the delay is capped (index clamped in JS) so a long list never exceeds
   ~0.5s total and the band still reads as calm. Same reduced-motion +
   no-JS guarantees as the section reveal above: without .js-reveal these
   selectors never match and every item is fully visible as authored. */
.js-reveal [data-reveal-child] {
  opacity: 1;
  transform: translateY(10px);
  transition: transform var(--duration-large) var(--ease-enter);
  transition-delay: calc(var(--reveal-index, 0) * 55ms);
}
.js-reveal [data-reveal].is-revealed [data-reveal-child] {
  opacity: 1;
  transform: translateY(0);
}
/* Entrance uses `transform`; interaction (card lift) uses `translate` — two
   independent properties, so a card that is BOTH a reveal-child and hover-
   liftable stacks the two instead of one overriding the other. */

/* Blueprint draw-in (BRAND_GUIDE §25 — process animation, not decoration).
   The delivery diagram assembles itself in flow order: nodes appear in place
   (fade + micro-scale, no vertical rise — a process step doesn't "fall in"),
   connector lines draw from their start edge (scaleX, RTL-correct via logical
   transform-origin). Reuses the Track-1 --reveal-index so the sequence reads
   left→right. No-JS / reduced-motion: .js-reveal is never added and the global
   collapse applies, so the diagram is simply fully drawn and static. */
.js-reveal .blueprint__flow > [data-reveal-child] { transform: none; }
.js-reveal .blueprint__flow > .blueprint__node { transform: scale(0.96); }
.js-reveal [data-reveal].is-revealed .blueprint__flow > .blueprint__node { transform: scale(1); }
.js-reveal .blueprint__flow .blueprint__line {
  transform: scaleX(0);
  transform-origin: inline-start;
  transition: transform var(--duration-standard) var(--ease-enter);
  transition-delay: calc(var(--reveal-index, 0) * 55ms);
}
.js-reveal [data-reveal].is-revealed .blueprint__flow .blueprint__line { transform: scaleX(1); }
