/* ==========================================================================
   base.css — design tokens, reset, typography, layout primitives.
   Loaded on every page, before style.css.
   ========================================================================== */

/* --- Tokens ------------------------------------------------------------- */
:root{
  /* Brand */
  --navy:#172c4d;
  --navy-deep:#0b1a2c;
  --teal:#0d4b60;
  --aqua:#66baba;
  --coral:#ec725a;

  /* Neutrals */
  --white:#fff;
  --mist:#f3f5f7;
  --ink:var(--navy);
  --muted:rgba(23,44,77,.74);
  --faint:rgba(23,44,77,.42);
  --line:rgba(23,44,77,.12);

  /* Type */
  --font:"Montserrat",system-ui,-apple-system,"Segoe UI",sans-serif;

  /* Rhythm */
  --wrap:min(1180px,calc(100% - 40px));
  --gap:clamp(48px,6vw,76px);
  --section-y:clamp(72px,10vw,120px);

  /* Header slab. The lockup is absolutely placed, so the band beneath it
     clears --header-clear (the slab's bottom edge) instead of flowing after
     it. Dialled back from the handoff's 1440px figures — the slab read too
     heavy on a desktop screen — but kept in proportion: the mark, the
     wordmark and the padding all came down by the same ~22%. Each value
     lands exactly on its target at 1440px and scales down from there, so the
     slab never grows into the nav. */
  --slab-top:24px;
  --slab-pad-y:clamp(14px,1.67vw,24px);
  --slab-pad-l:clamp(26px,3.34vw,48px);
  --slab-pad-r:clamp(48px,6.12vw,88px);
  --slab-logo:clamp(56px,5.56vw,80px);
  --slab-gap:clamp(11px,1.05vw,15px);
  --header-clear:calc(var(--slab-top) + var(--slab-pad-y) * 2 + var(--slab-logo));

  /* Surface */
  --radius:20px;
  --radius-lg:28px;
  --shadow-sm:0 16px 40px rgba(23,44,77,.07);
  --shadow-md:0 28px 68px rgba(23,44,77,.13);
  --shadow-lg:0 34px 80px rgba(23,44,77,.17);

  /* Motion */
  --ease:cubic-bezier(.2,.8,.2,1);
  --t:.22s var(--ease);
  --ease-reveal:cubic-bezier(.22,.9,.22,1);   /* long, settles rather than stops */
}

@media (max-width:1023px){
  :root{
    --slab-top:0px;
    --slab-pad-y:16px;
    --slab-pad-l:20px;
    --slab-pad-r:40px;
    --slab-logo:52px;
    --slab-gap:11px;
  }
}

/* --- Reset -------------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}

html{
  scroll-behavior:smooth;
  scroll-padding-top:24px;   /* the header is an overlay and does not stick */
  -webkit-text-size-adjust:100%;
}

body{
  margin:0;
  min-width:320px;
  background:var(--white);
  color:var(--ink);
  font-family:var(--font);
  font-weight:500;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
body.is-nav-open{overflow:hidden}

h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}
ul,ol{margin:0;padding:0;list-style:none}
img,svg{display:block;max-width:100%}
img{height:auto}
button{font:inherit;color:inherit}
a{color:var(--teal);text-decoration:none;transition:color var(--t)}
a:hover{color:var(--coral)}
a,button{-webkit-tap-highlight-color:transparent}
::selection{background:var(--aqua);color:var(--navy)}

:where(a,button,input,select,textarea,summary):focus-visible{
  outline:3px solid var(--coral);
  outline-offset:3px;
  border-radius:6px;
}

/* --- Typography scale ---------------------------------------------------
   Kept complete on purpose. .h3 currently has no user in the markup; it is
   the third step of the scale, there for the next section that needs it. */
.h1{font-size:clamp(42px,7.4vw,96px);line-height:.9;letter-spacing:-.05em;font-weight:800;text-wrap:balance}
.h2{font-size:clamp(32px,5vw,58px);line-height:.96;letter-spacing:-.045em;font-weight:800;text-wrap:balance}
.h3{font-size:clamp(24px,3vw,32px);line-height:1.06;letter-spacing:-.035em;font-weight:800;text-wrap:balance}

.eyebrow{
  font-size:11px;
  letter-spacing:.18em;
  text-transform:uppercase;
  font-weight:800;
  color:var(--faint);
}

