/* ============================================================================
   Informed Software Solutions — Components
   Site furniture and reusable UI: header/nav, mega-flyout, mobile overlay,
   scroll-progress ridge, buttons, cards, tags, trust strip, forms, footer,
   custom cursor, section-header pattern.
   Consumes tokens.css + base.css. Raw colours never appear here.
   CLASS NAMES ARE A CONTRACT — page agents rely on them. Do not rename.
   ========================================================================== */

/* ===========================================================================
   [hidden] SAFETY — guarantee the HTML `hidden` attribute always collapses an
   element, even when a component sets its own `display` (flex/grid/inline-flex)
   at higher specificity. Used to recoverably hide sections/links (e.g. the
   Insights section + its footer link — search "INSIGHTS-HIDDEN") without
   deleting markup.
   =========================================================================== */
[hidden] {
  display: none !important;
}

/* ===========================================================================
   SCROLL-PROGRESS RIDGE — 3px beacon fill along the top edge.
   Lives OUTSIDE #smooth-wrapper (fixed). JS sets transform: scaleX().
   =========================================================================== */
.scroll-progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 3px;
  z-index: var(--z-progress);
  pointer-events: none;
  background: transparent;
}

.scroll-progress__bar {
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--beacon-600), var(--beacon-500) 60%, var(--beacon-400));
  box-shadow: 0 0 10px rgba(200, 134, 44, 0.5);
  will-change: transform;
}

/* ===========================================================================
   SITE HEADER / NAV
   Fixed, slim (72px). Transparent over hero; .is-scrolled → paper + blur.
   Lives OUTSIDE #smooth-wrapper.
   =========================================================================== */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex;
  align-items: center;
  transition:
    height var(--dur-fast) var(--ease-out),
    background-color var(--dur-med) var(--ease-standard),
    box-shadow var(--dur-med) var(--ease-standard),
    backdrop-filter var(--dur-med) var(--ease-standard);
}

.site-header__inner {
  width: 100%;
  max-width: var(--container-wide);
  margin-inline: auto;
  padding-inline: var(--container-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
}

/* Transparent-over-hero variant: light text for the dark navy hero */
.site-header--over-hero {
  color: var(--ink);
}

/* Scrolled state — glass-NAVY blur (the site is dark site-wide), hairline,
   deep shadow. Cool off-white text rides the blur. */
.site-header.is-scrolled {
  height: var(--header-h-scrolled);
  background-color: var(--glass-navy);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  backdrop-filter: blur(16px) saturate(1.2);
  box-shadow: 0 1px 0 var(--line-strong), var(--shadow-md);
  color: var(--ink);
}

/* Logo */
.site-header__logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
  line-height: 0;
}

.site-header__logo img,
.site-header__logo svg {
  /* Brand lockup (mark + wordmark) is ~3.1:1 — taller than the old prototype
     wordmark, so it runs 40-44px inside the 72px header. */
  height: 40px;
  width: auto;
}

/* Full wordmark vs. compact mark swap (<640px shows only the mark) */
.site-header__logo .logo-mark { display: none; }
.site-header__logo .logo-full { display: block; }

/* Context-aware brand artwork. The site is now dark in EVERY state (incl. the
   glass-navy scrolled header), so the LIGHT (white) lockup shows by default and
   in all states. The navy lockup remains in markup for future LIGHT-ground
   contexts: a header opts into it with `.site-header--light-ground`. On index
   (no such class) the light lockup always wins — including .is-scrolled. */
.site-header__logo .logo-img--light { display: inline-block; }
.site-header__logo .logo-img--navy  { display: none; }

/* Future light-ground header: swap to the navy lockup. */
.site-header--light-ground .logo-img--light { display: none; }
.site-header--light-ground .logo-img--navy  { display: inline-block; }

/* Primary nav links (right) */
.site-nav {
  display: none; /* mobile-first: hidden until ≥ desktop breakpoint */
  align-items: center;
  gap: var(--space-6);
}

.site-nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.site-nav__link {
  position: relative;
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  letter-spacing: 0.01em;
  padding-block: var(--space-2);
  color: inherit;
}

