/* CADOpt site chrome — header, mega menu, mobile drawer, footer
   Structural behaviour re-themed from
   _skills/13_web_experience_craft/patterns/thumb360-kit.css §4–6 onto
   CADOpt's own tokens (tokens.css). Only this file's values change per
   client; the state machine in main.js stays the same everywhere. */

/* ---- Header ---- */
.site-header{
  position:sticky; top:0; z-index:var(--z-header);
  background:rgba(255,255,255,.92);
  backdrop-filter:saturate(180%) blur(8px);
  border-bottom:1px solid transparent;
  transition:border-color var(--duration-base) var(--ease-out), box-shadow var(--duration-base) var(--ease-out);
}
.site-header[data-scrolled="true"]{
  border-bottom-color:var(--border-subtle);
  box-shadow:var(--shadow-sm);
}
.site-header__bar{
  display:flex; align-items:center; gap:var(--space-6);
  height:var(--header-h);
  transition:height var(--duration-base) var(--ease-out);
}
.site-header[data-scrolled="true"] .site-header__bar{ height:var(--header-h-scrolled); }
.site-header__logo img{ height:70px; width:auto; }
.site-header__logo{ display:flex; align-items:center; flex:none; }

/* ---- Primary nav ---- */
.primary-nav{ margin-left:auto; }
.primary-nav > ul{ list-style:none; display:flex; align-items:center; gap:var(--space-1); margin:0; padding:0; }
.nav-item{ position:relative; }
.nav-link{
  display:inline-flex; align-items:center; gap:6px;
  height:44px; padding-inline:var(--space-3);
  font-family:var(--font-brand); font-size:15px; font-weight:600; color:var(--text-body);
  background:none; border:0; cursor:pointer; border-radius:var(--radius-sm);
  transition:color var(--duration-fast) var(--ease-out), background-color var(--duration-fast) var(--ease-out);
}
.nav-link:hover{ color:var(--brand); background:var(--surface-brand-soft); text-decoration:none; }
.nav-link[aria-expanded="true"]{ color:var(--brand); background:var(--surface-brand-soft); }
.nav-link svg{ width:12px; height:12px; flex:none; transition:transform var(--duration-fast) var(--ease-out); }
.nav-link[aria-expanded="true"] svg{ transform:rotate(180deg); }

/* ---- Header CTA / phone ---- */
.site-header__cta{ display:flex; align-items:center; gap:var(--space-5); flex:none; }
.site-header__phone{
  display:flex; align-items:center; gap:8px;
  font-family:var(--font-brand); font-size:14px; font-weight:600; color:var(--text-body);
}
.site-header__phone:hover{ color:var(--brand); text-decoration:none; }
.site-header__phone svg{ width:16px; height:16px; color:var(--brand-bright); }
@media (max-width:1180px){ .site-header__phone{ display:none; } }

/* ---- Mega menu panel ---- */
.mega-panel{
  position:absolute; top:calc(100% + 12px); left:50%; z-index:var(--z-panel);
  width:min(920px, calc(100vw - var(--gutter) * 2));
  max-height:70vh; overflow:auto;
  transform:translateX(-50%) translateY(-6px);
  background:var(--white);
  border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);
  padding:var(--space-8);
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity var(--duration-base) var(--ease-out),
             transform var(--duration-base) var(--ease-out),
             visibility 0s linear var(--duration-base);
}
.mega-panel[data-open="true"]{
  opacity:1; visibility:visible; pointer-events:auto;
  transform:translateX(-50%) translateY(0);
  transition-delay:0s;
}
.mega-panel--narrow{
  width:min(340px, calc(100vw - var(--gutter) * 2)); left:0;
  transform:translateY(-6px); padding:var(--space-4);
  border-radius:var(--radius-xl); /* same approved radius as the full mega menus */
}
.mega-panel--narrow[data-open="true"]{ transform:translateY(0); }