.lead{
  margin-top:22px;
  max-width:56ch;
  font-size:clamp(16px,1.9vw,17.5px);
  line-height:1.72;
  font-weight:500;
  color:var(--muted);
  text-wrap:pretty;
}
.lead + .lead{margin-top:16px}

/* Rich text typed in the CMS comes back as its own paragraphs. blocks.css
   gives .rich > p the same measure and rhythm as .lead. */

/* --- Layout primitives -------------------------------------------------- */
.wrap{width:var(--wrap);margin-inline:auto}

.section{padding-block:var(--section-y)}
.section--mist{background:var(--mist)}
.section--navy{
  background:linear-gradient(158deg,var(--navy-deep),var(--navy) 48%,var(--teal));
  color:var(--white);
}
.section--navy .eyebrow{color:var(--aqua)}
.section--navy .lead{color:rgba(255,255,255,.72)}

/* Two-column split that collapses to one column on narrow screens. */
.split{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,360px),1fr));
  gap:var(--gap);
  align-items:center;
}

/* Framed photo. */
.figure{
  overflow:hidden;
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);
  background:var(--mist);
}
.figure img{width:100%;height:100%;object-fit:cover}
.figure--4x3{aspect-ratio:4/3}

/* --- Utilities ---------------------------------------------------------- */
.stack-sm{margin-top:14px}

.skip-link{
  position:fixed;
  left:14px;
  top:14px;
  z-index:999;
  transform:translateY(-180%);
  background:var(--navy);
  color:var(--white);
  padding:12px 18px;
  border-radius:999px;
  font-size:13px;
  font-weight:800;
  transition:transform var(--t);
}
.skip-link:focus{transform:translateY(0);color:var(--white)}


/* --- Motion -------------------------------------------------------------
   One vocabulary, a few words in it. Everything enters once, on the same
   curve, at the same speed — only the direction changes, so the page reads
   as one considered move rather than a set of unrelated tricks.

     data-reveal          rise from below — the default
     data-reveal="left"   in from the left  } for the two-column splits, so
     data-reveal="right"  in from the right } the halves meet in the middle
     data-reveal="zoom"   settle out of a slight scale — framed photographs
     data-mask            a headline sliding up from behind its own edge

   Elements only start hidden once JS confirms it will run, so a visitor with
   no JavaScript sees the finished page. --reveal-delay is set per element by
   js/modules/reveal.js to cascade things that arrive together. */
.js [data-reveal],
.js [data-mask]{
  transition:opacity .7s ease var(--reveal-delay,0ms),
             transform .8s var(--ease-reveal) var(--reveal-delay,0ms);
}

.js [data-reveal]{opacity:0;transform:translate3d(0,24px,0)}
.js [data-reveal="left"]{transform:translate3d(-30px,0,0)}
.js [data-reveal="right"]{transform:translate3d(30px,0,0)}
.js [data-reveal="zoom"]{transform:scale(.965)}
.js [data-reveal].is-visible{opacity:1;transform:none}

/* Words. The headline itself never moves — each word rises and fades on its
   own beat instead, so a three-line headline reads as a line of type arriving
   rather than a slab sliding, and no single thing travels more than a third of
   an em. js/modules/reveal.js does the splitting at runtime, so the HTML on
   disk stays plain editable text; --word-index is set per word there and
   composes with whatever cascade delay the element itself was given.

   Words stay hidden until the split has happened, which is why the element
   carries the opacity rather than starting visible and flashing. */
.js [data-reveal="words"]{opacity:0;transform:none}
.js [data-reveal="words"].is-split{opacity:1}
.js [data-reveal="words"] .word{
  display:inline-block;
  opacity:0;
  transform:translate3d(0,.34em,0);
  transition:opacity .55s ease,transform .75s var(--ease-reveal);
  transition-delay:calc(var(--reveal-delay,0ms) + var(--word-index,0) * 45ms);
}
.js [data-reveal="words"].is-visible .word{opacity:1;transform:none}

/* Headline mask. The wrapper does the clipping and the headline slides up
   inside it; the wrapper's padding is what keeps descenders off the edge,
   and 125% is far enough that nothing peeks over it at rest. */
.mask{display:block;overflow:hidden;padding-block:.1em}
.js [data-mask]{display:inline-block;transform:translate3d(0,125%,0)}
.js [data-mask].is-visible{transform:none}

@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 [data-reveal],
  .js [data-mask],
  .js [data-reveal="words"] .word{opacity:1;transform:none}
}