/* Animated underline (draws from left) */
.site-nav__link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background-color: var(--beacon-500);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-fast) var(--ease-out);
}

.site-nav__link:hover::after,
.site-nav__link:focus-visible::after,
.site-nav__link[aria-current="page"]::after,
.site-nav__link[aria-expanded="true"]::after {
  transform: scaleX(1);
}

.site-nav__link:hover {
  color: var(--accent-text);
}

/* Header actions cluster (phone / CTA) */
.site-header__actions {
  display: none;
  align-items: center;
  gap: var(--space-4);
}

/* ===========================================================================
   MEGA-FLYOUT — 3-column products dropdown.
   Panel positioned below header; JS toggles [data-open] / animates draw.
   =========================================================================== */
.has-flyout {
  position: relative;
}

.mega-flyout {
  position: absolute;
  top: calc(100% + var(--space-3));
  left: 50%;
  transform: translateX(-50%) translateY(-8px);
  width: min(840px, calc(100vw - var(--space-8)));
  background-color: var(--paper-raised);
  border: var(--rule-light);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  padding: var(--space-6);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: var(--z-flyout);
  transition:
    opacity var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out),
    visibility 0s linear var(--dur-fast);
}

/* Visibility is driven by the JS-set [data-open] state plus a pure-CSS hover
   affordance. focus-within is ALSO honoured, but ONLY when JS has not explicitly
   closed the panel — i.e. it must not override data-open="false". Without the
   :not([data-open="false"]) guard, focus-within kept the panel visually open
   after Escape (which sets data-open="false" and focuses the trigger), so it
   could never be dismissed by keyboard. */
.mega-flyout[data-open="true"],
.has-flyout:hover .mega-flyout:not([data-open="false"]),
.has-flyout:focus-within .mega-flyout:not([data-open="false"]) {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
  transition:
    opacity var(--dur-med) var(--ease-out),
    transform var(--dur-med) var(--ease-out),
    visibility 0s;
}

.mega-flyout__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
}

/* A single product entry in the flyout */
.flyout-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border-radius: var(--radius);
  border: 1px solid transparent;
  transition:
    background-color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    transform var(--dur-fast) var(--ease-out);
}

.flyout-item:hover,
.flyout-item:focus-visible {
  background-color: var(--navy-700);
  border-color: var(--line-strong);
  transform: translateY(-2px);
  color: var(--ink);
}

.flyout-item__head {
  display: flex;
  /* Pin the dot to the FIRST text line, not the vertical centre of the (1- or
     2-line) product name — so the dot sits consistently across all three items. */
  align-items: flex-start;
  gap: var(--space-3);
}

/* Accent dot — colour set inline or via product modifier */
.flyout-item__dot {
  width: 9px;
  height: 9px;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
  background-color: var(--accent);
  /* Centre the 9px dot within the product NAME's first line box. The name is
     --fs-h3 at line-height 1.1, so its first line is ~(--fs-h3 * 1.1) tall;
     offset the dot by half the leftover space to sit on that line (not the
     vertical centre of a 2-line name). */
  margin-top: calc((var(--fs-h3) * 1.1 - 9px) / 2);
}

/* Per-product accent dots — brightened for the dark flyout panel so each reads
   as a clear glint (the raw IV/DF navies are too low-contrast on navy-800). */
.flyout-item--ims    .flyout-item__dot { background-color: var(--beacon-400); }
.flyout-item--iv     .flyout-item__dot { background-color: var(--navy-400); }
.flyout-item--df     .flyout-item__dot { background-color: var(--navy-300); }

.flyout-item__name {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-display);
  font-variation-settings: 'opsz' 36, 'wght' var(--fw-display);
  color: var(--heading); /* cool off-white on the navy flyout panel */
  line-height: 1.1;
}

.flyout-item__tag {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  font-weight: 500;
  letter-spacing: var(--ls-tag);
  color: var(--text-soft);
}

.flyout-item__line {
  font-size: var(--fs-small);
  color: var(--text-soft);
  line-height: var(--lh-snug);
}

