/* ============================================================================
   LAYOUT, containers, page shell, header, footer
   ========================================================================== */

.container {
  width: 100%;
  max-width: var(--width-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: var(--width-narrow); }

/* --- Page shell -----------------------------------------------------------
   Structure on a black page comes from SPACE, not from boxes and lines, surfaces sit at 1.05:1 against the page, so a card barely reads as a box.
   That is why the section gap is generous rather than decorative.           */

/* The header is fixed, so it is out of flow and no longer pushes content
   down. This is the clearance it used to provide. */
.page {
  flex: 1;
  padding-block: var(--space-10) var(--section-gap);
}
.page > * + * { margin-top: var(--section-gap); }

/* A page whose whole content is one card centres it, rather than leaving it
   against the top of a tall viewport with the rest of the page empty. */
.page--single { display: flex; flex-direction: column; justify-content: center; }

.page-title { margin-bottom: var(--space-7); }

/* --- Bleed ----------------------------------------------------------------
   Breaks a child out of its container to the full width of the viewport.
   Uses margin rather than 100vw, because 100vw ignores the scrollbar and
   causes horizontal overflow on Windows. */

.bleed {
  margin-inline: calc(50% - 50vw);
  width: auto;
}
.bleed--padded { padding-inline: var(--gutter); }


/* --- Stack: the general vertical rhythm helper ---------------------------- */
.stack       { display: flex; flex-direction: column; }
.stack--1    { gap: var(--space-1); }
.stack--2    { gap: var(--space-2); }
.stack--3    { gap: var(--space-3); }
.stack--4    { gap: var(--space-4); }
.stack--5    { gap: var(--space-5); }
.stack--6    { gap: var(--space-6); }
.stack--8    { gap: var(--space-8); }

/* --- Site header ----------------------------------------------------------
   Adapted from the Sterling Gate kinetic navigation. What is taken from it:
   a header stripped to a wordmark and a Menu control, a full-screen overlay
   behind layered panels that slide in one after another, and links that rise
   into place in sequence.

   What is deliberately not taken:

   The abstract SVG shapes that animate in behind each link on hover. They are
   decoration unrelated to the content, and five separate shape sets is a lot
   of moving parts to maintain for something that says nothing.

   Its indigo, violet and pink palette, replaced with our tokens.

   GSAP. Every movement here is a CSS transition with a delay, so the site
   keeps its zero dependencies.
   ------------------------------------------------------------------------- */

/* The header sits at the top of the document and scrolls away with it, so the
   wordmark stays where the page begins. Only the controls are pinned, and they
   are pulled out into their own fixed element below. */
.site-header {
  position: absolute;
  inset-inline: 0;
  top: 0;
  z-index: calc(var(--layer-overlay) + 1);
  padding-block: var(--space-4);
  pointer-events: none;
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  width: 100%;
  max-width: var(--width-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.site-header__inner > * { pointer-events: auto; }
.site-header__actions > * { pointer-events: auto; }

/* Pinned on its own. It re-creates the container box rather than offsetting
   from the viewport edge, so the controls stay in line with the content column
   at every width. Done with margin and padding, not a vw calc, because 100vw
   includes the scrollbar and would push them a few pixels out of line. */
.site-header__actions {
  position: fixed;
  top: var(--space-4);
  left: 0;
  right: 0;
  z-index: calc(var(--layer-overlay) + 1);
  width: 100%;
  max-width: var(--width-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
  pointer-events: none;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-3);
}

/* The language switch is sized off the same token as the Menu button, and set
   in bone rather than the accent.

   The accent is reserved for calls to action. Switching language is not one:
   it is a setting. Using the neon there spends the loudest colour on the page
   on the least important control, and leaves nothing louder for the actual
   call to action sitting beneath it. Bone is the system's other surface, so it
   reads as a control without competing. */
.site-header__actions .toggle {
  height: var(--control-height);
  padding: 3px;
  /* Opaque. The header is fixed, so a transparent control shows whatever
     scrolls underneath it. The base .toggle has no background because it is
     used on solid surfaces elsewhere. */
  background: var(--color-surface);
}
.site-header__actions .toggle__option {
  height: 100%;
  display: inline-flex;
  align-items: center;
  padding-inline: var(--space-3);
  font-size: var(--size-200);
}
.site-header__actions .toggle__option[aria-pressed="true"] {
  background: var(--color-panel);       /* 17.5:1 out of the page */
  color: var(--color-panel-text);       /* 16.7:1 on bone         */
}
.site-header__actions .toggle__option[aria-pressed="true"]:hover {
  background: var(--color-text);
}

.site-logo { display: flex; align-items: center; }
.site-logo img {
  height: 22px;
  width: auto;
  filter: brightness(0);
  transition: opacity var(--duration-fast) var(--ease);
}
.site-logo:hover img { opacity: 0.65; }

/* --- The Menu control -----------------------------------------------------
   The label swaps between Menu and Close by sliding, rather than by being
   replaced, so the control reads as one object with two states.             */

.menu-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--control-height);
  padding: 0 var(--space-4) 0 var(--space-5);
  background: var(--color-accent);
  border: var(--stroke-thin) solid var(--color-accent);
  border-radius: var(--radius-full);
  color: var(--color-on-accent);      /* 14.9:1 on the fill */
  font-family: var(--family-sans);
  font-size: var(--size-300);
  font-weight: var(--weight-medium);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease);
}
.menu-button:hover { background: var(--color-accent-hover); border-color: var(--color-accent-hover); }