/* ---- Full-width mega menu (Products, Services, Industries) ----
   True mega menus break out of their trigger's anchor, but are still
   bounded to the SAME box as the header bar's own .container (same
   --container-lg / --gutter tokens, no independent numbers) — logo-left
   to CTA-right, never the raw viewport edge. Centred with the same
   left:50% + translateX(-50%) technique the base .mega-panel already
   uses above, just with a width formula instead of a fixed px width. */
.mega-panel--full{
  position:fixed; top:var(--header-h); left:50%;
  width:calc(min(var(--container-lg), 100vw) - var(--gutter) * 2);
  transform:translateX(-50%) translateY(-8px);
  /* Now that the panel is inset from the viewport edge rather than
     flush against it, squared-off corners read as a leftover of the old
     full-bleed layout. --radius-xl is this design system's own token for
     a large dark rounded surface (the same value .products-showcase
     already uses on /solutions/) — reused here rather than a one-off
     20px. overflow:auto (inherited from .mega-panel) already clips
     content to these corners, so it isn't switched to overflow:hidden —
     that would drop the panel's own scrollbar-when-tall behaviour. */
  border-radius:var(--radius-xl); border-left:0; border-right:0; border-top:0;
  box-shadow:var(--shadow-lg);
  padding:var(--space-8) 0;
}
/* One shared outer height across Products, Services and Industries (the
   three panels that carry both --full and --dark) — not left to each
   panel's own content, so switching between them never itself changes
   the dropdown's footprint, and the hero/banner behind it never sees a
   height that varies by which menu happens to be open.
   Products' tallest column (Cadence's 8-item list: 32px logo + 14px
   gap + 8 links at 13px/1.5 line-height with 3px top/bottom padding
   each ≈ 204px + 14px of list gaps ≈ 264px of content) is the binding
   constraint again: Services' and Industries' own intro paragraphs
   (the other candidate — eyebrow + heading + lead paragraph + a
   margin-top:28px .btn) were shortened on client direction specifically
   so they'd no longer need more room than Products does, rather than
   inflating the shared height to fit a long paragraph every panel then
   has to carry. 340px (328px of Products' own padding+content, plus a
   small margin) is tight for Products and leaves Services/Industries
   with a modest, not excessive, gap below their own shorter content —
   still engineered from the CSS, not a live DOM measurement; the
   inherited overflow:auto from .mega-panel is the safety net if real
   content ever runs longer than estimated (scrolls instead of
   clipping). align-items:start on .products-showcase (the shared base
   rule) keeps content pinned to the top rather than centering into
   whatever room is left. */
.mega-panel--full.mega-panel--dark{ height:340px; }
.mega-panel--full[data-open="true"]{ transform:translateX(-50%) translateY(0); }
.site-header[data-scrolled="true"] .mega-panel--full{ top:var(--header-h-scrolled); }
/* .mega-panel--full above already resolves to the exact logo-to-CTA
   content width, so the inner wrapper just fills it — no second
   max-width/margin layer duplicating that math. The one padding kept
   here (--space-3) is a deliberate, exact match for the negative
   margin-inline already used by .mega-panel__link / .products-showcase__
   company / __product (padding X, margin -X — a hover-hitbox trick), so
   their hover backgrounds reach exactly to the panel's edge and never
   spill past it; it is not a leftover of the old --gutter inset. */
.mega-panel__inner{ width:100%; padding-inline:var(--space-3); }

/* Dark variant (Products menu) — reuses the site's --grad-ink surface,
   never a flat #000. Every mega-panel primitive (heading, link, all-link,
   proof strip) gets a light-on-dark counterpart here rather than a
   separate component, since the structure is identical, only the surface
   flips. */
