/* =============================================================
   Bench — Core design system
   "Deep & Glowing"
   -------------------------------------------------------------
   1.  Tokens
   2.  Reset & base
   3.  Atmosphere (mesh · grain)
   4.  Typography
   5.  Layout
   6.  Header (floating pill)
   7.  Buttons
   8.  Cards & surfaces
   8d. Long-form prose
   9.  Niche system
   10. Command palette
   11. Footer
   12. Motion & utilities
   ============================================================= */

/* ---------- 1. Tokens ---------------------------------------- */

:root {
  /* Canvas */
  --bg:        #070709;
  --bg-2:      #0B0B0F;
  --void:      #000000;

  /* Glass surfaces */
  --surface:      rgba(255, 255, 255, 0.034);
  --surface-2:    rgba(255, 255, 255, 0.058);
  --surface-3:    rgba(255, 255, 255, 0.085);
  --solid:        #101014;
  --solid-2:      #16161B;
  --inset:        rgba(0, 0, 0, 0.28);

  /* Ink — reading text is pure white on the void, and pure black on paper.
     The scale below it (ink-3, ink-4) is what is left for genuine meta —
     eyebrows, captions, hint text — so hierarchy comes from size and weight
     rather than from dimming the copy the reader actually came for. */
  --ink:   #FFFFFF;
  --ink-2: #E6E6EC;
  --ink-3: #6B6B78;
  --ink-4: #45454F;

  /* Lines */
  --line:   rgba(255, 255, 255, 0.085);
  --line-2: rgba(255, 255, 255, 0.16);
  --line-3: rgba(255, 255, 255, 0.28);
  --edge:   inset 0 1px 0 rgba(255, 255, 255, 0.07);

  /* Ember accent */
  --accent:      #FF6B35;
  --accent-2:    #FF9A3D;
  --accent-ink:  #180700;
  --accent-soft: rgba(255, 107, 53, 0.11);
  --accent-line: rgba(255, 107, 53, 0.34);
  --glow:        rgba(255, 107, 53, 0.30);
  --glow-strong: rgba(255, 107, 53, 0.55);

  /* Status */
  --ok:      #3DDC97;
  --ok-soft: rgba(61, 220, 151, 0.12);
  --warn:    #FBBF24;
  --warn-soft: rgba(251, 191, 36, 0.12);
  --danger:  #FF5C5C;
  --danger-soft: rgba(255, 92, 92, 0.12);

  /* Niche hues — one per discipline */
  --n-security: #FF6B35;
  --n-images:   #38BDF8;
  --n-colour:   #F472B6;
  --n-data:     #A78BFA;
  --n-text:     #34D399;

  /* Radii */
  --r-xs: 7px;
  --r-sm: 10px;
  --r:    14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-2xl: 36px;
  --r-pill: 999px;

  /* Elevation */
  --sh-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
  --sh:    0 4px 24px -8px rgba(0, 0, 0, 0.7);
  --sh-lg: 0 24px 70px -26px rgba(0, 0, 0, 0.9);
  --sh-glow: 0 0 0 1px var(--accent-line), 0 8px 34px -8px var(--glow);

  /* Type */
  --font-ui: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-display: 'Fraunces', 'Iowan Old Style', Georgia, serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Metrics */
  --maxw: 1200px;
  --gut: 24px;
  --header-h: 66px;

  /* Motion */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --t-fast: 140ms;
  --t: 240ms;
  --t-slow: 480ms;

  /* Card face — a solid, layered surface rather than translucent glass.
     Glass blur is reserved for chrome that genuinely floats over moving
     content (the sticky header, the hero window). */
  --card-face:
    linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.014) 42%),
    #101014;
  /* One step up — the hover state, so an interactive surface stays
     opaque instead of turning translucent under the cursor. */
  --card-face-hi:
    linear-gradient(180deg, rgba(255, 255, 255, 0.095), rgba(255, 255, 255, 0.032) 44%),
    #17171D;
  --card-shadow:
    var(--edge),
    0 1px 2px rgba(0, 0, 0, 0.5),
    0 18px 42px -24px rgba(0, 0, 0, 0.85);
  --card-shadow-hover:
    var(--edge),
    0 1px 2px rgba(0, 0, 0, 0.5),
    0 26px 54px -26px rgba(0, 0, 0, 0.9);

  color-scheme: dark;
}

