/* The primary navigation, shared by every page under site/public, and the
 * colour tokens the hand-written pages are painted with.
 *
 * One stylesheet rather than the inline styles each page used to carry: the
 * nav is now two dropdowns plus five links, which is more markup than is
 * sensible to repeat inline twelve times, and "consistent across pages" is
 * only true if there is one place to change it.
 *
 * THE DROPDOWNS NEED NO JAVASCRIPT, deliberately, and not merely as a
 * nicety. session.js's header explains why: support.js is a generated React
 * runtime that re-renders the document from freshly-fetched source whenever
 * map.json or stats.json arrives, so any state written into the body is
 * clobbered -- including a <details open> a visitor had just opened. These
 * menus hold no state at all. They open on :hover for a pointer and on
 * :focus-within for a keyboard or a tap, so there is nothing for a re-render
 * to reset.
 *
 * The phone menu (2026-10-04) is the one exception, and it keeps to the same
 * rule: its open/shut state is an attribute on <html> (data-nav-open), which
 * session.js toggles and React never renders. The collapse only happens once
 * session.js has marked <html> with data-nav-js, so a visitor without
 * JavaScript gets the whole nav, wrapped, exactly as before.
 *
 * Each page sets --nav-max in its own stylesheet to match its content column
 * (44rem on the legal pages, 54rem, 56rem on who-we-watch, 60rem on the wide
 * ones). The markup itself is byte-identical everywhere except the
 * aria-current marker.
 */

/* --- colour tokens --------------------------------------------------------
 *
 * Light values are the colours every page was written in, so a page that
 * reads none of these (the generated /jobs, /employers and /salaries pages,
 * whose own style is jobsearch/public_html.py's) looks exactly as it did.
 *
 * Dark values apply only to a page that opts in with <html data-scheme="auto">
 * and only when the device asks for dark. Opt-in rather than global because
 * the generated pages share this file and still hard-code light colours: a
 * dark nav over a light page would be worse than no dark mode at all.
 *
 * The brand green stays #117a35 as a FILL in both schemes (white on it is
 * 5.3:1); green TEXT on a dark surface uses --accent-ink, a lighter green,
 * because #117a35 on near-black is about 3:1. */
:root {
  --bg: #fbfbfa;          /* page background, and quiet buttons on cards */
  --surface: #fff;        /* cards and panels */
  --subtle: #f3f5f6;      /* a faint panel inside a card */
  --ink: #10161a;         /* body text */
  --ink-2: #3c464d;       /* secondary text */
  --muted: #5b6770;       /* supporting text */
  --faint: #66717a;       /* the quietest text that still passes AA */
  --line: #e4e8ea;        /* card borders */
  --hair: #eef1f2;        /* row rules inside a card */
  --line-2: #c9d1d5;      /* input and quiet-button borders */
  --accent: #117a35;      /* green fills and borders */
  --accent-ink: #117a35;  /* green text */
  --accent-deep: #0d5c28; /* green text on a green tint */
  --accent-soft: #eaf4ed; /* green tint */
  --accent-line: #cfe6d6; /* border of a green tint */
  --slate: #10161a;       /* the dark bands (recruiters, "Straight up") */
  --slate-line: #3c464d;  /* a quiet border on a dark band */
  --danger-ink: #b8442b;  /* error text */
  --danger-soft: #fdf2f0; /* error panel */
  --danger-line: #f3d5cf; /* border of an error panel */
  --warn-ink: #8a6d16;
}
html[data-scheme="auto"] { color-scheme: light dark; }
@media (prefers-color-scheme: dark) {
  html[data-scheme="auto"] {
    color-scheme: dark;
    --bg: #0f1412;
    --surface: #161c19;
    --subtle: #1c2420;
    --ink: #e5eae7;
    --ink-2: #c3ccc7;
    --muted: #a0aba5;
    --faint: #8f9a94;
    --line: #2a332f;
    --hair: #222a26;
    --line-2: #3d4843;
    --accent: #117a35;
    --accent-ink: #5fcb84;
    --accent-deep: #7fd89d;
    --accent-soft: #15291d;
    --accent-line: #24452f;
    --slate: #29342f;
    --slate-line: #46524c;
    --danger-ink: #ff9b80;
    --danger-soft: #36201c;
    --danger-line: #6b342b;
    --warn-ink: #e3c463;
  }
  /* Shadows written for a white page read as smudges on a dark one. */
  html[data-scheme="auto"] [style*="box-shadow"] { box-shadow: none !important; }
}

