/* Top bar: wordmark, section nav and the theme toggle.
   The bar is sticky and full-bleed; .top-inner carries the .wrap gutter so the
   contents still line up with the columns below. */

.top-sentinel { height: 1px; }

header.top {
  position: sticky;
  top: 0;
  z-index: 60;
  padding: 1.1rem 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  /* Transparent while the page is at the top: the bar only grows a surface
     once content starts passing underneath it. */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color .4s var(--ease-settle),
              border-color .4s var(--ease-settle);
}
@media (prefers-reduced-motion: no-preference) {
  header.top { transition: padding .4s var(--ease-settle),
                           background-color .4s var(--ease-settle),
                           border-color .4s var(--ease-settle); }
}
.top-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

/* Pinned state: a tinted, blurred pane so the type below stays legible as it
   scrolls under. color-mix keeps it tied to --bg, so it follows the theme. */
header.top.is-stuck {
  padding: .6rem 0;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  border-bottom-color: var(--rule);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  header.top.is-stuck {
    background: color-mix(in srgb, var(--bg) 62%, transparent);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    backdrop-filter: blur(14px) saturate(1.4);
  }
}

.mark {
  display: flex; align-items: baseline; gap: .6rem;
  white-space: nowrap;
}
.mark-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent);
  transform: translateY(-1px);
}
/* Given/family gap, opened with word-spacing rather than by splitting the name
   into two elements. The separator MUST stay a plain U+0020: Blink and WebKit
   apply word-spacing only to the regular space, so a &nbsp; here silently
   swallows this rule (Firefox honours both, which makes it easy to miss).
   Nothing is lost by dropping the nbsp — .mark sets white-space: nowrap, so the
   wordmark still cannot break across lines.
   A step down from the bar's 12px so the name sits quieter beside the nav rail,
   which is now the largest type in the header. */
.mark span:not(.mark-dot) {
  font-size: 11px;
  word-spacing: .5em;
}

/* ---------- Section nav ----------
   A hairline rail rather than four loose words: it reads as one control next to
   the round theme toggle, and it gives the active-section marker something to
   travel inside. */
nav.topnav {
  position: relative;
  display: flex;
  align-items: center;
  gap: .15rem;
  padding: 4px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: color-mix(in srgb, var(--paper) 55%, transparent);
}
nav.topnav a {
  position: relative;
  z-index: 1;
  padding: .5rem .85rem;
  border-radius: 999px;
  color: var(--ink-mute);
  white-space: nowrap;
  transition: color .3s var(--ease-settle), background-color .3s var(--ease-settle);
}
/* Only the inactive links take a hover wash; the active one already has the
   marker sitting under it. */
nav.topnav a:not(.is-active):hover {
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}
nav.topnav a:focus-visible { outline-offset: 1px; }
/* The section currently on screen; set by the scroll spy in index.html. */
nav.topnav a.is-active { color: var(--accent); }

.topnav-thumb {
  position: absolute;
  top: 4px; bottom: 4px;
  left: 0;
  width: var(--thumb-w, 0px);
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, var(--paper));
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  /* Scaled down while idle so the marker grows into its first section rather
     than blinking on at full size. Both states carry the translate, or there is
     nothing to interpolate between. */
  transform: translateX(var(--thumb-x, 0px)) scale(.9);
  opacity: 0;
  pointer-events: none;
  will-change: transform, width;
}
nav.topnav.has-active .topnav-thumb {
  transform: translateX(var(--thumb-x, 0px)) scale(1);
  opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
  .topnav-thumb {
    transition: transform .5s var(--ease-settle),
                width .5s var(--ease-settle),
                opacity .3s ease;
  }
}

/* Anchor jumps have to clear the pinned bar, or the heading lands underneath it. */
.hero, .block, .foot { scroll-margin-top: 5.5rem; }

/* ---------- Round bar buttons ----------
   One shape shared by the CV link and the theme toggle, so the pair reads as a
   set and matches the pill radius of the nav rail. */
.bar-actions {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex: none;
}
.bar-btn {
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  width: 44px; height: 44px;
  flex: none;
  cursor: pointer;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: border-color .25s var(--ease-settle),
              color .25s var(--ease-settle),
              transform .25s var(--ease-settle);
}
.bar-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.bar-btn svg { width: 16px; height: 16px; }

/* The CV button is the only icon-only control whose meaning is not obvious, so
   it carries a caption. Stacking it inside the same 44px circle keeps the pair
   of buttons the same size; the icon gives up the 2px the caption needs. */
.cv-bar-btn {
  flex-direction: column;
  gap: 1px;
  text-decoration: none;
}
.cv-bar-btn svg { width: 14px; height: 14px; }
.cv-bar-label {
  font-family: var(--mono);
  font-size: 8px;
  line-height: 1;
  letter-spacing: .08em;
}

/* The arrow already points down, so the nudge follows it. */
.cv-bar-btn:hover { transform: translateY(2px); }
.theme-toggle:hover { transform: rotate(15deg); }
@media (prefers-reduced-motion: reduce) {
  .cv-bar-btn:hover, .theme-toggle:hover { transform: none; }
}

.theme-toggle .sun { display: none; }
[data-theme="dark"] .theme-toggle .sun { display: block; }
[data-theme="dark"] .theme-toggle .moon { display: none; }


/* The name is already the largest thing in the hero, so on small screens the bar
   drops it and gives the whole row to the nav, which scrolls sideways if the
   labels do not fit. */
@media (max-width: 820px) {
  header.top { padding: .7rem 0; }
  header.top.is-stuck { padding: .5rem 0; }
  .mark { display: none; }
  .top-inner { gap: .4rem; justify-content: center; }
  .bar-actions { gap: .4rem; }
  .bar-btn { width: 40px; height: 40px; }
  /* Counterweight matching the button pair, so the rail sits on the middle of
     the screen and not just left of it. It is given a huge shrink factor: where
     the labels need the room, this collapses first and the rail keeps its
     width. Track the pair's width (2 * 40px + .4rem) if those change. */
  .top-inner::before {
    content: "";
    flex: 0 999 86px;
    width: 86px;
  }

  /* The rail takes the row the wordmark gave up and centres its labels inside
     it. safe centring matters here: plain `center` in a scroll container pushes
     the first label past the left edge, out of reach, once the labels overflow. */
  nav.topnav {
    flex: 0 1 auto;
    min-width: 0;
    gap: 0;
    justify-content: safe center;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    font-size: 11px;
  }
  nav.topnav::-webkit-scrollbar { display: none; }
  nav.topnav a { padding: .45rem .5rem; }
}

/* Small phones: tighten the labels far enough that all four still fit the row
   and stay centred rather than starting to scroll. */
@media (max-width: 400px) {
  nav.topnav { letter-spacing: .04em; }
  nav.topnav a { padding: .45rem .3rem; }
}

/* Narrower still (360px Androids): the four labels plus both buttons only fit
   if the type comes down a step and the buttons give back a few pixels. */
@media (max-width: 380px) {
  nav.topnav { font-size: 10px; letter-spacing: .03em; }
  nav.topnav a { padding: .45rem .25rem; }
  .bar-btn { width: 36px; height: 36px; }
  .cv-bar-btn svg { width: 12px; height: 12px; }
  .cv-bar-label { font-size: 7px; }
  .top-inner::before { flex: 0 999 78px; width: 78px; }
}
