/* ==========================================================================
   OPTIMA PRO SERVICE LLC — style.css
   Hand-written. No framework, no build step, no preprocessor.
   --------------------------------------------------------------------------
   BREAKPOINTS  480 / 720 / 1000 / 1280   (literal — custom properties do not
                work inside @media, so this comment is the source of truth)
   ANGLES       38.7deg roofline (rise/run 0.80) and 81.6deg pin apex.
                Both measured from the logo pixels. NO other angles exist.
   RULE         Components read SEMANTIC tokens only: --surface, --text,
                --accent, --line, --btn. Never a raw brand or ink scale step,
                never a hex. Dark contexts remap those tokens, which is why
                this file contains no cross-block descendant selectors and no
                overrides of the form ".footer .thing".

   TABLE OF CONTENTS
     01  TOKENS                  07  MEDIA / PHOTO TREATMENT
     02  DARK CONTEXT REMAP      08  COMPONENTS
     03  RESET                       header · nav · drawer · hero · panes
     04  ELEMENTS                    buttons · cards · stats · quote
     05  TYPOGRAPHY                  plate · accordion · forms · footer
     06  LAYOUT + SECTIONS           callbar · breadcrumb · svcnav
   Components live in components.css, which every page loads immediately
   AFTER this file. Three separate <link> tags (fonts / style / components)
   download in parallel; an @import chain would serialize them. Cascade order
   is guaranteed by the order of the <link> tags in the <head>.
   ========================================================================== */

/* ==========================================================================
   01 · TOKENS
   Every contrast ratio in a comment below was computed against WCAG 2.1
   relative luminance, not estimated.
   ========================================================================== */