/* Light mode — same skeleton, warm paper instead of void */
[data-theme='light'] {
  --bg:     #FAF9F6;
  --bg-2:   #F3F2ED;
  --void:   #FFFFFF;

  --surface:   rgba(255, 255, 255, 0.75);
  --surface-2: rgba(255, 255, 255, 0.95);
  --surface-3: rgba(18, 18, 22, 0.05);
  --solid:     #FFFFFF;
  --solid-2:   #F6F5F1;
  --inset:     rgba(18, 18, 22, 0.035);

  --ink:   #000000;
  --ink-2: #1E1E25;
  --ink-3: #85858F;
  --ink-4: #B0B0B8;

  --line:   rgba(18, 18, 22, 0.10);
  --line-2: rgba(18, 18, 22, 0.18);
  --line-3: rgba(18, 18, 22, 0.30);
  --edge:   inset 0 1px 0 rgba(255, 255, 255, 0.9);

  --accent:      #D9480F;
  --accent-2:    #B93A0A;
  --accent-ink:  #FFFFFF;
  --accent-soft: rgba(217, 72, 15, 0.09);
  --accent-line: rgba(217, 72, 15, 0.32);
  --glow:        rgba(217, 72, 15, 0.22);
  --glow-strong: rgba(217, 72, 15, 0.4);

  --ok:      #0F7B4F;
  --ok-soft: rgba(15, 123, 79, 0.10);
  --warn:    #A16207;
  --warn-soft: rgba(161, 98, 7, 0.10);
  --danger:  #C0362C;
  --danger-soft: rgba(192, 54, 44, 0.10);

  --n-security: #D9480F;
  --n-images:   #0369A1;
  --n-colour:   #BE185D;
  --n-data:     #6D28D9;
  --n-text:     #047857;

  --sh-sm: 0 1px 2px rgba(18, 18, 22, 0.06);
  --sh:    0 4px 20px -8px rgba(18, 18, 22, 0.16);
  --sh-lg: 0 24px 60px -26px rgba(18, 18, 22, 0.28);

  /* Card face — in light mode the light comes from a pure white top
     rather than a translucent film, so cards read as paper on a desk. */
  --card-face: linear-gradient(180deg, #FFFFFF, #FBFAF7 46%);
  --card-face-hi: linear-gradient(180deg, #FFFFFF, #F4F3EE 46%);
  --card-shadow:
    var(--edge),
    0 1px 1px rgba(18, 18, 22, 0.04),
    0 14px 34px -22px rgba(18, 18, 22, 0.3);
  --card-shadow-hover:
    var(--edge),
    0 1px 1px rgba(18, 18, 22, 0.05),
    0 26px 54px -26px rgba(18, 18, 22, 0.34);

  color-scheme: light;
}

/* ---------- 2. Reset & base ---------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 110px;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.6;
  font-feature-settings: 'ss01', 'cv01';
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
}

img, svg, video, canvas { display: block; max-width: 100%; }
img { height: auto; }

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
button:disabled { cursor: not-allowed; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
hr { border: 0; border-top: 1px solid var(--line); }

::selection { background: var(--accent); color: var(--accent-ink); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

input[type='text'], input[type='number'], textarea, select {
  background: var(--inset);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 11px 13px;
  font-size: 0.9rem;
  outline: none;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
  width: 100%;
}

input:focus, textarea:focus, select:focus {
  border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

textarea { resize: vertical; line-height: 1.6; }

@supports (scrollbar-width: thin) {
  html { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line-2);
  border-radius: 6px;
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background-clip: content-box; background-color: var(--line-3); }

/* ---------- 3. Atmosphere ------------------------------------ */

/* Mesh glow — fixed behind everything */
.atmosphere {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
}

.atmosphere__blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.5;
  will-change: transform;
}

.atmosphere__blob--1 {
  top: -28vh; left: 8vw;
  width: 62vw; height: 62vw;
  max-width: 900px; max-height: 900px;
  background: radial-gradient(circle, rgba(255, 107, 53, 0.30), transparent 68%);
  animation: drift-a 26s var(--ease) infinite alternate;
}

.atmosphere__blob--2 {
  top: 22vh; right: -12vw;
  width: 48vw; height: 48vw;
  max-width: 720px; max-height: 720px;
  background: radial-gradient(circle, rgba(255, 154, 61, 0.16), transparent 70%);
  animation: drift-b 32s var(--ease) infinite alternate;
}

.atmosphere__blob--3 {
  bottom: -22vh; left: 26vw;
  width: 54vw; height: 54vw;
  max-width: 800px; max-height: 800px;
  background: radial-gradient(circle, rgba(167, 139, 250, 0.13), transparent 72%);
  animation: drift-c 38s var(--ease) infinite alternate;
}

[data-theme='light'] .atmosphere__blob { opacity: 0.42; filter: blur(100px); }
[data-theme='light'] .atmosphere__blob--1 { background: radial-gradient(circle, rgba(217, 72, 15, 0.20), transparent 68%); }
[data-theme='light'] .atmosphere__blob--2 { background: radial-gradient(circle, rgba(217, 72, 15, 0.11), transparent 70%); }
[data-theme='light'] .atmosphere__blob--3 { background: radial-gradient(circle, rgba(109, 40, 217, 0.07), transparent 72%); }

@keyframes drift-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(7vw, 6vh, 0) scale(1.14); }
}
@keyframes drift-b {
  from { transform: translate3d(0, 0, 0) scale(1.08); }
  to   { transform: translate3d(-6vw, 9vh, 0) scale(0.94); }
}
@keyframes drift-c {
  from { transform: translate3d(0, 0, 0) scale(0.96); }
  to   { transform: translate3d(9vw, -7vh, 0) scale(1.12); }
}

/* Film grain — hides gradient banding, adds texture */
body::after {
  content: '';
  position: fixed;
  inset: -50%;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}

[data-theme='light'] body::after { opacity: 0.09; mix-blend-mode: multiply; }

/* ---------- 4. Typography ------------------------------------ */

