/* ═══════════════════════════════════════════════════════════════
   Site chrome — the ONE stylesheet for the top nav bar, its ☰ menu and
   the skip link, on every page.

   Astro pages link it from Layout.astro (with a content-hash query so a
   deploy busts the 4-hour cache); the hand-written standalone pages under
   public/ link it directly. Navigation.astro carries markup and script
   only -- never add .rd-nav* rules anywhere else. Colours come from each
   page's :root palette (src/styles/tokens.css on Astro pages, the copied
   :root block on standalone pages).
   ═══════════════════════════════════════════════════════════════ */

/* Layout, type and shape scale. An identical copy lives in
   src/styles/tokens.css; the ui-style-check static pass fails if the two
   drift apart. Standalone pages get these only from here. */
:root {
  --gutter: clamp(24px, 4vw, 56px);
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --text-xs: 12px;
  --text-sm: 14px;
  --text-md: 16px;
  --text-lg: 18px;
  --text-xl: 22px;
  --text-2xl: 28px;
  --lh-tight: 1.2;
  --lh-body: 1.6;
  --track-label: 0.08em;
  --radius-control: 999px;
  --radius-card: 24px;
  --radius-field: 12px;
  --radius-chip: 4px;
}

/* ═══ BAR ═══════════════════════════════════════════════════════
   Brand on the left, then one right-aligned group. Items carry their own
   12px side padding as hit area and nothing grows, so every visible gap in
   the bar is the same 24px at every width. The bar's side padding is the
   page gutter minus that 12px, which puts the wordmark on the same vertical
   line as the page content below it. */
.rd-nav {
  --nav-item-pad: 12px;
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  max-width: 1440px;
  margin-inline: auto;
  /* The 1px is the side border, which the flat bar carries transparent so
     the pill's border can fade in instead of snapping on. */
  padding-inline: calc(var(--gutter) - var(--nav-item-pad) - 1px);
  overflow-x: auto;
  scrollbar-width: none;
  white-space: nowrap;
  border: 1px solid transparent;
  border-bottom-color: var(--rule, var(--border));
  border-radius: 0;
  background: var(--bg);
  box-shadow: 0 2px 12px rgb(0 0 0 / 0);
  color: var(--ink, var(--text-primary));
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.2;
  /* Every part of the flat-bar/pill change runs on one duration and curve,
     so the corners, inset, border and shadow arrive together. */
  --nav-ease: cubic-bezier(0.22, 1, 0.36, 1);
  transition-property: top, left, right, padding, border-radius, border-color, background-color, box-shadow, transform, opacity;
  transition-duration: 340ms, 340ms, 340ms, 340ms, 340ms, 340ms, 340ms, 340ms, 340ms, 220ms;
  transition-timing-function: var(--nav-ease), var(--nav-ease), var(--nav-ease), var(--nav-ease), var(--nav-ease), var(--nav-ease), var(--nav-ease), var(--nav-ease), var(--nav-ease), ease;
}
/* Set by the nav script for one frame while the bar is out of view, so it
   can change shape there instead of morphing on screen. */
.rd-nav.is-instant { transition: none !important; }
.rd-nav::-webkit-scrollbar { display: none; }
.rd-nav a { color: inherit; text-decoration: none; }

/* Floating pill once the page has scrolled. It is inset 12px from each
   side, so its padding drops by the same amount and the wordmark stays on
   the gutter line; never tighter than 8px against the pill's curve. */
.rd-nav.is-scrolled {
  top: 8px; left: 12px; right: 12px;
  /* The pill's 12px inset only matters while the viewport is narrower than
     its 1440px cap plus that inset; on wider screens it is centred like the
     page and needs no compensation (it put the wordmark 12px left of the
     content at 1920px). */
  --pill-inset: clamp(0px, calc(12px - (100vw - 1464px) / 2), 12px);
  padding-inline: max(8px, calc(var(--gutter) - var(--nav-item-pad) - var(--pill-inset) - 1px));
  border-color: var(--rule, var(--border));
  /* The card radius (24px) is already fully round on a 47px bar. The
     control radius (999px) got there a few pixels into the transition, so
     the corners snapped instead of easing in. */
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  box-shadow: 0 2px 12px rgb(0 0 0 / 0.05);
}
/* Homepage only: the flat bar slides out of view between the hero and
   About, then returns as the pill (see Navigation.astro). */