:root {
  color-scheme: light;

  /* --- fixed, never remapped ------------------------------------------- */
  --white: #ffffff;
  --black-ink: #151f26;

  /* --- brand blue, derived from the 2026 logo's #005ADC --------------------- */
  --brand-50:  #eff4fb;
  --brand-100: #dce8f6;
  --brand-200: #b7d1ee;
  --brand-300: #85afe0;   /* links on dark          7.10:1 on --brand-950 */
  --brand-400: #347fd5;
  --brand-500: #1563bc;
  /* 600/700/800 sit on the 2026 logo hue (#005adc). The logo blue itself is
     6.01:1 on white, which is AA but not AAA, so the UI steps are the same
     hue darkened until they clear 7:1 -- same family to the eye, no loss of
     contrast on links and buttons. Ratios measured, not estimated. */
  --brand-600: #0052c7;   /* focus ring on light    6.93:1 on white       */
  --brand-700: #004dbd;   /* UI blue, links, button 7.51:1 on white AAA   */
  --brand-800: #003b91;   /* hover / pressed       10.32:1 white on it    */
  --brand-850: #103a63;   /* dark-theme feature band — see 02b            */
  --brand-900: #0e3053;
  --brand-950: #0d2235;   /* darkest panel + footer                       */

  /* --- cool neutrals, derived from the logo's #1D2B35 ------------------ */
  --ink-0:   #ffffff;
  --ink-25:  #fafbfc;
  --ink-50:  #f4f7f9;
  --ink-100: #eaeff2;
  --ink-200: #d9e0e5;   /* default hairline */
  --ink-300: #bdc8d0;   /* input border     */
  --ink-400: #91a0ac;
  --ink-500: #687d8d;   /* 4.28:1 — PLACEHOLDER TEXT ONLY, never content  */
  --ink-600: #4f6472;   /* 6.18:1 on white  AA                            */
  --ink-700: #384a57;   /* 9.19:1 on white  AAA — body                    */
  --ink-800: #1d2b35;   /* THE LOGO CHARCOAL 14.49:1 AAA — headings       */
  --ink-900: #151f26;

  /* --- signal amber. NOT in the logo; introduced for CTA emphasis.
         HARD RULE: amber only ever appears on a DARK surface. It is
         1.87:1 on white, so the token architecture below makes it
         structurally impossible to place on light.                       */
  --signal-400: #ffc44d;
  --signal-500: #f2b32b;   /* 8.68:1 on --brand-950 AAA */
  --signal-600: #d99408;

  /* --- form semantics -------------------------------------------------- */
  --success-50:  #eaf5ee;
  --success-600: #1e7a47;   /* 5.34:1 on white AA */
  --danger-50:   #fdecea;
  --danger-600:  #b42318;   /* 6.57:1 on white AA */
  --danger-700:  #8f1c13;

  /* --- SEMANTIC TOKENS — the only thing components are allowed to read - */
  --surface-0: var(--ink-0);
  --surface-1: var(--ink-50);
  --surface-2: var(--ink-100);
  --surface-brand: var(--brand-50);
  --text-strong: var(--ink-800);
  --text-body:   var(--ink-700);
  --text-muted:  var(--ink-600);
  --text-faint:  var(--ink-500);
  --text-invert: var(--white);
  --text-link:       var(--brand-700);
  --text-link-hover: var(--brand-800);
  --line:        var(--ink-200);
  --line-strong: var(--ink-300);
  --accent: var(--brand-700);
  --focus:     var(--brand-600);
  --focus-gap: var(--white);
  --btn-primary-bg:       var(--brand-700);
  --btn-primary-fg:       var(--white);
  --btn-primary-bg-hover: var(--brand-800);
  --btn-plinth: 0 3px 0 0 var(--brand-900);
  --plate-shadow: 6px 6px 0 0 var(--brand-100);

  /* Two switches so components never have to name a theme. A raster logo and
     a sun/moon icon cannot be recoloured by a token, so instead the token
     says which of the pair is displayed. This is what keeps every
     theme-conditional rule inside this file. */
  --on-light: block;
  --on-dark: none;

  /* --- type families --------------------------------------------------- */
  --font-ui: 'Archivo', 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue',
    Arial, sans-serif;
  --font-body: 'Source Sans 3', 'Segoe UI', system-ui, -apple-system, Roboto,
    'Helvetica Neue', Arial, sans-serif;

  /* --- Archivo width-axis stops (used with font-stretch) --------------- */
  --wd-display: 82%;
  --wd-h1: 84%;
  --wd-h2: 88%;
  --wd-h3: 96%;
  --wd-ui: 100%;
  --wd-plate: 110%;

  /* --- fluid type scale, 360px -> 1440px viewport ---------------------- */
  --fs-display:  clamp(2.5rem, 1.75rem + 3.33vw, 4.5rem);
  --fs-h1:       clamp(2rem, 1.542rem + 2.04vw, 3.25rem);
  --fs-h2:       clamp(1.625rem, 1.333rem + 1.3vw, 2.5rem);
  --fs-h3:       clamp(1.25rem, 1.167rem + 0.37vw, 1.5rem);
  --fs-h4:       clamp(1.0625rem, 1.021rem + 0.19vw, 1.1875rem);
  --fs-lead:     clamp(1.1875rem, 1.104rem + 0.37vw, 1.4375rem);
  --fs-body:     clamp(1.0625rem, 1.042rem + 0.09vw, 1.125rem);
  --fs-small:    0.9375rem;
  --fs-micro:    0.8125rem;
  --fs-overline: clamp(0.75rem, 0.688rem + 0.13vw, 0.8125rem);
  --fs-stat:     clamp(2.5rem, 2rem + 2.22vw, 3.75rem);
  --fs-nav:      0.9375rem;

  /* --- line-height + tracking ----------------------------------------- */
  --lh-flat: 1;
  --lh-body: 1.65;
  --ls-plate: 0.16em;
  --ls-badge: 0.06em;

  /* --- spacing, 4px base ---------------------------------------------- */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;  --s-5: 20px;
  --s-6: 24px;  --s-7: 32px;  --s-8: 40px;  --s-9: 48px;  --s-10: 64px;
  --s-11: 80px; --s-12: 96px;

  /* --- vertical rhythm. These four values are the ONLY section paddings */
  --section-y:    clamp(56px, 8.5vw, 112px);
  --section-y-lg: clamp(72px, 11vw, 148px);
  --section-y-sm: clamp(40px, 5.5vw, 72px);
  --band-y:       clamp(44px, 6vw, 80px);
  --head-gap:     clamp(28px, 3.4vw, 44px);

  /* --- containers + grid ---------------------------------------------- */
  --w-container: 1216px;
  --w-wide: 1440px;
  --w-narrow: 880px;
  --w-prose: 68ch;
  --gutter: clamp(20px, 4.5vw, 48px);
  --grid-gap: clamp(16px, 2.2vw, 32px);
  --card-min: 264px;

  /* --- motif geometry, measured from the logo -------------------------- */
  --point-w: 112px;                              /* apex 81.6deg          */
  --point-d: calc(var(--point-w) * 0.5789);
  --gable-w: 40px;                               /* pitch 38.7deg         */
  --gable-h: calc(var(--gable-w) * 0.4);
  --diamond-w: 7px;
  --diamond-h: calc(var(--diamond-w) * 1.1578);
  --mullion: clamp(8px, 1.6vw, 18px);

  /* --- radii. Deliberately near-square. No pills exist on this site. --- */
  --r-xs: 2px;  --r-sm: 3px;  --r-md: 4px;  --r-lg: 6px;

  /* --- borders --------------------------------------------------------- */
  --bw-hair: 1px;  --bw-thick: 2px;  --bw-rule: 3px;

  /* --- shadows. Structural, not atmospheric. -------------------------- */
  --shadow-sm: 0 1px 2px rgba(13, 32, 53, 0.06), 0 1px 1px rgba(13, 32, 53, 0.04);
  --shadow-md: 0 2px 4px rgba(13, 32, 53, 0.05), 0 8px 20px -6px rgba(13, 32, 53, 0.1);
  --shadow-header: 0 1px 0 rgba(13, 32, 53, 0.05), 0 6px 16px -10px rgba(13, 32, 53, 0.18);
  --shadow-focus: 0 0 0 3px var(--focus-gap), 0 0 0 6px var(--focus);

  /* --- z-index --------------------------------------------------------- */
  --z-raised: 10;  --z-callbar: 60;  --z-header: 70;
  --z-scrim: 80;   --z-drawer: 90;   --z-skip: 110;

  /* --- motion ---------------------------------------------------------- */
  --dur-1: 120ms;  --dur-2: 180ms;  --dur-3: 260ms;
  --dur-4: 420ms;  --dur-5: 600ms;
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-plate: cubic-bezier(0.2, 0.8, 0.2, 1);
  --reveal-y: 14px;
  --reveal-stagger: 55ms;

  /* --- chrome ---------------------------------------------------------- */
  --header-h: 64px;
  --strip-h: 34px;
  --callbar-h: 56px;
}