/* One heading voice. Page title, section heading and sub-heading all use
   the display serif — rank is carried by size and by a small step in weight,
   never by switching typeface.
   Fraunces replaced Instrument Serif here. Instrument Serif was a single
   roman plus its italic with no bold cut at all, so every heading under the
   title came out thin, and there was no way to fix that without changing
   the face. Fraunces is variable across 100–900 (and carries an optical
   size axis, so small headings get sturdier letterforms on their own).
   `.panel__title` and `h4` still name the UI sans explicitly: they are
   labels, not headings. */
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 550;
  line-height: 1.14;
  letter-spacing: -0.018em;
  text-wrap: balance;
}

h1 { font-size: clamp(2.6rem, 7vw, 4.8rem); font-weight: 600; letter-spacing: -0.02em; }
h2 { font-size: clamp(1.85rem, 4vw, 2.9rem); letter-spacing: -0.018em; }
h3 { font-size: clamp(1.16rem, 1.8vw, 1.4rem); letter-spacing: -0.012em; }

/* h4 is furniture, not a heading — it labels a footer column. It stays in
   the UI sans, so a dense list of links stays scannable. */
h4 {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 0.98rem;
  letter-spacing: -0.01em;
}

p { text-wrap: pretty; }

/* The emphasis move, everywhere a heading carries one: a single word set in
   the italic, in the accent. Both faces of the same family, no second
   typeface. The italic inherits the heading's weight, so a heavier heading
   gets a heavier emphasis word with it. */
h1 em, h2 em, h3 em, .display em {
  font-style: italic;
  color: var(--accent);
  padding-right: 0.06em;
}

/* Alternate display face — for hero lines and pull quotes */
.display {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.02;
}

.lede {
  font-size: clamp(1rem, 1.5vw, 1.12rem);
  color: var(--ink);
  line-height: 1.65;
  max-width: 58ch;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.eyebrow::before {
  content: '';
  width: 18px;
  height: 1px;
  background: linear-gradient(to right, transparent, var(--accent));
}

.mono { font-family: var(--font-mono); font-variant-ligatures: none; }
.tnum { font-variant-numeric: tabular-nums; }


/* ---------- 5. Layout ---------------------------------------- */

.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gut);
}

.section { padding-block: clamp(60px, 8vw, 112px); }
.section--tight { padding-block: clamp(36px, 5vw, 64px); }

/* For a section that follows a page head, which already brings its own
   bottom padding — two lots of it leaves a dead band between them. */
.section--flush { padding-top: 0; }

.section-head {
  display: flex;
  flex-direction: column;
  gap: 15px;
  max-width: 60ch;
  margin-bottom: clamp(32px, 4vw, 56px);
}

.section-head--center { margin-inline: auto; text-align: center; align-items: center; }
.section-head--center .eyebrow::before { display: none; }

.stack { display: flex; flex-direction: column; }
.stack-6  { gap: 6px; }
.stack-8  { gap: 8px; }
.stack-10 { gap: 10px; }
.stack-12 { gap: 12px; }
.stack-14 { gap: 14px; }
.stack-16 { gap: 16px; }
.stack-20 { gap: 20px; }
.stack-24 { gap: 24px; }
.stack-32 { gap: 32px; }

.row { display: flex; align-items: center; gap: 12px; }
.row-wrap { flex-wrap: wrap; }
.spacer { flex: 1; }

.grid { display: grid; gap: var(--gut); }

/* Self-sufficient: every .grid-2 in the site stands on its own, so it
   carries its own display and gap rather than depending on .grid also
   being present — which it never was. */
.grid-2 {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Three-up, for the "already answered elsewhere" row on the contact page.
   It wraps rather than breaking to one column at a fixed width, so it
   still reads as a row of equal cards on a tablet. */
.grid-3 {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(236px, 1fr));
}

@media (max-width: 720px) {
  :root { --gut: 18px; }
  .grid-2 { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- 6. Header (floating pill) ------------------------ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  padding: 12px var(--gut) 0;
  pointer-events: none;
}

.header-pill {
  pointer-events: auto;
  position: relative;
  max-width: var(--maxw);
  margin-inline: auto;
  height: 60px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 9px 0 15px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg) 62%, transparent);
  backdrop-filter: blur(22px) saturate(190%);
  -webkit-backdrop-filter: blur(22px) saturate(190%);
  box-shadow: var(--edge), 0 10px 34px -18px rgba(0, 0, 0, 0.9);
  transition: background var(--t) var(--ease), border-color var(--t) var(--ease),
              box-shadow var(--t) var(--ease);
}

@supports not (backdrop-filter: blur(1px)) {
  .header-pill { background: var(--solid); }
}

.site-header.is-stuck .header-pill {
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  border-color: var(--line-2);
  box-shadow: var(--edge), 0 16px 44px -18px rgba(0, 0, 0, 1);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  padding: 5px;
  margin-inline: -5px;
  border-radius: var(--r-sm);
}

.brand__mark {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  color: var(--accent-ink);
  background: var(--accent);
  display: grid;
  place-items: center;
  box-shadow: var(--edge), 0 3px 10px -4px var(--glow-strong);
  transition: box-shadow var(--t) var(--ease);
}

.brand:hover .brand__mark { box-shadow: var(--edge), 0 6px 18px -4px var(--glow-strong); }

.brand__mark svg { width: 20px; height: 20px; }

.brand__name { font-size: 1.06rem; font-weight: 800; letter-spacing: -0.032em; }