.rd-nav.is-home.is-hidden { transform: translateY(-130%); opacity: 0; pointer-events: none; }

/* min-width: max-content is load-bearing: the bar is nowrap, so a cell
   allowed to shrink past its text would bleed under its neighbour. */
.rd-nav-brand,
.rd-nav-item,
.rd-nav-btn {
  flex: none;
  min-width: max-content;
  min-height: 44px;
  display: flex;
  align-items: center;
  padding: 14px var(--nav-item-pad);
  transition: color 160ms ease;
}
.rd-nav-brand { margin-right: auto; gap: 8px; }
.rd-nav-dot { width: 9px; height: 9px; background: var(--accent); display: inline-block; flex: none; }
.rd-nav-name { font-weight: 600; }
.rd-nav-nick { font-style: italic; font-weight: 400; color: var(--muted, var(--text-tertiary)); }

/* Hover and "you are here" are colour only -- no background block, which
   drew a square inside the rounded pill. */
.rd-nav-brand:hover,
.rd-nav-item:hover,
.rd-nav-btn:hover,
.rd-nav-item.is-active,
.rd-nav-item[aria-current="page"] { color: var(--accent); }

.rd-nav-btn {
  justify-content: center;
  min-width: 44px;
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  gap: 6px;
}
.rd-nav svg { width: 16px; height: 16px; display: block; flex: none; }
.rd-nav-lang svg { width: 14px; height: 14px; }

/* Sun/moon swap is driven by the theme attribute on <html>. */
.rd-nav-theme { position: relative; min-width: 48px; }
.rd-nav-theme svg {
  position: absolute; left: 50%; top: 50%;
  opacity: 0;
  transform: translate(-50%, -50%) rotate(-40deg) scale(0.7);
  transition: opacity 180ms ease, transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
}
:root:not([data-theme="dark"]) .rd-nav-theme .icon-moon,
[data-theme="dark"] .rd-nav-theme .icon-sun { opacity: 1; transform: translate(-50%, -50%) rotate(0) scale(1); }

.rd-menu-icon { display: block; position: relative; width: 18px; height: 16px; flex: none; }
.rd-menu-icon span {
  position: absolute; left: 0; width: 18px; height: 2px;
  background: currentColor; border-radius: var(--radius-control);
  transition: transform 280ms cubic-bezier(0.22, 1, 0.36, 1);
}
.rd-menu-icon span:first-child { top: 4px; }
.rd-menu-icon span:last-child { top: 12px; }
.rd-nav-menu[aria-expanded="true"] .rd-menu-icon span:first-child { transform: translateY(4px) rotate(45deg); }
.rd-nav-menu[aria-expanded="true"] .rd-menu-icon span:last-child { transform: translateY(-4px) rotate(-45deg); }

/* ☰ appears only when the bar does not fit. The nav script measures the
   bar with every item showing and sets .is-compact (links move into the
   menu) and, if that is still too wide, .is-tight (the language switch
   moves too). */
.rd-nav-menu { display: none; }
.rd-nav.is-compact .rd-nav-item { display: none; }
.rd-nav.is-compact .rd-nav-menu { display: flex; }
.rd-nav.is-tight .rd-nav-lang { display: none; }
@media (max-width: 860px) {
  .rd-nav-nick { display: none; }
}

.rd-nav-spacer { height: var(--nav-h, 57px); }

