.skip-link {
  position: absolute;
  top: -40px;
  left: 8px;
  z-index: 1000;
  background: var(--color-ink);
  color: #fff;
  padding: 8px 14px;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transition: top var(--transition-fast);
}
.skip-link:focus {
  top: 0;
  outline: 2px solid var(--focus-ring-inverse);
  outline-offset: 2px;
}
.skip-link:visited {
  color: #fff;
}
/* The site chrome top bar. Scoped to classless <nav> so this never leaks into
   in-content <nav> landmarks (e.g. .book-subnav, .faq-toc), which carry a class
   and style themselves — an unscoped `nav {}` turned those into 108px flex bars
   and overlapped their contents. Chrome navs (HOME_NAV / AUTH_NAV /
   confirm-email-change) are classless, so they still match. */
nav:not([class]) {
  background: var(--color-ink);
  padding: 0 32px;
  height: 108px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative;
}
.nav-brand { text-decoration: none; line-height: 0; }
/* width:auto is load-bearing: the nav logo <img> carries width/height HTML
   attributes (CLS reservation) whose 1536px width is a presentational hint.
   Pinning only height would leave that hint to size the box at 1536px and blow
   out the nav on every page — width:auto (any author rule outranks the hint)
   lets the attribute-derived aspect-ratio drive width from height instead. */
.nav-brand img { height: 108px; width: auto; }
.nav-links { display: flex; gap: 24px; align-items: center; }
/* text-align:center is load-bearing in the band just above the 980px collapse
   (measured 2026-07-23: 981–~1015px with a short list name, stretching to
   ~1070px when the switcher pill is at its 180px cap — the pill's width moves
   the ceiling, which is why no hard upper number is encoded here). The row is a
   no-wrap flex line, so instead of breaking onto a second row the links SHRINK:
   each <a> is a flex item with min-width:auto, which floors at its longest word
   and wraps the label internally ("Email List" → Email / List, "Mission
   Archive" → Mission / Archive). The gap stays a constant 24px either way, but
   left-aligned short lines hug their box edge and read as uneven gutters.
   Centering balances the stacked lines. Don't "fix" this with white-space:nowrap
   — that trades the wrap for a page-wide horizontal scrollbar, the exact failure
   the 980px collapse below exists to prevent. Overridden back to left in the
   mobile panel, where the links are full-width rows. */