/* ===========================================================================
   HAMBURGER — mobile menu toggle (visible below desktop breakpoint)
   =========================================================================== */
.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 10px;
  margin-right: calc(var(--space-2) * -1);
  color: inherit;
}

.nav-toggle__bar {
  display: block;
  height: 2px;
  width: 100%;
  background-color: currentColor;
  border-radius: 2px;
  transition:
    transform var(--dur-fast) var(--ease-out),
    opacity var(--dur-fast) var(--ease-standard);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* ===========================================================================
   MOBILE FULL-SCREEN OVERLAY MENU
   =========================================================================== */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background-color: var(--navy-900);
  color: var(--paper);
  display: flex;
  flex-direction: column;
  padding: calc(var(--header-h) + var(--space-6)) var(--container-pad) var(--space-8);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-2%);
  transition:
    opacity var(--dur-med) var(--ease-out),
    transform var(--dur-med) var(--ease-out),
    visibility 0s linear var(--dur-med);
  overflow-y: auto;
}

.mobile-menu.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
  transition:
    opacity var(--dur-med) var(--ease-out),
    transform var(--dur-med) var(--ease-out),
    visibility 0s;
}

.mobile-menu__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-6);
}

.mobile-menu__link {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  padding-block: var(--space-4);
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-display);
  font-variation-settings: 'opsz' 48, 'wght' var(--fw-display);
  color: var(--paper);
  border-bottom: 1px solid rgba(143, 168, 194, 0.16);
}

.mobile-menu__link .index {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  font-weight: 500;
  letter-spacing: var(--ls-tag);
  color: var(--beacon-400);
  /* Index codes ('MS-01' etc.) must stay on ONE line and not hug the screen
     edge. Reserve a fixed column and keep the glyphs upright. */
  display: inline-block;
  min-width: 3.5rem;
  padding-right: var(--space-2);
  white-space: nowrap;
  flex-shrink: 0;
}

.mobile-menu__link:hover,
.mobile-menu__link:focus-visible {
  color: var(--beacon-400);
}

.mobile-menu__footer {
  margin-top: auto;
  padding-top: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  color: var(--navy-300);
  font-size: var(--fs-small);
}

/* Lock scroll when overlay open (JS adds to <html>/<body>) */
.is-menu-open {
  overflow: hidden;
}

/* ===========================================================================
   BUTTONS
   .btn base; .btn-primary (navy on light / beacon on dark); .btn-ghost outline.
   Inner <span class="btn__label"> for magnetic transforms.
   =========================================================================== */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-6);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.01em;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  border: var(--border-thick) solid transparent;
  transition:
    background-color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    color var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}

/* Inner label — JS translates this for the magnetic effect */
.btn__label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  will-change: transform;
}

.btn:active {
  transform: translateY(1px);
}

/* PRIMARY — navy fill on light, beacon glow on hover */
.btn-primary {
  background-color: var(--navy-700);
  color: var(--paper);
  border-color: var(--navy-700);
}

.btn-primary:hover {
  background-color: var(--navy-600);
  border-color: var(--navy-600);
  color: var(--paper);
  box-shadow: var(--shadow-beacon);
}

/* On dark (Operations) the primary becomes beacon */
.theme-operations .btn-primary {
  background-color: var(--beacon-500);
  border-color: var(--beacon-500);
  color: var(--navy-900);
}

.theme-operations .btn-primary:hover {
  background-color: var(--beacon-400);
  border-color: var(--beacon-400);
  color: var(--navy-900);
  box-shadow: var(--shadow-beacon);
}

/* GHOST — outline on the dark ground, fills toward amber on hover.
   Dark is the default site-wide; .theme-operations reinforces it identically. */
.btn-ghost {
  background-color: transparent;
  color: var(--ink);
  border-color: var(--line-strong);
}

.btn-ghost:hover {
  border-color: var(--beacon-400);
  color: var(--beacon-400);
  background-color: transparent;
  background-color: color-mix(in srgb, var(--beacon-400) 8%, transparent);
}

.theme-operations .btn-ghost {
  color: var(--ink);
  border-color: var(--line-strong);
}

