/* ============================================================================
   THE SITE HEADER, for pages that do not load v3's global stylesheets
   ----------------------------------------------------------------------------
   v3's own rules, not a re-creation. Amanda: "Why not just use the existing one
   to keep the consistency."

   The project pages cannot load v3's styles.css: it carries a global reset and
   would restyle five hand-built pages. So the rules are scoped under .master-header
   instead, and the tokens they read are redeclared there rather than on :root.
   Same declarations, same measured numbers, no leakage.

   The scope class goes on a WRAPPER, never on the component's own root element:
   every rule here is scoped as a DESCENDANT, and a descendant selector does not
   match the element carrying the class.

   Rules are collected BY SELECTOR from the whole of each source file, not from
   one banner-delimited block -- v3 keeps its mobile overrides in a shared @media
   block far from the component they belong to, and missing them is how the
   footer headline came to overflow a phone.

   The blocks are in v3's own load order -- styles.css, type-system.css,
   chrome.css -- because that order decides the winner between two equally
   specific single-class rules.

   GENERATED by scripts/gen-master-chrome.py. Regenerate; do not hand-edit.
   ========================================================================== */
.master-header {

  /* ============================================================
     MASTER COLOUR
     ------------------------------------------------------------
     Two ramps of four, and nothing repeated. Everything that used to be
     --black, --ink and --line-strong was the same #111111 under three names;
     it is one token now.

     BLACK serves light surfaces: 1 is the ink, the outline and the primary
     dark ground; 2 is a raised panel on top of 1; 3 and 4 are secondary and
     tertiary text.
     WHITE serves dark surfaces, and carries #F8FAFC's cool cast down the ramp
     so greys on this site are never a flat neutral.

     Contrast, measured: black-3 is 5.33:1 on white-1 and black-4 is 3.45:1,
     so secondary text passes AA for body and tertiary passes for large text
     and UI. white-3 is 8.63:1 on black-1 and white-4 is 4.87:1.
     ============================================================ */
  --black-1: #111111;   /* ink · outline · primary dark ground   */
  --black-2: #1C1C1C;   /* secondary dark ground, raised on 1    */
  --black-3: #6B6B6B;   /* secondary text on a light ground      */
  --black-4: #8A8A8A;   /* tertiary text, meta, disabled         */

  --white-1: #FFFFFF;   /* primary light ground                  */
  --white-2: #F8FAFC;   /* secondary light ground                */
  --white-3: #A9B0B9;   /* secondary text on a dark ground       */
  --white-4: #7A828E;   /* tertiary text on a dark ground        */

  /* ---- three surface utilities ----
     Not colours in the ramps above, and not duplicates of them: a hairline is
     translucent so it rides whatever is underneath, and --fill is the one grey
     allowed as a fill inside an outlined container. */
  --line: rgba(17, 17, 17, 0.18);        /* hairline on a light ground */
  --line-light: rgba(255, 255, 255, 0.35); /* hairline on a dark ground */
  --fill: #ECECEC;                       /* progress track, filled bar, nested panel */

  --container-max: 1720px;
  --gutter: clamp(20px, 5.2vw, 100px);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --radius-media: clamp(6px, 0.55vw, 8px);


  /* from styles.css's body rule, which these components inherit from on v3 */
  font-family: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--black-1);
  line-height: 1.2;
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
.master-header *,
.master-header *::before,
.master-header *::after { box-sizing: border-box; }
.master-header * { margin: 0; padding: 0; }
.master-header img { display: block; max-width: 100%; }
.master-header a { color: inherit; text-decoration: none; }
.master-header ul { list-style: none; }

/* ---- the host page's own rules stop here ---------------------------------
   THIS BLOCK IS LOAD-BEARING. These pages were built before this chrome existed
   and they use the same class names: aspire, identity and nobi each define their
   own .footer, and nobi defines .footer__legal. Their rules were landing on v3's
   markup -- aspire's `.footer { background: var(--navy) }` put a navy band across
   the bottom of the site footer, and nobi's `.footer__legal { color: var(--muted) }`
   painted the copyright line dark on dark until it disappeared.

   The scope class is doubled so this sits at (0,2,0): it beats any single-class
   rule a host page has, and loses to every rule below it in this file, which is
   also (0,2,0) but comes later. So it wipes the host's declarations and then v3's
   own put back exactly what belongs. Placed FIRST for that reason. */