.nav { display: flex; align-items: center; gap: 1px; margin-inline: auto; }

.nav__link {
  position: relative;
  padding: 8px 14px;
  border-radius: var(--r-pill);
  font-size: 0.885rem;
  font-weight: 600;
  color: var(--ink);
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}

.nav__link:hover { color: var(--ink); background: var(--surface-2); }
.nav__link[aria-current='page'] { color: var(--ink); }

.nav__link[aria-current='page']::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 1px;
  transform: translateX(-50%);
  width: 14px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
  box-shadow: 0 0 8px var(--glow-strong);
}

.header-actions { display: flex; align-items: center; gap: 7px; flex-shrink: 0; }

.search-trigger {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: 36px;
  padding: 0 9px 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink-3);
  font-size: 0.83rem;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}

.search-trigger:hover { border-color: var(--line-2); color: var(--ink-2); background: var(--surface-2); }
.search-trigger svg { width: 15px; height: 15px; flex-shrink: 0; }

kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 21px;
  height: 21px;
  padding: 0 5px;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--ink-3);
  font-family: var(--font-ui);
  font-size: 0.67rem;
  font-weight: 600;
  line-height: 1;
}

.icon-btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-2);
  display: grid;
  place-items: center;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}

.icon-btn:hover { border-color: var(--line-2); color: var(--ink); background: var(--surface-2); transform: translateY(-1px); }
.icon-btn svg { width: 16px; height: 16px; }

.theme-toggle .icon-moon { display: none; }
[data-theme='dark'] .theme-toggle .icon-moon { display: block; }
[data-theme='dark'] .theme-toggle .icon-sun { display: none; }

.nav-toggle { display: none; }

@media (max-width: 880px) {
  .nav { display: none; }
  .search-trigger { display: none; }
  .nav-toggle { display: grid; }

  /* .nav carries `margin-inline: auto`, which is what holds the bar in
     three parts above this width — brand, nav, actions. Hide the nav and
     that push disappears with it, leaving the two buttons stranded beside
     the logo and the right third of the pill empty. Put the push back on
     the actions themselves, which is where it belongs once there is only
     one thing to push. */
  .header-actions { margin-left: auto; }

  /* The pill spans most of the width here, so the frosted gap above and
     beside it stops reading as depth and starts reading as page text
     sliding under a bar. On a phone the header is a bar: give it a
     background, and fade it out just under the pill so the edge is soft
     rather than a printed line. */
  .site-header.is-stuck::before {
    content: '';
    position: absolute;
    inset: 0 0 auto;
    height: calc(100% + 16px);
    background: linear-gradient(to bottom, var(--bg) calc(100% - 16px), transparent);
    pointer-events: none;
    z-index: -1;
  }
}

/* ---------- 6b. Categories mega menu ------------------------- */

/* The panel is a child of the trigger so hovering it keeps the trigger
   hovered, but it is positioned against the header pill so it spans the
   full bar rather than hanging off one word. */
.nav-item { display: flex; align-items: center; }

.nav__link--btn {
  appearance: none;
  border: 0;
  background: none;
  cursor: pointer;
  /* The reset at the top of the file makes every svg a block box. Every
     other icon-and-label control in the header is a flex or grid
     container, so the block svg simply becomes a flex item and sits on
     the line. This one declared no display of its own, so the chevron
     stacked underneath the label and turned the trigger into a two-line
     box — 13px taller than the links beside it, and centred on that
     taller box, so the word itself sat high. Flex puts them back on one
     line and lets the gap replace the space the markup used to supply. */
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* Deliberately no `font: inherit` here, though the reset above supplies
     one for every other button. It reads as harmless and does the
     opposite: being a shorthand, it sets font-size and font-weight back
     to the inherited page default — and because this rule sits below
     .nav__link at equal specificity, it wins. That is how the trigger
     ended up a size larger and a weight lighter than its neighbours.
     .nav__link owns the type; this rule only strips the UA chrome. */
}

.nav__link--btn svg {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  color: var(--ink-4);
  transform: rotate(90deg);
  transition: transform var(--t) var(--ease), color var(--t) var(--ease);
}

.nav-item.is-open > .nav__link--btn { color: var(--ink); background: var(--surface-2); }
.nav-item.is-open > .nav__link--btn svg { transform: rotate(-90deg); color: var(--ink-2); }

.mega {
  position: absolute;
  inset-inline: 10px;
  top: calc(100% + 12px);
  padding: 22px;
  border-radius: var(--r-xl);
  border: 1px solid var(--line-2);
  background: var(--card-face-hi);
  box-shadow: var(--edge), var(--sh-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease),
              visibility var(--t) var(--ease);
}

.nav-item.is-open > .mega { opacity: 1; visibility: visible; transform: none; }

.mega__grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px 22px;
}

.mega__col { min-width: 0; }

.mega__head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 8px 12px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: -0.012em;
}

.mega__head svg { width: 16px; height: 16px; color: var(--hue, var(--accent)); flex-shrink: 0; }

.mega__list { display: grid; gap: 1px; }

.mega__list a {
  display: block;
  padding: 7px 8px;
  border-radius: var(--r-sm);
  font-size: 0.83rem;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.35;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}

.mega__list a:hover { background: var(--surface-2); color: var(--ink); }

