/* TITECH v3 · header.css: owned by the work order listed in work-orders/DESIGN-SPEC.md §1. */
/* The header (WO-03): a dark frosted bar that is transparent over dark heroes, hides while scrolling down and
   opens a dark full-screen menu on mobile. header.js toggles .is-scrolled, .is-over-hero and .is-hidden. */

/* The header is dark on every page, so it carries the dark context values itself (DESIGN-SPEC §2).
   The mobile menu inside it inherits them. */
.site-header {
  --ctx-bg: var(--c-banner); /* owner (2026-09-22): the header is the banner's navy, not ink, so it never reads as a black strip */
  --ctx-surface: rgb(255 255 255 / .04);
  --ctx-surface-hover: rgb(255 255 255 / .07);
  --ctx-heading: #F2F5FA;
  --ctx-body: #C5D0DE;
  --ctx-muted: #93A3B8;
  --ctx-line: rgb(255 255 255 / .09);
  --ctx-line-strong: rgb(255 255 255 / .18);
  --ctx-link: var(--c-signal-soft);
  --ctx-tint: rgb(255 255 255 / .04);
  --ctx-focus: var(--c-signal-soft); /* over the glass on a white page --c-signal is only 2.5:1, this is 3.6:1 */
  color: rgb(255 255 255 / .72);
  background: none;
  border-block-end: 0; /* moves to ::before, so the header is exactly --header-height tall */
  transition: transform var(--dur-base) var(--ease-out);
}

/* Base state, every page: frosted dark glass. The glass is a pseudo-element on purpose. A backdrop-filter or
   transform on .site-header itself would make it the containing block of the fixed #mobile-nav and shrink the
   full-screen menu to the height of the bar. */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* Frosted banner navy, from the banner's top tone to its middle one (owner, 2026-09-22; the ink glass read as a black strip
     over the navy sections). Architect: .72 read slate grey over light sections; the navy needs .92 to stay navy there. */
  background: linear-gradient(180deg, rgb(29 55 97 / .92), rgb(19 40 72 / .92));
  border-block-end: 1px solid rgb(255 255 255 / .06);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  transition: opacity var(--dur-base) var(--ease-out);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-header::before { background: var(--c-banner); }
}

/* At the very top of a page that opens with a dark hero the glass fades out, leaving the hero visible. */
.site-header.is-over-hero::before { opacity: 0; }

/* Scrolling down hides the header; scrolling up brings it back. It never stays hidden while it holds focus. */
.site-header.is-hidden { transform: translateY(-100%); }
.site-header.is-hidden:focus-within { transform: none; }
/* No motion on the first frame, so a page that loads over a hero doesn't visibly fade its glass away. */
.site-header.is-static,
.site-header.is-static::before { transition: none; }

/* Overlay. On a page whose first main child is a hero, the sticky header takes no room in the flow, so the hero
   starts at the top of the page underneath it. --header-overlap is the one switch, and header.js reads it too.
   It stays 0 on mobile until site.js has added .js: without JS the mobile header wraps its links into a second
   row and is taller than --header-height. */
body { --header-overlap: 0px; }
@media (min-width: 1001px) {
  body:has(main > :is(.hero, .page-hero):first-child) { --header-overlap: var(--header-height); }
}
@media (max-width: 1000px) {
  .js body:has(main > :is(.hero, .page-hero):first-child) { --header-overlap: var(--header-height); }
}
.site-header { margin-block-end: calc(-1 * var(--header-overlap)); }
/* The heroes keep their own content clear of the header: hero.css reserves --header-height at the top of .hero,
   and the top padding of .page-hero in surfaces.css (96px or more) is taller than the header at every width. */

/* Navigation. The ::after indicator keeps its legacy geometry (2px line, grows from the inline-start). */
.site-header .nav-link,
.site-header .language-link {
  color: rgb(255 255 255 / .72);
  transition: color var(--dur-hover) var(--ease-hover);
}
.site-header .nav-link:is(:hover, :focus-visible, [aria-current="page"]),
.site-header .language-link:is(:hover, :focus-visible) { color: var(--c-white); }
/* Owner (2026-09-22): a thin vertical line between the last menu item and the language link, only while the desktop menu
   shows. Logical properties put it on the link's inline-start side, so it mirrors in Arabic. */