.mega-panel--dark{ background:var(--grad-ink); }
.mega-panel--dark .mega-panel__heading{ color:rgba(255,255,255,.55); border-bottom-color:rgba(255,255,255,.18); }
.mega-panel--dark .mega-panel__link strong{ color:var(--white); }
.mega-panel--dark .mega-panel__link span{ color:rgba(255,255,255,.62); }
.mega-panel--dark .mega-panel__link:hover{ background:rgba(255,255,255,.08); }
.mega-panel--dark .mega-panel__link:hover strong{ color:var(--blue-300); }
.mega-panel--dark .mega-panel__all{ color:var(--blue-300); }
.mega-panel--dark .mega-panel__proof{ border-top-color:rgba(255,255,255,.16); color:rgba(255,255,255,.55); }

.mega-panel__grid{ display:grid; gap:var(--space-8); }
.mega-panel__grid--feature{ grid-template-columns:1fr 280px; }
@media (max-width:900px){ .mega-panel__grid--feature{ grid-template-columns:1fr; } }

.mega-panel__heading{
  font-family:var(--font-brand); font-size:12px; font-weight:700;
  text-transform:uppercase; letter-spacing:.1em; color:var(--text-muted);
  margin:0 0 var(--space-3); padding-bottom:var(--space-2);
  border-bottom:1px solid var(--border-subtle);
}
.mega-panel__cols{ display:grid; grid-template-columns:1fr 1fr; gap:0 var(--space-6); }
.mega-panel__list{ list-style:none; margin:0; padding:0; }
.mega-panel__list li + li{ margin-top:2px; }
.mega-panel__link{
  display:block; padding:var(--space-2) var(--space-3);
  margin-inline:calc(var(--space-3) * -1);
  border-radius:var(--radius-sm); color:var(--text-strong);
  transition:background-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.mega-panel__link:hover{ background:var(--surface-brand-soft); color:var(--brand); text-decoration:none; }
/* Global mega-menu typography tokens (tokens.css) — same primary-item and
   description scale as the Products/Services/Industries full mega panels
   (.products-showcase__company, .products-showcase__panel p) and the
   mobile accordion equivalents, so Company/Resources/Support read at the
   identical weight/size as every other menu. */
.mega-panel__link strong{ display:block; font-family:var(--font-brand); font-size:var(--mega-item-size); font-weight:var(--mega-item-weight); line-height:var(--mega-item-line); }
.mega-panel__link span{ display:block; font-size:var(--mega-desc-size); font-weight:var(--mega-desc-weight); color:var(--text-muted); line-height:var(--mega-desc-line); margin-top:2px; }

.mega-panel__all{
  display:inline-flex; align-items:center; gap:6px;
  margin-top:var(--space-4); font-family:var(--font-brand); font-size:13px; font-weight:700; color:var(--blue-600);
}
.mega-panel__all svg{ width:14px; height:14px; }
.mega-panel__all:hover{ text-decoration:underline; }

.mega-panel__feature{
  background:var(--surface-brand-soft); border-radius:var(--radius-md);
  padding:var(--space-5); display:flex; flex-direction:column;
}
.mega-panel__kicker{
  font-family:var(--font-mono); font-size:11px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--brand-bright); margin-bottom:var(--space-2);
}
.mega-panel__feature h4{ font-size:16px; margin:0 0 var(--space-2); }
.mega-panel__feature p{ font-size:13px; color:var(--text-muted); margin-bottom:var(--space-4); }
.mega-panel__feature .btn{ margin-top:auto; height:40px; padding-inline:var(--space-4); font-size:13px; }

.mega-panel__proof{
  grid-column:1 / -1; margin-top:var(--space-6); padding-top:var(--space-4);
  border-top:1px solid var(--border-subtle);
  display:flex; flex-wrap:wrap; gap:var(--space-5);
  font-family:var(--font-mono); font-size:12px; color:var(--text-muted); letter-spacing:.02em;
}

/* ---- Homepage Solutions tabs (Products/Services — click-to-swap, no
   dropdown/hover/overlay). Replaces an earlier hover mega-menu version:
   client direction was explicit that this control must never open a
   floating panel — it only switches which of the two card grids below is
   visible, in place, with no layout shift. ---- */