@media (min-width: 1000px) {
  :root { --header-h: 76px; }
}

/* ==========================================================================
   02 · DARK CONTEXT REMAP
   Remap tokens; never write descendant overrides. Every component placed
   inside one of these inverts for free, including buttons (which become the
   amber signal button automatically).
   ========================================================================== */
.section--dark,
.site-footer,
.drawer {
  color-scheme: dark;
  --surface-0: var(--brand-950);
  --surface-1: var(--brand-900);
  --surface-2: var(--brand-800);
  --surface-brand: var(--brand-900);
  --text-strong: var(--white);      /* 16.19:1 AAA */
  --text-body:   var(--ink-100);    /* 13.97:1 AAA */
  --text-muted:  var(--ink-300);    /*  9.51:1 AAA */
  --text-faint:  var(--ink-400);    /*  6.03:1 AA  */
  --text-invert: var(--ink-900);
  --text-link:       var(--brand-300);
  --text-link-hover: var(--white);
  --line:        rgba(255, 255, 255, 0.14);
  --line-strong: rgba(255, 255, 255, 0.24);
  /* Accent on dark is the logo's own on-dark blue, not amber. The lockup is
     charcoal #182430 + blue #00489c, and the knockout variant reads #84a8d8 —
     which is what --brand-300 is. Amber is NOT in the logo (see the token
     comment above) so it no longer carries brand identity here; it is reserved
     below for actions only: the primary button, the focus ring and the call
     bar. Keeping the focus ring amber matters more now, not less — a blue ring
     around blue accents would be invisible. */
  --accent: var(--brand-300);
  --focus:     var(--signal-400);
  --focus-gap: var(--brand-950);
  --btn-primary-bg:       var(--signal-500);
  --btn-primary-fg:       var(--black-ink);   /* 8.96:1 AAA */
  --btn-primary-bg-hover: var(--signal-400);
  --btn-plinth: 0 3px 0 0 rgba(0, 0, 0, 0.35);
  --plate-shadow: 6px 6px 0 0 rgba(242, 179, 43, 0.85);
  background-color: var(--surface-0);
  color: var(--text-body);
}