.theme-operations .btn-ghost:hover {
  border-color: var(--beacon-400);
  color: var(--beacon-400);
  background-color: transparent;
  background-color: color-mix(in srgb, var(--beacon-400) 8%, transparent);
}

/* Beacon solid (used on light where strong CTA wanted) */
.btn-beacon {
  background-color: var(--beacon-500);
  color: var(--navy-900);
  border-color: var(--beacon-500);
}

.btn-beacon:hover {
  background-color: var(--beacon-600);
  border-color: var(--beacon-600);
  color: var(--paper);
  box-shadow: var(--shadow-beacon);
}

/* Sizes */
.btn-lg { padding: var(--space-4) var(--space-8); font-size: var(--fs-body); }
.btn-sm { padding: var(--space-2) var(--space-4); font-size: var(--fs-kicker); }

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

/* Text link with arrow — "Explore" / "Visit site ↗" */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-small);
  color: var(--ink); /* cool off-white on the dark ground */
}

.theme-operations .link-arrow { color: var(--ink); }

.link-arrow__icon {
  transition: transform var(--dur-fast) var(--ease-out);
}

.link-arrow:hover {
  color: var(--accent-text);
}

.link-arrow:hover .link-arrow__icon {
  transform: translate(2px, -2px);
}

/* Coming-soon treatment for placeholder "Visit site" links */
.coming-soon {
  position: relative;
  opacity: 0.78;
  cursor: default;
}

.coming-soon::after {
  content: 'Coming soon';
  font-family: var(--font-mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: var(--ls-tag);
  text-transform: uppercase;
  /* Amber tag on the dark ground (site-wide default). */
  color: var(--beacon-400);
  padding: 2px var(--space-2);
  border: 1px solid var(--beacon-600);
  border: 1px solid color-mix(in srgb, var(--beacon-400) 30%, transparent);
  border-radius: var(--radius-pill);
  background-color: var(--navy-800);
  background-color: color-mix(in srgb, var(--beacon-400) 12%, transparent);
  margin-left: var(--space-1);
}

.theme-operations .coming-soon::after {
  color: var(--beacon-400);
  border-color: var(--beacon-600);
  border-color: color-mix(in srgb, var(--beacon-400) 30%, transparent);
  background-color: var(--navy-800);
  background-color: color-mix(in srgb, var(--beacon-400) 12%, transparent);
}

/* ===========================================================================
   CARDS — paper-raised, 8px radius, navy-tinted shadow, hover lift
   =========================================================================== */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  /* navy-800 surface, subtle navy-600 hairline, deep cool shadow */
  background-color: var(--navy-800);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  transition:
    transform var(--dur-med) var(--ease-out),
    box-shadow var(--dur-med) var(--ease-out),
    border-color var(--dur-med) var(--ease-standard),
    background-color var(--dur-med) var(--ease-standard);
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: color-mix(in srgb, var(--navy-600) 55%, transparent);
  background-color: var(--navy-700);
}

/* Interactive (clickable) card raises affordance */
.card--link {
  cursor: pointer;
}

.card--link:hover {
  border-color: color-mix(in srgb, var(--beacon-400) 45%, transparent);
}

.card__title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-display);
  font-variation-settings: 'opsz' 36, 'wght' var(--fw-display);
  color: var(--heading); /* cool off-white on the navy card surface */
  line-height: 1.15;
}

.card__body {
  font-size: var(--fs-body);
  color: var(--text-soft);
  line-height: var(--lh-body);
}

/* Card on dark theme */
.theme-operations .card {
  background-color: var(--navy-800);
  border-color: rgba(143, 168, 194, 0.18);
  box-shadow: none;
}

.theme-operations .card:hover {
  border-color: rgba(143, 168, 194, 0.35);
  box-shadow: var(--shadow-lg);
}

.theme-operations .card__title { color: var(--paper); }
.theme-operations .card__body  { color: var(--navy-300); }

/* Accent top-edge for product/feature cards (uses --accent or product var) */
.card--accent::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  border-radius: var(--radius) var(--radius) 0 0;
  background-color: var(--accent);
}

