/* nav-mobile.css — shared mobile-nav styling across all pages.
   Loaded after the page's inline <style> so it can override the defaults.
   The base nav layout (brand on left, links on right) is defined per-page;
   this file only adds the mobile-specific dropdown + hamburger behaviour. */

nav.top .nav-right {
  display: flex;
  align-items: center;
  gap: 28px;
}
nav.top .nav-burger { display: none; }

/* Desktop styling for the Try Free CTA — used to live under .links .nav-cta
   in each page's inline <style>. Moved here since the button now sits in
   .nav-right (outside .links) where the per-page rules no longer reach it.
   [2026-05-12] Fallback for pages without `.is-on-dark` (kept for safety,
   but the canonical partial now always adds is-on-dark — see below). */
nav.top .nav-right > .nav-cta {
  background: #0A0A0A;
  color: #FFFFFF;
  padding: 8px 14px;
  font-family: 'Instrument Sans', -apple-system, system-ui, sans-serif;
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: all 0.15s;
}
nav.top .nav-right > .nav-cta:hover {
  background: #0B7A95;
  transform: translate(-1px, -1px);
  box-shadow: 2px 2px 0 #0A0A0A;
}

/* ============================================================================
   [2026-05-12] is-on-dark — canonical nav theme on legacy raw-HTML pages.
   ----------------------------------------------------------------------------
   Astro pages get these rules from base.css. Legacy pages (account.html,
   welcome.html, feedback.html, app.html, dashboard.html + worker SSR blog)
   don't load base.css, so we duplicate the rules here. Both stylesheets
   stay in sync — change in one place, mirror to the other.

   Josh's directives :
   - "Le sticky doit rester black tout le temps" (2026-05-10) — nav bg is
     hardcoded #0A0A0A regardless of page theme.
   - "Try Free a plein de comportement different selon la page" + "shadow
     blanche au hover c'est moche" (2026-05-12) — CTA is cyan ghost
     everywhere ; hover fills cyan + 1px translate, no white shadow.
   ============================================================================ */