/* --- the nav ---------------------------------------------------------------- */

.site-nav {
  max-width: var(--nav-max, 60rem);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .35rem 1.25rem;
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--line);
  font-size: .85rem;
  position: relative;
  z-index: 30;
}

.site-nav a { text-decoration: none; color: var(--muted); }
.site-nav a:hover { color: var(--accent-ink); }
.site-nav a.brand {
  font-weight: 680; font-size: .95rem; letter-spacing: -.01em;
  color: var(--accent-ink); margin-right: auto;
}
.site-nav a[aria-current="page"] { color: var(--ink); font-weight: 600; }

/* "Sign in" and "Your account" are never shown together. Each page's own
 * head rule hides [data-session-only] for a signed-out visitor, but the phone
 * rules below give nav links display:inline-flex at a higher specificity, and
 * until 2026-10-04 that put both links on a signed-out phone. These win
 * whatever display a width sets. */
html:not([data-signed-in]) .site-nav [data-session-only],
html[data-signed-in] .site-nav [data-session-anon] { display: none !important; }

/* The phone menu button: hidden until the phone rules below show it. */
.site-nav .nav-toggle { display: none; }

/* --- the two dropdowns --------------------------------------------------- */

.site-nav .nav-group { position: relative; display: inline-flex; }

/* The bridge across the gap between a heading and its menu.
 *
 * Without it the menu opens on hover and then shuts before the pointer can
 * reach it: the menu is offset below the heading, and crossing that gap
 * leaves .nav-group, which ends :hover. The symptom a reader sees is a menu
 * that appears by itself but whose links only become clickable after the
 * heading is CLICKED -- the click focuses the heading, :focus-within takes
 * over, and the menu stops depending on the pointer being anywhere.
 *
 * This is an invisible strip covering that gap. It belongs to .nav-group, so
 * the pointer never leaves the group on its way down. It is as wide as the
 * MENU rather than the heading, because the path from a short heading to the
 * far side of the menu is diagonal. It sits inside the nav's own bottom
 * padding, so it covers nothing on the page below.
 *
 * It exists ONLY while its own group is open. A bridge is wider than its
 * heading, so bridges that were always present overlapped their neighbours,
 * and the strip below "Job seekers" was painted over by the one belonging to
 * "Recruiters" -- moving the pointer down hovered the NEIGHBOUR and shut the
 * menu, which is the same bug one step subtler.
 */
.site-nav .nav-group:hover::after,
.site-nav .nav-group:focus-within::after {
  content: "";
  position: absolute;
  top: 100%;
  left: -.75rem;
  width: 14rem;
  height: .6rem;
}

.site-nav .nav-trigger {
  appearance: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--muted);
  cursor: pointer;
  display: inline-flex;
  align-items: baseline;
  gap: .34rem;
}
.site-nav .nav-trigger[aria-current="page"] { color: var(--ink); font-weight: 600; }
.site-nav .nav-trigger::after {
  content: "";
  width: .3rem; height: .3rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-.14rem) rotate(45deg);
}
.site-nav .nav-group:hover .nav-trigger,
.site-nav .nav-group:focus-within .nav-trigger { color: var(--accent-ink); }

.site-nav .nav-menu {
  display: none;
  position: absolute;
  /* Kept in step with the bridge's height above: any gap the bridge does not
   * cover is a gap the pointer falls through. */
  top: calc(100% + .6rem);
  left: -.75rem;
  margin: 0;
  padding: .4rem;
  list-style: none;
  min-width: 11.75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(16, 22, 26, .05), 0 12px 28px -14px rgba(16, 22, 26, .28);
}
.site-nav .nav-group:hover .nav-menu,
.site-nav .nav-group:focus-within .nav-menu { display: block; }

/* One menu at a time. Clicking "Job seekers" FOCUSES it, and focus stays
 * after the pointer moves on -- so hovering "Recruiters" opened a second menu
 * over the first, both lit (reported 2026-09-23). While any group is hovered,
 * the pointer wins: every other group's menu, bridge and highlight give way.
 * A keyboard reader never hovers, so :focus-within alone still drives it. */