/* ═══ ☰ MENU ═══════════════════════════════════════════════════ */
.rd-mobile-menu {
  position: fixed;
  top: calc(var(--nav-h, 57px) + 16px); left: 12px; right: 12px;
  z-index: 99;
  display: flex;
  flex-direction: column;
  max-height: calc(100dvh - var(--nav-h, 57px) - 28px);
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--rule, var(--border));
  border-radius: var(--radius-card);
  background: var(--bg);
  color: var(--ink, var(--text-primary));
  font: 600 var(--text-sm)/1.35 'Helvetica Neue', Helvetica, Arial, sans-serif;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-8px);
  transition: opacity 180ms ease, transform 260ms cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear 260ms;
}
.rd-mobile-menu.is-open { opacity: 1; visibility: visible; pointer-events: auto; transform: none; transition-delay: 0s; }
.rd-mobile-menu a {
  display: flex; align-items: center;
  min-height: 44px; flex-shrink: 0;
  padding: 10px 20px;
  border-bottom: 1px solid var(--rule, var(--border));
  color: inherit; text-decoration: none;
  transition: color 160ms ease;
}
.rd-mobile-menu a:last-child { border-bottom: none; }
.rd-mobile-menu a:hover,
.rd-mobile-menu a[aria-current="page"] { color: var(--accent); }
.rd-mobile-menu .rd-menu-language { display: none; }
.rd-nav.is-tight ~ .rd-mobile-menu .rd-menu-language { display: flex; }

/* ═══ FOOTER ═══════════════════════════════════════════════════
   Footer.astro on Astro pages; the archive and credentials pages copy its
   markup. */
.rd-footer {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  padding: var(--space-4) var(--gutter);
  border-top: 1px solid var(--rule);
  background: var(--bg);
  color: var(--muted);
  font: 500 var(--text-xs)/1.4 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.rd-footer > :nth-child(2) { text-align: center; }
.rd-footer-links { display: flex; justify-content: flex-end; gap: 18px; }
.rd-footer a { color: inherit; text-decoration: none; }
.rd-footer a:hover { color: var(--accent); }

@media (max-width: 600px) {
  .rd-footer { grid-template-columns: 1fr auto; gap: 7px 18px; padding-block: 16px; }
  .rd-footer > :nth-child(2) { grid-column: 1; grid-row: 2; text-align: left; }
  .rd-footer-links { grid-column: 2; grid-row: 1 / span 2; align-items: flex-end; flex-direction: column; gap: 7px; }
}

/* ═══ SKIP LINK ════════════════════════════════════════════════ */
.skip-link {
  position: fixed;
  left: 12px; top: -100px;
  z-index: 200;
  padding: 12px 18px;
  border-radius: var(--radius-control);
  background: var(--accent);
  color: var(--accent-ink, var(--bg));
  font: 600 var(--text-sm) 'Helvetica Neue', Helvetica, Arial, sans-serif;
  text-decoration: none;
  transition: top 150ms ease;
}
.skip-link:focus, .skip-link:focus-visible { top: 8px; color: var(--accent-ink, var(--bg)); }

/* ═══ SHARED FLOORS ════════════════════════════════════════════ */
/* Anchor jumps must clear the fixed bar. */
:target { scroll-margin-top: calc(var(--nav-h, 57px) + 2px); }
main { scroll-margin-top: calc(var(--nav-h, 57px) + 24px); }

/* The focus ring every interactive element gets, on every page. Pages may
   still add bespoke focus treatments on top. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Standalone case-study controls share the pill shape of the Astro pages. */
.case-cta-btn, .case-stack-item, .rd-badge, .rd-verify { border-radius: var(--radius-control) !important; }
.case-cta-btn { min-height: 44px; box-sizing: border-box; }

@media (prefers-reduced-motion: reduce) {
  .rd-nav, .rd-nav-brand, .rd-nav-item, .rd-nav-btn, .rd-nav-theme svg,
  .rd-menu-icon span, .rd-mobile-menu, .rd-mobile-menu a, .skip-link { transition: none; }
  .rd-mobile-menu { transform: none; }
}