/* Mobile drawer */
.mobile-nav {
  pointer-events: auto;
  max-width: var(--maxw);
  margin: 8px auto 0;
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(22px) saturate(180%);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  box-shadow: var(--sh-lg);
  /* The drawer lists every tool on the site, so it is taller than a phone.
     Cap it against the viewport and let it scroll on its own — with the
     scroll chained away from the page behind it. */
  max-height: calc(100vh - 96px);
  max-height: calc(100dvh - 96px);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  animation: panel-in 220ms var(--ease-out);
}

@keyframes panel-in {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}

.mobile-nav a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px 20px;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--ink-2);
  border-bottom: 1px solid var(--line);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}

.mobile-nav a:last-child { border-bottom: 0; }
.mobile-nav a:hover { background: var(--surface-2); color: var(--ink); }
.mobile-nav svg { width: 15px; height: 15px; color: var(--ink-4); }

/* Tool rows carry their own mark on the left, so the menu reads as an
   index of what exists rather than a column of identical chevrons. The
   chevron stays on the right where it belongs — as affordance, not as
   the only thing distinguishing one row from the next. */
.mobile-nav__item {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
}

.mobile-nav a svg.mobile-nav__icon {
  width: 17px;
  height: 17px;
  color: var(--hue, var(--accent));
  flex-shrink: 0;
}

.mobile-nav__group {
  padding: 16px 20px 7px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-4);
}

@media (min-width: 881px) { .mobile-nav { display: none !important; } }

/* ---------- 7. Buttons --------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  padding: 0 20px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  white-space: nowrap;
  position: relative;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease),
              box-shadow var(--t-fast) var(--ease);
}

.btn:active { transform: translateY(1px) scale(0.99); }
.btn svg { width: 16px; height: 16px; flex-shrink: 0; }

.btn--primary {
  background: linear-gradient(180deg, var(--accent-2) 0%, var(--accent) 100%);
  color: var(--accent-ink);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.14) inset, 0 6px 22px -6px var(--glow-strong);
}

.btn--primary:hover {
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.2) inset, 0 10px 32px -6px var(--glow-strong);
  filter: brightness(1.06);
}

.btn--ghost {
  background: var(--solid-2);
  border-color: var(--line-2);
  color: var(--ink);
  box-shadow: var(--edge);
}

.btn--ghost:hover { border-color: var(--line-3); background: var(--surface-2); }

.btn--quiet { color: var(--ink-2); }
.btn--quiet:hover { color: var(--ink); background: var(--surface-2); }

.btn--lg { height: 50px; padding: 0 26px; font-size: 0.95rem; }
.btn--sm { height: 34px; padding: 0 14px; font-size: 0.82rem; gap: 6px; }
.btn--sm svg { width: 14px; height: 14px; }
.btn--block { width: 100%; }
.btn:disabled { opacity: 0.45; pointer-events: none; }

.btn .arrow { transition: transform var(--t) var(--ease); }
.btn:hover .arrow { transform: translateX(3px); }

/* ---------- 8. Cards & surfaces ------------------------------ */

.card {
  position: relative;
  /* A solid face, lit from above: a hairline of light along the top edge
     fading into the body colour. No blur — cards here sit on a flat
     backdrop, so glass would only cost paint and muddy the edge. */
  background: var(--card-face);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--card-shadow);
}

.panel { padding: clamp(20px, 2.6vw, 28px); }

/* A card that is itself the link target — used where the whole tile is
   one destination and the heading inside it is the only text worth
   reading. The anchor is block-level so the panel padding behaves. */
a.card {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: border-color var(--t) var(--ease), transform var(--t) var(--ease),
              box-shadow var(--t) var(--ease);
}

a.card:hover {
  border-color: var(--line-3);
  box-shadow: var(--card-shadow-hover);
  transform: translateY(-2px);
}

a.card:hover .panel__title { color: var(--accent); }

.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

/* A panel label, not a heading. It is set on an h2 or an h3 in the markup
   for document structure, so it has to name the UI sans explicitly — the
   heading rule above would otherwise hand it the display serif. */
.panel__title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 0.71rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Cursor spotlight — JS sets --mx / --my */
.spotlight { position: relative; overflow: hidden; }

.spotlight::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 0%), var(--spot, var(--accent-soft)), transparent 62%);
  opacity: 0;
  transition: opacity var(--t) var(--ease);
  pointer-events: none;
  z-index: 0;
}

.spotlight:hover::before { opacity: 1; }
.spotlight > * { position: relative; z-index: 1; }

/* Icon tile — a solid, saturated app mark with the glyph knocked out in
   white, rather than a tinted square with a coloured line drawing in it.
   The tile is darkened at its foot so the white glyph holds contrast even
   against the pale hues (sky, mint) in dark mode. */