/* ==========================================================================
   02b · DARK THEME (whole page)
   Same idea one level up: remap the semantic tokens on :root and every
   component follows. Nothing below this line is a descendant override of a
   component — only tokens, plus the two places where a raster asset or a
   native control cannot read a token.

   Every ratio below was computed, not estimated.
   ========================================================================== */
:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-0: #0a1520;            /* page   */
  --surface-1: #101f2d;            /* .section--alt                         */
  --surface-2: #182b3c;            /* cards, inputs, photo placeholder      */
  --surface-brand: #12283f;
  --text-strong: #f3f7fa;          /* 17.09:1 on surface-0 AAA              */
  --text-body:   #cfdae3;          /* 12.96:1 AAA                           */
  --text-muted:  #a3b3c0;          /*  8.56:1 AAA                           */
  --text-faint:  #8295a4;          /*  5.95:1 AA  — UI and large text only  */
  --text-invert: #0a1520;
  --text-link:       var(--brand-300);   /* 8.07:1 AAA */
  --text-link-hover: var(--brand-200);   /* 11.72:1    */
  --line:        rgba(255, 255, 255, 0.13);
  --line-strong: rgba(255, 255, 255, 0.24);
  --accent: var(--brand-300);
  --focus:     var(--signal-400);        /* 11.62:1 */
  --focus-gap: #0a1520;
  /* Amber stays the action colour, exactly as on dark bands today. The hard
     rule "amber only on a dark surface" still holds — in this theme every
     surface is dark. */
  --btn-primary-bg:       var(--signal-500);
  --btn-primary-fg:       var(--black-ink);   /* 8.96:1 AAA */
  --btn-primary-bg-hover: var(--signal-400);
  --btn-plinth: 0 3px 0 0 rgba(0, 0, 0, 0.45);
  --plate-shadow: 6px 6px 0 0 rgba(133, 175, 224, 0.28);
  --on-light: none;
  --on-dark: block;
  /* Form semantics are raw tokens the components read directly, so unlike
     everything else they do NOT invert for free. Left alone, .notice--error
     keeps its pale pink panel and inherits near-white text onto it: 1.06:1,
     i.e. the emergency notice on contact.html becomes invisible. */
  --success-50:  #16351f;   /* body text on it 9.46:1  */
  --success-600: #7ddba6;   /* rule on it      8.03:1  */
  --danger-50:   #3f1a16;   /* body text on it 10.79:1 */
  --danger-600:  #ff9d94;   /* rule on it      7.66:1  */
  --danger-700:  #ffb3ab;
}

/* THE PROBLEM THIS SOLVES
   .section--dark earns its keep in the light theme by being a 16.19:1 jump
   away from a white page. Run the same rule on a dark page and it lands at
   1.37:1 — the band stops being a band and the whole page flattens into one
   slab. So in this theme the feature bands go the other way and LIFT into the
   brand blue: --brand-850 sits 1.58:1 off the page, which is more separation
   than .section--alt gets in the light theme (1.08:1), and every token
   .section--dark already sets still passes on it (white 11.62:1, ink-300
   6.83:1, brand-300 5.09:1, signal-500 6.23:1).

   Only the surfaces move. Text, accent and button tokens are inherited from
   the block above, which is why this is four lines and not forty. */