/* ===========================================================================
   TAGS — "evidence tag" mono labels (MS-01, IV-02, DF-03)
   =========================================================================== */
.tag,
.mono-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  font-weight: 500;
  letter-spacing: var(--ls-tag);
  text-transform: uppercase;
  line-height: 1;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  background-color: var(--paper-raised);
}

/* Accent variant — amber text + faint amber wash on the dark ground */
.tag--accent,
.mono-tag--accent {
  color: var(--accent-text);
  border-color: var(--beacon-600);
  border-color: color-mix(in srgb, var(--beacon-400) 40%, transparent);
  background-color: var(--navy-800);
  background-color: color-mix(in srgb, var(--beacon-400) 10%, transparent);
}

.theme-operations .tag,
.theme-operations .mono-tag {
  color: var(--navy-300);
  border-color: rgba(143, 168, 194, 0.28);
  background-color: transparent;
}

.theme-operations .tag--accent,
.theme-operations .mono-tag--accent {
  color: var(--beacon-400);
  /* Static fallbacks for pre-color-mix browsers (tag border + wash). */
  border-color: var(--beacon-600);
  border-color: color-mix(in srgb, var(--beacon-400) 40%, transparent);
  background-color: var(--navy-800);
  background-color: color-mix(in srgb, var(--beacon-400) 10%, transparent);
}

/* ===========================================================================
   TRUST STRIP — client logo row, grayscale → navy on hover
   =========================================================================== */
.trust-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(var(--space-6), 5vw, var(--space-10));
}

.trust-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  flex-shrink: 0;
}

.trust-logo img,
.trust-logo svg {
  height: 100%;
  width: auto;
  max-width: 160px;
  object-fit: contain;
  /* The client crests/wordmarks are dark navy artwork on transparent — on the
     deep navy ground they'd vanish. Knock them to pure white, then dim, so they
     read as elegant uniform LIGHT marks; warm to full white on hover. */
  filter: brightness(0) invert(1) opacity(0.62);
  transition: filter var(--dur-med) var(--ease-standard);
}

.trust-logo:hover img,
.trust-logo:hover svg {
  filter: brightness(0) invert(1) opacity(1);
}

/* Typographic mark for the fictional client (West Engineering Ltd) */
.trust-logo--type {
  font-family: var(--font-display);
  font-size: var(--fs-lead);
  font-weight: var(--fw-display);
  font-variation-settings: 'opsz' 28, 'wght' var(--fw-display);
  color: var(--navy-500);
  letter-spacing: -0.01em;
  opacity: 0.7;
  transition: color var(--dur-med) var(--ease-standard), opacity var(--dur-med) var(--ease-standard);
}

.trust-logo--type:hover {
  color: var(--navy-700);
  opacity: 1;
}

/* ===========================================================================
   FORM ELEMENTS — top-label, 1px bottom-border, beacon focus underline.
   Dark-theme variant for the Operations contact section.
   =========================================================================== */
.field {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
}

.field__label {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  font-weight: 500;
  letter-spacing: var(--ls-tag);
  text-transform: uppercase;
  color: var(--ink-soft);
  transition: color var(--dur-fast) var(--ease-standard);
}

.field__control {
  position: relative;
}

.field__input,
.field__textarea,
.field__select {
  width: 100%;
  padding: var(--space-3) 0;
  background-color: transparent;
  border: 0;
  border-bottom: var(--border-thick) solid var(--line);
  color: var(--ink);
  font-size: var(--fs-body);
  line-height: 1.4;
  border-radius: 0;
  transition: border-color var(--dur-fast) var(--ease-standard);
  appearance: none;
}

.field__textarea {
  min-height: 7.5rem;
  resize: vertical;
}

.field__input::placeholder,
.field__textarea::placeholder {
  color: var(--ink-soft);
  opacity: 0.6;
}

/* Animated focus underline — beacon bar draws under the field */
.field__underline {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background-color: var(--beacon-500);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-med) var(--ease-out);
  pointer-events: none;
}

