/* The site header, shared by every page. The markup comes from ONE place —
   templates/shell.js header() — rendered server-side on sub-pages and
   injected into index.html by server.js, and this file is the ONE place its
   styles live (index.html and every sub-page link here instead of
   carrying their own copy). Behaviour (dropdown grace period, burger,
   the overlay scroll flip) lives in /assets/nav.js.

   Two states of the same component:
   - default: paper bar, sticky, hairline bottom border (every sub-page)
   - .is-overlay (the homepage): fixed and transparent over the dark video
     hero with white text; nav.js adds .scrolled once the hero is gone and
     the bar becomes the same paper treatment as everywhere else. */

/* ===== the bar ===== */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(250, 250, 249, 0.92);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.site-header .bar {
  display: flex; align-items: center; gap: clamp(20px, 3.4vw, 44px); height: 64px;
}
.site-header .mark { height: 16px; width: auto; display: block; transition: filter 0.4s var(--ease); }
.nav-left { display: flex; align-items: center; gap: clamp(20px, 3.4vw, 44px); min-width: 0; }
.site-nav { display: flex; align-items: center; gap: 26px; }
.site-nav a { font-size: 14px; color: rgba(15, 14, 13, 0.62); transition: color 0.25s var(--ease); white-space: nowrap; }
.site-nav a:hover, .site-nav a[aria-current] { color: var(--foreground); }
.site-nav a[aria-current] { color: var(--primary); }
.site-header .actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }
/* the nav buttons sit a notch above .btn-sm */
.site-header .btn-sm { height: 36px; }

/* ===== the homepage overlay state ===== */
.site-header.is-overlay {
  position: fixed; left: 0; right: 0;
  background: transparent; border-bottom-color: transparent;
  /* blur(0), not none. backdrop-filter makes the bar a containing block AND a
     stacking context for its fixed descendants — the dropdown panels. The
     paper bar always has one, so leaving the overlay state at `none` meant
     the same panel markup resolved against the viewport on the landing page
     and against the header everywhere else. Identical geometry today, but two
     different boxes to reason about; blur(0) is a visual no-op that makes both
     navbar types behave the same. Same trap the mobile drawer documents. */
  backdrop-filter: blur(0px); -webkit-backdrop-filter: blur(0px);
  transition: background-color 0.4s var(--ease), border-color 0.4s var(--ease);
}
/* White chrome over the dark video — bar-level links only (the plain items
   and the dropdown triggers). A bare `.site-nav a` would also catch every
   anchor INSIDE the dropdown panels, which are always a white card: vendor
   heads and the panel footer links went white-on-white on the homepage. */
