/* ============================================================
   SCUBAzen — base: fonts, tokens, reset, primitives
   Register: brand. Two-palette identity guarded:
   Picton Blue = brand, teal meditating diver = mark.
   ============================================================ */

/* ---- Fonts (self-hosted, variable) ---- */
@font-face {
  font-family: "Quicksand";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../assets/fonts/quicksand-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2074,
    U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Mulish";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../assets/fonts/mulish-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2074,
    U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ---- Brand (Picton Blue family) ---- */
  --brand: oklch(0.72 0.11 232);        /* #50b2e9 — primary brand */
  --brand-deep: oklch(0.55 0.12 235);   /* #1c7fbf — text-on-light / hover */
  --brand-deeper: oklch(0.46 0.11 238); /* darker still, for text emphasis */
  /* Fill behind white text (the CTA pills). --brand-deep computes to 4.73:1
     against white — passing, but with 0.23 of margin, and the pills are the
     site's primary conversion so they should not sit that close to the line.
     A separate token because --brand-deep also serves as text-on-white and as
     a hover colour, where its lightness is right; only the fill role needs to
     go darker. 5.78:1 here. */
  --brand-fill: oklch(0.50 0.12 235);
  --zen: oklch(0.50 0.14 150);          /* wordmark green — sparing accent */

  /* ---- Neutrals (honest, faint cool tint toward brand) ---- */
  --bg: oklch(0.988 0.002 230);         /* #fcfcfc page bg */
  --surface: oklch(0.965 0.004 230);    /* raised panels */
  --ink: oklch(0.24 0.02 240);          /* primary text ~13:1 */
  --ink-soft: oklch(0.44 0.02 240);     /* secondary text >=4.6:1 */
  --line: oklch(0.90 0.004 230);        /* hairlines */

  /* ---- Deep water (immersive dark folds) ---- */
  --deep: oklch(0.28 0.05 245);         /* deep-ocean bg */
  --deep-2: oklch(0.20 0.045 248);      /* deeper, for gradients */
  --deep-ink: oklch(0.97 0.008 230);    /* off-white on deep */
  --deep-ink-soft: oklch(0.82 0.015 232);

  /* ---- Type ---- */
  --font-display: "Quicksand", ui-rounded, "Segoe UI", system-ui, sans-serif;
  --font-body: "Mulish", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Fluid type scale, ratio ~1.25, hero max <= 6rem */
  --step--1: clamp(0.83rem, 0.79rem + 0.18vw, 0.94rem);
  --step-0:  clamp(1rem, 0.95rem + 0.25vw, 1.15rem);
  --step-1:  clamp(1.2rem, 1.1rem + 0.5vw, 1.55rem);
  --step-2:  clamp(1.5rem, 1.32rem + 0.9vw, 2.15rem);
  --step-3:  clamp(1.9rem, 1.55rem + 1.7vw, 3rem);
  --step-4:  clamp(2.3rem, 1.7rem + 3vw, 4.2rem);
  --step-hero: clamp(2.7rem, 1.6rem + 5.4vw, 5.6rem);

  /* ---- Fluid spacing (breathes on large screens) ---- */
  --space-2xs: clamp(0.5rem, 0.45rem + 0.25vw, 0.75rem);
  --space-xs:  clamp(0.75rem, 0.68rem + 0.35vw, 1rem);
  --space-s:   clamp(1rem, 0.9rem + 0.5vw, 1.5rem);
  --space-m:   clamp(1.5rem, 1.3rem + 1vw, 2.5rem);
  --space-l:   clamp(2.5rem, 2rem + 2.5vw, 4.5rem);
  --space-xl:  clamp(4rem, 3rem + 5vw, 8rem);
  --space-2xl: clamp(6rem, 4.5rem + 7.5vw, 12rem);

  --measure: 65ch;
  --radius: 14px;
  --radius-lg: 22px;
  --shell: min(1200px, 92vw);
  --shell-narrow: min(760px, 90vw);

  /* ---- Motion ---- */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-calm: 900ms;
  --dur-slow: 1200ms;

  /* ---- Semantic z-index scale ---- */
  --z-base: 1;
  --z-raised: 10;
  --z-sticky: 100;
  --z-nav: 200;
  --z-overlay: 300;
}

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; }
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* The nav is fixed, so anchor jumps must stop below it or the section's
     first line lands underneath the bar. */
  scroll-padding-top: clamp(4.5rem, 9vh, 6rem);
}
body {
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img, picture, svg { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; border: none; background: none; }
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
p { text-wrap: pretty; }

:focus-visible {
  outline: 2.5px solid var(--brand-deep);
  outline-offset: 3px;
  border-radius: 4px;
}
::selection { background: color-mix(in oklch, var(--brand) 30%, transparent); }

/* ---- Touch targets ----
   WCAG 2.5.5 wants standalone controls to be at least 44x44px. Three separate
   components shipped under that (footer links at 20px, the legal contents rail
   at 33px, the nav CTA at 43.7px) because each was sized by its typography and
   nobody was enforcing a floor — three symptoms of one missing rule.

   There is deliberately no blanket `a { min-height: 44px }`: the rule does not
   apply to every link. WCAG exempts links inline in a sentence, and padding
   those would break the text flow of the legal pages and blog prose. The floor
   belongs to standalone CONTROLS — nav items, footer entries, the contents
   rail, buttons — which are styled per component anyway.

   So the shared thing is the VALUE, not a class. Components opt in with
   `min-height: var(--tap)`; the token means the number cannot drift between
   them, and grepping `var(--tap)` lists every control that has opted in.

   The floor is enforced for real by `node src/audit.mjs`, which measures
   rendered geometry on touch viewports — CSS cannot assert its own output. */
:root { --tap: 44px; }

/* ---- Light type over photography: the scrim invariant ----
   This is an image-led brand, so most headline type sits on a photograph. The
   photographs are not controlled by the stylesheet — a hero crop can be deep
   blue water or a sunlit pool, and swapping one for another changes legibility
   without touching a line of code. Two rules, both learned the hard way:

   1. EVERY light-on-photo text block sits over a scrim. There is no exception
      for "this image looks dark enough"; the blog heroes measured 1.5-4.0:1
      under exactly that assumption, and the nav shipped at 1.20:1.
   2. The scrim is sized to the TEXT AREA, not the section. A full-bleed wash
      flattens the photograph, which is the thing the brand is selling. A plume
      shaped to the text block keeps the bright water bright.

   Scrims are per-section (.hero__scrim, .post-hero__scrim, …) because each is
   shaped to its own composition — the shared part is the rule, not the gradient.
   Two mechanical details that caused real bugs:
     - Always run the gradient to `transparent 100%`. Stopping short
       (`transparent 88%`) leaves a hard edge that reads as a grey band.
     - Small type over photography does not get brand blue. Picton Blue is a
       light blue; measured on these crops it ran 1.5-4.0:1 and failed on all
       four. Off-white plus weight carries identity instead.

   Enforcement is `node src/audit.mjs`, which measures rendered glyph pixels
   against the actual photograph behind them. A stylesheet cannot assert this;
   only a browser can. Run it before deploying, and after ANY image swap. */

/* ---- Layout primitives ---- */
.shell { width: var(--shell); margin-inline: auto; }
.shell-narrow { width: var(--shell-narrow); margin-inline: auto; }
.measure { max-width: var(--measure); }

.section { position: relative; padding-block: var(--space-2xl); }

.skip-link {
  position: absolute;
  left: 50%;
  top: -100px;
  transform: translateX(-50%);
  background: var(--brand-fill);
  color: #fff;
  padding: 0.75rem 1.25rem;
  border-radius: 0 0 12px 12px;
  z-index: var(--z-overlay);
  transition: top 200ms var(--ease-out-quint);
}
.skip-link:focus { top: 0; }

.eyebrow {
  font-family: var(--font-display);
  font-weight: 500;
  color: var(--brand-deep);
  font-size: var(--step-0);
  letter-spacing: 0.01em;
}
.eyebrow--light { color: var(--brand); }