.site-nav:has(.nav-group:hover) .nav-group:not(:hover) .nav-menu { display: none; }
.site-nav:has(.nav-group:hover) .nav-group:not(:hover)::after { content: none; }
.site-nav:has(.nav-group:hover) .nav-group:not(:hover) .nav-trigger:not([aria-current="page"]) { color: var(--muted); }

.site-nav .nav-menu a {
  display: block;
  padding: .42rem .62rem;
  border-radius: 8px;
  color: var(--ink-2);
  white-space: nowrap;
}
.site-nav .nav-menu a:hover { background: var(--accent-soft); color: var(--accent-ink); }

/* Medium widths (2026-09-23). Signed in, the row needs 831px, so between
 * about 780 and 880px it wrapped and "Your account" dropped under the logo on
 * its own. The logo already goes home, so the separate "Home" link goes
 * first; below 50rem the logo takes its own line and the links sit under it
 * as one row, rather than wrapping one orphan link at a time. */
@media (max-width: 60rem) {
  .site-nav { gap: .35rem 1rem; }
  .site-nav > a[href="/"]:not(.brand) { display: none; }
}
@media (max-width: 50rem) {
  .site-nav a.brand { flex-basis: 100%; }
}

/* A narrow screen: the menu is revealed by tapping the trigger (which focuses
 * it) and drops as a full-width panel UNDER THE WHOLE NAV.
 *
 * It used to open inline, under its heading, inside the wrapping flex row --
 * and that made the nav unusable by thumb. "The app for jobseekers" is wider
 * than "Job seekers", so opening the menu widened its group and re-wrapped
 * the row: the heading jumped to another line and the tap that opened it
 * landed on whatever slid under the finger ("Open the app", most often).
 * A phone applies :hover on touch-start, BEFORE the click is dispatched, so
 * any layout change on open moves the target mid-tap. An overlay changes no
 * layout, so nothing the reader can hit ever moves. (Reported 2026-09-22.)
 *
 * These rules are what a phone WITHOUT JavaScript gets. With it, the phone
 * menu below replaces them. */
@media (max-width: 36rem) {
  .site-nav { gap: .3rem .9rem; }
  /* static, so the menu positions against .site-nav (relative) and can span
     its full width rather than hanging off a heading near the right edge. */
  .site-nav .nav-group { position: static; }
  /* The bridge is sized for a menu offset from its heading; here the menu
     sits under the nav's padding instead, so the bridge would only overlap
     neighbours. */
  .site-nav .nav-group:hover::after,
  .site-nav .nav-group:focus-within::after { content: none; }
  .site-nav .nav-menu {
    top: calc(100% - .6rem);
    left: 0;
    right: 0;
    min-width: 0;
  }
  .site-nav .nav-menu a { padding: .3rem .62rem; }
  /* 24x24 is the WCAG 2.5.8 minimum and these are inline text at .85rem,
     which measures about 21px tall -- under a thumb that is a miss about as
     often as a hit (measured across the nav on 2026-09-16). inline-flex with
     a min-height grows the TARGET without moving anything visually, because
     the extra height is centred on the same baseline. */
  .site-nav a,
  .site-nav .nav-trigger { display: inline-flex; align-items: center; min-height: 1.75rem; }
  .site-nav .nav-menu a { min-height: 2rem; }

  /* --- the phone menu (2026-10-04) ---------------------------------------
   * The wrapped nav took four lines of a phone's first screen. With
   * JavaScript, the bar is the logo and a Menu button; the button opens the
   * whole nav as one list under it, every group already expanded, so there
   * is nothing further to tap open. */
  html[data-nav-js] .site-nav { align-items: center; flex-wrap: wrap; padding: .9rem 0; }
  html[data-nav-js] .site-nav a.brand { flex-basis: auto; }
  html[data-nav-js] .site-nav .nav-toggle {
    display: inline-flex; align-items: center; gap: .5rem;
    min-height: 2.5rem; padding: 0 .85rem; margin: 0;
    font: inherit; font-size: .85rem; font-weight: 560; color: var(--ink);
    background: var(--surface); border: 1px solid var(--line-2); border-radius: 999px;
    cursor: pointer;
  }
  /* Three bars, drawn with borders so there is no image to load. */
  html[data-nav-js] .site-nav .nav-toggle::before {
    content: ""; width: .9rem; height: .55rem;
    border-top: 2px solid currentColor; border-bottom: 2px solid currentColor;
    background: linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat;
  }
  html[data-nav-js][data-nav-open] .site-nav .nav-toggle::before {
    border: 0; height: .9rem;
    background:
      linear-gradient(45deg, transparent 44%, currentColor 44% 56%, transparent 56%),
      linear-gradient(-45deg, transparent 44%, currentColor 44% 56%, transparent 56%);
  }
  html[data-nav-js] .site-nav > :not(.brand):not(.nav-toggle) { display: none; }
  html[data-nav-js][data-nav-open] .site-nav > :not(.brand):not(.nav-toggle) {
    display: flex; flex-basis: 100%; min-height: 2.75rem; align-items: center;
    border-top: 1px solid var(--hair); font-size: .95rem;
  }
  html[data-nav-js][data-nav-open] .site-nav > a:not(.brand):not([aria-current]) { color: var(--ink-2); }
  html[data-nav-js][data-nav-open] .site-nav > a:first-of-type:not(.brand) { margin-top: .6rem; }
  html[data-nav-js][data-nav-open] .site-nav > a[href="/"]:not(.brand) { display: flex; }
  /* As specific as the rule above that it overrides, and then some. */
  html[data-nav-js][data-nav-open] .site-nav > div.nav-group:not(.brand):not(.nav-toggle) {
    display: block; padding: .7rem 0 .3rem;
  }
  html[data-nav-js][data-nav-open] .site-nav .nav-trigger {
    pointer-events: none; min-height: 0; color: var(--faint);
    font-size: .68rem; font-weight: 650; text-transform: uppercase; letter-spacing: .11em;
  }
  html[data-nav-js][data-nav-open] .site-nav .nav-trigger::after { content: none; }
  html[data-nav-js][data-nav-open] .site-nav .nav-menu,
  html[data-nav-js][data-nav-open] .site-nav:has(.nav-group:hover) .nav-group .nav-menu {
    display: block; position: static; padding: .2rem 0 0; margin: 0;
    border: 0; box-shadow: none; background: none;
  }
  html[data-nav-js][data-nav-open] .site-nav .nav-menu a { min-height: 2.75rem; display: flex; align-items: center; font-size: .95rem; padding: 0 .1rem; }
  html[data-nav-js][data-nav-open] .site-nav .nav-menu a:hover { background: none; }
}