.field__input:focus ~ .field__underline,
.field__textarea:focus ~ .field__underline,
.field__select:focus ~ .field__underline {
  transform: scaleX(1);
}

.field__input:focus,
.field__textarea:focus,
.field__select:focus {
  outline: none;
  border-bottom-color: var(--beacon-500);
}

.field:focus-within .field__label {
  color: var(--accent-text);
}

/* States */
.field--error .field__input,
.field--error .field__textarea {
  border-bottom-color: var(--danger);
}

.field--error .field__label {
  color: var(--danger);
}

.field--success .field__input,
.field--success .field__textarea {
  border-bottom-color: var(--success);
}

.field__message {
  font-size: var(--fs-small);
  color: var(--ink-soft);
  min-height: 1.2em;
}

.field--error .field__message  { color: var(--danger); }
.field--success .field__message { color: var(--success); }

/* Dark (Operations) form variant */
.theme-operations .field__label { color: var(--navy-300); }

.theme-operations .field__input,
.theme-operations .field__textarea,
.theme-operations .field__select {
  color: var(--paper);
  border-bottom-color: rgba(143, 168, 194, 0.32);
}

.theme-operations .field__input::placeholder,
.theme-operations .field__textarea::placeholder {
  color: var(--navy-300);
  opacity: 0.7;
}

.theme-operations .field__underline { background-color: var(--beacon-400); }

.theme-operations .field__input:focus,
.theme-operations .field__textarea:focus,
.theme-operations .field__select:focus {
  border-bottom-color: var(--beacon-400);
}

.theme-operations .field:focus-within .field__label { color: var(--beacon-400); }

/* Form success / transmission state container */
.form-status {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: var(--ls-tag);
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.form-status--success { color: var(--success); }
.form-status--error   { color: var(--danger); }
.theme-operations .form-status--success { color: var(--beacon-400); }

/* ===========================================================================
   SECTION-HEADER COMPONENT — kicker + h2 + lead with consistent rhythm
   =========================================================================== */
.section-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: var(--measure);
  margin-bottom: var(--space-9);
}

.section-head--center {
  margin-inline: auto;
  text-align: center;
  align-items: center;
}

.section-head__title {
  font-size: var(--fs-h2);
  margin: 0;
}

.section-head__lead {
  font-size: var(--fs-lead);
  line-height: var(--lh-snug);
  color: var(--text-soft);
}

/* ===========================================================================
   FOOTER — navy-800, columns, hairline top rule
   =========================================================================== */
.site-footer {
  /* deepest band — the footer floor of the layered-navy site */
  background-color: var(--navy-950);
  color: var(--navy-300);
  /* Tightened top padding: the footer read sparse/tall with a slab of empty
     navy above the columns. --space-8 brings the columns up to a confident
     rhythm without crowding the top hairline. */
  padding-block: var(--space-8) var(--space-7);
  position: relative;
  overflow: clip; /* contain the oversized wordmark watermark below */
}

/* top hairline + a faint amber glint at the seam for a premium finish */
.site-footer::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  z-index: 1;
  background:
    linear-gradient(90deg,
      transparent 0%,
      rgba(224, 162, 61, 0.22) 50%,
      transparent 100%),
    var(--line-strong);
}

/* Anchoring watermark — an oversized, very faint brand wordmark bleeding off the
   lower-left. It gives the tall navy floor a deliberate weight (so the columns
   no longer float in empty space) without adding any markup or competing with
   the copy. Decorative + non-interactive; sits behind the content (the footer's
   .container is lifted above it). Hidden from a11y/flow entirely (CSS-only). */
.site-footer::after {
  content: 'Informed';
  position: absolute;
  left: -0.04em;
  bottom: -0.30em;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  font-family: var(--font-display);
  font-weight: var(--fw-display-bold);
  font-variation-settings: 'opsz' 144, 'wght' var(--fw-display-bold);
  font-size: clamp(7rem, 4rem + 16vw, 16rem);
  line-height: 0.8;
  letter-spacing: -0.04em;
  color: var(--navy-100);
  opacity: 0.03; /* whisper-faint: presence, not legibility */
  white-space: nowrap;
}

