/* ============================================================
   base.css · site kit 1.1.0 · mechanics only, no look
   Linked first on every page, before the site's own styles.css. Don't edit it per build.
   styles.css sets the real token VALUES in its own :root (it loads later, so it wins).
   Keep the token NAMES: color-system.md §1, ux-rules.md §4 and §7, motion-system.md §4 and §6.

   1 Tokens            2 Reset and base       3 Accessibility helpers
   4 Preloader         5 Reveal               6 Skeleton
   7 Toast             8 Forms and states     9 Empty state and 404
   10 Header states    11 Off-screen pause, slot labels    12 Reduced motion
   ============================================================ */

/* ---------- 1 Tokens (placeholder values: every build replaces them in styles.css) ---------- */
:root{
  /* Color roles, each fill with its on- partner */
  --bg:#ffffff; --fg:#141414;
  --card:#ffffff; --card-fg:#141414;
  --muted:#f1f1f1; --muted-fg:#4d4d4d;
  --primary:#141414; --on-primary:#ffffff;
  --secondary:#3d3d3d; --on-secondary:#ffffff;
  --accent:#141414; --on-accent:#ffffff;
  --border:#cfcfcf;
  --ring:#141414; --ring-outer:#ffffff;
  --danger:#b42318; --on-danger:#ffffff; --danger-text:var(--danger); /* dark bands set a light --danger-text */
  --ok:#1f7a4d;

  /* Type: families and body size only; the display scale belongs to the site */
  --font-body:system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-display:var(--font-body);
  --fs-body:1.0625rem; --lh-body:1.55;

  /* Spacing on a 4/8 rhythm, gutters and section padding */
  --sp-1:8px; --sp-2:16px; --sp-3:24px; --sp-4:32px; --sp-5:48px; --sp-6:72px; --sp-7:112px;
  --gut:clamp(16px,4vw,48px); --sec:clamp(72px,9vw,112px); --max:1280px;

  /* Radius, elevation, z-index */
  --r-1:4px; --r-2:8px; --r-3:16px; --r-full:999px;
  --e-1:0 1px 2px rgb(0 0 0 / .08); --e-2:0 8px 24px rgb(0 0 0 / .12); --e-3:0 24px 64px rgb(0 0 0 / .18);
  --z-raised:10; --z-sticky:20; --z-overlay:40; --z-modal:100; --z-toast:200; --z-loader:300;

  /* Motion: easing and the reveal tier (subtle 12px/.35s, standard 24px/.5s, complex 32px/.7s) */
  --ease:cubic-bezier(.22,1,.36,1); --ease-io:cubic-bezier(.65,0,.35,1); --ease-spring:cubic-bezier(.3,1.4,.5,1);
  --ease-drawer:cubic-bezier(.32,.72,0,1);  /* sheets, drawers, the mobile menu (motion-judgement.md §3) */
  --spring:linear(0, .044, .152, .29, .437, .577, .701, .805, .887, .949, .993, 1.021, 1.037, 1.045, 1.046, 1.043, 1.037, 1.031, 1.024, 1.018, 1.012, 1.008, 1.004, 1.002, 1, .999, .998, .998, .998, .998, .998, .999, .999); /* real spring, dial 3-5 (component-libraries.md §2) */
  --dur-hover:.2s; --dur-state:.45s;
  --rv-dist:24px; --rv-dur:.5s;
}

@supports not (transition-timing-function:linear(0,1)){:root{--spring:cubic-bezier(.34,1.56,.64,1)}}

/* ---------- 2 Reset and base ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;-webkit-tap-highlight-color:transparent;scroll-behavior:smooth;scroll-padding-top:calc(var(--header-h,0px) + 8px)}
body{margin:0;min-height:100svh;background:var(--bg);color:var(--fg);font:400 var(--fs-body)/var(--lh-body) var(--font-body);-webkit-font-smoothing:antialiased}
:where(h1,h2,h3,h4,h5,h6,p,figure,blockquote,dl,dd){margin:0}
:where(h1,h2,h3,h4){text-wrap:balance;overflow-wrap:break-word}
:where(p,li){text-wrap:pretty}
:where(img,svg,video,canvas,picture){display:block;max-width:100%}
:where(img,video){height:auto}
:where(input,button,textarea,select){font:inherit;color:inherit}
:where(a,button,label,summary,input,select,textarea,[role="button"]){touch-action:manipulation}
@media (pointer:coarse){:where(input,select,textarea){font-size:max(16px,1em)}}  /* no zoom-on-focus; never disable zoom instead */
:where(a){color:inherit;text-underline-offset:.18em;text-decoration-thickness:from-font}
::selection{background:var(--accent);color:var(--on-accent)}
:where(input,textarea){caret-color:var(--accent)}
:root{accent-color:var(--accent)}   /* browser surfaces carry the palette (direction-and-substance.md §7) */
:where(table){border-collapse:collapse}
.tnum{font-variant-numeric:tabular-nums}

/* ---------- 3 Accessibility helpers ---------- */
:focus-visible{outline:3px solid var(--ring);outline-offset:3px}
.skip{position:fixed;left:var(--sp-2);top:var(--sp-2);z-index:calc(var(--z-loader) + 1);padding:12px 18px;border-radius:var(--r-2);background:var(--fg);color:var(--bg);font-weight:600;text-decoration:none;transform:translateY(calc(-100% - 24px))}
.skip:focus{transform:none}
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
[hidden]{display:none!important}
/* Honest placeholders (components.md §3): unconfirmed text and one "to confirm" note per section at most */
.ph{border-bottom:1px dashed currentColor}
.ph-note{display:inline-block;padding:4px 10px;border:1px dashed currentColor;border-radius:var(--r-full);font-size:.875rem;line-height:1.2}