:root[data-theme="dark"] .section--dark,
:root[data-theme="dark"] .site-footer,
:root[data-theme="dark"] .drawer {
  --surface-0: var(--brand-850);
  --surface-1: #16406b;
  --surface-2: #1b4a78;
  --surface-brand: #16406b;
  --focus-gap: var(--brand-850);
  /* Lifting the band costs contrast at the quiet end: ink-400 is 6.03:1 on the
     light theme's brand-950 footer but only 4.33:1 here, which fails AA for the
     small print and the footer legal links. This is the one text token the
     band has to raise. 4.83:1, and still a clear step below --text-muted. */
  --text-faint: #9aa9b6;
}

/* Light is the default, full stop. prefers-color-scheme is deliberately NOT
   consulted: the client asked for the site to open light for everyone, so a
   visitor whose laptop is set to dark still gets the light site until they
   press the toggle themselves. That press writes data-theme and localStorage,
   and the block above takes over from then on.

   This is why the dark palette is declared exactly ONCE. It used to be
   duplicated into an @media (prefers-color-scheme: dark) copy, with a check
   in tools/check_site.py comparing the two for drift. Both the copy and that
   check are gone -- there is nothing left to drift against. */

/* ==========================================================================
   03 · RESET
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

:where(h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ul, ol) {
  margin: 0;
}
:where(ul, ol) { padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-block-start: calc(var(--header-h) + 12px);
  tab-size: 4;
}

:where(img, picture, video, canvas, svg) {
  display: block;
  max-width: 100%;
}

/* MUST come after the rule above. Author styles beat the browser's built-in
   [hidden] { display: none } no matter the specificity, so the :where(svg)
   rule was forcing the hidden inline icon sprite to render -- it appeared as a
   ~150px empty white block above the header on every page. */
[hidden] {
  display: none !important;
}

:where(input, button, textarea, select) { font: inherit; color: inherit; }
:where(button) { background: none; border: 0; }

:where(:focus-visible) {
  outline: var(--bw-thick) solid var(--focus);
  outline-offset: 2px;
}

/* Anchor targets clear the sticky header */
:where([id]) { scroll-margin-block-start: calc(var(--header-h) + 20px); }

/* ==========================================================================
   04 · ELEMENTS
   ========================================================================== */
body {
  margin: 0;
  background-color: var(--surface-0);
  color: var(--text-body);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: var(--text-link); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--text-link-hover); }

hr {
  height: var(--bw-hair);
  margin: 0;
  border: 0;
  background: var(--line);
}

::selection { background: var(--brand-700); color: var(--white); }

address { font-style: normal; }

/* ==========================================================================
   05 · TYPOGRAPHY
   Case discipline: UPPERCASE exists in exactly two places on this site,
   .eyebrow and .plate. Not in nav, not in buttons, not in headings.
   ========================================================================== */
.display, .h1, .h2, .h3, .h4 {
  font-family: var(--font-ui);
  color: var(--text-strong);
  text-wrap: balance;
}

.display {
  font-size: var(--fs-display);
  font-weight: 800;
  font-stretch: var(--wd-display);
  line-height: 0.98;
  letter-spacing: -0.022em;
  max-inline-size: 18ch;
}
.h1 {
  font-size: var(--fs-h1);
  font-weight: 800;
  font-stretch: var(--wd-h1);
  line-height: 1.04;
  letter-spacing: -0.018em;
  max-inline-size: 22ch;
}
.h2 {
  font-size: var(--fs-h2);
  font-weight: 700;
  font-stretch: var(--wd-h2);
  line-height: 1.12;
  letter-spacing: -0.014em;
  max-inline-size: 26ch;
}
.h3 {
  font-size: var(--fs-h3);
  font-weight: 600;
  font-stretch: var(--wd-h3);
  line-height: 1.25;
  letter-spacing: -0.008em;
}
.h4 {
  font-size: var(--fs-h4);
  font-weight: 600;
  font-stretch: var(--wd-ui);
  line-height: 1.35;
  letter-spacing: -0.004em;
}