.site-header.is-overlay:not(.scrolled) .mark { filter: brightness(0) invert(1); }
.site-header.is-overlay:not(.scrolled) .site-nav > a,
.site-header.is-overlay:not(.scrolled) .site-nav .nav-drop > a { color: rgba(255, 255, 255, 0.8); }
.site-header.is-overlay:not(.scrolled) .site-nav > a:hover,
.site-header.is-overlay:not(.scrolled) .site-nav > a[aria-current],
.site-header.is-overlay:not(.scrolled) .site-nav .nav-drop > a:hover,
.site-header.is-overlay:not(.scrolled) .site-nav .nav-drop > a[aria-current] { color: #fff; }
.site-header.is-overlay:not(.scrolled) .actions .btn-ghost { color: rgba(255, 255, 255, 0.9); }
.site-header.is-overlay:not(.scrolled) .actions .btn-ghost:hover { color: #fff; }
.site-header.is-overlay:not(.scrolled) .actions .btn-outline { color: #fff; border-color: rgba(255, 255, 255, 0.4); }
.site-header.is-overlay:not(.scrolled) .actions .btn-outline:hover { border-color: rgba(255, 255, 255, 0.75); }
.site-header.is-overlay:not(.scrolled) .actions .btn-primary { background: #fff; color: var(--ink); }
.site-header.is-overlay:not(.scrolled) .nav-burger { color: #fff; border-color: rgba(255, 255, 255, 0.4); }
/* past the hero (nav.js adds .scrolled) the overlay bar IS the paper bar */
/* Still over the hero, but the visitor has started scrolling. The bar keeps
   its white chrome — the hero behind it is dark — but takes a blur and a
   light ink wash so it separates from a background that is now a fast,
   colourful, moving screenshot. Without this the bar is fully transparent
   for a whole screen height, which is exactly where the nav is hardest to
   read. Superseded by .scrolled once the hero is gone. */
.site-header.is-overlay.over-hero:not(.scrolled) {
  background: rgba(15, 14, 13, 0.3);
  backdrop-filter: blur(12px) saturate(1.05); -webkit-backdrop-filter: blur(12px) saturate(1.05);
  border-bottom-color: rgba(255, 255, 255, 0.1);
}

.site-header.is-overlay.scrolled {
  background: rgba(250, 250, 249, 0.92);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom-color: var(--border);
}
/* dropdown panels are always a white card, so their contents keep ink colours
   in both bar states */
.site-header .nav-panel { color: var(--foreground); }

/* ===== dropdown menus (hover, plus focus-within for keyboards) ===== */
/* The trigger fills the bar's full height. It used to be a 17px-tall box in a
   64px bar, which left dead space between it and the panel: crossing that gap
   took the pointer out of .nav-drop and snapped the menu shut mid-move. */
.nav-left { align-self: stretch; }
.site-nav { height: 100%; }
.nav-drop { position: relative; display: flex; align-items: center; height: 100%; }
.nav-drop > a { display: inline-flex; align-items: center; gap: 5px; height: 100%; }
.nav-chev { transition: transform 0.25s var(--ease); opacity: 0.6; }
.nav-drop:hover:not(.dismissed) .nav-chev, .nav-drop:focus-within:not(.dismissed) .nav-chev { transform: rotate(180deg); opacity: 1; }
/* One box for every menu. The panel is a fixed-size surface the content lays
   out INSIDE of — content count never drives geometry, so hovering across the
   bar never resizes the menu. Centred on the viewport (its `top` is the 64px
   bar plus 14px of air), which also means it can never overflow the window. */
.nav-panel {
  position: fixed; top: 78px; left: 50%; z-index: 60;
  width: min(880px, calc(100vw - 48px)); min-height: 356px;
  display: flex; flex-direction: column;
  padding: 22px 24px 18px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: 0 20px 60px rgba(15, 14, 13, 0.18);
  opacity: 0; visibility: hidden; transform: translate(-50%, -6px);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
}
/* keeps the pointer from falling through the gap between trigger and panel */
.nav-panel::before { content: ""; position: absolute; inset: -16px 0 auto 0; height: 16px; }
/* :hover/:focus-within are the no-JS fallbacks; `.open` is what nav.js
   drives. `.dismissed` (set by nav.js on Escape) beats both pseudo-classes,
   otherwise a panel Escape just "closed" would stay visible while the
   pointer hovers it or focus sits on its trigger. */
.nav-drop:hover:not(.dismissed) .nav-panel,
.nav-drop:focus-within:not(.dismissed) .nav-panel,
.nav-drop.open .nav-panel {
  opacity: 1; visibility: visible; transform: translate(-50%, 0);
}
/* Inside the box: an intro rail on the left that says what the section is,
   content in a fixed grid on the right, and a footer strip pinned to the
   bottom edge. The rail's rule runs the full body height, so shorter content
   reads as air inside the same panel rather than a smaller panel. */
.nav-panel-body { flex: 1; display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 28px; align-items: stretch; }
.nav-intro { display: flex; flex-direction: column; gap: 10px; padding: 4px 28px 4px 0; border-right: 1px solid var(--border); min-width: 0; }
.nav-intro-label { font-size: 11.5px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase; color: var(--primary); padding: 0 8px; }
.nav-intro-desc { font-size: 13.5px; line-height: 1.55; color: var(--muted-foreground); padding: 0 8px; text-wrap: pretty; }
/* The rail's picture, pinned to the bottom so every panel's rail fills the
   same space. The base is a finished surface on its own — a soft primary
   tint with a dot grid — which is both the deliberate placeholder (Use
   cases, until real artwork exists) and what remains if an image inside a
   variant is missing or fails to load. Fixed height on purpose: the visual
   must never drive the 880x356 panel geometry. */
.nav-visual {
  position: relative; overflow: hidden; flex-shrink: 0;
  margin: auto 8px 2px; height: 116px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background-color: rgba(100, 0, 255, 0.04);
  background-image: radial-gradient(rgba(100, 0, 255, 0.14) 1px, transparent 1.4px);
  background-size: 12px 12px; background-position: -3px -3px;
}
/* AI Coworkers: the same drawn portraits the menu's links carry, clustered */
.nav-visual-people { display: flex; align-items: center; justify-content: center; }
.nav-visual-face {
  width: 54px; height: 54px; border-radius: 999px; overflow: hidden; flex-shrink: 0;
  background: var(--muted); border: 2px solid var(--card);
  box-shadow: 0 1px 4px rgba(15, 14, 13, 0.14);
}
.nav-visual-face + .nav-visual-face { margin-left: -12px; }
.nav-visual-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Product: a zoomed detail of the task-board render, not the whole shot —
   at rail size the full frame reads as white mush */
.nav-visual-shot img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 38% 22%; display: block;
  transform: scale(2.1); transform-origin: 38% 22%;
}
/* Use cases: the rail carries the section's own abstract field (inline SVG
   from templates/art.js) over the dot-grid base */
.nav-visual-abstract svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* The Use cases panel: one grid of jobs, two columns of three — each job's
   seeded abstract swatch, its title, and its primary industry underneath */
.nav-jobs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 16px; align-content: start; }
.nav-jobs .nav-col-link { padding: 9px 12px; }
.nav-swatch {
  width: 34px; height: 34px; border-radius: var(--r-sm); overflow: hidden; flex-shrink: 0;
  border: 1px solid var(--border); background: rgba(100, 0, 255, 0.04);
}
.nav-swatch svg { width: 100%; height: 100%; display: block; }
/* a full-width strip above the foot — the most-used work as a wrapping row of
   links, so it never dictates the panel's height the way a column would */
.nav-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border); }
.nav-strip-label { font-size: 11.5px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted-foreground); padding: 0 8px; margin-right: 6px; }
/* three fixed tracks with hairline dividers between occupied columns */
.nav-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-content: start; }
.nav-col { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 0 20px; }
.nav-col:first-child { padding-left: 0; }
.nav-col:last-child { padding-right: 0; }
.nav-col + .nav-col { border-left: 1px solid var(--border); }
.nav-col-head {
  font-size: 11.5px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--muted-foreground); padding: 4px 8px; margin-bottom: 4px;
  transition: color 0.2s var(--ease);
}
.nav-col-head:hover { color: var(--foreground); }
/* a wordmark replaces the vendor name in the column head; .invert flattens
   white artwork to ink so it reads on the panel's white card */