.solutions-tabs{ display:flex; gap:10px; }
.solutions-tabs__btn{
  display:inline-flex; align-items:center;
  height:44px; padding-inline:22px;
  font-family:var(--font-brand); font-size:14px; font-weight:600; color:var(--text-body);
  background:var(--white); border:1px solid var(--border-subtle); border-radius:var(--radius-md);
  cursor:pointer;
  transition:background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.solutions-tabs__btn:hover{ border-color:var(--brand); }
.solutions-tabs__btn.is-active{ background:var(--surface-brand-soft); border-color:var(--brand); color:var(--brand); }
.solutions-tabs__btn:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
@media (max-width:600px){ .solutions-tabs{ width:100%; } .solutions-tabs__btn{ flex:1; justify-content:center; } }

/* Both tab panels share the same grid; only one is ever in the DOM's
   rendered flow ([hidden] removes the other), so switching never reserves
   space for the hidden set and never shifts the page. grid-template-rows
   is not needed for equal card height — the cards' own min-height
   (components.css) is the floor, since a two-row grid does not equalise
   height across rows on its own (only within a row). */
.solutions-cards[hidden]{ display:none; }
.solutions-cards:not([hidden]){
  display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:var(--space-6);
  animation:solutionsTabFade var(--duration-base) var(--ease-out);
}
/* --duration-base resolves to 0ms under prefers-reduced-motion (tokens.css),
   so this animation is already inert there without a separate override. */
@keyframes solutionsTabFade{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:translateY(0); } }
@media (max-width:900px){ .solutions-cards:not([hidden]){ grid-template-columns:repeat(2, minmax(0, 1fr)); } }
@media (max-width:600px){ .solutions-cards:not([hidden]){ grid-template-columns:1fr; } }

/* ---- Clientele filter/grid (homepage "Trusted by engineering teams") ----
   Own tab style, not a reuse of .solutions-tabs__btn — that pattern's
   active state is a soft-blue background with blue text (right for the
   Products/Services pair), but this section's reference is a SOLID
   brand-blue active tab with white text, so it needed its own active
   rule rather than inheriting the wrong one. Base geometry (height,
   padding, radius, font) is deliberately the same scale as
   .solutions-tabs__btn for visual consistency across the two tab groups
   on this page. flex-wrap:wrap is the one real structural difference —
   11 categories were never going to fit one row like the 2-item
   Products/Services pair does. */
