/* The hidden attribute must actually hide: the UA's [hidden]{display:none} is
   author-level-overridable, so any class with its own display rule (e.g. .btn's
   inline-flex) would silently defeat it. Enforce the semantics globally. */
[hidden] { display: none !important; }

/* =====================================================================
   nav.css — the canonical public top navbar, shared by every marketing /
   auth page. Mirrors the homepage nav (styles.css) with hard-coded colours
   so it renders identically regardless of each page's own design tokens.
   MUST be linked LAST so it overrides any per-page nav styling.
   ===================================================================== */

nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 40px;
  background: #ffffff;
  border-bottom: 1px solid #e8edf6;
  position: sticky;
  top: 0;
  z-index: 100;
  box-shadow: 0 2px 12px rgba(30,58,138,0.07);
}

nav .logo {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 1.3rem;
  color: #020C45;
  display: flex;
  align-items: center;
  gap: 6px;
  text-decoration: none;
}
nav .logo .check { color: #3b82f6; font-size: 1.2rem; }

nav .nav-links {
  display: flex;
  align-items: center;
  gap: 32px;
  list-style: none;
  margin: 0;
  padding: 0;
}
nav .nav-links > li { list-style: none; }
nav .nav-links a {
  text-decoration: none;
  color: #0f1f4b;
  font-size: 0.95rem;
  font-weight: 500;
  transition: color 0.2s;
}
nav .nav-links a:hover,
nav .nav-links a.active { color: #3b82f6; }

/* ── Agent dropdown ── */
.nav-dropdown { position: relative; }
.nav-dropdown-toggle { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.nav-dropdown-toggle svg { transition: transform 0.2s; }
.nav-dropdown:hover .nav-dropdown-toggle svg,
.nav-dropdown:focus-within .nav-dropdown-toggle svg { transform: rotate(180deg); }
/* invisible bridge so the menu doesn't close in the gap under the toggle */
.nav-dropdown::after { content: ''; position: absolute; top: 100%; left: 0; right: 0; height: 14px; }
.nav-dropdown-menu {
  position: absolute;
  top: calc(100% + 12px);
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  min-width: 190px;
  background: #ffffff;
  border: 1px solid #e8edf6;
  border-radius: 10px;
  box-shadow: 0 8px 28px rgba(2,12,69,0.12);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
  z-index: 200;
}
.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown:focus-within .nav-dropdown-menu {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
.nav-dropdown-menu a {
  padding: 9px 12px;
  border-radius: 7px;
  font-size: 0.9rem;
  color: #0f1f4b;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s;
}
.nav-dropdown-menu a:hover { background: #f8faff; color: #3b82f6; }

nav .nav-right { display: flex; align-items: center; gap: 16px; }
nav .nav-icon {
  width: 36px; height: 36px;
  border: 1.5px solid #c4cfe3;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: #64748b;
  transition: border-color 0.2s, color 0.2s;
}
nav .nav-icon:hover { border-color: #3b82f6; color: #3b82f6; }
nav .nav-right .sep { color: #c4cfe3; }

nav .btn-login {
  background: none; border: none;
  font-family: 'DM Sans', sans-serif;
  font-size: 0.95rem; font-weight: 500;
  color: #0f1f4b; cursor: pointer;
  transition: color 0.2s;
}
nav .btn-login:hover { color: #3b82f6; }
nav .btn-signup {
  background: #3b82f6;
  color: #ffffff;
  border: none;
  border-radius: 8px;
  padding: 9px 20px;
  font-family: 'DM Sans', sans-serif;
  font-size: 0.95rem; font-weight: 500;
  cursor: pointer;
  transition: background 0.2s, transform 0.15s;
}
nav .btn-signup:hover { background: #1d4ed8; transform: translateY(-1px); }

/* ── Anti-flash for the signed-in header (paired with JS/publicHeader.js) ──
   Public pages ship static Log In / Sign Up buttons, and publicHeader.js only
   swaps them for the avatar chip after a refresh + /me round-trip: a signed-in
   visitor saw the WRONG header for 117-160ms on every public page, then a ~150px
   layout jump as the pair was replaced by a 34px chip.

   When the session hint says a refresh cookie probably exists, the head snippet
   on those pages sets .tp-auth-pending before first paint, so the buttons are
   never painted. publicHeader.js lifts the cloak only on the logged-out
   outcomes (no TP, stale hint, dead session — the buttons come back); when the
   chip renders the cloak deliberately STAYS set, keeping the buttons hidden
   next to it. A page still can't get stuck with no header controls: every
   chip-less path uncloaks, and the head snippet carries a 4s failsafe for the
   case where publicHeader.js never runs at all. Only the 9 pages that actually
   load publicHeader.js carry the snippet; the auth-flow pages (login, signup,
   reset…) must keep showing the pair regardless.

   The anchor is hidden, not just the button: .nav-right is a flex row with a
   16px gap, so two empty <a> wrappers would leave 32px of dead space. */
html.tp-auth-pending nav .nav-right > a:has(> .btn-login),
html.tp-auth-pending nav .nav-right > a:has(> .btn-signup) { display: none; }

@media (max-width: 768px) {
  nav { padding: 14px 20px; }
  nav .nav-links { gap: 18px; }
  nav .nav-right { gap: 10px; }
  nav .nav-icon, nav .nav-right .sep { display: none; }
}

/* =====================================================================
   Dark mode — the navbar's own skin, same values as styles.css's dark
   block. This file is the ONE place that owns the navbar in both themes:
   per-page sheets (agent.css, signUp.css, …) each copied a partial nav
   repaint and drifted — none of them covered .nav-dropdown-menu, leaving
   a white panel with near-white links on every page whose dark tokens
   don't come from styles.css/app-shell.css. Keeping the full repaint
   here means a page can no longer load the navbar without its dark skin.
   ===================================================================== */
body.dark nav { background: #111a38; border-bottom: 1px solid #26325c; }
body.dark nav .logo { color: #ffffff; }
body.dark nav .nav-links a { color: #dbe4f8; }
body.dark nav .nav-links a:hover,
body.dark nav .nav-links a.active { color: #50A2FF; }
body.dark .nav-dropdown-menu {
  background: #111a38;
  border-color: #26325c;
  box-shadow: 0 8px 28px rgba(0,0,0,0.5);
}
body.dark .nav-dropdown-menu a { color: #dbe4f8; }
body.dark .nav-dropdown-menu a:hover { background: rgba(59,130,246,0.12); color: #50A2FF; }
body.dark nav .btn-login { color: #dbe4f8; }
body.dark nav .btn-login:hover { color: #50A2FF; }
body.dark nav .nav-icon { background: transparent; border-color: #34426e; color: #93a3c8; }
body.dark nav .nav-icon:hover { border-color: #3b82f6; color: #50A2FF; }
body.dark nav .nav-right .sep { color: #34426e; }

/* ── Mobile nav collapse (paired with JS/navToggle.js) ──
   Colours are hard-coded to this file's own palette — per the header comment,
   nav.css deliberately avoids per-page design tokens (several sheets never
   define --text/--border in light mode).

   Console pages share this <nav> and now load navToggle.js too, so the drawer
   machinery below (hamburger, panel, submenu accordion) is UNSCOPED. Without it
   the console nav kept its desktop layout at every width: at 390px the logo
   collided with "Find Jobs" and the bell/avatar sat ~85px off-screen on all 25
   signed-in pages.

   What stays scoped to body:not(.console) is only the chrome-compaction —
   padding, logo size, the Log In/Sign Up sizing. app-shell.css owns the console
   bar's own geometry (fixed --topbar-h height, its own padding), and the drawer
   is position:absolute so it never grows that fixed height. */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 36px; height: 36px;
  border: none; background: none; cursor: pointer; padding: 0;
  order: 3;
  color: #0f1f4b; /* buttons don't inherit colour; matches the nav links */
}
body.dark .nav-toggle { color: #dbe4f8; }
.nav-toggle span {
  display: block; width: 100%; height: 2px;
  background: currentColor; /* follows the active theme via the rules above */
  border-radius: 2px;
  transition: transform 0.2s, opacity 0.2s;
}
nav.nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
nav.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
nav.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Theme toggle's drawer row — JS/navToggle.js clones the page's theme button in here (from
   the top bar on public pages, from the sidebar footer on console ones). Hidden by default
   because the clone exists in the DOM at every width: this pair of files gates the drawer
   from CSS, never from JS, exactly as it does for the hamburger. The mobile block reveals it. */
.nav-drawer-toggle,
.nav-drawer-signout { display: none; }

/* ── The console nav's own theme toggle (minted by JS/navToggle.js) ──
   Public pages carry a theme toggle in `nav .nav-right`; console pages keep theirs in the
   sidebar footer instead — and the two stylesheets that own console chrome hand over at
   DIFFERENT widths:

     app-shell.css  ≤900px  its `@media (max-width: 900px)` block turns the sidebar
                            horizontal and puts `.sidebar-foot` in its display:none list
     this file      ≤768px  nav collapses, `.nav-drawer-toggle` takes the toggle over

   769–900px falls between them, so a signed-in visitor had no theme toggle anywhere on the
   page. Widening either breakpoint to meet the other is not on: app-shell's 900px block also
   re-lays-out kpi-row/form-grid/detail-grid/app-content, and moving the drawer to 900px for
   console alone would mean a second copy of every rule in the block below — the copy-and-drift
   this file's header exists to prevent. So the console nav gets a toggle of its own covering
   exactly the orphaned band.

   The two numbers below ARE the reconciliation — one-past app-shell's 900, and just past this
   file's 768. The lower bound is 768.02px, not 769px: viewport width is a CSS-pixel *fraction*
   under browser zoom (e.g. 768.5px at 110%), and min-width:769 with max-width:768 next door
   would leave that sliver with no toggle at all — the exact bug this block fixes. Change either
   breakpoint and this range moves with it, or the gap reopens. */
.nav-console-theme { display: none; }
/* Sign out (minted by JS/shell.js) has the exact same two orphaned widths as the theme toggle —
   its only home is the sidebar footer, which app-shell.css hides at ≤900px — so it gets the same
   two copies: this bar icon for the band, a drawer row (.nav-drawer-signout, below) for ≤768px. */
.nav-console-signout { display: none; }
@media (min-width: 768.02px) and (max-width: 900px) {
  body.console > nav .nav-console-theme,
  body.console > nav .nav-console-signout {
    display: flex; align-items: center;
    /* the bare icon-button skin every other copy of this button carries inline */
    background: none; border: none; cursor: pointer;
    color: inherit; opacity: .7; padding: 6px; border-radius: 8px;
  }
}

@media (max-width: 768px) {
  nav .nav-toggle { display: flex; }
  nav .nav-right { order: 2; }

  /* The console bar's height is fixed by app-shell.css, so it must NOT wrap —
     a second row would overflow that height rather than grow the bar. It has no
     Log In/Sign Up pair to run out of room for, and its three icons always fit. */
  body:not(.console) nav { flex-wrap: wrap; }
  body.console > nav { flex-wrap: nowrap; }

  /* Logged out, the top row is logo + Log In + Sign Up + hamburger (theme toggle has
     moved into the drawer — see .nav-drawer-toggle below), and `nav` must stay
     wrappable for the drawer — so if that trio doesn't fit, the hamburger drops onto
     a second row. Compact the chrome to keep it on one. */
  body:not(.console) nav { padding: 14px 16px; }
  body:not(.console) nav .logo { font-size: 1.1rem; }
  body:not(.console) nav .nav-right { gap: 8px; }
  body:not(.console) nav .btn-login,
  body:not(.console) nav .btn-signup { font-size: 0.9rem; }
  body:not(.console) nav .btn-signup { padding: 8px 14px; }

  /* Equal margins either side of the hamburger. The nav is `justify-content:
     space-between`, which splits the leftover space EVENLY between logo | nav-right |
     hamburger — so the nav-right→hamburger gap was whatever happened to be left over and
     never matched the nav's own edge padding. Giving the logo `margin-right: auto` makes
     it eat all the slack instead, which leaves `gap` as the only thing sizing the
     nav-right→hamburger distance. Set that gap to each layout's own horizontal padding
     and the two margins match: one is paid as padding-right, the other as the gap.
     (nav-links is position:absolute here, so `gap` never applies to it.) */
  nav .logo { margin-right: auto; }
  body:not(.console) nav { gap: 16px; }          /* matches the 16px padding above */
  body.console > nav { gap: 14px; }              /* app-shell.css pads the console bar 0 14px */

  /* Theme toggle no longer lives in the top bar on mobile — navToggle.js has put a copy in
     the drawer. The avatar chip (or, logged out, the Log In / Sign Up pair) stays put.
     !important because every page ships this button with an inline `display:flex` (a bare
     icon button skinned inline, not via a class), and inline style beats any external rule
     short of !important — the same reason [hidden] is forced at the top of this file. */
  nav .nav-right .theme-toggle-btn { display: none !important; }
  body:not(.console) nav .nav-right .nav-avatar { display: flex; }

  /* The drawer hangs below the bar as an overlay panel rather than sitting in
     the nav's flex flow. In flow it grew the sticky nav's own height, which
     pushed the hero — and every section under it — down as the menu opened.
     Out of flow the bar keeps a fixed height and the page never moves.
     (`nav` is sticky, i.e. positioned, so it is the containing block here.) */
  /* `visibility: hidden` as well as the clip, because max-height:0 + overflow:hidden only stops the
     links being PAINTED — they keep their layout boxes, stay in the tab order and stay in the
     accessibility tree. A keyboard user tabbing off the logo would otherwise walk through seven
     invisible links against a blank screen, and a screen reader would announce a shut menu's
     contents as available. visibility is inherited and animatable-by-delay, so it can be deferred
     until the collapse finishes and does not cut the transition short. */
  nav .nav-links {
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 2px;
    padding: 0 12px; /* + the links' own 4px = flush with the logo */
    background: #ffffff;
    max-height: 0; overflow: hidden;
    visibility: hidden;
    transition: max-height 0.2s ease, visibility 0s linear 0.2s;
  }
  body.dark nav .nav-links { background: #111a38; }
  nav.nav-open .nav-links {
    max-height: 70vh; overflow-y: auto;
    visibility: visible;
    transition: max-height 0.2s ease, visibility 0s;
    border-bottom: 1px solid #e8edf6;
    box-shadow: 0 10px 18px rgba(30,58,138,0.08);
  }
  body.dark nav.nav-open .nav-links {
    border-bottom-color: #26325c;
    box-shadow: 0 10px 18px rgba(0,0,0,0.45);
  }
  nav .nav-links a { display: block; padding: 10px 4px; }

  /* Flyout becomes an inline block — no hover on touch, and it would clip.
     The :hover/:focus-within variants must be repeated here: the desktop show
     rules above are (0,3,0), so the bare .nav-dropdown-menu override (0,1,0)
     would lose transform/opacity to them while the tapped toggle keeps focus.
     The two repeats are (0,3,0) — equal to the desktop rules, winning on order. */
  .nav-dropdown-menu,
  .nav-dropdown:hover .nav-dropdown-menu,
  .nav-dropdown:focus-within .nav-dropdown-menu {
    position: static; transform: none; box-shadow: none; border: none;
    padding: 0 0 0 12px;
    /* opacity stays 1 — the accordion is revealed by height, not by fading. visibility is hidden
       while shut for the same reason as the drawer above: a clipped link is still tabbable. */
    opacity: 1; visibility: hidden;
    max-height: 0; overflow: hidden;
    transition: max-height 0.2s ease, visibility 0s linear 0.2s;
  }
  /* Equal specificity to the :hover/:focus-within variants above (0,3,0) and declared after them,
     so it wins on order — the same reason those variants have to be repeated in the first place. */
  .nav-dropdown.open .nav-dropdown-menu {
    max-height: 240px;
    visibility: visible;
    transition: max-height 0.2s ease, visibility 0s;
  }
  /* the desktop hover-bridge strip would overlap the first inline submenu row */
  .nav-dropdown::after { display: none; }

  /* Theme toggle's drawer row (minted by JS/navToggle.js). Styled as a full-width menu row
     — icon + label — rather than the bare icon button it is in the top bar / sidebar footer,
     since here it sits among the drawer's text links and should read like one. */
  .nav-drawer-toggle {
    display: block;
    border-top: 1px solid #e8edf6;
    margin-top: 4px;
    padding: 4px 4px 8px;
  }
  body.dark .nav-drawer-toggle { border-top-color: #26325c; }
  .nav-drawer-toggle .theme-toggle-btn {
    display: flex; align-items: center; gap: 10px;
    width: 100%;
    background: none; border: none; padding: 10px 0; margin: 0;
    cursor: pointer; color: inherit; font: inherit; text-align: left;
  }
  .nav-drawer-toggle .theme-toggle-label { font-size: 0.95rem; font-weight: 500; }

  /* Sign out's drawer row (minted by JS/shell.js) — console pages only, since only they have a
     sign-out to copy. Same menu-row look as the theme row above, minus the border-top: the theme
     row's divider already fences the controls section off from the links, and shell.js appends
     this row after it. */
  .nav-drawer-signout {
    display: block;
    padding: 0 4px 8px;
  }
  .nav-drawer-signout .sign-out-btn {
    display: flex; align-items: center; gap: 10px;
    width: 100%;
    background: none; border: none; padding: 10px 0; margin: 0;
    cursor: pointer; color: inherit; font: inherit; text-align: left;
  }
  .nav-drawer-signout .sign-out-label { font-size: 0.95rem; font-weight: 500; }
}

/* Narrow phones: the top-row trio needs a few more px to stay on one line. */
@media (max-width: 400px) {
  body:not(.console) nav { padding: 14px 12px; gap: 12px; } /* gap matches the new padding, so the two margins stay equal */
  nav .nav-links { padding: 0 8px; } /* stay flush with the logo */
  body:not(.console) nav .nav-right { gap: 6px; }
  body:not(.console) nav .btn-login,
  body:not(.console) nav .btn-signup { font-size: 0.85rem; }
  body:not(.console) nav .btn-signup { padding: 7px 11px; }
}

/* =====================================================================
   Shared interaction-state rules. They live here because nav.css is
   linked LAST on every page, and :where() keeps specificity at 0 so no
   per-page styling is overridden.
   ===================================================================== */

/* Keyboard-only focus ring for controls that previously fell back to the UA
   default (text inputs keep their own border+box-shadow rings, which win
   visually). Same pattern consent.css already established. */
:where(button, [role="button"], a.btn, .btn, .tab, select, summary,
       input[type="checkbox"], input[type="radio"], input[type="range"],
       .nav-dropdown-menu a, .sidebar-link, a):focus-visible {
  outline: 2px solid var(--blue, #3b82f6);
  outline-offset: 2px;
}

/* Disabled affordance for the button families that had none (only .btn and
   .btn-submit carried their own). transform:none stops hover lifts firing. */
:where(.btn-cta-primary, .btn-cta-secondary, .btn-apply, .btn-apply-instant,
       .btn-apply-normal, .btn-hero, .btn-login, .btn-signup, .btn-next,
       .btn-back, .type-btn, .page-btn, .carousel-btn):disabled {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* Skip link: visually off-screen until keyboard-focused, then a small pill at
   the top-left. Target is the per-page id="main" content root. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 12px;
  z-index: 300; /* above the sticky nav (100) and the open drawer */
  background: #020C45;
  color: #ffffff;
  padding: 10px 16px;
  border-radius: 8px;
  font-family: 'DM Sans', sans-serif;
  font-size: 0.9rem;
  text-decoration: none;
}
.skip-link:focus {
  left: 12px;
}

/* Reduced motion: collapse decorative animation/transitions site-wide (fadeUp
   entrances, popIn/stepIn, theme crossfade, smooth scroll, chat slide-in).
   Spinners are exempt — they convey in-progress state, which WCAG 2.3.3
   explicitly permits. Autoplay (carousel) is disabled in carousel.js. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .spinner {
    animation-duration: 0.7s !important;
    animation-iteration-count: infinite !important;
  }
}