/* text and wordmark heads share a height so the columns line up */
.nav-col-head { display: flex; align-items: center; min-height: 26px; }
.nav-col-head.has-logo { padding: 0 8px; margin-bottom: 6px; opacity: 0.78; transition: opacity 0.2s var(--ease); }
.nav-col-head.has-logo:hover { opacity: 1; }
.nav-col-logo { display: block; }
.nav-col-logo img { height: 17px; width: auto; max-width: 124px; object-fit: contain; display: block; }
.nav-col-logo.invert img { filter: brightness(0); }
.nav-col-link {
  display: flex; flex-direction: column; gap: 1px; padding: 7px 8px; border-radius: var(--r-sm);
  transition: background-color 0.2s var(--ease);
}
.nav-col-link:hover { background: var(--muted); }
/* a portrait next to each coworker in the menu — a name alone gives no sense
   of who is on the other side of the link */
.nav-col-link.has-face { flex-direction: row; align-items: center; gap: 10px; }
.nav-face {
  width: 30px; height: 30px; border-radius: 999px; overflow: hidden; flex-shrink: 0;
  background: var(--muted); display: block;
}
.nav-face img { width: 100%; height: 100%; object-fit: cover; display: block; transform: scale(1.08); }
.nav-face.is-blank { border: 1px solid var(--border); }
.nav-face-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }

.nav-col-link span { font-size: 14px; font-weight: 400; color: var(--foreground); }
.nav-col-link small { font-size: 12px; color: var(--muted-foreground); }
/* The Product items: the page name sits quiet on top, the one-line
   explanation under it carries the weight — the item reads as what the page
   IS, not as a bare link */
.nav-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 12px; align-content: start; }
.nav-grid .nav-col-link { padding: 10px 12px; gap: 3px; }
.nav-grid .nav-col-link span {
  font-size: 12.5px; font-weight: 500; letter-spacing: 0.02em;
  color: var(--muted-foreground); transition: color 0.2s var(--ease);
}
.nav-grid .nav-col-link small { font-size: 13.5px; color: var(--foreground); line-height: 1.45; }
.nav-grid .nav-col-link:hover span { color: var(--foreground); }
.nav-panel-foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 24px;
  margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border);
}
.nav-panel-foot a {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--muted-foreground); padding: 0 8px;
  transition: color 0.2s var(--ease);
}
.nav-panel-foot a:hover { color: var(--foreground); }
/* the one accent in the panel: the strongest way onward, in Sokosumi purple */
.nav-panel-foot .nav-foot-accent { color: var(--primary); }
.nav-panel-foot .nav-foot-accent:hover { color: var(--primary); opacity: 0.75; }
/* .site-nav a sets nowrap for the bar itself; inside a panel that stops the
   use-case titles wrapping and they run into the next column */
.nav-panel a, .nav-panel span { white-space: normal; }
.nav-panel .icon { flex-shrink: 0; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ===== mobile: burger + drawer ===== */
.nav-burger {
  display: none;
  width: 36px; height: 36px; flex-shrink: 0;
  /* column, or the two bars sit SIDE BY SIDE: the button is a flex container
     and its default row direction turned the "burger" into one broken dash
     and the open state's X into a chevron that never crossed */
  flex-direction: column;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--border); border-radius: var(--r-md);
  color: inherit; cursor: pointer; padding: 0;
  transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease);
}
.nav-burger span {
  display: block; width: 15px; height: 1.5px; background: currentColor; border-radius: 2px;
  transition: transform 0.25s var(--ease), opacity 0.2s var(--ease);
}
.nav-burger span + span { margin-top: 4px; }
.nav-burger[aria-expanded="true"] span:first-child { transform: translateY(2.75px) rotate(45deg); }
.nav-burger[aria-expanded="true"] span:last-child { transform: translateY(-2.75px) rotate(-45deg); }

/* Lives outside the header on purpose: the bar uses backdrop-filter, which
   makes it a containing block for fixed descendants, so a drawer nested in it
   would collapse to the bar's own 64px height. */
.mobile-nav {
  position: fixed; top: 64px; left: 0; right: 0; bottom: 0; z-index: 49;
  background: var(--background);
  border-top: 1px solid var(--border);
  overflow-y: auto;
  /* a swipe that runs out of drawer must not hand its momentum to the page */
  overscroll-behavior: contain;
  padding: 8px clamp(24px, 6vw, 40px) 40px;
  display: flex; flex-direction: column;
}
.mobile-nav[hidden] { display: none; }
.mobile-nav a.m-link {
  display: flex; align-items: baseline; gap: 10px;
  padding: 17px 0; border-bottom: 1px solid var(--border);
  font-size: 19px; font-weight: 300; letter-spacing: -0.015em; color: var(--foreground);
}
.mobile-nav a.m-link small { font-size: 13px; font-weight: 400; color: var(--muted-foreground); }
.mobile-nav .m-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 28px; }
.mobile-nav .m-actions .btn { width: 100%; height: 46px; font-size: 15px; }
.mobile-nav .m-foot { margin-top: 28px; font-size: 13px; color: var(--muted-foreground); }

@media (max-width: 900px) {
  .nav-burger { display: inline-flex; }
  .site-nav { display: none; }
  .site-header .actions .btn-ghost { display: none; }
}
@media (max-width: 560px) {
  .site-header .actions .btn-outline { display: none; }
}
/* the drawer is paper, so the bar above it has to be too (nav.js also adds
   .scrolled while the drawer is open, which carries the text colours) */