.clientele-tabs{ display:flex; flex-wrap:wrap; justify-content:center; gap:10px; margin:28px auto 0; max-width:960px; }
.clientele-tabs__btn{
  display:inline-flex; align-items:center;
  height:44px; padding-inline:22px;
  font-family:var(--font-brand); font-size:14px; font-weight:600; color:var(--text-body);
  background:var(--white); border:1px solid var(--border-subtle); border-radius:var(--radius-pill);
  cursor:pointer;
  transition:background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.clientele-tabs__btn:hover{ border-color:var(--brand); }
.clientele-tabs__btn.is-active{ background:var(--grad-blade); border-color:transparent; color:#fff; }
.clientele-tabs__btn:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
@media (max-width:600px){ .clientele-tabs{ gap:8px; } .clientele-tabs__btn{ height:40px; padding-inline:16px; font-size:13px; } }

/* Grid — same [hidden]-driven show/hide as .solutions-cards above (native
   attribute, toggled by the same initSolutionsTabs() JS), just its own
   column counts per this section's spec: 5 desktop, 3 tablet, 2 mobile.
   justify-content:center (not stretch) on the last, often-partial row —
   Foundries has exactly 1 logo, Tooling 11 (not a clean multiple of 5) —
   so a short final row centers instead of stretching one card oddly wide
   or leaving a ragged left-aligned gap. */
.clientele-grid[hidden]{ display:none; }
.clientele-grid:not([hidden]){
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:16px; margin-top:28px;
  animation:solutionsTabFade var(--duration-base) var(--ease-out);
}
.clientele-card{
  display:flex; align-items:center; justify-content:center;
  width:calc((100% - 4 * 16px) / 5); min-width:150px; height:84px;
  padding:14px 18px; box-sizing:border-box;
  background:var(--white); border:1px solid var(--border-subtle); border-radius:var(--radius-md);
  box-shadow:var(--shadow-sm);
}
.clientele-card img{ max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain; }
@media (max-width:900px){ .clientele-card{ width:calc((100% - 2 * 16px) / 3); } }
@media (max-width:600px){ .clientele-card{ width:calc((100% - 1 * 16px) / 2); min-width:0; height:72px; } }

/* ---- Burger (mobile toggle) ---- */
.burger{
  display:none; width:44px; height:44px; flex:none;
  align-items:center; justify-content:center;
  background:none; border:1px solid var(--border-strong); border-radius:var(--radius-sm);
  cursor:pointer;
}
.burger span{
  display:block; width:18px; height:2px; background:var(--text-strong);
  border-radius:2px; position:relative;
  transition:transform var(--duration-base) var(--ease-out), background-color var(--duration-fast) var(--ease-out);
}
.burger span::before, .burger span::after{
  content:""; position:absolute; left:0; width:18px; height:2px;
  background:var(--text-strong); border-radius:2px;
  transition:transform var(--duration-base) var(--ease-out);
}
.burger span::before{ top:-6px; }
.burger span::after{ top:6px; }
.burger[aria-expanded="true"] span{ background:transparent; }
.burger[aria-expanded="true"] span::before{ transform:translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span::after{ transform:translateY(-6px) rotate(-45deg); }

@media (max-width:900px){
  /* UPDATE (2026-09-15, mobile-only header fix): the logo was rendering at
     its desktop height (70px) here too. At the declared custom-logo ratio
     (320x88, ~3.6:1) that's ~254px wide — combined with the gutter (20px
     each side at narrow widths, tokens.css --gutter) and the burger
     (44px), that's ~322px of required width against only ~280px of
     content area at a 320px viewport, on a `.site-header__bar` with no
     flex-wrap: guaranteed horizontal overflow, not just a cramped fit.
     Shrinking the logo (and the header itself) at this same breakpoint
     the drawer already uses removes that overflow risk with room to
     spare (~160px logo + burger + gap comfortably under 280px). Desktop's
     70px/92px are untouched — these rules only apply ≤900px. */
  .site-header__bar{ height:64px; gap:var(--space-4); }
  .site-header[data-scrolled="true"] .site-header__bar{ height:60px; }
  .site-header__logo img{ height:44px; }
  .primary-nav, .site-header__cta{ display:none; }
  .burger{ display:inline-flex; margin-left:auto; }
}

/* ---- Mobile drawer ---- */
.scrim{
  position:fixed; inset:0; z-index:var(--z-scrim);
  background:rgba(28,33,38,.55);
  opacity:0; visibility:hidden;
  transition:opacity var(--duration-base) var(--ease-out), visibility 0s linear var(--duration-base);
}
.scrim[data-open="true"]{ opacity:1; visibility:visible; transition-delay:0s; }

.drawer{
  position:fixed; top:0; right:0; z-index:var(--z-drawer);
  width:min(400px, 88vw); height:100dvh;
  background:var(--white);
  display:flex; flex-direction:column;
  transform:translateX(100%);
  transition:transform var(--duration-slow) var(--ease-out);
}
@supports not (height: 100dvh){ .drawer{ height:100vh; } }
.drawer[data-open="true"]{ transform:translateX(0); }

.drawer__head{
  display:flex; align-items:center; justify-content:space-between;
  padding:var(--space-4) var(--space-5); border-bottom:1px solid var(--border-subtle); flex:none;
}
.drawer__title{ font-family:var(--font-brand); font-weight:700; font-size:15px; }
.drawer__close{
  width:40px; height:40px; display:grid; place-items:center;
  background:none; border:1px solid var(--border-strong); border-radius:var(--radius-sm); cursor:pointer;
}
.drawer__body{ flex:1; overflow-y:auto; padding:var(--space-4) var(--space-5); -webkit-overflow-scrolling:touch; }
.drawer__link{
  display:flex; align-items:center; min-height:52px;
  font-family:var(--font-brand); font-size:15px; font-weight:600; color:var(--text-strong);
  border-bottom:1px solid var(--border-subtle);
}
.drawer__foot{
  flex:none; padding:var(--space-5);
  border-top:1px solid var(--border-subtle); background:var(--surface-sunken);
}
.drawer__foot .btn{ width:100%; }
.drawer__contact{ margin-top:var(--space-4); display:flex; flex-direction:column; gap:var(--space-2); font-size:14px; }

/* ---- Accordion (drawer sections) ---- */
.acc{ border-bottom:1px solid var(--border-subtle); }
/* Mobile drawer accordion — the mega menus' small-screen equivalent, so
   it shares the same --mega-item-*/--mega-subitem-* scale (tokens.css):
   .acc__trigger is the top-level Company/Products/Services/Industries/
   Resources/Support row (matches .nav-link's own trigger role); leaf
   links (.acc__panel a) get the submenu scale, matching .products-
   showcase__product / .mega-panel__link strong on desktop. */
.acc__trigger{
  display:flex; align-items:center; justify-content:space-between; gap:var(--space-3);
  width:100%; min-height:52px; padding:var(--space-3) 0;
  background:none; border:0; cursor:pointer; text-align:left;
  font-family:var(--font-brand); font-size:var(--mega-item-size); font-weight:var(--mega-item-weight); line-height:var(--mega-item-line); color:var(--text-strong);
}
.acc__trigger svg{ width:12px; height:12px; flex:none; transition:transform var(--duration-fast) var(--ease-out); }
.acc__trigger[aria-expanded="true"] svg{ transform:rotate(180deg); }
.acc__panel{ display:grid; grid-template-rows:0fr; transition:grid-template-rows var(--duration-base) var(--ease-out); }
.acc__panel > div{ overflow:hidden; }
.acc__trigger[aria-expanded="true"] + .acc__panel{ grid-template-rows:1fr; }
.acc__panel a{
  display:block; padding:var(--space-3) 0 var(--space-3) var(--space-4);
  min-height:44px; font-family:var(--font-brand); font-size:var(--mega-subitem-size); font-weight:var(--mega-subitem-weight); line-height:var(--mega-subitem-line); color:var(--text-body);
}

body.no-scroll{ overflow:hidden; }

/* ---- Footer ---- */
/* ---- Site footer — light blue surface ----
   --blue-50, the theme's own existing token (not a new colour) — the
   lightest step of the same blue ramp, settled on after trying blue-200
   and blue-100 first (each one step lighter, per direct client choice).
   --text-muted (graphite-500) sits right at the WCAG AA edge (~4.1:1,
   just under the 4.5:1 floor) directly on this background even at its
   lightest, so the two spots that sat straight on it
   (.site-footer__logo-sub, .site-footer__bottom) keep using --text-body
   (graphite-700, comfortably >7:1) instead — see the accessibility note
   by each below. --text-muted stays wherever it sits on white instead
   (the social icons' own white circle), which is unaffected.
   No overlap logic here — the CARD in front of it (.home-cta) is what
   pulls itself down and forward, not the footer pulling itself up.
   padding-top clears .home-cta's own overlap — exactly half of that
   card's own --home-cta-h (clamp(220px,24vw,264px), so half is
   110-132px) — plus an explicit +23px breathing gap on top of that
   clearance (was +15px; +8px added per client direction for more
   breathing room between the card and the footer columns), so the
   logo/column row visibly starts below the card's curved bottom edge
   instead of butting straight up against it. .home-cta and .site-footer
   are siblings (not ancestor/descendant), so this can't reference the
   same custom property directly; the range below is kept in sync with
   it by hand — on pages without an overlapping card this just reads as
   a slightly roomier top edge, not a gap. */
.site-footer{
  background:var(--blue-50); color:var(--text-body);
  padding-block:calc(clamp(115px,11vw,145px) + 23px) var(--space-8);
}
@media (max-width:700px){
  /* Matches .home-cta's mobile --home-cta-h (clamp(260px,60vw,320px)) —
     half of that is 130-160px, so this clears it with the same margin
     of safety as the desktop rule above, plus the same +23px breathing
     gap below the card's edge. */
  .site-footer{ padding-top:calc(clamp(160px,42vw,200px) + 23px); }
}
.site-footer a{ color:var(--text-body); }
.site-footer a:hover{ color:var(--blue-700); }
.site-footer h4{ color:var(--text-strong); font-size:14px; letter-spacing:.06em; text-transform:uppercase; margin-bottom:var(--space-4); }
.site-footer__grid{ display:grid; grid-template-columns:1.4fr 1fr 1fr 1fr 1fr; gap:var(--space-8); }
.site-footer__grid ul{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:var(--space-2); font-size:14px; }
.site-footer__logo{
  display:inline-flex; align-items:center; gap:var(--space-3);
  margin-bottom:var(--space-4); text-decoration:none;
}
.site-footer__logo:hover{ color:inherit; }
.site-footer__logo-icon{ height:40px; width:auto; flex:none; }
.site-footer__logo-text{ display:flex; flex-direction:column; line-height:1.15; }
.site-footer__logo-name{
  font-family:var(--font-brand); font-weight:700; font-size:22px; color:var(--text-strong);
}
/* --text-body, not --text-muted: graphite-500 falls to ~2.9:1 against
   the new blue-200 footer background, below WCAG AA's 4.5:1 floor for
   text this size — graphite-700 clears it comfortably (~7.2:1). */
.site-footer__logo-sub{
  font-family:var(--font-brand); font-weight:400; font-size:14px; color:var(--text-body);
}
.site-footer__social{ display:flex; gap:var(--space-3); margin-top:var(--space-5); }
.site-footer__social a{
  display:inline-flex; align-items:center; justify-content:center;
  width:34px; height:34px; border-radius:50%;
  background:#fff; color:var(--text-muted); box-shadow:0 1px 3px rgba(15,45,80,.08);
  transition:background-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.site-footer__social a:hover{ background:var(--blue-50); color:var(--blue-700); }
.site-footer__social svg{ width:18px; height:18px; }
/* Contact column — icon + text pairs rather than plain link text. */
.site-footer__contact li{ display:flex; }
.site-footer__contact a{ display:inline-flex; align-items:center; gap:var(--space-2); }
.site-footer__contact svg{ width:16px; height:16px; flex:none; color:var(--blue-700); }
/* border-top uses a translucent dark ink rather than --border-subtle
   (graphite-150): that token is a near-white grey built for a near-white
   background and nearly disappears against blue-200. color:--text-body,
   not --text-muted, for the same contrast reason as .site-footer__logo-sub
   above. */
.site-footer__bottom{
  margin-top:var(--space-12); padding-top:var(--space-6);
  border-top:1px solid rgba(15,45,80,.15);
  display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:var(--space-3);
  font-family:var(--font-brand); font-size:12px; color:var(--text-body);
}
@media (max-width:1024px){
  .site-footer__grid{ grid-template-columns:1fr 1fr 1fr; gap:var(--space-6); }
}
@media (max-width:768px){
  .site-footer__grid{ grid-template-columns:1fr 1fr; }
}
@media (max-width:480px){
  .site-footer__grid{ grid-template-columns:1fr; }
}