/* Lift the real footer content above the watermark. */
.site-footer > .container { position: relative; z-index: 1; }

.site-footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  margin-bottom: var(--space-9);
}

.site-footer__brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 34ch;
}

.site-footer__brand img,
.site-footer__brand svg {
  /* White brand lockup on the deepest navy footer floor — full presence. */
  height: 42px;
  width: auto;
  color: var(--navy-100);
  opacity: 1;
}

.site-footer__tagline {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  letter-spacing: var(--ls-tag);
  text-transform: uppercase;
  color: var(--beacon-400);
}

.footer-col__heading {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  font-weight: 500;
  letter-spacing: var(--ls-tag);
  text-transform: uppercase;
  color: var(--paper);
  margin-bottom: var(--space-4);
}

.footer-col__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.footer-col__link {
  font-size: var(--fs-small);
  color: var(--navy-300);
}

.footer-col__link:hover {
  color: var(--beacon-400);
}

.site-footer__bottom {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-top: var(--space-6);
  border-top: 1px solid rgba(143, 168, 194, 0.16);
  font-size: var(--fs-small);
  color: var(--navy-300);
}

.site-footer__sovereignty {
  max-width: 60ch;
  line-height: var(--lh-snug);
}

/* ===========================================================================
   CUSTOM CURSOR — desktop fine-pointer only; the amber print IS the cursor.
   A soft lerp-follow RING (trails the pointer) + a solid centre DOT pinned 1:1
   to the exact pointer position (zero lag). Hidden on touch / coarse / reduced
   motion. JS (initCursor) drives transforms and toggles the state classes.
   =========================================================================== */
.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  width: 28px;
  height: 28px;
  border: 1.5px solid var(--beacon-500);
  border-radius: var(--radius-pill);
  pointer-events: none;
  z-index: var(--z-cursor);
  transform: translate(-50%, -50%);
  mix-blend-mode: difference;
  opacity: 0;
  transition:
    width var(--dur-fast) var(--ease-out),
    height var(--dur-fast) var(--ease-out),
    opacity var(--dur-fast) var(--ease-standard),
    background-color var(--dur-fast) var(--ease-standard);
  will-change: transform;
}

.cursor-ring.is-active { opacity: 1; }

/* Magnetic / interactive hover grows + fills the ring */
.cursor-ring.is-hovering {
  width: 46px;
  height: 46px;
  background-color: rgba(200, 134, 44, 0.12);
}

/* Solid centre dot — the precise hit point. Tracks the pointer 1:1 (JS sets its
   transform straight to clientX/Y each move — no lerp), so it sits exactly under
   the pointer while the ring drifts behind. ~5px, solid amber. */
.cursor-dot {
  position: fixed;
  top: 0;
  left: 0;
  width: 5px;
  height: 5px;
  border-radius: var(--radius-pill);
  background-color: var(--beacon-400);
  pointer-events: none;
  z-index: var(--z-cursor);
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-standard);
  will-change: transform;
}

.cursor-dot.is-active { opacity: 1; }

/* --- Native-cursor handover -------------------------------------------------
   JS adds html.custom-cursor once the ring activates. We hide the native cursor
   ONLY here, and ONLY on a fine pointer with motion allowed — so a no-JS /
   reduced-motion / touch session never loses its native cursor (the class is
   simply never added, and this rule is additionally media/`:not(.no-motion)`
   gated as belt-and-braces). Applied broadly so the native arrow is gone over
   links, buttons and plain ground alike (the ring + dot are the affordance). */