nav.top.is-on-dark {
  background: #0A0A0A !important;
  border-bottom-color: transparent !important;
}
nav.top.is-on-dark .brand { color: #FFFFFF !important; }
nav.top.is-on-dark .brand-wordmark { color: #FFFFFF !important; }
nav.top.is-on-dark .brand-wordmark::before { background: var(--cyan, #00D4FF) !important; }
nav.top.is-on-dark .links { color: rgba(255, 255, 255, 0.7) !important; }
nav.top.is-on-dark .links a:hover,
nav.top.is-on-dark .links a.active { color: var(--cyan, #00D4FF) !important; }
nav.top.is-on-dark .links .nav-sep { background: rgba(255, 255, 255, 0.18) !important; }
/* Try Free CTA — outlined cyan ghost on idle, filled cyan on hover. */
nav.top.is-on-dark .nav-right > .nav-cta {
  background: transparent;
  color: var(--cyan, #00D4FF);
  box-shadow: inset 0 0 0 1px var(--cyan, #00D4FF);
}
nav.top.is-on-dark .nav-right > .nav-cta:hover {
  background: var(--cyan, #00D4FF);
  color: #0A0A0A;
  box-shadow: inset 0 0 0 1px var(--cyan, #00D4FF);
  transform: translate(-1px, -1px);
}
/* Burger lines stay WHITE on dark. */
nav.top.is-on-dark .nav-burger span,
nav.top.is-on-dark .nav-burger span:before,
nav.top.is-on-dark .nav-burger span:after { background: #FFFFFF !important; }
@media (max-width: 768px) {
  /* Show wordmark, hide PNG logo on mobile dark. */
  nav.top.is-on-dark .brand-wordmark { display: inline-block; }
  nav.top.is-on-dark .brand-logo { display: none; }
  /* Hide desktop CTA on mobile — only burger + wordmark visible. */
  nav.top.is-on-dark .nav-right > .nav-cta { display: none; }
  /* Burger overlay : dark bg + white links + cyan hover. */
  nav.top.is-on-dark.is-open .links { background: #0A0A0A; color: #FFFFFF; }
  nav.top.is-on-dark.is-open .links a { color: #FFFFFF; }
  nav.top.is-on-dark.is-open .links a:hover,
  nav.top.is-on-dark.is-open .links a:active,
  nav.top.is-on-dark.is-open .links a.active { color: var(--cyan, #00D4FF); }
}

@media (max-width: 768px) {
  nav.top {
    padding: 14px 16px;
    flex-wrap: wrap;
  }
  nav.top .nav-right {
    gap: 10px;
  }

  /* CRITICAL : the page-level nav.top has backdrop-filter for the frosted-
     glass effect. Per CSS spec, that creates a containing block for any
     descendant with position: fixed — meaning the .links overlay would be
     anchored to nav.top (a thin bar), not the viewport. So when the menu
     opens, we drop the filter on nav.top so .links can cover the full
     viewport. The closed state keeps the frosted look. */
  nav.top.is-open {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    background: transparent !important;
    /* same trick for any other CSS prop that creates a containing block */
    transform: none !important;
    filter: none !important;
  }

  /* Full-screen overlay menu when `.is-open` is set on nav.top.
     Detroit / Crafting-Culture style : opaque page-bg, top-aligned big
     display-font page links flush-left. Lock body scroll when open.
     [Run #21.3] Theme-aware via CSS tokens : `--bone` flips to dark on
     pages with `body.is-dark-theme`, so the menu auto-matches the page.
     Explicit `width: 100vw; height: 100dvh` because some Astro pages have
     parent stacking-contexts (backdrop-filter on nav.top, body::before
     grain) that make `inset: 0` resolve to the wrong containing block —
     forcing the viewport units side-steps that. `dvh` handles iOS Safari's
     bottom toolbar without leaving a gap. */
  /* [Hotfix 2026-05-23] `html` prefix bumps specificity from (0,2,1) to
     (0,2,2) so this mobile rule wins over the per-page desktop rules
     that all Astro pages define as `nav.top .links { display: flex; … }`
     in their <style is:global> blocks. The CLS optimization (commit
     94e98e1) moved this stylesheet into <head>, putting it BEFORE the
     per-page styles in the cascade ; without the specificity bump, the
     desktop rules win at mobile widths (same specificity + later source
     order), which keeps this full-viewport overlay visible AND replaces
     the Big Shoulders 48-80px layout with desktop's 11px mono. Result :
     mobile homepage was a white box, mobile burger menu opened with the
     wrong typography. Both fixed at once by the bumped specificity. */
  html nav.top .links {
    display: none;
    position: fixed;
    top: 0; left: 0;
    width: 100vw;
    height: 100dvh;
    background: var(--bone, #FFFFFF);
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    padding: 88px 20px 48px;
    gap: 8px;
    font-family: 'Big Shoulders Display', Impact, Arial, sans-serif;
    font-weight: 900;
    font-size: clamp(48px, 12vw, 80px);
    line-height: 0.95;
    letter-spacing: -0.025em;
    text-transform: uppercase;
    color: var(--ink, #0A0A0A);
    /* [Run #21.5] z-index 9999 (was 1) — base.css sets nav/main/footer/section/
       header to z-index: 2, which made the page content render OVER the menu
       overlay. Bumped to defeat all known stacking contexts on the site. */
    z-index: 9999;
    overflow-y: auto;
    backdrop-filter: none;
    border-bottom: none;
    box-shadow: none;
  }
  html nav.top.is-open .links { display: flex; }
  nav.top.is-open .links a {
    color: var(--ink, #0A0A0A);
    transition: color 0.15s;
    line-height: 0.95;
  }
  nav.top.is-open .links a:hover,
  nav.top.is-open .links a:active { color: var(--cyan-deep, #0B7A95); }
  nav.top.is-open .links a.active {
    color: var(--cyan-deep, #0B7A95);
    border-left: none;
    padding-left: 0;
    margin-left: 0;
  }

  /* Lock background scroll while overlay is open. */
  body:has(nav.top.is-open) { overflow: hidden; }

  /* Brand + CTA + MENU button sit ON TOP of the overlay so they stay tappable.
     [Run #21.5] z-index bumped 2 → 10000 (just above menu's 9999) since the
     menu got bumped to defeat page content's z-index 2. */
  nav.top .brand { position: relative; z-index: 10000; }
  nav.top .nav-right > .nav-cta { position: relative; z-index: 10000; }
  nav.top .nav-burger { position: relative; z-index: 10000; }

  /* Hide the inline separator (it lived between links and CTA on desktop). */
  nav.top .links .nav-sep { display: none; }

  /* Try Free / Open app CTA — visible on mobile in the closed state next
     to MENU, single line. Hidden when the overlay menu is open so it
     doesn't compete with the big page links. */
  nav.top .nav-right .nav-cta {
    white-space: nowrap;
    padding: 7px 12px;
    font-size: 13px;
    line-height: 1;
    font-weight: 600;
    letter-spacing: 0.04em;
  }
  nav.top.is-open .nav-right .nav-cta { display: none; }

  /* Hamburger icon : 3 horizontal bars at rest, animates into an X when
     the menu opens (Josh 2026-04-29 — replaced the previous "MENU/CLOSE"
     text label for a more universal icon). Each <span> in the burger is
     one of the bars ; transforms reposition the top + bottom bars into an
     X and fade the middle one out. */
  nav.top .nav-burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: transparent;
    border: 0;
    cursor: pointer;
    padding: 0;
    flex-shrink: 0;
    position: relative;
  }
  /* Reset whatever inherited "MENU" text content there might have been. */
  nav.top .nav-burger::before { content: none; }
  /* The 3 bars. The host page's nav-burger may render them as <span>s, so
     this rule grabs any direct <span> child. */
  nav.top .nav-burger span {
    display: block;
    position: absolute;
    left: 7px; right: 7px;
    height: 2px;
    /* [Run #21.3] Theme-aware burger : `--ink` is dark text on light pages
       and white on dark pages (body.is-dark-theme). So the bars match. */
    background: var(--ink, #0A0A0A);
    border-radius: 1px;
    transform-origin: center center;
    transition:
      transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1),
      opacity 0.2s ease,
      top 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  nav.top .nav-burger span:nth-child(1) { top: 10px; }
  nav.top .nav-burger span:nth-child(2) { top: 15px; }
  nav.top .nav-burger span:nth-child(3) { top: 20px; }
  /* Open state : top + bottom bars rotate into an X centered on row 15px,
     middle bar fades to nothing. */
  nav.top.is-open .nav-burger span:nth-child(1) {
    top: 15px;
    transform: rotate(45deg);
  }
  nav.top.is-open .nav-burger span:nth-child(2) {
    opacity: 0;
    transform: scaleX(0);
  }
  nav.top.is-open .nav-burger span:nth-child(3) {
    top: 15px;
    transform: rotate(-45deg);
  }
  /* If the markup only ships 1 span (older partials/pages), synthesize the
     other two via pseudo-elements so the icon still works. The same
     transform set is mirrored on ::before / ::after. */
  nav.top .nav-burger:not(:has(span:nth-child(2)))::before,
  nav.top .nav-burger:not(:has(span:nth-child(2)))::after {
    content: "";
    position: absolute;
    left: 7px; right: 7px;
    height: 2px;
    background: var(--ink, #0A0A0A);
    border-radius: 1px;
    transform-origin: center center;
    transition:
      transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1),
      top 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  nav.top .nav-burger:not(:has(span:nth-child(2)))::before { top: 10px; }
  nav.top .nav-burger:not(:has(span:nth-child(2)))::after  { top: 20px; }
  nav.top.is-open .nav-burger:not(:has(span:nth-child(2)))::before { top: 15px; transform: rotate(45deg); }
  nav.top.is-open .nav-burger:not(:has(span:nth-child(2)))::after  { top: 15px; transform: rotate(-45deg); }
}

/* [Run #20] Auth-gated Dashboard + Account links in the nav. Hidden by
   default ; shown only when nav-mobile.js flips data-auth="in" on the
   parent nav after probing /api/account/me. Keeps the links invisible to
   logged-out visitors (they'd hit a sign-in wall on click).
   [Run #20.11] Account joined Dashboard in the gated set for consistency. */
.nav-dashboard-link,
.nav-account-link { display: none; }
nav.top[data-auth="in"] .nav-dashboard-link,
nav.top[data-auth="in"] .nav-account-link { display: inline-flex; }

/* [2026-05-12] Inverse gating for the Sign-in link. Default hidden — no
   data-auth attribute means the probe hasn't run yet, and we'd rather show
   nothing than flash the Sign-in link to a logged-in returning visitor
   before nav-mobile.js sets data-auth="in". Once the probe resolves to
   "out", the link surfaces. Lands on /account where the magic-link form,
   Google OAuth and password sign-in all live. */
.nav-signin-link { display: none; }
nav.top[data-auth="out"] .nav-signin-link { display: inline-flex; }

/* [2026-05-10] "Try free →" entry inside the mobile burger panel.
   The desktop CTA (`a.nav-cta` outside the panel) is hidden on mobile
   when the nav is in `is-on-dark` state, so without this entry the
   mobile menu had no path to /app. Hidden on desktop so we don't
   show the CTA twice.

   [v2 2026-05-10] Restyled as an outlined cyan CTA button — sat as a
   plain link in the same big-display font as the other nav items, it
   read as a fifth menu entry instead of the primary action. Now it
   gets its own bottom-margin block, mono caps, cyan stroke + cyan
   text, and inverts to solid cyan on press. Sits at the bottom of
   the panel by default (last child in markup). */
.nav-app-link { display: none; }
@media (max-width: 768px) {
  .nav-app-link {
    display: inline-flex !important;
    align-items: center;
    gap: 10px;
    margin-top: 28px;
    padding: 14px 22px;
    border: 1.5px solid var(--cyan, #00D4FF);
    color: var(--cyan, #00D4FF) !important;
    font-family: 'JetBrains Mono', ui-monospace, monospace !important;
    font-size: 13px !important;
    font-weight: 500 !important;
    letter-spacing: 0.14em;
    line-height: 1 !important;
    text-transform: uppercase;
    transition: background-color 0.18s ease, color 0.18s ease, transform 0.18s ease;
    align-self: flex-start;
  }
  /* Stronger specificity than `nav.top.is-open .links a:hover` (which
     turns the rest of the panel cyan-deep) so this CTA doesn't drift
     into the wrong colour. */
  nav.top.is-open .links a.nav-app-link:hover,
  nav.top.is-open .links a.nav-app-link:active,
  nav.top.is-open .links a.nav-app-link.active {
    background: var(--cyan, #00D4FF);
    color: #0A0A0A !important;
    transform: translate(-1px, -1px);
  }
}

/* === [Run #20.11] Skip-to-content link =====================================
   First focusable element in body. Visually hidden until focused (Tab on
   page load) — then surfaces top-left as a high-contrast cyan pill. Lets
   keyboard + screen reader users jump past the nav directly to <main>.
   Tier-1 a11y standard (Vercel, Linear, GOV.UK pattern). =================== */
.skip-link {
  position: absolute;
  top: -40px;
  left: 8px;
  z-index: 9999;
  padding: 10px 16px;
  background: #00D4FF;
  color: #0A0A0A;
  font-family: 'Instrument Sans', 'LT Superior', -apple-system, system-ui, sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-decoration: none;
  border: 1px solid #0A0A0A;
  transition: top 0.18s ease;
}
.skip-link:focus,
.skip-link:focus-visible {
  top: 8px;
  outline: 2px solid #0A0A0A;
  outline-offset: 2px;
}