.menu-button__label {
  position: relative;
  display: block;
  height: 1em;
  overflow: hidden;
  line-height: 1;
}
.menu-button__label span {
  display: block;
  transition: transform var(--duration-base) var(--ease);
}
.menu-button[aria-expanded="true"] .menu-button__label span { transform: translateY(-100%); }

.menu-button__icon {
  width: 14px; height: 14px;
  flex-shrink: 0;
  transition: transform var(--duration-slow) var(--ease);
}
.menu-button[aria-expanded="true"] .menu-button__icon { transform: rotate(315deg); }

/* --- The overlay ---------------------------------------------------------- */

.nav-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--layer-overlay);
  visibility: hidden;
  pointer-events: none;
}
.nav-overlay.is-open { visibility: visible; pointer-events: auto; }

.nav-overlay__scrim {
  position: absolute;
  inset: 0;
  background: rgba(13, 13, 12, 0.6);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease);
}
.nav-overlay.is-open .nav-overlay__scrim { opacity: 1; }

/* Layered panels. Three of them, sliding in behind one another, which is what
   gives the opening its depth without any library. */
.nav-overlay__panel {
  position: absolute;
  inset: 0;
  transform: translateX(101%);
  transition: transform var(--duration-slow) var(--ease-spring);
}
/* The scrim is the overlay's first child, so the panels are children 2, 3
   and 4. Counting from 1 here left the last panel unstyled and transparent. */
/* The menu's job is to contrast with the page. The page is light now, so the
   panels run dark. Same relationship as before, inverted. */
.nav-overlay__panel:nth-child(2) { background: var(--neutral-500); transition-delay: 0ms; }
.nav-overlay__panel:nth-child(3) { background: var(--neutral-800); transition-delay: 60ms; }
.nav-overlay__panel:nth-child(4) { background: var(--color-panel); transition-delay: 120ms; }
.nav-overlay.is-open .nav-overlay__panel { transform: none; }
/* Closing: run them out together, so it does not feel sluggish. */
.nav-overlay:not(.is-open) .nav-overlay__panel { transition-delay: 0ms; }

@media (min-width: 52rem) {
  /* Narrow enough that the links sit in a column rather than floating in an
     empty half-screen, wide enough to keep air to the right of the longest
     word. */
  .nav-overlay__panel { inset-inline: auto 0; width: min(32rem, 44vw); }
  .nav-overlay__panel:nth-child(4) { border-left: var(--stroke-thin) solid var(--neutral-750); }
}

.nav-overlay__body {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-8);
  padding: var(--space-10) var(--gutter) var(--space-8);
  overflow-y: auto;
}
@media (min-width: 52rem) {
  .nav-overlay__body { inset-inline: auto 0; width: min(32rem, 44vw); padding-inline: var(--space-8); }
}

/* --- Links ----------------------------------------------------------------
   Each rises into place, staggered. Hover is a colour change and nothing
   else: no shapes, no backgrounds sliding around behind the text.           */

.nav-overlay__links { display: flex; flex-direction: column; gap: var(--space-2); }

.nav-overlay__links li { overflow: hidden; }