.site-header.is-overlay.nav-open {
  background: rgba(250, 250, 249, 0.92);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom-color: var(--border);
}
.site-header.is-overlay.nav-open .mark { filter: none; }
.site-header.is-overlay.nav-open .nav-burger { color: var(--foreground); border-color: var(--border); }
/* The scroll lock while the drawer is open. `overflow: hidden` on body alone
   does NOT lock anything here: body's overflow only propagates to the viewport
   when <html>'s overflow is `visible`, and styles.css puts overflow-x: clip on
   html — so the page happily scrolled behind the open drawer and the visitor
   closed it somewhere else entirely. Lock the real scroller (html), and pin
   body with position: fixed, which is the one approach iOS Safari actually
   honours for touch (overflow: hidden famously is not). nav.js records the
   scroll offset, sets body's inline `top` to keep the page visually in place,
   and restores the scroll position on close. */
html.nav-locked { overflow: hidden; }
body.nav-locked { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden; }
/* Inside a position: fixed body a position: sticky header stops sticking — its
   static position is the top of the pinned body, which sits at -scrollY, so
   the bar (and the close button in it) slid off screen the moment the drawer
   opened anywhere but the top of a sub-page. While the lock is on, the bar is
   plainly fixed to the viewport instead; the homepage's .is-overlay bar is
   fixed anyway, so this only changes the sub-page state. */
body.nav-locked .site-header { position: fixed; top: 0; left: 0; right: 0; }

/* ===== the footer ===== */
/* Same deal as the header above: markup comes from ONE place —
   templates/shell.js footerHtml() — rendered server-side on sub-pages and
   injected into index.html by server.js, and this file is the ONE place its
   styles live.
   The hairline sits on the footer itself so it spans the window rather than
   stopping at the 1240px content grid. */
footer.site {
  padding: 0 0 40px; background: var(--background);
  border-top: 1px solid var(--border); margin-top: clamp(48px, 7vw, 96px);
}

/* brand on the left, the four labelled columns on the right */
.foot-grid {
  padding-top: 48px;
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 40px 64px;
}
.foot-brand { display: flex; flex-direction: column; gap: 16px; max-width: 300px; }
.foot-mark { height: 15px; width: auto; display: block; }
.foot-tag { margin: 0; font-size: 13px; line-height: 1.65; color: var(--muted-foreground); }

.foot-cols { display: grid; grid-template-columns: repeat(4, minmax(120px, auto)); gap: 32px 56px; }
.foot-h {
  margin: 0 0 14px; font-size: 12px; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--foreground);
}
.foot-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.foot-col a { font-size: 13px; color: var(--muted-foreground); transition: color 0.25s var(--ease); }
.foot-col a:hover { color: var(--foreground); }

/* the disclosure + social row, separated from the columns by a hairline */
.foot-meta {
  margin-top: 48px; padding-top: 20px; border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px 32px;
}
.foot-ai { display: flex; align-items: center; gap: 10px; }
.foot-ai img { width: 32px; height: 32px; display: block; }
.foot-ai p { margin: 0; font-size: 12.5px; color: var(--muted-foreground); }
.foot-social { display: flex; flex-wrap: wrap; gap: 8px 20px; }
.foot-social a, .foot-legal a { font-size: 13px; color: var(--muted-foreground); transition: color 0.25s var(--ease); }
.foot-social a:hover, .foot-legal a:hover { color: var(--foreground); }

/* copyright left, legal right */
.foot-bottom {
  margin-top: 24px;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 32px;
}
.foot-legal { display: flex; flex-wrap: wrap; gap: 8px 18px; }
.foot-copy { margin: 0; font-size: 12px; color: var(--muted-foreground); }

/* language switcher: quiet, same register as the legal links */
.foot-lang { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.foot-lang a { color: var(--muted-foreground); transition: color 0.25s var(--ease); }
.foot-lang a:hover { color: var(--foreground); }
.foot-lang span[aria-current] { color: var(--foreground); }
.foot-lang .sep { color: var(--muted-foreground); opacity: 0.5; }

@media (max-width: 640px) {
  .foot-cols { grid-template-columns: repeat(2, minmax(130px, 1fr)); width: 100%; }
}