.tile {
  --tile-hue: var(--hue, var(--accent));
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  border-radius: 13px;
  display: grid;
  place-items: center;
  background:
    linear-gradient(157deg,
      color-mix(in srgb, var(--tile-hue) 88%, #ffffff) 0%,
      var(--tile-hue) 44%,
      color-mix(in srgb, var(--tile-hue) 72%, #05070d) 100%);
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.36),
    inset 0 0 0 1px color-mix(in srgb, var(--tile-hue) 62%, #05070d 38%),
    0 7px 16px -9px color-mix(in srgb, var(--tile-hue) 72%, transparent);
  transition: transform var(--t) var(--ease), box-shadow var(--t) var(--ease);
}

.tile svg { width: 22px; height: 22px; }
.tile--sm { width: 38px; height: 38px; border-radius: 11px; }
.tile--sm svg { width: 18px; height: 18px; }

/* The duotone wash reads as a soft interior highlight against white, so it
   stays — but at a lower strength, since the ground is no longer pale. */
.tile svg [opacity='0.19'] { opacity: 0.26; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 11px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--ink-2);
  white-space: nowrap;
}

.chip--hue {
  background: color-mix(in srgb, var(--hue) 12%, transparent);
  border-color: color-mix(in srgb, var(--hue) 28%, transparent);
  color: var(--hue);
}

/* ---------- 8b. Reference table ------------------------------ */

/* One table component for the whole site. It was written for the
   homepage's format matrix and generalised once the tool pages and the
   blog both needed one — a second near-identical block would have been
   two things to keep in step.

   `.table-wrap` carries the surface and the horizontal scroll, so a
   wide table scrolls inside its own card instead of pushing the page
   sideways. Markup: a <div class="table-wrap"> around the <table>. */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--card-face);
  box-shadow: var(--card-shadow);
}

.table {
  width: 100%;
  border-collapse: collapse;
}

.table th,
.table td {
  padding: 15px 20px;
  text-align: left;
  border-bottom: 1px solid var(--line);
}

.table tbody tr:last-child th,
.table tbody tr:last-child td { border-bottom: 0; }

.table tbody tr:hover { background: var(--surface); }

.table thead th {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* A row header is a value — an algorithm, a format, a level — so it is
   set in the mono face and left at full ink while the cells beside it
   stay dim. That contrast is what makes the table scannable. */
.table tbody th {
  font-family: var(--font-mono);
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--ink);
}

.table td { font-size: 0.84rem; color: var(--ink-2); }

/* Two classes deep so the cell colour holds against `.table td`. */
.table .table__yes { color: var(--ink); }
.table .table__no  { color: var(--ink-3); }

.table-caption {
  margin-top: 20px;
  max-width: 82ch;
  font-size: 0.84rem;
  color: var(--ink-3);
  line-height: 1.72;
}

/* ---------- 8c. Legal documents and forms -------------------- */

/* A legal page reads straight down. One column, a measure short enough
   to track with the eye, and no rail beside it competing for attention —
   the contents list sits above the document rather than next to it. */
.legal {
  display: grid;
  gap: clamp(28px, 3.4vw, 44px);
  max-width: 76ch;
}

/* The document body: sections separated by a rule rather than by cards,
   so nothing interrupts the reading between one clause and the next.
   Block, not grid — the rules do the spacing, and a grid gap on top of
   them would double it. */
.legal--doc {
  display: block;
  max-width: 72ch;
}

.legal--doc h2 {
  font-size: clamp(1.32rem, 2.4vw, 1.7rem);
  text-wrap: balance;
}

.legal--doc p {
  color: var(--ink-2);
  line-height: 1.78;
}

.legal--doc a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent-line);
  text-underline-offset: 3px;
  text-decoration-thickness: 1.5px;
  transition: color var(--t-fast) var(--ease), text-decoration-color var(--t-fast) var(--ease);
}

.legal--doc a:hover { color: var(--accent); text-decoration-color: var(--accent); }

.legal--doc hr {
  margin-block: clamp(30px, 3.6vw, 46px);
  border: 0;
  border-top: 1px solid var(--line);
}

/* The section wrapper is a .stack-10 for the contents list's sake; in the
   document it wants a paragraph's worth of air instead. */
.legal--doc .stack { gap: 15px; }

/* The contents list. Navigation, so it is labelled and quiet rather than
   headed and loud, and it breaks into two columns once there is room for
   them. The numbers are counters, not markup — a clause reordered in the
   contents cannot fall out of step with its own position. */
.toc {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  column-gap: clamp(24px, 3vw, 40px);
  margin-top: 14px;
  padding: 0;
  counter-reset: toc;
  list-style: none;
}

.toc__link {
  display: flex;
  gap: 12px;
  padding: 10px 2px;
  border-top: 1px solid var(--line);
  color: var(--ink-2);
  font-size: 0.94rem;
  text-decoration: none;
  transition: color var(--t-fast) var(--ease);
}

.toc__link::before {
  counter-increment: toc;
  content: counter(toc, decimal-leading-zero);
  flex: none;
  padding-top: 2px;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--ink-3);
  transition: color var(--t-fast) var(--ease);
}

.toc__link:hover { color: var(--accent); }
.toc__link:hover::before { color: var(--accent); }

/* ---------- 8d. Long-form prose ------------------------------ */

/* The reading register, shared by the blog and by every tool page's
   long-form body. The measure is the point of it: long-form reading
   wants a shorter line than the rest of the site, and a slightly
   larger body than a tool's explanatory panels. */
.prose {
  max-width: 70ch;
  font-size: 1.02rem;
  line-height: 1.78;
  color: var(--ink-2);
}

.prose > * + * { margin-top: 22px; }

.prose p { text-wrap: pretty; }

