/* Site header and navigation.
   Kept in its own file because 100-problems.html is a print/serif document
   that must not load main.css: it links this file alone, so the header is
   defined once for every page instead of being duplicated inline there. */

.site-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  max-width: 84rem;
  margin: 0 auto;
  padding: 1.25rem 1rem;
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid transparent;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

/* Pinned header: transparent at the top (seamless with the page); a solid bar
   plus a faint hairline appear once the page scrolls (.scrolled toggled in
   main.js). */
.site-header.scrolled {
  background-color: #0a0f1f;
  border-bottom-color: rgba(255, 255, 255, 0.06);
}

/* ---------------------------------------------------------------------------
   Glass header (.glass, on index.html only for now).

   Instead of the scrolled bar covering the page with a slab of #0a0f1f, the
   region blurs what passes behind it and keeps the page's own colour, while
   the pills take the dark fill so they stay legible in front of it -- the
   arrangement macOS uses for a toolbar over scrolling content.

   The blur is on a pseudo-element rather than on the header, because it has to
   be masked: a hard blur edge reads as a pane of glass sitting on the page, so
   it fades out over the lower part of the header instead of ending. */
.site-header.glass.scrolled {
  background-color: transparent;
  border-bottom-color: transparent;
}

.site-header.glass::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  /* The header is a 84rem column, so on a wide window the glass stopped at
     its edges and the page showed through in two strips either side.  The
     layer runs to the window edges instead, while the pills stay in the
     column.  Same full-bleed idiom as .hero-fullbleed in main.css. */
  left: calc(50% - 50vw);
  right: calc(50% - 50vw);
  z-index: -1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
  background-color: rgba(4, 7, 15, 0.3);
  backdrop-filter: blur(16px) saturate(130%);
  -webkit-backdrop-filter: blur(16px) saturate(130%);
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
}

.site-header.glass.scrolled::before {
  opacity: 1;
}

/* The pills are outlines over the hero and gain their fill as the region goes
   to glass, so that they keep reading against whatever scrolls behind. */
.site-header.glass .header-link,
.site-header.glass .header-sublink {
  background-color: transparent;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.site-header.glass.scrolled .header-link,
.site-header.glass.scrolled .header-sublink {
  background-color: rgba(10, 15, 31, 0.92);
  border-color: rgba(171, 186, 255, 0.34);
}

html {
  scroll-padding-top: 5rem;
}

.brand-lockup {
  width: 11rem;
  height: auto;
}

.header-links {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.header-link {
  color: var(--ink-muted, #b3bad0);
  text-decoration: none;
  font-size: 0.95rem;
  border: 1px solid var(--line, rgba(171, 186, 255, 0.24));
  border-radius: 999px;
  padding: 0.45rem 0.9rem;
  white-space: nowrap;
}

.header-link:hover {
  color: #fff;
}

.header-link[aria-current="page"] {
  opacity: 0.45;
  pointer-events: none;
  cursor: default;
}

/* Sub-links to the deeper pages of the section the reader is in.  They hang
   directly under the pill they belong to, so that clicking a section shows
   its deeper pages where the reader is already looking.
   They are taken out of flow to get there: laying them out in the row as a
   flex column (as they were) made the row as tall as the column and raised
   the section's own pill above its siblings' baseline.  Out of flow, the
   group is exactly one pill high and the row stays level.  The row never
   wraps -- below 72rem the whole navigation becomes a panel -- so the pill
   they are anchored to always keeps its place. */
.header-nav-group {
  position: relative;
  display: flex;
  align-items: center;
}

.header-sublinks {
  position: absolute;
  top: calc(100% + 0.32rem);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.32rem;
}

/* Room under the pill row for the sub-links, so they stay inside the header
   and the bar that appears on scroll covers them.  They are out of flow, so
   the header cannot take its height from them: it is reserved per number of
   sub-links instead. */
.site-header.has-sublinks {
  padding-bottom: 3.3rem;
}

.site-header:has(.header-sublinks > :nth-child(2)) {
  padding-bottom: 5.3rem;
}

.site-header:has(.header-sublinks > :nth-child(3)) {
  padding-bottom: 7.3rem;
}

.header-sublink {
  color: var(--ink-muted, #b3bad0);
  text-decoration: none;
  font-size: 0.88rem;
  border: 1px solid var(--line, rgba(171, 186, 255, 0.24));
  border-radius: 999px;
  padding: 0.3rem 0.8rem;
  line-height: 1.2;
  white-space: nowrap;
}

.header-sublink:hover {
  color: #fff;
}

.header-sublink[aria-current="page"] {
  opacity: 0.45;
  pointer-events: none;
  cursor: default;
}

/* Hamburger.  Hidden above the mobile breakpoint, where the pill row is the
   navigation; main.js toggles .nav-open on .site-header. */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 0.28rem;
  width: 2.6rem;
  height: 2.4rem;
  padding: 0 0.6rem;
  border: 1px solid var(--line, rgba(171, 186, 255, 0.24));
  border-radius: 0.6rem;
  background: transparent;
  cursor: pointer;
}

.nav-toggle span {
  display: block;
  height: 1.5px;
  width: 100%;
  border-radius: 2px;
  background: var(--ink-muted, #b3bad0);
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.site-header.nav-open .nav-toggle span:nth-child(1) {
  transform: translateY(0.44rem) rotate(45deg);
}

.site-header.nav-open .nav-toggle span:nth-child(2) {
  opacity: 0;
}

.site-header.nav-open .nav-toggle span:nth-child(3) {
  transform: translateY(-0.44rem) rotate(-45deg);
}

/* Above this width the pill row is the navigation, wrapping to a second line
   on narrower windows as it always has.  Below it the six labels would need
   three or four lines, so they collapse into a panel opened from the
   hamburger. */
@media (max-width: 40rem) {
  .site-header {
    padding-top: 0.9rem;
  }

  .brand-lockup {
    width: 9.5rem;
  }

  .nav-toggle {
    display: flex;
  }

  .header-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0.45rem;
    padding: 0.9rem 1rem 1.1rem;
    background: #0a0f1f;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  }

  .site-header.nav-open .header-links {
    display: flex;
  }

  .header-link,
  .header-sublink {
    padding: 0.6rem 0.9rem;
    font-size: 1rem;
    white-space: normal;
  }

  /* In the panel the group is a stack, and the sub-links come back into flow
     as entries indented under the section they belong to -- the same reading
     as the pill row, turned vertical.  The room reserved under the row is not
     needed here. */
  .header-nav-group {
    flex-direction: column;
    align-items: stretch;
    gap: 0.45rem;
  }

  .header-sublinks {
    position: static;
    transform: none;
    align-items: stretch;
    gap: 0.45rem;
    padding-left: 1.1rem;
  }

  /* The sub-links are in the panel here, not under the row, so none of the
     reserved space applies.  Every selector that sets it has to be answered:
     the :has() ones outrank a plain .has-sublinks even inside this query. */
  .site-header.has-sublinks,
  .site-header:has(.header-sublinks > :nth-child(2)),
  .site-header:has(.header-sublinks > :nth-child(3)) {
    padding-bottom: 1.25rem;
  }
}