/* The audience switch (2026-09-23, James: "start should clearly split
 * seekers / recruiters, toggle was good"). The first thing under the nav on
 * the home page (the jobseekers' page) and on /recruiters (theirs), in the
 * look of /pricing's audience toggle. Unlike that one it holds no state: each
 * half is a LINK to its audience's page, and the half you are on carries
 * aria-current="page" and its audience's colour -- green for jobseekers,
 * slate for recruiters, the colours /pricing already gives them. */
.aud-switch {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .4rem;
  padding: .35rem;
  margin: 0 0 2.4rem;
  max-width: 40rem;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--surface);
}
.aud-switch a {
  display: block;
  padding: .75rem 1rem;
  border-radius: 12px;
  color: var(--ink);
  text-decoration: none;
  line-height: 1.3;
}
.aud-switch a b { display: block; font-size: 1rem; font-weight: 650; }
.aud-switch a span { display: block; margin-top: .12rem; font-size: .8rem; color: var(--muted); }
.aud-switch a:not([aria-current]):hover { background: var(--subtle); color: var(--ink); }
.aud-switch a:not([aria-current]) b::after { content: " \2192"; font-weight: 500; }
.aud-switch a[aria-current="page"] { color: #fff; }
.aud-switch a[aria-current="page"] span { color: rgba(255, 255, 255, .85); }
.aud-switch .seeker[aria-current="page"] { background: #117a35; }
.aud-switch .recruiter[aria-current="page"] { background: var(--slate); }
@media (max-width: 26rem) {
  .aud-switch a { padding: .65rem .75rem; }
  .aud-switch a b { font-size: .92rem; }
}

/* --- the raw template ----------------------------------------------------
 * Before support.js renders a page (and for a reader or crawler that runs no
 * JavaScript at all) the browser shows the <x-dc> template as written. A
 * list template is one sample row of empty slots, so it is hidden there;
 * the rendered page never contains an <sc-for> element, so this hides
 * nothing a visitor with JavaScript sees. [data-js-only] marks a section
 * that only means something once its data has loaded (a chart, a live
 * list); it is hidden in the template and shown as rendered. */
x-dc sc-for, x-dc [data-js-only] { display: none; }