.prose h2 {
  margin-top: clamp(44px, 5vw, 68px);
  margin-bottom: 4px;
  padding-top: clamp(20px, 2.4vw, 30px);
  border-top: 1px solid var(--line);
  font-size: clamp(1.5rem, 3vw, 2.05rem);
  color: var(--ink);
}

.prose h3 {
  margin-top: 34px;
  margin-bottom: 2px;
  font-size: clamp(1.12rem, 1.8vw, 1.34rem);
  color: var(--ink);
}

.prose h2 + *, .prose h3 + * { margin-top: 14px; }

.prose strong { color: var(--ink); font-weight: 650; }
.prose em { font-style: italic; }

/* Emphasis inside body copy is ordinary italics — the accent italic is
   reserved for the one <em> a heading carries, so a paragraph full of
   emphasis does not compete with the headings. */
.prose p em, .prose li em { color: var(--ink); }

.prose a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent-line);
  text-underline-offset: 3px;
  text-decoration-thickness: 1.5px;
  transition: color var(--t-fast) var(--ease), text-decoration-color var(--t-fast) var(--ease);
}

.prose a:hover { color: var(--accent); text-decoration-color: var(--accent); }

.prose ul, .prose ol {
  display: grid;
  gap: 10px;
  padding-left: 4px;
}

.prose li {
  position: relative;
  padding-left: 24px;
}

.prose ul > li::before {
  content: '';
  position: absolute;
  left: 6px;
  top: 0.72em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--hue, var(--accent));
}

.prose ol { counter-reset: prose-ol; }

.prose ol > li { counter-increment: prose-ol; }

.prose ol > li::before {
  content: counter(prose-ol);
  position: absolute;
  left: 0;
  top: 0.1em;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--hue, var(--accent));
}

.prose blockquote {
  margin-top: 30px;
  padding: 4px 0 4px 22px;
  border-left: 2px solid var(--accent-line);
  font-family: var(--font-display);
  font-size: 1.14rem;
  font-style: italic;
  line-height: 1.55;
  color: var(--ink);
}

.prose hr {
  margin-top: 40px;
  border: 0;
  border-top: 1px solid var(--line);
}

/* A code sample is the one place a reader stops reading and starts
   copying, so it gets its own surface rather than an inline tint. */
.prose pre {
  margin-top: 26px;
  padding: 16px 18px;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--inset);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  line-height: 1.62;
  color: var(--ink);
}

.prose code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  padding: 0.12em 0.4em;
  border-radius: var(--r-xs);
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--ink);
}

.prose pre code { padding: 0; border: 0; background: none; font-size: 1em; }

/* A note that stands slightly outside the argument. */
.prose__note {
  margin-top: 30px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: var(--r);
  background: var(--inset);
}

.prose__note p { font-size: 0.94rem; line-height: 1.7; }
.prose__note p + p { margin-top: 12px; }

.prose__note b { color: var(--ink); }

/* Illustration built from markup, since inline SVG is not available
   to a page in this build. A row of labelled cells reads as a diagram
   without pretending to be a chart. */
.prose__figure {
  margin-top: 30px;
  display: grid;
  gap: 10px;
}

.prose__figure-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
}

.prose__figure-cell {
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
}

.prose__figure-cell b {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.9rem;
  color: var(--hue, var(--accent));
}

.prose__figure-cell span {
  display: block;
  margin-top: 4px;
  font-size: 0.78rem;
  color: var(--ink-3);
}

.prose__figure figcaption {
  font-size: 0.78rem;
  color: var(--ink-3);
}

/* ---------- the contact form --------------------------------- */

/* Three fields and a button. The form composes a mailto: message in the
   visitor's own client, so there is no validation state to style and no
   submission to report — only focus, which has to stay visible. */
.field { display: grid; gap: 7px; }

.field__label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink-2);
}

.field__input {
  width: 100%;
  height: 44px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--inset);
  font-family: var(--font-ui);
  font-size: 0.9rem;
  color: var(--ink);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease);
}

.field__input::placeholder { color: var(--ink-4); }

.field__input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface-2);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.field__input--area {
  height: auto;
  min-height: 122px;
  padding: 12px 14px;
  line-height: 1.62;
  resize: vertical;
}

/* ---------- 9. Niche system ---------------------------------- */

/* Each niche carries its own hue through --hue */
[data-niche='security'] { --hue: var(--n-security); }
[data-niche='images']   { --hue: var(--n-images); }
[data-niche='colour']   { --hue: var(--n-colour); }
[data-niche='data']     { --hue: var(--n-data); }
[data-niche='text']     { --hue: var(--n-text); }


/* ---------- 10. Command palette ------------------------------ */

.palette {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: max(13vh, 80px) 18px 18px;
}

.palette[hidden] { display: none; }

.palette__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(4, 4, 6, 0.6);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: fade-in 160ms var(--ease);
}

.palette__panel {
  position: relative;
  width: 100%;
  max-width: 580px;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(26px) saturate(180%);
  -webkit-backdrop-filter: blur(26px) saturate(180%);
  border: 1px solid var(--line-2);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lg), 0 0 90px -30px var(--glow);
  overflow: hidden;
  animation: palette-in 240ms var(--ease-out);
}