.master-header.master-header *,
.master-header.master-header *::before,
.master-header.master-header *::after {
  background: none;
  border: 0;
  box-shadow: none;
  text-shadow: none;
  color: inherit;
  opacity: 1;
  filter: none;
  transform: none;
  animation: none;
  float: none;
  position: static;
  min-height: 0;
  max-width: none;
  text-align: inherit;
  text-transform: none;
  font-style: normal;
  font-variant: normal;
}

/* ==== styles.css ========================================================= */
.master-header .container {
  width: 100%;
  max-width: calc(var(--container-max) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}.master-header .header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: saturate(140%) blur(12px);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
}.master-header .header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: linear-gradient(
    to right,
    rgba(0, 0, 0, 0) 0%,
    rgba(0, 0, 0, 0.3) 50%,
    rgba(0, 0, 0, 0) 100%
  );
  opacity: 0;
  transition: opacity 0.45s var(--ease);
}.master-header .header.is-scrolled::after { opacity: 1; }.master-header .header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 88px;
  gap: 24px;
}.master-header .header__name {
  font-weight: 700;
  font-size: 24px;
  letter-spacing: -0.03em;
  white-space: nowrap;
}.master-header .nav {
  display: flex;
  align-items: center;
  gap: clamp(22px, 2.6vw, 54px);
}.master-header .nav__link {
  position: relative;
  font-weight: 500;
  font-size: 20px;
  letter-spacing: -0.02em;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: opacity 0.3s var(--ease);
}.master-header .nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 100%;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease-out);
}.master-header .nav__link:hover::after { transform: scaleX(1); }.master-header .ext-arrow {
  width: 13px;
  height: 13px;
  transition: transform 0.35s var(--ease-out);
}.master-header .nav__link--ext:hover .ext-arrow { transform: translate(2px, -2px); }.master-header .nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  border: none;
  background: transparent;
  color: var(--black-1);
  cursor: pointer;
  align-items: center;
  justify-content: center;
}.master-header .nav-toggle svg { width: 26px; height: 26px; }.master-header .mobile-menu {
  /* Overlays the page (does not push content down) — sits just below the header */
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 99;
  background: rgba(252, 252, 252, 0.97);
  backdrop-filter: saturate(140%) blur(12px);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  padding: 8px var(--gutter) 22px;
  gap: 4px;
}.master-header .mobile-menu__link {
  font-size: 22px;
  font-weight: 500;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  transition: padding-left 0.3s var(--ease);
}.master-header .mobile-menu__link:last-child { border-bottom: none; }.master-header .mobile-menu__link:active { padding-left: 8px; }.master-header .mobile-menu[hidden] { display: none; }.master-header .mobile-menu {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height 0.5s var(--ease), opacity 0.4s var(--ease);
}.master-header .mobile-menu.is-open {
  max-height: 460px;
  opacity: 1;
}
@media (max-width: 760px) {.master-header .nav { display: none; }.master-header .nav-toggle { display: inline-flex; }.master-header .header__inner { min-height: 64px; }.master-header .header__name { font-size: 20px; }

}


/* ==== chrome.css ========================================================= */
.master-header .nav__link.is-active::after { transform: scaleX(1); }


/* ---- the wrapper must not exist as a box --------------------------------
   .header is position: sticky, and a sticky element only travels inside its
   own containing block. A plain wrapper div is exactly as tall as the header,
   so the header would unstick the instant it had scrolled its own height --
   which is to say, never stick at all. display: contents removes the wrapper's
   box while leaving it in the DOM, so the descendant selectors above still
   match and the header sticks against the page. Amanda: "Keep the top-navbar
   always visible on top of the screen." */
.master-header { display: contents; }

/* ---- the reading progress bar -------------------------------------------
   v3's header carries the same element the case studies do, but its rules live
   in v1's css/case-study.css, which the Hazen page does not load. They are
   restated here, WIDTH-driven rather than transform-driven: case-study.js
   animates scaleX, and Hazen's own chrome script sets style.width. This file is
   only ever loaded by Hazen, so it follows Hazen's script. */
.master-header .cs-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  z-index: 101;
  pointer-events: none;
}
.master-header .cs-progress__bar {
  display: block;
  height: 100%;
  width: 0;
  background: var(--black-1);
}