.lead {
  font-size: var(--fs-lead);
  line-height: 1.5;
  letter-spacing: -0.003em;
  color: var(--text-body);
  max-inline-size: 48ch;
  text-wrap: pretty;
}
.small { font-size: var(--fs-small); line-height: 1.55; }
.micro { font-size: var(--fs-micro); line-height: 1.45; letter-spacing: 0.005em; }
.muted { color: var(--text-muted); }

/* --- the sign plate label. Highest-frequency device on the site. ------- */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-block-end: var(--s-3);
  font-family: var(--font-ui);
  font-size: var(--fs-overline);
  font-weight: 600;
  font-stretch: var(--wd-plate);
  line-height: var(--lh-flat);
  letter-spacing: var(--ls-plate);
  text-transform: uppercase;
  color: var(--accent);
}
.eyebrow::before {                     /* the 81.6deg rhombus */
  content: "";
  flex: none;
  width: var(--diamond-w);
  height: var(--diamond-h);
  background: currentColor;
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
.eyebrow::after {                      /* hairline runs out to the edge */
  content: "";
  flex: 1 1 auto;
  min-width: 24px;
  height: var(--bw-hair);
  background: var(--line);
}
.eyebrow--inline::after { display: none; }

/* --- prose flow ------------------------------------------------------- */
.prose { max-inline-size: var(--w-prose); }
.prose > * + * { margin-block-start: 1.1em; }
.prose > * + :is(h2, h3, .h2, .h3) { margin-block-start: 1.9em; }
.prose p { text-wrap: pretty; }

/* --- diamond bullet list ---------------------------------------------- */
.ticks { list-style: none; display: grid; gap: var(--s-3); }
.ticks li {
  position: relative;
  padding-inline-start: 22px;
  font-size: var(--fs-small);
  line-height: 1.5;
}
.ticks li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 0.55em;
  width: var(--diamond-w);
  height: var(--diamond-h);
  background: var(--accent);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}

/* ==========================================================================
   06 · LAYOUT + SECTIONS
   `.section` is the ONLY selector in this file that sets section
   padding-block. Every variation is a .section--* modifier declared
   immediately below it. This is what prevents padding-cancellation bugs.
   ========================================================================== */
.l-container {
  width: 100%;
  max-inline-size: var(--w-container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.l-container--narrow { --w-container: var(--w-narrow); }
.l-container--wide   { --w-container: var(--w-wide); }

.l-stack { display: grid; gap: var(--stack, var(--s-5)); }
.l-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cluster, var(--s-3));
}
.l-grid {
  display: grid;
  gap: var(--grid-gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--card-min)), 1fr));
}
.l-grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.l-grid--fixed2 { grid-template-columns: 1fr; }
.l-grid--fixed3 { grid-template-columns: 1fr; }
@media (min-width: 720px) {
  /* fixed, not auto-fit: four cards in an auto-fit track land 3 + 1 orphan at
     container width, which reads as a broken row rather than a grid */
  .l-grid--fixed2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .l-grid--fixed3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.l-split { display: grid; gap: clamp(28px, 4vw, 56px); }
@media (min-width: 1000px) {
  .l-split {
    grid-template-columns: minmax(0, var(--split-a, 1fr)) minmax(0, var(--split-b, 1fr));
    align-items: center;
  }
  .l-split--top { align-items: start; }
  .l-split--flip > :first-child { order: 2; }
}

.section { padding-block: var(--section-y); }
.section--lg   { padding-block: var(--section-y-lg); }
.section--sm   { padding-block: var(--section-y-sm); }
.section--band { padding-block: var(--band-y); }
.section--flush-top    { padding-block-start: 0; }
.section--flush-bottom { padding-block-end: 0; }
.section--alt { background: var(--surface-1); }
.section--tint { background: var(--surface-brand); }

/* faint window-grid wash, from the logo's 2x2 panes */
.section--grid {
  background-image:
    repeating-linear-gradient(90deg, var(--line) 0 1px, transparent 1px 64px),
    repeating-linear-gradient(0deg, var(--line) 0 1px, transparent 1px 64px);
  background-position: center;
}

.sec-head { max-inline-size: 62ch; margin-block-end: var(--head-gap); }
.sec-head > .h2 + p, .sec-head > .h1 + p { margin-block-start: var(--s-4); }
.sec-head--split { max-inline-size: none; display: grid; gap: var(--s-4); }
@media (min-width: 1000px) {
  .sec-head--split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    gap: var(--s-9);
    align-items: end;
  }
}
.sec-head--center { margin-inline: auto; text-align: center; }
.sec-head--center .h2, .sec-head--center .lead { margin-inline: auto; }
.sec-head--center .eyebrow { justify-content: center; }
.sec-head--center .eyebrow::after { display: none; }

