/* ==========================================================================
   SiteMura.ph — Base: reset, elements, layout primitives
   Layout primitives handle spacing via gap. Avoid per-element margins.
   ========================================================================== */

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

/* The `hidden` attribute is only a user-agent style, so ANY class rule that
   sets display beats it — .btn is inline-flex, .field__error is flex, and both
   stayed visible when hidden. Without this, hiding by attribute silently fails
   on exactly the elements that use it most. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--s-5));
}

body {
  margin: 0;
  background: var(--ground);           /* explicit — never inherit a ground */
  color: var(--ink-body);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Proper apostrophes and quotes without hand-typing entities. */
  font-kerning: normal;
  font-variant-ligatures: common-ligatures contextual;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 700;
  line-height: var(--leading-tight);
  text-wrap: balance;
  /* Bricolage is variable — let it pick the optical size for the point size. */
  font-optical-sizing: auto;
}

/* Tracking is optical, not fixed: large type needs tightening, small type needs
   room. A single letter-spacing across the scale is what makes headings look
   set by default rather than drawn. */
h1 { font-size: var(--step-5); letter-spacing: -0.028em; }
h2 { font-size: var(--step-4); letter-spacing: -0.022em; }
h3 { font-size: var(--step-3); letter-spacing: -0.016em; }
h4 { font-size: var(--step-2); letter-spacing: -0.011em; }
h5 { font-size: var(--step-1); letter-spacing: -0.006em; }

p, ul, ol, dl, figure, table, blockquote { margin: 0; }
p { max-width: var(--measure); text-wrap: pretty; }

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
  transition: text-decoration-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
a:hover { color: var(--accent-hover); text-decoration-color: currentColor; }

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

ul, ol { padding-left: 1.25em; }
li { margin-block: 0.15em; }

strong, b { font-weight: 600; color: var(--ink); }

hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin-block: var(--s-6);
}

code, kbd, samp { font-family: var(--font-mono); font-size: 0.9em; }

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

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

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

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--s-5);
}

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

/* Vertical rhythm between page bands. One selector owns section padding so
   nothing downstream fights it. Modifiers only ever change the tokens used. */
.band { padding-block: var(--s-8); }
.band--tight { padding-block: var(--s-7); }
.band--loose { padding-block: var(--s-9); }
.band--invert { background: var(--surface-invert); color: var(--ink-invert); }
.band--invert h1, .band--invert h2,
.band--invert h3, .band--invert h4 { color: var(--ink-invert); }

/* A .card or .callout keeps its own LIGHT surface inside an inverted band, so
   it has to re-assert its text colours. Without this it inherits --ink-invert
   and paints near-white text on a near-white card — invisible. The element
   selectors above are what force the extra specificity here; keep both in sync
   if either changes. */
.band--invert .card,
.band--invert .callout { color: var(--ink-body); }
.band--invert .card h1, .band--invert .card h2,
.band--invert .card h3, .band--invert .card h4,
.band--invert .callout h1, .band--invert .callout h2,
.band--invert .callout h3, .band--invert .callout h4 { color: var(--ink); }
.band--sunken { background: var(--surface-sunken); }
.band--surface { background: var(--surface); }
.band + .band--surface,
.band--surface + .band { border-top: 1px solid var(--line); }

/* Stack: vertical flow with a single gap. */
.stack { display: flex; flex-direction: column; gap: var(--s-4); }
.stack--xs { gap: var(--s-2); }
.stack--sm { gap: var(--s-3); }
.stack--lg { gap: var(--s-6); }
.stack--xl { gap: var(--s-7); }

/* Cluster: horizontal, wrapping. */
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }
.cluster--sm { gap: var(--s-2); }
.cluster--lg { gap: var(--s-5); }

/* Auto-fitting grid. --min sets the smallest comfortable column. */
.grid {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(var(--min, 260px), 100%), 1fr));
}
.grid--2 { --min: 380px; }
.grid--3 { --min: 300px; }
.grid--4 { --min: 220px; }

/* Two-column split that collapses on small screens. */
.split {
  display: grid;
  gap: var(--s-7);
  align-items: center;
}
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; }
  .split--wide-first { grid-template-columns: 1.15fr 0.85fr; }
  .split--wide-last  { grid-template-columns: 0.85fr 1.15fr; }
}

/* Anything that could overflow horizontally scrolls inside itself. */
.scroll-x {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

/* --- Utilities ------------------------------------------------------------ */

.lead { font-size: var(--step-2); line-height: var(--leading-snug); color: var(--ink-body); }
.muted { color: var(--ink-muted); }
.small { font-size: var(--step--1); }
.center { text-align: center; }
.center p, .center .lead { margin-inline: auto; }
.nowrap { white-space: nowrap; }
.tnum { font-variant-numeric: tabular-nums; }

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.band--invert .eyebrow { color: var(--ink-invert-muted); }

.visually-hidden {
  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: absolute;
  top: var(--s-2); left: var(--s-2);
  z-index: 200;
  padding: var(--s-2) var(--s-4);
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
}
.skip-link:focus { transform: translateY(0); }

/* --- Motion --------------------------------------------------------------- */

/* Page-load entrance. Ordered by --i on each element so the hero arrives as one
   composition rather than six things appearing at once. */
.enter {
  animation: enter-up 640ms var(--ease) both;
  animation-delay: calc(var(--i, 0) * 85ms);
}
@keyframes enter-up {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

/* Scroll reveal. Hidden only when JS is running — .js is set by the inline
   head script, so a visitor without JS gets the content, not a blank page. */
.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
}
.js .reveal.is-visible { opacity: 1; transform: none; }

/* Children arrive in sequence rather than as a block. */
.js .reveal--stagger.is-visible > * {
  animation: enter-up 620ms var(--ease) both;
}
.js .reveal--stagger.is-visible > *:nth-child(1) { animation-delay:  60ms; }
.js .reveal--stagger.is-visible > *:nth-child(2) { animation-delay: 140ms; }
.js .reveal--stagger.is-visible > *:nth-child(3) { animation-delay: 220ms; }
.js .reveal--stagger.is-visible > *:nth-child(4) { animation-delay: 300ms; }
.js .reveal--stagger.is-visible > *:nth-child(5) { animation-delay: 380ms; }
.js .reveal--stagger.is-visible > *:nth-child(6) { animation-delay: 460ms; }

/* The price briefly lifts when the currency switch swaps it, so the change is
   felt rather than just noticed. */
.money.is-swapping { animation: money-swap 340ms var(--ease); }
@keyframes money-swap {
  0%   { opacity: 1; transform: none; }
  40%  { opacity: 0; transform: translateY(-6px); }
  41%  { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: none; }
}

@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;
  }
  /* Collapsing durations lands `both`-filled animations on their FIRST keyframe
     when delayed — which for these is opacity 0. Force the end state. */
  .js .reveal, .enter, .js .reveal--stagger.is-visible > * {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
}