@keyframes palette-in {
  from { opacity: 0; transform: translateY(-12px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

.palette__search {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 17px;
  border-bottom: 1px solid var(--line);
}

.palette__search svg { width: 18px; height: 18px; color: var(--ink-3); flex-shrink: 0; }

.palette__search input {
  flex: 1;
  border: 0;
  background: none;
  padding: 0;
  outline: none;
  font-size: 0.97rem;
  min-width: 0;
  box-shadow: none;
}

.palette__search input:focus { box-shadow: none; border: 0; }
.palette__search input::placeholder { color: var(--ink-4); }

.palette__list { max-height: 356px; overflow-y: auto; padding: 8px; }

.palette__item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 11px;
  border-radius: var(--r-sm);
  color: var(--ink);
  transition: background var(--t-fast) var(--ease);
}

.palette__item[aria-selected='true'] { background: var(--surface-2); }
.palette__item-text { min-width: 0; flex: 1; }
.palette__item-text strong { display: block; font-size: 0.9rem; font-weight: 600; }
.palette__item-text span { display: block; font-size: 0.78rem; color: var(--ink-3); }

.palette__empty { padding: 28px 16px; text-align: center; color: var(--ink-3); font-size: 0.88rem; }

.palette__foot {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 15px;
  border-top: 1px solid var(--line);
  background: var(--surface);
  font-size: 0.74rem;
  color: var(--ink-3);
}

.palette__foot span { display: inline-flex; align-items: center; gap: 5px; }

/* ---------- 11. Footer --------------------------------------- */

.site-footer {
  margin-top: auto;
  border-top: 1px solid var(--line);
  padding-block: 60px 30px;
  background: color-mix(in srgb, var(--bg-2) 60%, transparent);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.8fr repeat(3, 1fr);
  gap: 40px 24px;
}

.footer-brand p {
  margin-top: 14px;
  font-size: 0.865rem;
  color: var(--ink-2);
  max-width: 36ch;
  line-height: 1.62;
}

/* The trust chips sit a beat below the blurb on every page's footer. */
.footer-brand .row { margin-top: 16px; }

.footer-col h4 {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 15px;
}

.footer-col li + li { margin-top: 10px; }

.footer-col a {
  font-size: 0.865rem;
  color: var(--ink-2);
  transition: color var(--t-fast) var(--ease);
}

.footer-col a:hover { color: var(--accent); }

.footer-bottom {
  margin-top: 48px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 0.8rem;
  color: var(--ink-3);
}

@media (max-width: 780px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}

/* ---------- 12. FAQ accordion -------------------------------- */

.faq { border-top: 1px solid var(--line); }

/* On a tool page the FAQ closes the page under a much wider tool chrome,
   so it is held to a reading measure and centred rather than stretched. */
.faq--narrow { max-width: 760px; margin-inline: auto; }

.faq details { border-bottom: 1px solid var(--line); }

.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 4px;
  cursor: pointer;
  list-style: none;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.016em;
  transition: color var(--t-fast) var(--ease);
}

.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }

.faq summary .plus {
  flex-shrink: 0;
  width: 24px; height: 24px;
  position: relative;
  border-radius: 50%;
  border: 1px solid var(--line-2);
  transition: transform var(--t) var(--ease), border-color var(--t) var(--ease), background var(--t) var(--ease);
}

.faq summary .plus::before,
.faq summary .plus::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 10px;
  height: 1.5px;
  margin: -0.75px 0 0 -5px;
  background: var(--ink-3);
  border-radius: 2px;
  transition: transform var(--t) var(--ease), background var(--t) var(--ease);
}

.faq summary .plus::after { transform: rotate(90deg); }

.faq details[open] summary .plus {
  transform: rotate(180deg);
  border-color: var(--accent-line);
  background: var(--accent-soft);
}
.faq details[open] summary .plus::before,
.faq details[open] summary .plus::after { background: var(--accent); }
.faq details[open] summary .plus::after { transform: rotate(0deg); }

.faq__body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--t-slow) var(--ease);
}

.faq details[open] .faq__body { grid-template-rows: 1fr; }
.faq__body > div { overflow: hidden; }

.faq__body p {
  padding: 0 4px 24px;
  color: var(--ink-2);
  font-size: 0.92rem;
  line-height: 1.7;
  max-width: 76ch;
}

/* ---------- 13. Motion & utilities --------------------------- */

/* The inline duotone sprite lives at the top of <body>; the attributes
   already collapse it, this is here so the class is self-describing. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Icons that ride inside a text run or a chip line up on the cap height
   rather than the baseline. */
.tile svg, .chip svg, .btn svg, kbd svg { display: block; }

.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 700ms var(--ease-out), transform 700ms var(--ease-out);
  will-change: opacity, transform;
}

.js .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js .reveal { opacity: 1; transform: none; }
  .atmosphere__blob { animation: none !important; }
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: 12px; left: 12px;
  z-index: 400;
  padding: 11px 18px;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 0.875rem;
  font-weight: 600;
  transform: translateY(-180%);
  transition: transform var(--t) var(--ease);
}

.skip-link:focus { transform: none; }

.text-accent { color: var(--accent); }
.text-muted { color: var(--ink-2); }
.text-dim { color: var(--ink-3); }
.nowrap { white-space: nowrap; }
.hue { color: var(--hue, var(--accent)); }