@media (min-width: 1001px) {
  .site-header .header-actions .language-link { display: inline-flex; align-items: center; }
  .site-header .header-actions .language-link::before {
    content: "";
    flex: none;
    width: 1px;
    height: 18px;
    margin-inline-end: 22px;
    background: rgb(255 255 255 / .24);
  }
}
@media (min-width: 1001px) and (forced-colors: active) {
  .site-header .header-actions .language-link::before { background: CanvasText; }
}
/* Colleague review 2026-09-29, note 4: the line under the active item (and the one that grows on hover) is white, not the signal blue. */
.site-header .nav-link::after {
  background: var(--c-white);
  transition: transform var(--dur-base) var(--ease-out);
}

/* Call to action: a 44px primary pill (DESIGN-SPEC §6), in the owner's option B: the header is a dark context, so it
   is the white pill with ink text that lights the bar around it (the --btn-* values come from components.css, with the
   same values as fallbacks). It is a .button in the markup. components.css leaves its shape and colours to this file
   (.button:not(.header-cta)) but draws its arrow, the RTL flip and the hover nudge like on every other button, so
   none of that is repeated here. The border is transparent rather than none, so the pill keeps an edge in
   forced-colours mode. */
.site-header .header-actions .header-cta {
  gap: 12px;
  height: 44px;
  min-height: 0;
  padding: 0 24px;
  border: 1px solid transparent;
  border-radius: var(--r-button); /* owner (2026-09-22): the same 6px rounded rectangle as every other button */
  background: var(--btn-fill, #F2F5FA);
  color: var(--btn-ink, var(--c-ink-950));
  box-shadow: var(--btn-glow, 0 0 0 1px rgb(255 255 255 / .05), 0 10px 32px -10px rgb(255 255 255 / .20));
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  transition: background-color var(--dur-hover) var(--ease-hover), color var(--dur-hover) var(--ease-hover),
    box-shadow var(--dur-hover) var(--ease-hover), translate var(--dur-fast) var(--ease-out);
}
.site-header .header-actions .header-cta::before { content: none; }
.site-header .header-actions .header-cta:is(:hover, :focus-visible) {
  border-color: transparent;
  background: var(--btn-fill-hover, var(--c-white));
  color: var(--btn-ink, var(--c-ink-950));
  box-shadow: var(--btn-glow-hover, 0 0 0 1px rgb(255 255 255 / .10), 0 10px 32px -10px rgb(255 255 255 / .40));
}
.site-header .header-actions .header-cta:active { translate: 0 1px; }
@media (max-width: 600px) {
  .site-header .header-actions .header-cta { display: none; } /* site.css hides it here too; the menu has a Contact link */
}

/* Menu toggle: the two legacy lines rotate into an X; only the colours change. */
.site-header .menu-toggle {
  border-color: var(--ctx-line-strong);
  border-radius: var(--r-pill);
  transition: border-color var(--dur-hover) var(--ease-hover), background-color var(--dur-hover) var(--ease-hover);
}
@media (hover: hover) {
  .site-header .menu-toggle:hover {
    border-color: var(--c-signal);
    background-color: rgb(76 141 255 / .08);
  }
}
.site-header .menu-toggle span:not(.screen-reader-text):not(.sr-only) { background: var(--c-white); }

/* Mobile menu (≤1000px): a dark panel over the whole viewport, with the header bar raised above it. The panel
   doesn't use the --menu-top that site.js measures, because that reads the header's box even mid-slide. */
@media (max-width: 1000px) {
  .site-header .header-inner {
    position: relative;
    z-index: 100;
  }
  .site-header .mobile-nav {
    inset-block-start: 0;
    padding-block: calc(var(--wp-adminbar-offset) + var(--header-height) + 30px) 50px;
    border-block-start: 0;
    background-color: var(--c-banner);
    background-image: var(--bg-banner-section); /* owner (2026-09-22): the banner's navy and aurora */
    color-scheme: dark;
  }
  /* The bar itself turns solid while the menu is open. On a short screen the list scrolls, and its links must
     pass behind the logo and the toggle, not through them. It paints the same background as the panel behind it:
     both boxes start at the top of the viewport at full width, and every stop of --bg-banner-section is measured from
     the top, so the bar is pixel for pixel the top of the panel and no seam shows. */
  body.menu-open .site-header::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 99;
    background-color: var(--c-banner);
    background-image: var(--bg-banner-section);
  }
  /* The subtle grid from DESIGN-SPEC §5.1: 1px lines every 64px, fading out from the top. */
  .site-header .mobile-nav::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image: linear-gradient(var(--grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 64px 64px;
    -webkit-mask-image: radial-gradient(ellipse 80% 60% at 70% 0%, #000 0%, transparent 75%);
    mask-image: radial-gradient(ellipse 80% 60% at 70% 0%, #000 0%, transparent 75%);
  }
  [dir="rtl"] .site-header .mobile-nav::before {
    -webkit-mask-image: radial-gradient(ellipse 80% 60% at 30% 0%, #000 0%, transparent 75%);
    mask-image: radial-gradient(ellipse 80% 60% at 30% 0%, #000 0%, transparent 75%);
  }
  .site-header .mobile-nav .nav-link {
    border-block-end: 1px solid var(--ctx-line);
    font-size: 28px;
    font-weight: 300;
    line-height: 1.35;
  }
  [dir="rtl"] .site-header .mobile-nav .nav-link {
    font-weight: 500;
    letter-spacing: 0;
  }

  /* Opening: the panel fades in and its links follow with a 40ms stagger. */
  body.menu-open .site-header .mobile-nav,
  body.menu-open .site-header::after { animation: header-menu-fade var(--dur-base) var(--ease-out) both; }
  body.menu-open .site-header .mobile-nav .nav-link { animation: header-menu-rise var(--dur-base) var(--ease-out) both; }
  body.menu-open .site-header .mobile-nav .nav-link:nth-child(2) { animation-delay: 40ms; }
  body.menu-open .site-header .mobile-nav .nav-link:nth-child(3) { animation-delay: 80ms; }
  body.menu-open .site-header .mobile-nav .nav-link:nth-child(4) { animation-delay: 120ms; }
  body.menu-open .site-header .mobile-nav .nav-link:nth-child(5) { animation-delay: 160ms; }
  body.menu-open .site-header .mobile-nav .nav-link:nth-child(n+6) { animation-delay: 200ms; }
}
@keyframes header-menu-fade { from { opacity: 0; } }
@keyframes header-menu-rise {
  from { opacity: 0; transform: translateY(var(--rise)); }
}

/* While the menu is open the header stays put and un-transformed (a transform would re-anchor the fixed panel). */
body.menu-open .site-header { transform: none; transition: none; }

@media (prefers-reduced-motion: reduce) {
  .site-header,
  .site-header::before { transition: none; }
  .site-header .header-actions .header-cta:active { translate: none; }
  body.menu-open .site-header .mobile-nav,
  body.menu-open .site-header::after,
  body.menu-open .site-header .mobile-nav .nav-link { animation: none; }
}

/* site.css hides the header when printing, so the room hero.css reserves for it goes too. */
@media print {
  .site-header { margin-block-end: 0; }
  main > .hero:first-child { padding-block-start: 0; }
}

/* ---------------------------------------------------------------- WO-22c: the white brand lockup (owner notes 1 + 2)
   header.php now serves assets/v3/brand/logo-horizontal-white.svg: the white mark and the white wordmark, as
   vector, in the proportions of the owner's own horizontal logo file. It replaces logo-on-dark.svg, which carried
   the full-colour mark (an embedded PNG) on the navy. The size and the box are unchanged, so nothing else moves.

   The plain white lockup is the owner's choice (2026-09-24) and the brandbook's approved treatment on Deep Navy
   (Logo Usage, pages 11 and 14). Two alternatives were built and rejected: a gradient glow behind the mark, and
   the colour mark on a light disc. */

/* ---------------------------------------------------------------- Colleague review, 2026-09-29 (notes 1 and 13)
   The logo is the lockup with the slogan ("Bridging Today, Connecting Tomorrow"), in the header and in the footer, and
   the footer no longer repeats the slogan as a line of its own. header.php serves assets/v3/brand/
   logo-horizontal-tagline-white.svg (built by tools/build-tagline-logo.py from the owner's vertical white lockup) above
   1000px, and the plain lockup below it through <picture>, because at phone size the slogan would be about 4px tall.
   The tagline lockup is 226 : 79, so 68px tall is 194px wide and its slogan is about 6px: as large as the 88px header
   allows without crowding it. The legacy widths (146px, 125px below 1151px) were for the plain lockup and still
   apply to it. */
@media (min-width: 1001px) {
  .site-header .brand { max-width: none; }
  .site-header .brand-img { width: 194px; max-height: none; }
}
/* The footer has room for the lockup to be read: 260px wide puts the slogan at 8px. */
.site-footer .footer-brand .brand-img { width: 260px; max-width: 100%; height: auto; max-height: none; }