/* ---------- 4 Preloader (components.md §4b; mechanics in core.js §5) ----------
   <html data-preloader="p1|p2|p3">. The head script adds .js .is-loading (and .is-repeat on later views).
   p1 and repeat views: the body fades in. p2/p3: #loader covers the page; the site styles its scene. */
.loader{display:none}
.js:is([data-preloader="p2"],[data-preloader="p3"]):not(.is-repeat) .loader{display:grid;place-items:center;position:fixed;inset:0;z-index:var(--z-loader);background:var(--primary);color:var(--on-primary);transition:opacity .5s var(--ease-io),visibility 0s linear .5s}
.loader.is-out{opacity:0;visibility:hidden;pointer-events:none}
.is-failsafe .loader{display:none!important}
.js.is-loading:is([data-preloader="p2"],[data-preloader="p3"]):not(.is-repeat){overflow:hidden}
/* p1 and repeat views: a veil in the page colour lifts once fonts are in. The page under it is painted
   at full opacity, so Largest Contentful Paint still counts it (an opacity:0 body hides it from LCP). */
.js::after{content:"";position:fixed;inset:0;z-index:var(--z-loader);background:var(--bg);pointer-events:none;opacity:0;visibility:hidden;transition:opacity .45s var(--ease),visibility 0s linear .45s}
.js.is-loading:is([data-preloader="p1"],:not([data-preloader]),.is-repeat)::after{opacity:1;visibility:visible;transition:none}

/* ---------- 5 Reveal (core.js §6) ---------- */
[data-reveal].is-armed{opacity:0;transform:translateY(var(--rv-dist))}
[data-reveal="fade"].is-armed{transform:none}
[data-reveal="scale"].is-armed{transform:scale(.96)}
[data-reveal].is-revealing{transition:opacity var(--rv-dur) var(--ease),transform var(--rv-dur) var(--ease)}
[data-reveal-group].is-armed>*{opacity:0;transform:translateY(var(--rv-dist))}
[data-reveal-group].is-revealing>*{transition:opacity var(--rv-dur) var(--ease) var(--rv-delay,0s),transform var(--rv-dur) var(--ease) var(--rv-delay,0s)}

/* ---------- 6 Skeleton (only where JS fills content) ---------- */
.sk{display:block;background:var(--muted);border-radius:var(--r-1);animation:sk-pulse 1.4s ease-in-out infinite}
@keyframes sk-pulse{50%{opacity:.55}}
html:not(.js) .sk-wrap{display:none}

/* ---------- 7 Toast (core.js §9) ---------- */
.toast-region{position:fixed;left:50%;bottom:max(16px,env(safe-area-inset-bottom));z-index:var(--z-toast);display:grid;gap:8px;width:min(calc(100vw - 32px),420px);transform:translateX(-50%);pointer-events:none}
.toast{padding:12px 16px;border-radius:var(--r-2);background:var(--fg);color:var(--bg);box-shadow:var(--e-2);pointer-events:auto;animation:toast-in .25s var(--ease) both}
.toast--error{background:var(--danger);color:var(--on-danger)}
.toast.is-out{animation:toast-out .18s var(--ease) both}
@keyframes toast-in{from{opacity:0;transform:translateY(12px)}}
@keyframes toast-out{to{opacity:0;transform:translateY(8px)}}

/* ---------- 8 Forms and states (core.js §10) ---------- */
.field{display:grid;gap:6px}
.field__error{color:var(--danger-text);font-size:.9375rem;line-height:1.4}
:where(input,select,textarea)[aria-invalid="true"]{border-color:var(--danger-text)}
.form-errors{padding:var(--sp-2) var(--sp-3);border:2px solid var(--danger-text);border-radius:var(--r-2)}
.form-errors ul{margin:0;padding-left:1.2em}
.form-errors a{color:inherit}
:where(button,[type="submit"])[aria-busy="true"]{cursor:progress}
:where(button,input,select,textarea):disabled{cursor:not-allowed}

/* ---------- 9 Empty state and 404 ---------- */
.empty{display:grid;justify-items:start;gap:var(--sp-2);padding:var(--sp-5) 0}
.notfound{min-height:70svh;display:grid;align-content:center;gap:var(--sp-3);width:100%;max-width:var(--max);margin:0 auto;padding:var(--sec) var(--gut)}
.notfound__links{display:flex;flex-wrap:wrap;gap:var(--sp-2) var(--sp-3);margin:0;padding:0;list-style:none}

/* ---------- 10 Header states (core.js §8; the look is the site's) ---------- */
[data-header="hide"]{transition:transform .3s var(--ease)}
[data-header].is-hidden{transform:translateY(-100%)}
.menu-open{overflow:hidden}

/* ---------- 11 Off-screen pause and slot labels (?slots) ---------- */
.show-slots [data-slot]{outline:2px dashed #e11d48;outline-offset:-2px}
.slot-label{position:absolute;left:8px;top:8px;z-index:var(--z-overlay);padding:4px 8px;border-radius:var(--r-1);background:#e11d48;color:#fff;font:600 13px/1.2 var(--font-body)}
[data-offscreen-pause].is-off,[data-offscreen-pause].is-off *{animation-play-state:paused!important}

/* ---------- 12 Reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
  .js::after{transition:opacity .2s linear,visibility 0s linear .2s!important}
}