.nav-links a { color: var(--color-gray-400); text-decoration: none; font-size: 14px; font-weight: 500; text-align: center; }
.nav-links a:visited { color: var(--color-gray-400); }
.nav-links a:hover { color: #fff; }
/* Active-page indicator (set by nav.js on both navs). Underline via
   text-decoration — not a border — so there's no layout shift on inactive
   links and no clash with the mobile menu's per-row bottom border. */
.nav-links a.active,
.nav-links a.active:visited { color: #fff; text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 2px; }
.nav-links a:focus-visible { outline: 2px solid var(--focus-ring-inverse); outline-offset: 3px; border-radius: 2px; }
/* Nav auth-flash guard (paired with the inline guard in lib/head.js +
   homenav.js). HOME_NAV's link cluster carries .nav-links--auth-guard and
   stays invisible while <html> has `nav-pending` — i.e. until the async
   session check resolves and homenav.js sets the correct logged-in/out
   links. Stops a logged-in user from flashing the logged-out nav (Log In /
   Start Now) on first paint. visibility (not display) keeps the bar's layout
   stable, so there's no shift on reveal. AUTH_NAV's .nav-links has no guard
   class, so authed pages are unaffected; the brand logo + hamburger stay
   visible throughout. */
.nav-pending .nav-links--auth-guard { visibility: hidden; }
.btn-nav {
  padding: 9px 20px;
  background: white;
  color: var(--color-ink) !important;
  border-radius: var(--radius-lg);
  font-weight: 700 !important;
  font-size: 14px;
  text-decoration: none;
}
.btn-nav:hover { background: var(--color-gray-200); color: var(--color-ink) !important; }
.nav-hamburger {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: 14px 10px;
  flex-direction: column;
  gap: 5px;
  width: auto;
  color: inherit;
}
.nav-hamburger:hover { background: none; }
.nav-hamburger:focus-visible { outline: 2px solid var(--focus-ring-inverse); outline-offset: 2px; border-radius: var(--radius-sm); }
.nav-hamburger span {
  display: block;
  width: 22px;
  height: 2px;
  background: #fff;
  border-radius: 2px;
}
footer {
  border-top: 1px solid var(--color-gray-200);
  padding: 40px 24px;
  text-align: center;
  font-size: 14px;
  color: var(--color-gray-400);
}
footer a { color: var(--color-gray-400); text-decoration: none; margin: 0 12px; }
footer a:visited { color: var(--color-gray-400); }
footer a:hover { color: var(--color-ink); }

/* ── List switcher ─────────────────────────────────────────────────────────── */
.nav-list-switcher { position: relative; }
.list-switcher-btn {
  background: rgba(255,255,255,0.1);
  border: 1px solid rgba(255,255,255,0.2);
  color: #fff;
  padding: 6px 12px;
  border-radius: var(--radius-lg);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  max-width: 180px;
  min-height: 44px;
  font-family: inherit;
}
.list-switcher-btn:hover { background: rgba(255,255,255,0.18); }
.list-switcher-btn:focus-visible { outline: 2px solid var(--focus-ring-inverse); outline-offset: 2px; }
#listSwitcherName { overflow: hidden; text-overflow: ellipsis; }
.list-switcher-chevron { display: inline-block; width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid currentColor; opacity: 0.7; flex-shrink: 0; margin-top: 1px; }
.list-switcher-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  background: #fff;
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-dropdown);
  min-width: 220px;
  z-index: 200;
  overflow: hidden;
}
.list-switcher-dropdown.open { display: block; }
.list-switcher-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  font-size: 14px;
  color: var(--color-ink);
  cursor: pointer;
  border-bottom: 1px solid var(--color-gray-200);
  gap: 12px;
}
.list-switcher-item:last-child { border-bottom: none; }
.list-switcher-item:hover { background: var(--color-gray-50); }
.list-switcher-item:focus-visible { outline: 2px solid var(--color-ink); outline-offset: -2px; }
.list-switcher-item-name { font-weight: 500; flex: 1; }
.list-switcher-item.active .list-switcher-item-name { font-weight: 700; }
.list-switcher-check { color: var(--color-ink); font-size: 14px; }
.list-switcher-dropdown .list-switcher-manage {
  display: block;
  padding: 10px 16px;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-gray-500);
  text-decoration: none;
  border-top: 1px solid var(--color-gray-200);
  background: var(--color-gray-50);
}
.list-switcher-dropdown .list-switcher-manage:visited { color: var(--color-gray-500); }
.list-switcher-dropdown .list-switcher-manage:hover { color: var(--color-ink); background: var(--color-gray-50); }
.list-switcher-dropdown .list-switcher-manage:focus-visible { outline: 2px solid var(--color-ink); outline-offset: -2px; }

/* Collapse the chrome nav to the hamburger at ≤980px. The authenticated bar
   carries the logo + list-switcher pill + up to 9 inline links: the 8 fixed
   links plus the conditionally-revealed "Orders" link (shown once a list has a
   book order). Worst case — a long list name pushing the switcher to its 180px
   cap — that content was ~970px wide, so any viewport below ~980px overflowed
   the bar and gave the whole PAGE a horizontal scrollbar. 980 clears the 9-link
   width with a cushion. The earlier 768 value only fit the 8-link nav (Orders
   hidden) and left a 769–969px dead zone whenever Orders was visible; the old
   769–900 "medium logo" tier lived entirely inside that broken zone and is gone
   with it.
   Since the icon-only Account treatment below (≥981px) trades the ~55px
   "Account" label for an 18px glyph, that worst case is now ~933px — so the
   cushion GREW. 980 is deliberately kept: the switcher pill's width varies with
   the list name, and re-tuning the breakpoint down to chase 47px would put us
   back near the overflow cliff this comment exists to document. */