/* ==========================================================================
   07 · MOTIFS + MEDIA
   ========================================================================== */

/* --- the pin point hanging off a band. ONE per page maximum. ---------- */
.has-point { position: relative; }
.has-point::after {
  content: "";
  position: absolute;
  z-index: var(--z-raised);
  inset-inline-start: var(--point-x, clamp(24px, 8vw, 120px));
  inset-block-end: calc(var(--point-d) * -1 + 1px);
  width: var(--point-w);
  height: var(--point-d);
  background: inherit;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.has-point > * { position: relative; z-index: 2; }

/* --- the 2x2 window glyph (true measured ratio: panes 10, mullion 4) --- */
.pane-glyph {
  display: grid;
  width: 22px;
  height: 22px;
  grid-template-columns: 9px 9px;
  grid-template-rows: 9px 9px;
  gap: 4px;
  flex: none;
}
.pane-glyph i { background: currentColor; }

/* --- the hero pane grid: the logo's window, enlarged ------------------ */
.panes-frame {
  padding: clamp(10px, 1.2vw, 16px);
  outline: var(--bw-hair) solid var(--line);
  outline-offset: -1px;
}
.panes {
  display: grid;
  aspect-ratio: 1 / 1;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: var(--mullion);
  background: var(--surface-0);
}
.panes > .ph { aspect-ratio: 1 / 1; }

/* --- photo wrapper. The ::after/::before pair is what makes photos from
       different photographers read as one set: shadows all pull toward the
       brand navy, highlights all cool. Layer 2 of 3 (Pillow does the rest). */
.ph {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--surface-2);
}
/* Descendant, not child: every photo is wrapped in <picture> for the WebP
   source, so the <img> is a grandchild of .ph. A `.ph > img` child selector
   silently misses it, the image renders at natural size inside an
   overflow:hidden box, and you get a zoomed, top-biased crop. */
.ph picture {
  display: block;
  width: 100%;
  height: 100%;
}
.ph img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--ph-pos, 50% 42%);
  filter: saturate(0.92) contrast(1.03);
  transition: transform var(--dur-5) var(--ease-out);
}
.ph::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(13, 34, 53, 0.07), rgba(13, 34, 53, 0.26));
  mix-blend-mode: multiply;
}
.ph--flat::after { display: none; }
.ph--16x9 { aspect-ratio: 16 / 9; }
.ph--4x3  { aspect-ratio: 4 / 3; }
.ph--5x4  { aspect-ratio: 5 / 4; }
.ph--1x1  { aspect-ratio: 1 / 1; }
.ph--21x9 { aspect-ratio: 3 / 2; }
@media (min-width: 720px) { .ph--21x9 { aspect-ratio: 21 / 9; } }

/* Scrim for text over a photo. Directional, never a symmetric black wash.
   Used at most twice on the whole site — the hero deliberately puts all its
   type on a light surface beside the photos instead. */
.ph--scrim::after {
  background:
    linear-gradient(180deg, rgba(13, 34, 53, 0.16) 0%, rgba(13, 34, 53, 0.62) 60%,
      rgba(13, 34, 53, 0.88) 100%),
    linear-gradient(90deg, rgba(13, 34, 53, 0.68) 0%, rgba(13, 34, 53, 0.16) 60%,
      transparent 100%);
  mix-blend-mode: normal;
}
.ph__text {
  position: relative;
  z-index: 2;
  text-shadow: 0 1px 2px rgba(13, 20, 25, 0.35);
}