.nav-overlay__links a {
  display: block;
  font-family: var(--family-display);
  font-weight: var(--weight-bold);
  font-size: clamp(2.25rem, 7vw, 3.75rem);
  letter-spacing: var(--tracking-tight);
  line-height: 1.1;
  color: var(--color-panel-text);    /* 17.8:1 on the dark menu */
  transform: translateY(115%);
  transition: transform var(--duration-slow) var(--ease),
              color var(--duration-fast) var(--ease);
}
.nav-overlay.is-open .nav-overlay__links a { transform: none; }
.nav-overlay__links li:nth-child(1) a { transition-delay: 220ms, 0ms; }
.nav-overlay__links li:nth-child(2) a { transition-delay: 280ms, 0ms; }
.nav-overlay__links li:nth-child(3) a { transition-delay: 340ms, 0ms; }
.nav-overlay__links li:nth-child(4) a { transition-delay: 400ms, 0ms; }
.nav-overlay:not(.is-open) .nav-overlay__links a { transition-delay: 0ms; }

/* Hover is an underline rather than a colour change. On a mid grey there is
   no second dark that stays readable: bone-800 is 3.6:1 and the accent is
   2.2:1, both below the line for text. An underline also means the state is
   not carried by colour alone. */
.nav-overlay__links a:hover,
.nav-overlay__links a:focus-visible {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
}
.nav-overlay__links a[aria-current="page"] { color: var(--color-panel-muted); }

/* --- Foot of the overlay --------------------------------------------------- */

.nav-overlay__foot {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding-top: var(--space-5);
  font-size: var(--size-300);
  color: var(--color-panel-muted);
  opacity: 0;
  transform: translateY(1rem);
  transition: opacity var(--duration-base) var(--ease) 420ms,
              transform var(--duration-base) var(--ease) 420ms;
}
.nav-overlay.is-open .nav-overlay__foot { opacity: 1; transform: none; }
/* The foot carries the one action worth having in a menu. It is a button, not
   an address, so it reads as the thing to do rather than as a footnote. The
   primary fill is dark text on the accent, which clears on the dark menu the
   same way it clears on the page. */
.nav-overlay__foot .button { font-size: var(--size-400); }
.nav-overlay__foot .button svg { flex: none; }
.nav-overlay:not(.is-open) .nav-overlay__foot { transition-delay: 0ms; }

/* Scroll is locked while the overlay is open, so the page behind cannot move. */
body.nav-is-open { overflow: hidden; }

/* The header floats above the overlay, so while the menu is open its controls
   sit on the dark menu rather than on the light page. Everything inverts. */
body.nav-is-open .site-logo img { filter: brightness(0) invert(1); }

body.nav-is-open .menu-button {
  background: var(--color-panel-text);
  border-color: var(--color-panel-text);
  color: var(--color-panel);
}
body.nav-is-open .menu-button:hover { background: var(--color-panel-body); }

body.nav-is-open .site-header__actions .toggle { border-color: var(--color-panel-muted); }
body.nav-is-open .site-header__actions .toggle__option { color: var(--color-panel-muted); }
body.nav-is-open .site-header__actions .toggle__option[aria-pressed="true"] {
  background: var(--color-panel-text);
  color: var(--color-panel);
}

@media (prefers-reduced-motion: reduce) {
  .nav-overlay__panel,
  .nav-overlay__links a,
  .nav-overlay__foot,
  .menu-button__icon,
  .menu-button__label span {
    transition-duration: 1ms;
    transition-delay: 0ms;
  }
  .nav-overlay__links a { transform: none; }
}

/* --- Site footer ---------------------------------------------------------- */

/* --- A page that runs dark all the way -------------------------------------
   Set on <body>, and it works by redefining the semantic tokens rather than by
   restating colours on each element. Everything downstream reads Tier 2, so
   the page title, the footer rule and every focus ring follow without being
   named here. --color-surface is deliberately left alone: the language switch
   is built on it and has to stay an opaque light pill, the same as it is when
   it sits over the dark menu. */

body.page-dark {
  --color-page:       var(--color-panel);
  --color-line:       var(--color-panel-line);
  --color-line-strong: var(--color-panel-frame);
  --color-text:       var(--color-panel-text);
  --color-text-body:  var(--color-panel-body);
  --color-text-muted: var(--color-panel-muted);
  --color-focus:      var(--color-panel-text);
  background: var(--color-page);
  color: var(--color-text-body);
}
body.page-dark .site-logo img { filter: brightness(0) invert(1); }

.site-footer {
  border-top: var(--stroke-thin) solid var(--color-line);
  padding-block: var(--space-6);
  font-size: var(--size-300);
  color: var(--color-text-muted);
}
.site-footer__inner {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}