@media (max-width: 980px) {
  nav:not([class]) { padding: 0 20px; height: 64px; }
  .nav-brand img { height: 64px !important; }
  .nav-hamburger { display: flex; margin-left: auto; }
  .nav-links {
    display: none;
    position: absolute;
    top: 64px;
    left: 0;
    right: 0;
    background: var(--color-ink);
    flex-direction: column;
    padding: 8px 20px 16px;
    gap: 0;
    z-index: 100;
    /* Clamp the open panel to the viewport and scroll it — on short/landscape
       phones the tail links (Log In / Start Now) otherwise sit below the fold
       with no cue. dvh tracks the iOS dynamic toolbar; vh is the fallback. */
    max-height: calc(100vh - 64px);
    max-height: calc(100dvh - 64px);
    overflow-y: auto;
  }
  .nav-links.open { display: flex; }
  /* text-align back to left: the desktop bar centers labels so an internally
     wrapped link reads evenly (see the .nav-links a rule at the top), but here
     the links are full-width stacked rows where centering would just look
     arbitrary. */
  .nav-links a { padding: 14px 0; border-bottom: 1px solid var(--color-gray-700); font-size: 15px; text-align: left; }
  .nav-links a:last-child { border-bottom: none; }
  .nav-links .btn-nav { background: none; color: var(--color-gray-400) !important; font-weight: 500 !important; }
  .nav-list-switcher { width: 100%; padding: 12px 0; border-bottom: 1px solid var(--color-gray-700); }
  .list-switcher-btn {
    background: none;
    border: none;
    padding: 0;
    color: #fff;
    font-size: 15px;
    font-weight: 700;
    max-width: 100%;
  }
  .list-switcher-btn:hover { background: none; }
  .list-switcher-dropdown {
    position: static;
    box-shadow: none;
    border: none;
    border-radius: 0;
    background: transparent;
    margin-top: 8px;
    min-width: 0;
    max-height: 60vh;
    overflow-y: auto;
  }
  .list-switcher-item { color: var(--color-gray-400); padding: 12px 0; border-bottom: none; background: transparent; }
  .list-switcher-item:hover { background: transparent; color: #fff; }
  .list-switcher-item:focus-visible { outline-color: var(--focus-ring-inverse); }
  .list-switcher-item.active .list-switcher-item-name { color: #fff; }
  .list-switcher-check { color: #fff; }
  .list-switcher-manage { background: transparent; color: var(--color-gray-350); border-top: none; padding: 8px 0 0; }
  .list-switcher-manage:hover { background: transparent; color: var(--color-gray-400); }
}

/* ── Account: icon-only on the desktop bar ───────────────────────────────────
   Scoped to ≥981px — the exact complement of the ≤980px hamburger query above,
   so "icon-only" and "horizontal bar" are the same state by construction and
   there is no third layout to reason about. Below 981 the mobile panel renders
   Account as an ordinary labeled row (a lone glyph in a vertical list of words
   is noise, not signal), which is why the label is hidden HERE rather than
   removed from the markup.
   The glyph is painted as a MASK over `currentColor` rather than as a
   background-image: nav links shift gray-400 → #fff on hover and when active
   (see the .nav-links rules at the top of this file), and a data-URI SVG with a
   baked-in fill would keep its gray while the rest of the bar lit up. Masking a
   solid currentColor rectangle makes the icon track every color state for free.
   Account is the LAST nav item (see lib/head.js) so this reads as terminal. */
@media (min-width: 981px) {
  .nav-links .nav-account-label { display: none; }
  /* Extra left gap detaches the glyph from the text-link cluster. */
  .nav-links .nav-account { margin-left: 8px; line-height: 0; }
  .nav-links .nav-account::before {
    content: "";
    display: inline-block;
    width: 18px; height: 18px;
    vertical-align: middle;
    background-color: currentColor;
    -webkit-mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%23000" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="8" r="4"/><path d="M4.5 20.5c0-4.1 3.4-7.5 7.5-7.5s7.5 3.4 7.5 7.5"/></svg>') center / contain no-repeat;
    mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%23000" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="8" r="4"/><path d="M4.5 20.5c0-4.1 3.4-7.5 7.5-7.5s7.5 3.4 7.5 7.5"/></svg>') center / contain no-repeat;
  }
  /* Active state. The shared .nav-links a.active rule marks the current page
     with an underline — which draws NOTHING under a label-less link, so /account
     would silently lose its active indicator. Suppress it and swap the outline
     glyph for a filled one instead; the white-vs-gray color shift still applies
     via currentColor, so the active icon reads as both filled and brighter. */
  .nav-links .nav-account.active,
  .nav-links .nav-account.active:visited { text-decoration: none; }
  .nav-links .nav-account.active::before {
    -webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23000"><circle cx="12" cy="8" r="4.2"/><path d="M12 13.2c-4.2 0-7.6 3.4-7.6 7.6h15.2c0-4.2-3.4-7.6-7.6-7.6Z"/></svg>');
    mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23000"><circle cx="12" cy="8" r="4.2"/><path d="M12 13.2c-4.2 0-7.6 3.4-7.6 7.6h15.2c0-4.2-3.4-7.6-7.6-7.6Z"/></svg>');
  }
}

/* ── Utility message classes ─────────────────────────────────────────────── */
.text-error { color: var(--color-danger); }
.text-success { color: var(--color-success); }
.text-warning { color: var(--color-warning); }
/* Follows the --radius-lg token (parity with the common.css .msg-box that
   shadows this on pages loading both); the 8px fallback keeps it correct on any
   page that loads nav.css without common.css (where the token is undefined). */
.msg-box { padding: 12px 16px; border-radius: var(--radius-lg, 8px); font-size: 14px; line-height: 1.5; text-align: left; display: none; }
.msg-box.error { display: block; background: var(--color-danger-bg); border: 1px solid var(--color-danger-border); color: var(--color-danger); }
.msg-box.success { display: block; background: var(--color-success-bg); border: 1px solid var(--color-success-border); color: var(--color-success); }

/* ── Load-failure banner ──────────────────────────────────── */
/* Injected by the early load-failure guard (LOAD_FAILURE_GUARD_SCRIPT in
   lib/head.js) when one of OUR scripts — /js/* or /config.js — fails to load or
   throws while evaluating. Nothing renders it otherwise, so it cannot move any
   visual baseline. It lives HERE rather than in common.css because nav.css is
   loaded by COMMON_HEAD on every served page, and the banner has to survive a
   page whose own stylesheet did not arrive.

   Colors are tokens with NO fallback, deliberately: if common.css itself failed
   the tokens resolve to nothing and the bar falls back to the browser default,
   which is still legible — getting the message to the visitor is the point, and
   a hex fallback here would need a css-hex-ratchet bump to buy very little.
   Non-color values DO carry fallbacks, matching .msg-box above.

   z-index sits above .mml-toast (1100) and the modal family (1000) in
   common.css: a page this broken outranks anything it might cover. */
.mml-load-failure {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1200;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 10px 16px;
  background: var(--color-warning-bg);
  border-bottom: 1px solid var(--color-warning-border);
  color: var(--color-warning-deep);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
}
.mml-load-failure-reload {
  flex-shrink: 0;
  padding: 4px 14px;
  border: 1px solid var(--color-warning-border-2);
  border-radius: var(--radius-lg, 8px);
  background: transparent;
  color: inherit;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.mml-load-failure-reload:hover { background: var(--color-warning-border); }