@media (pointer: fine) {
  html.custom-cursor:not(.no-motion),
  html.custom-cursor:not(.no-motion) body,
  html.custom-cursor:not(.no-motion) a,
  html.custom-cursor:not(.no-motion) button,
  html.custom-cursor:not(.no-motion) [role="button"],
  html.custom-cursor:not(.no-motion) .card--link,
  html.custom-cursor:not(.no-motion) [data-anim="magnetic"] {
    cursor: none;
  }

  /* Precision typing: over a form field the native caret RETURNS and the custom
     ring + dot fade to near-zero. html.cursor-over-field is toggled by JS while
     the pointer is over an input/textarea/select/contenteditable. We re-assert
     the native cursor on html (overriding cursor:none above) and let each field
     show its own caret (text for inputs/textarea, default arrow for selects). */
  html.custom-cursor.cursor-over-field:not(.no-motion),
  html.custom-cursor.cursor-over-field:not(.no-motion) body {
    cursor: auto;
  }
  html.custom-cursor:not(.no-motion) input,
  html.custom-cursor:not(.no-motion) textarea,
  html.custom-cursor:not(.no-motion) [contenteditable=""],
  html.custom-cursor:not(.no-motion) [contenteditable="true"] {
    cursor: text;
  }
  html.custom-cursor:not(.no-motion) select {
    cursor: default;
  }

  /* Fade the ring + dot away while over a field so exactly ONE affordance (the
     native caret) shows during precision typing. */
  html.cursor-over-field .cursor-ring,
  html.cursor-over-field .cursor-dot {
    opacity: 0.04;
  }
}

/* Hide custom cursor where a precise pointer isn't available */
@media (hover: none), (pointer: coarse) {
  .cursor-ring,
  .cursor-dot { display: none !important; }
}

/* Reduced motion: no custom cursor at all — native pointer everywhere. The
   ring/dot are JS-activated (initCursor never runs under reduced motion), but
   hide them defensively so nothing can show, and never suppress the native
   cursor (the html.custom-cursor class is gated `:not(.no-motion)` above). */
@media (prefers-reduced-motion: reduce) {
  .cursor-ring,
  .cursor-dot { display: none !important; }
}

.no-motion .cursor-ring,
.no-motion .cursor-dot { display: none !important; }

/* ===========================================================================
   RESPONSIVE — progressive enhancement upward
   =========================================================================== */

/* ≥ 640px — show full logo wordmark (mark-only is for the very smallest) */
@media (min-width: 640px) {
  .site-header__logo img,
  .site-header__logo svg { height: 42px; }
}

/* Compact mark on the smallest screens */
@media (max-width: 639.98px) {
  .site-header__logo .logo-full { display: none; }
  .site-header__logo .logo-mark { display: block; }
  .site-header__logo .logo-mark img,
  .site-header__logo .logo-mark svg { height: 40px; }
}

/* ≥ 960px — desktop nav appears, hamburger hides */
@media (min-width: 960px) {
  .site-nav { display: flex; }
  .site-header__actions { display: flex; }
  .nav-toggle { display: none; }
  .mobile-menu { display: none; }
}

/* Footer multi-column at tablet+ */
@media (min-width: 640px) {
  .site-footer__grid {
    grid-template-columns: 1.5fr 1fr 1fr;
  }
}

@media (min-width: 960px) {
  .site-footer__grid {
    grid-template-columns: 2fr 1fr 1fr 1fr;
  }
  .site-footer__bottom {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

/* ===========================================================================
   PARTICLE WARP OVERLAY  (js/warp-transition.js)
   ---------------------------------------------------------------------------
   Full-viewport fixed host for the long-jump particle warp. The CANVAS does all
   the visuals; this element only positions/layers it and gates its visibility.

   Layering: z-index 1200 — ABOVE the header (300), cursor (900), modal (1000)
   and toast (1100), but FAR BELOW the home preloader (9999) so a warp can never
   sit over the loading screen. pointer-events:none always (the overlay is brief
   ~1s and never needs to intercept input). Hidden (display:none) until the
   module adds .is-active for the life of a single transition, then removed
   again on teardown — so it costs nothing when idle.

   No reduced-motion rules are needed here: main.js never invokes the warp under
   reduced motion (it falls back to the existing instant/auto navigation), so
   the overlay is simply never activated in that mode.
   =========================================================================== */
.warp-overlay {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: none;          /* idle: out of the layout + paint entirely */
  pointer-events: none;   /* brief + decorative — never intercepts input */
}

.warp-overlay.is-active {
  display: block;
}

.warp-overlay__canvas {
  display: block;
  width: 100%;
  height: 100%;
}
