/* =============================================
   EMOS Landing Page — Mentalista
   Hume.ai-inspired: mesh gradients, organic shapes,
   staggered fades, mono labels, code showcase,
   warm-yet-technical aesthetic
   ============================================= */

/* IBM Plex Mono is requested from the page head (index.php), not from here:
   an @import only starts once this file has fully arrived. */

:root {
  /* Brand */
  --accent: #1c0fc2;
  --accent-dark: #150b94;
  --accent-light: #4f46e5;
  /* The brand blue is unreadable on --bg; this is the gradient's mid-stop,
     light enough to carry small type on the dark sections. */
  --accent-on-dark: #8079db;
  --accent-dim: hsl(245 60% 95%);
  --accent-08: rgba(28, 15, 194, 0.08);
  --accent-15: rgba(28, 15, 194, 0.15);
  --accent-30: rgba(28, 15, 194, 0.3);

  /* Surfaces */
  --bg: #0c0b12;
  --bg-warm: #faf9f7;
  --surface: #ffffff;
  --surface-2: #f5f4f2;
  --surface-dark: #18171f;

  /* Text */
  --fg: #1a1a1e;
  --fg-60: rgba(26, 26, 30, 0.6);
  --fg-40: rgba(26, 26, 30, 0.4);
  --fg-20: rgba(26, 26, 30, 0.2);
  --fg-10: rgba(26, 26, 30, 0.1);
  --fg-inv: #ffffff;
  --fg-inv-60: rgba(255, 255, 255, 0.6);
  --fg-inv-40: rgba(255, 255, 255, 0.4);
  --fg-inv-20: rgba(255, 255, 255, 0.2);
  --fg-inv-10: rgba(255, 255, 255, 0.1);

  /* Scrollbars — dark-on-light by default; dark surfaces flip these. */
  --scrollbar-thumb: var(--fg-20);
  --scrollbar-thumb-hover: var(--fg-40);

  /* Semantic */
  --red: #dc2626;
  --purple: #a855f7;
  --green: #059669;
  --orange: #e07540;
  --mint: #34d399;

  /* Rhythm — the band above and below every section. One knob, because the
     mobile block at the foot of this file halves it and there are a dozen
     sections that would otherwise each need their own override. */
  --section-y: 120px;

  /* Shape */
  --r-sm: 10px;
  --r: 16px;
  --r-lg: 24px;
  --r-xl: 32px;
  --r-full: 9999px;

  /* Motion */
  --ease: cubic-bezier(0.25, 0.1, 0.25, 1);
  --ease-out: cubic-bezier(0, 0, 0.25, 1);
}

/* ── Reset ── */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  /* The scrollbar gutter sits outside the content box, so no section background
     ever reaches it — the canvas paints it. Without this, body's near-white
     propagated to the canvas and left a pale strip beside the dark sections.
     interactive.js keeps this colour in step with the section alongside it. */
  background: var(--bg-warm);
  transition: background-color 0.3s var(--ease);
}
/* Beside a dark section the dark-on-light thumb would vanish, so it flips.
   Firefox picks this up too, through scrollbar-color below. */
html[data-canvas="dark"] {
  --scrollbar-thumb: var(--fg-inv-20);
  --scrollbar-thumb-hover: var(--fg-inv-40);
}
body {
  font-family:
    "Euclid Square",
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;
  color: var(--fg);
  line-height: 1.6;
  background: var(--bg-warm);
  overflow-x: hidden;
}
/* Korean is spaced like Latin but browsers break it like Chinese, anywhere
   between two syllables — "멀티모달" split across lines reads as two words.
   keep-all wraps at spaces only; overflow-wrap still rescues a box narrower
   than its longest word. Chinese and Japanese have no spaces and keep the
   default. */
:lang(ko) {
  word-break: keep-all;
  overflow-wrap: break-word;
}

/* ── Scrollbars ── */
/* One bar on every platform, rather than the OS default — which is why the
   gutter is styled at all: a classic bar takes layout space, and the canvas,
   not the section, paints that space. <html> carries the section's colour so
   the gutter reads as an extension of it.
   The widget also paints its own background UNDER the track, white by default
   in Chrome, so all three layers have to be cleared. */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
  background: transparent;
}
::-webkit-scrollbar-track,
::-webkit-scrollbar-track-piece {
  background: transparent;
  border: 0;
  box-shadow: none;
}
::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: 99px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--scrollbar-thumb-hover);
}
::-webkit-scrollbar-corner {
  background: transparent;
}
/* Firefox has no ::-webkit-scrollbar, and scrollbar-color is its only hook.
 * Scoped to browsers without the pseudo-element so Chrome keeps the 6px rules
 * above — where both are supported, scrollbar-color wins and widens the bar. */
@supports not selector(::-webkit-scrollbar) {
  * {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb) transparent;
  }
}

/* ── Typography ── */
h1,
h2,
h3,
h4,
h5 {
  line-height: 1.12;
  font-weight: 600;
  letter-spacing: -0.02em;
}
h1 {
  /* The vw term only overtakes the floor above ~590px, so on a phone the floor
     IS the size — every width from 320 to 590 got the same 48px. At 3rem the
     headline ran six lines at 320px and stood the hero 835px tall inside an
     800px viewport, which put the buttons on the fold and the logo bar under
     it. 2.4rem costs the desktop curve nothing: 6.5vw still governs from 590px
     up, where it always did. */
  font-size: clamp(2.4rem, 6.5vw, 5.5rem);
  letter-spacing: -0.035em;
}
h1 em {
  font-style: italic;
  font-weight: 600;
}
h2 {
  /* Same shape as h1, and the same reason: below 800px the floor is all there
     is, and 2rem left the section headings wrapping to three lines. */
  font-size: clamp(1.75rem, 4vw, 3.2rem);
}
h3 {
  font-size: 1.15rem;
  letter-spacing: -0.01em;
}
h4 {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--accent);
  font-family: "IBM Plex Mono", monospace;
}
h5 {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--fg-40);
  font-family: "IBM Plex Mono", monospace;
  font-weight: 500;
}
p {
  color: var(--fg-60);
}

.label-mono {
  display: inline-block;
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 14px;
}

/* ── Layout ── */
.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
}
.section-header {
  text-align: center;
  max-width: 600px;
  margin: 0 auto 64px;
}
.section-header p {
  margin-top: 14px;
  font-size: 1.05rem;
}

/* ── Buttons (Hume-style pill) ── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 28px;
  border-radius: var(--r-full);
  font-family: inherit;
  font-size: 0.88rem;
  font-weight: 500;
  text-decoration: none;
  border: none;
  cursor: pointer;
  transition: all 0.2s var(--ease);
}
.btn:active {
  transform: scale(0.98);
}

.btn-primary {
  background: var(--fg);
  color: var(--fg-inv);
}
.btn-primary:hover {
  opacity: 0.88;
}

.btn-secondary {
  background: transparent;
  color: var(--fg-inv);
  border: 1px solid var(--fg-inv-20);
}
.btn-secondary:hover {
  background: var(--fg-inv-10);
  border-color: var(--fg-inv-40);
}

.btn-nav {
  padding: 8px 20px;
  font-size: 0.8rem;
  background: var(--fg-inv);
  color: var(--bg);
}
.btn-nav:hover {
  opacity: 0.88;
}

.btn-chip {
  padding: 6px 14px;
  font-size: 0.75rem;
  font-weight: 500;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--fg-60);
  border: 1px solid var(--fg-10);
  font-family: inherit;
}
.btn-chip:hover {
  background: var(--accent-08);
  color: var(--accent);
  border-color: var(--accent-15);
}

/* ── Fade-In (staggered, Hume-style) ── */
.fade-in {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 0.7s var(--ease-out),
    transform 0.7s var(--ease-out);
}
.fade-in.visible {
  opacity: 1;
  transform: translateY(0);
}

/* ── Placeholder ── */
.placeholder-media {
  background: var(--surface-2);
  border: 2px dashed var(--fg-10);
  border-radius: var(--r);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 250px;
  color: var(--fg-40);
  font-size: 0.82rem;
  font-weight: 500;
}
.placeholder-media small {
  font-size: 0.7rem;
  opacity: 0.5;
}

/* =============================================
   NAV — Central floating island
   ============================================= */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  display: flex;
  justify-content: center;
  padding: 16px 24px;
  pointer-events: none;
  transition: padding 0.4s var(--ease);
}
.nav.scrolled {
  padding: 10px 24px;
}

/* Island (desktop) */
.nav-island {
  display: flex;
  align-items: center;
  gap: 6px;
  /* Right: the CTA is a pill of its own, so 6px nests it evenly inside the cap.
     Left: a flat label meets the cap at its widest point, so it is inset to
     where the cap ends (radius − border − the link's own 12px), which lands the
     first label the same distance from the edge as the CTA's label is on the
     right. Anything larger leaves the left end reading empty. */
  padding: 6px 6px 6px 12px;
  border-radius: var(--r-full);
  background: rgba(12, 11, 18, 0.55);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--fg-inv-10);
  pointer-events: auto;
  transition: all 0.4s var(--ease);
}
.nav.scrolled .nav-island {
  background: rgba(255, 255, 255, 0.88);
  border-color: var(--fg-10);
  box-shadow: 0 2px 16px rgba(0, 0, 0, 0.08);
}
.nav-island a {
  text-decoration: none;
  color: var(--fg-inv-60);
  font-size: 0.8rem;
  font-weight: 500;
  padding: 6px 12px;
  border-radius: var(--r-full);
  transition: all 0.2s;
}
.nav-island a:hover {
  color: var(--fg-inv);
  background: var(--fg-inv-10);
}
.nav.scrolled .nav-island a {
  color: var(--fg-60);
}
.nav.scrolled .nav-island a:hover {
  color: var(--fg);
  background: var(--fg-10);
}

.nav-island-cta {
  background: var(--fg-inv) !important;
  color: var(--bg) !important;
  font-weight: 500 !important;
  padding: 8px 18px !important;
}
.nav-island-cta:hover {
  opacity: 0.88;
  background: var(--fg-inv) !important;
}
.nav.scrolled .nav-island-cta {
  background: var(--fg) !important;
  color: var(--fg-inv) !important;
}

/* Language bubble — a second island, so the nav one stays centred */
.nav-lang {
  position: absolute;
  right: 24px;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: auto;
  transition: transform 0.4s var(--ease), opacity 0.4s var(--ease);
}
.nav.nav-hidden .nav-lang {
  transform: translateY(-80px);
  opacity: 0;
  pointer-events: none;
}
.nav-lang-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  /* Fixed, not padding-driven — it sits just under the 50px nav island. */
  height: 45px;
  padding: 0 14px 0 11px;
  border-radius: var(--r-full);
  background: rgba(12, 11, 18, 0.55);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--fg-inv-10);
  color: var(--fg-inv-60);
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: all 0.4s var(--ease);
}
.nav-lang-btn:hover {
  color: var(--fg-inv);
}
.nav.scrolled .nav-lang-btn {
  background: rgba(255, 255, 255, 0.88);
  border-color: var(--fg-10);
  box-shadow: 0 2px 16px rgba(0, 0, 0, 0.08);
  color: var(--fg-60);
}
.nav.scrolled .nav-lang-btn:hover {
  color: var(--fg);
}
.nav-lang-flag {
  width: 20px;
  height: 20px;
  flex: none;
  display: block;
}
.nav-lang-caret {
  width: 11px;
  height: 11px;
  opacity: 0.7;
  transition: transform 0.2s var(--ease);
}
.nav-lang.open .nav-lang-caret {
  transform: rotate(180deg);
}

.nav-lang-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 168px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px;
  border-radius: 16px;
  background: var(--surface);
  border: 1px solid var(--fg-10);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease),
    visibility 0.2s;
}
.nav-lang.open .nav-lang-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
}
/* The options are links now (?lang=…, so switching survives JS being off),
   which brings the browser's own anchor styling with it: the reset below is
   what keeps them looking like menu items. */
.nav-lang-menu a {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  background: none;
  border-radius: 11px;
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--fg-60);
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: all 0.15s;
}
.nav-lang-menu a:hover {
  background: var(--surface-2);
  color: var(--fg);
}
.nav-lang-menu a[aria-checked='true'] {
  color: var(--fg);
}
.nav-lang-check {
  margin-left: auto;
  width: 12px;
  height: 12px;
  flex: none;
  color: var(--accent);
  opacity: 0;
}
.nav-lang-menu a[aria-checked='true'] .nav-lang-check {
  opacity: 1;
}

/* Mobile nav */
/* No surface of its own: the logo and the burger sit straight on the page, and
   take their colour from it. Each is a shape with no ink — what fills it is its
   own backdrop, pulled to greyscale and inverted, so the mark is always the
   tonal opposite of whatever happens to be behind it at that moment.

   A light/dark class toggle could not do this. It can only read the section's
   background, so the mark lands the opposite of the section and therefore the
   SAME tone as the section's own headline type — and the hero's wordmark sat
   at exactly the height the headings pass through. Filtering the backdrop
   inverts per pixel, so the mark parts around the type it crosses instead of
   disappearing into it.

   The filter is masked to the glyph shapes, never applied to the whole bar:
   a bar-wide filter would drag a visibly desaturated band across the page.
   Greyscale before invert is what keeps the wordmark from going lime over the
   brand blue — a plain inversion shifts hue, this one only shifts tone, and
   the contrast() below then snaps that tone to black or white. */
.nav-mobile {
  display: none;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  pointer-events: auto;
  transition: transform 0.4s var(--ease), opacity 0.4s var(--ease);
}
/* The island and the language bubble both slide away on the way down; the
   mobile bar never had the rule, so it alone stayed pinned over the page. */
.nav.nav-hidden .nav-mobile {
  transform: translateY(-80px);
  opacity: 0;
  pointer-events: none;
}

/* The wordmark, as a mask rather than a painted path — the same geometry the
   inline <svg> used to carry, moved into the cached stylesheet. 1938.3 x 311
   is the artwork's box; 112px is what 18px of height comes to. */
.nav-logo {
  display: block;
  line-height: 0;
}
.nav-logo-mark {
  display: block;
  width: 112px;
  height: 18px;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1938.3 311'%3E%3Cpath d='M137.2,156.3c0-24.8-7.4-43.7-32.7-43.7c-32.1,0-44.8,32.1-44.8,56.9v131.2H9.1V77.8h49.5v33.7C69.7,92,86.6,73,119.8,73c34.8,0,54.8,17.9,63.2,41.6c11.6-21.1,30-41.6,64.8-41.6c49,0,68,34.8,68,73.8v153.9h-50.6V156.3c0-24.8-7.4-43.7-32.7-43.7c-32.1,0-44.8,32.1-44.8,56.9v131.2h-50.6L137.2,156.3L137.2,156.3z'/%3E%3Cpath d='M453.4,304.9c-60.6,0-102.8-50.6-102.8-114.9c0-62.7,36.9-117,104.9-117c68.5,0,102.8,54.3,97,130.2H403.9c1.6,41.6,17.4,66.9,53.2,66.9c38.5,0,44.8-33.7,48-49.5l46.4,10.5C549.9,242.7,529.9,304.9,453.4,304.9z M404.4,168.4h93.8c0-24.2-9.5-60.6-46.9-60.6c-31.1,0-44.8,23.7-46.9,56.4L404.4,168.4z'/%3E%3Cpath d='M725.4,156.3c0-24.8-10.5-43.7-36.9-43.7c-33.2,0-49,32.1-49,56.9v131.2h-50.6V77.8h49.5v35.8c12.6-20,31.1-40.1,65.4-40.1c50.1,0,72.7,35.3,72.7,73.8v153.9h-50.6V156.3H725.4z'/%3E%3Cpath d='M801.3,77.8h36.4V6.6h50.1v71.2h53.2v39h-52.7V229c0,26.9,7.4,32.1,29,32.1h27.4v39h-50.1c-39,0-56.9-17.4-56.9-64.8V116.8h-36.4V77.8z'/%3E%3Cpath d='M1118.6,268.5c-12.1,19-30.6,36.4-66.9,36.4c-44.8,0-89.1-38.5-89.1-115.4C962.5,112,1006.3,73,1050,73c34.8,0,54.3,17.4,66.9,35.3V77.8h50.6v222.9h-49L1118.6,268.5L1118.6,268.5z M1067.4,112.5c-35.8,0-51.6,35.3-51.6,76.9c0,40.6,15.8,76.4,51.6,76.4c35.3,0,52.2-36.4,52.2-76.4C1119.6,147.3,1102.7,112.5,1067.4,112.5z'/%3E%3Cpath d='M1212.4,6.1h50.6v294.1h-50.6V6.1z'/%3E%3Cpath d='M1307.8,6.1h50.6v38.5h-50.6V6.1z M1307.8,77.8h50.6v222.9h-50.6V77.8z'/%3E%3Cpath d='M1466.4,116.8c-21.6,0-31.1,7.4-31.1,22.1c0,17.9,15.8,20.6,31.1,24.8l38.5,10.5c34.8,10,53.8,25.8,53.8,62.2c0,40.6-27.4,63.2-77.5,63.2h-86.4v-38.5h85.9c19.5,0,32.1-1.6,32.1-20.6c0-16.9-15.8-21.6-39-28.5l-32.7-10c-29-9-51.6-22.1-51.6-60.6c0-42.7,30.6-64.3,74.8-64.3h78.5l-3.7,39h-72.7V116.8z'/%3E%3Cpath d='M1562.8,77.8h36.4V6.6h50.1v71.2h53.2v39h-52.7V229c0,26.9,7.4,32.1,29,32.1h27.4v39h-50.1c-39,0-56.9-17.4-56.9-64.8V116.8h-36.4V77.8z'/%3E%3Cpath d='M1880.1,268.5c-12.1,19-30.6,36.4-66.9,36.4c-44.8,0-89.1-38.5-89.1-115.4c0-77.5,43.7-116.5,87.5-116.5c34.8,0,54.3,17.4,66.9,35.3V77.8h50.6v222.9h-49L1880.1,268.5L1880.1,268.5z M1829,112.5c-35.8,0-51.6,35.3-51.6,76.9c0,40.6,15.8,76.4,51.6,76.4c35.3,0,52.2-36.4,52.2-76.4C1881.2,147.3,1864.3,112.5,1829,112.5z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1938.3 311'%3E%3Cpath d='M137.2,156.3c0-24.8-7.4-43.7-32.7-43.7c-32.1,0-44.8,32.1-44.8,56.9v131.2H9.1V77.8h49.5v33.7C69.7,92,86.6,73,119.8,73c34.8,0,54.8,17.9,63.2,41.6c11.6-21.1,30-41.6,64.8-41.6c49,0,68,34.8,68,73.8v153.9h-50.6V156.3c0-24.8-7.4-43.7-32.7-43.7c-32.1,0-44.8,32.1-44.8,56.9v131.2h-50.6L137.2,156.3L137.2,156.3z'/%3E%3Cpath d='M453.4,304.9c-60.6,0-102.8-50.6-102.8-114.9c0-62.7,36.9-117,104.9-117c68.5,0,102.8,54.3,97,130.2H403.9c1.6,41.6,17.4,66.9,53.2,66.9c38.5,0,44.8-33.7,48-49.5l46.4,10.5C549.9,242.7,529.9,304.9,453.4,304.9z M404.4,168.4h93.8c0-24.2-9.5-60.6-46.9-60.6c-31.1,0-44.8,23.7-46.9,56.4L404.4,168.4z'/%3E%3Cpath d='M725.4,156.3c0-24.8-10.5-43.7-36.9-43.7c-33.2,0-49,32.1-49,56.9v131.2h-50.6V77.8h49.5v35.8c12.6-20,31.1-40.1,65.4-40.1c50.1,0,72.7,35.3,72.7,73.8v153.9h-50.6V156.3H725.4z'/%3E%3Cpath d='M801.3,77.8h36.4V6.6h50.1v71.2h53.2v39h-52.7V229c0,26.9,7.4,32.1,29,32.1h27.4v39h-50.1c-39,0-56.9-17.4-56.9-64.8V116.8h-36.4V77.8z'/%3E%3Cpath d='M1118.6,268.5c-12.1,19-30.6,36.4-66.9,36.4c-44.8,0-89.1-38.5-89.1-115.4C962.5,112,1006.3,73,1050,73c34.8,0,54.3,17.4,66.9,35.3V77.8h50.6v222.9h-49L1118.6,268.5L1118.6,268.5z M1067.4,112.5c-35.8,0-51.6,35.3-51.6,76.9c0,40.6,15.8,76.4,51.6,76.4c35.3,0,52.2-36.4,52.2-76.4C1119.6,147.3,1102.7,112.5,1067.4,112.5z'/%3E%3Cpath d='M1212.4,6.1h50.6v294.1h-50.6V6.1z'/%3E%3Cpath d='M1307.8,6.1h50.6v38.5h-50.6V6.1z M1307.8,77.8h50.6v222.9h-50.6V77.8z'/%3E%3Cpath d='M1466.4,116.8c-21.6,0-31.1,7.4-31.1,22.1c0,17.9,15.8,20.6,31.1,24.8l38.5,10.5c34.8,10,53.8,25.8,53.8,62.2c0,40.6-27.4,63.2-77.5,63.2h-86.4v-38.5h85.9c19.5,0,32.1-1.6,32.1-20.6c0-16.9-15.8-21.6-39-28.5l-32.7-10c-29-9-51.6-22.1-51.6-60.6c0-42.7,30.6-64.3,74.8-64.3h78.5l-3.7,39h-72.7V116.8z'/%3E%3Cpath d='M1562.8,77.8h36.4V6.6h50.1v71.2h53.2v39h-52.7V229c0,26.9,7.4,32.1,29,32.1h27.4v39h-50.1c-39,0-56.9-17.4-56.9-64.8V116.8h-36.4V77.8z'/%3E%3Cpath d='M1880.1,268.5c-12.1,19-30.6,36.4-66.9,36.4c-44.8,0-89.1-38.5-89.1-115.4c0-77.5,43.7-116.5,87.5-116.5c34.8,0,54.3,17.4,66.9,35.3V77.8h50.6v222.9h-49L1880.1,268.5L1880.1,268.5z M1829,112.5c-35.8,0-51.6,35.3-51.6,76.9c0,40.6,15.8,76.4,51.6,76.4c35.3,0,52.2-36.4,52.2-76.4C1881.2,147.3,1864.3,112.5,1829,112.5z'/%3E%3C/svg%3E") no-repeat center / contain;
}
/* contrast() pivots on 50% grey, so a value this large is a threshold rather
   than a boost: every pixel of the backdrop lands either side of mid and snaps
   to pure black or pure white. Without it a mid-tone section inverts to a
   mid-tone mark — technically the opposite, visually a grey smudge. */
.nav-logo-mark,
.nav-toggle span {
  -webkit-backdrop-filter: grayscale(1) invert(1) contrast(100);
  backdrop-filter: grayscale(1) invert(1) contrast(100);
}
/* Firefox before 103 has no backdrop-filter: the mark would be a hole with
   nothing in it. Paint it instead, on the .scrolled swap the bar used to use. */
@supports not (
  (backdrop-filter: invert(1)) or (-webkit-backdrop-filter: invert(1))
) {
  .nav-logo-mark,
  .nav-toggle span {
    background: var(--fg-inv);
    transition: background 0.4s var(--ease);
  }
  .nav.scrolled .nav-logo-mark,
  .nav.scrolled .nav-toggle span {
    background: var(--fg);
  }
}

.nav-toggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  width: 24px;
  height: 16px;
  position: relative;
}
.nav-toggle span {
  display: block;
  width: 100%;
  height: 1.5px;
  position: absolute;
  left: 0;
  transition: top 0.3s var(--ease), transform 0.3s var(--ease),
    opacity 0.3s var(--ease);
  border-radius: 1px;
}
.nav-toggle span:nth-child(1) {
  top: 0;
}
.nav-toggle span:nth-child(2) {
  top: 7px;
}
.nav-toggle span:nth-child(3) {
  top: 14px;
}
.nav-toggle.open span:nth-child(1) {
  top: 7px;
  transform: rotate(45deg);
}
.nav-toggle.open span:nth-child(2) {
  opacity: 0;
}
.nav-toggle.open span:nth-child(3) {
  top: 7px;
  transform: rotate(-45deg);
}

/* Mobile links dropdown (hidden by default) */
.nav-links {
  display: none;
}
.nav-links.open {
  display: flex;
  flex-direction: column;
  position: fixed;
  top: var(--nav-drop, 60px);
  left: 16px;
  right: 16px;
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: 16px 20px;
  gap: 12px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
  border: 1px solid var(--fg-10);
  pointer-events: auto;
}
.nav-links > a {
  text-decoration: none;
  color: var(--fg-60);
  font-size: 0.88rem;
  font-weight: 500;
}
.nav-links > a:hover {
  color: var(--fg);
}
/* The dropdown is a light card, so the bar's white-on-dark CTA inverts here —
   as it was, it painted a white pill on a white sheet. */
.nav-links .btn-nav {
  justify-content: center;
  background: var(--fg);
  color: var(--fg-inv) !important;
}

/* Locale picker — the bubble's job, inside the menu. Closed it is one line
   whatever the list grows to; open, the list scrolls rather than pushing the
   CTA off a short screen. */
.nav-links-lang {
  padding-top: 14px;
  border-top: 1px solid var(--fg-10);
}
.nav-links-lang summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border: 1px solid var(--fg-10);
  border-radius: var(--r-full);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--fg-60);
  cursor: pointer;
  list-style: none;
}
/* Safari draws its own triangle unless both of these are said. */
.nav-links-lang summary::-webkit-details-marker {
  display: none;
}
.nav-links-lang summary::marker {
  content: '';
}
.nav-links-lang summary:hover {
  color: var(--fg);
}
.nav-links-lang .nav-lang-caret {
  margin-left: auto;
  width: 11px;
  height: 11px;
  opacity: 0.7;
  transition: transform 0.2s var(--ease);
}
.nav-links-lang[open] .nav-lang-caret {
  transform: rotate(180deg);
}
.nav-links-lang-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* Ten-plus locales would run past the foot of the screen; cap and scroll. */
  max-height: 208px;
  overflow-y: auto;
  margin-top: 6px;
  padding: 2px;
  overscroll-behavior: contain;
}
.nav-links-lang-list a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 11px;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--fg-60);
  text-decoration: none;
}
.nav-links-lang-list a:hover {
  background: var(--surface-2);
  color: var(--fg);
}
.nav-links-lang-list a[aria-current='true'] {
  color: var(--fg);
}
.nav-links-lang-list a[aria-current='true'] .nav-lang-check {
  opacity: 1;
}
.nav-links-lang .nav-lang-flag {
  width: 17px;
  height: 17px;
}

/* =============================================
   HERO — Animated mesh gradient (Hume style)
   ============================================= */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--bg);
  overflow: hidden;
}
.hero-mesh {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}
.hero-fade-bottom {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 200px;
  z-index: 1;
  background: linear-gradient(transparent, var(--bg));
}
.hero-container {
  position: relative;
  z-index: 2;
  text-align: center;
  /* .logo-bar's margin-top:auto swallows the free space, which cancels the
     hero's justify-content. So the block centres itself here instead, and the
     asymmetric padding offsets the fixed nav — otherwise it reads as sitting
     high, centred on the section box rather than on what a reader can see. */
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 146px 24px 40px;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}

.hero-title {
  color: var(--fg-inv);
  margin-bottom: 24px;
}

.hero-sub {
  font-size: 1.12rem;
  line-height: 1.7;
  max-width: 560px;
  margin: 0 auto 36px;
  color: var(--fg-inv-60);
}

.hero-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: 40px;
}


/* Hero wave */
.hero-wave {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100px;
  z-index: 1;
  opacity: 0.35;
}

/* =============================================
   EXPLORE — Interactive Widgets
   ============================================= */
/* ── What EMOS reveals ── */
.reveal {
  padding: var(--section-y) 0;
  background: var(--bg-warm);
}
/* The reveal shot is a crop of the report's own cards, which arrive with their
   own borders and shadows — the frame .tour-shot puts round a browser view
   would box a box. */
.tour-shot.tour-shot--bare img {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* The verdict, in the page's own type rather than in the picture's pixels —
   the sentence the section promises, readable at any width. */
.reveal-shot figcaption.reveal-verdict {
  margin-top: 30px;
  /* The same size as .section-header p, which is the other run of prose in
     this section and its equal in rank. At 1.15rem it was the largest text on
     the page bar the headlines — larger than the hero's own sub-headline — and
     read as a size it had not earned. The emphasis is carried where it belongs
     instead: full ink against the lead's 60%, and the product name in bold. */
  font-size: 1.05rem;
  line-height: 1.55;
  color: var(--fg);
  text-align: center;
  max-width: 56ch;
  margin-left: auto;
  margin-right: auto;
}
.reveal-shot .reveal-verdict strong {
  font-weight: 700;
}
.reveal-shot figcaption {
  margin-top: 16px;
  font-size: 0.82rem;
  color: var(--fg-40);
  text-align: center;
  max-width: 62ch;
  margin-left: auto;
  margin-right: auto;
}
/* The "Also included" grid moved down into the reveal band, and the use cases
   up into the tour — so each takes the ground of the section it now sits on. */
.reveal-also {
  margin-top: 72px;
}
.reveal-also .label-mono {
  display: block;
  text-align: center;
  margin-bottom: 26px;
}
.reveal-also .tour-fact {
  background: var(--bg-warm);
}
.uses-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--fg-10);
  border: 1px solid var(--fg-10);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.use {
  padding: 26px 24px;
  background: var(--surface);
}
.use-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-bottom: 16px;
  border-radius: var(--r-sm);
  background: var(--accent-08);
  color: var(--accent);
}
.use-icon svg {
  width: 24px;
  height: 24px;
}
.use h3 {
  font-size: 1rem;
  margin-bottom: 7px;
}
.use p {
  font-size: 0.84rem;
  line-height: 1.6;
}


/* =============================================
   DEVELOPERS — Code Showcase
   ============================================= */
.developers {
  padding: var(--section-y) 0;
  background: var(--bg);
  color: var(--fg-inv);
  overflow: hidden;
}
.developers .label-mono {
  color: var(--mint);
}
.developers p {
  color: var(--fg-inv-60);
}

.dev-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 60px;
  align-items: center;
}
.dev-text h2 {
  color: var(--fg-inv);
  margin-bottom: 16px;
}
.dev-features {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 24px;
}
.dev-feature {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.88rem;
  color: var(--fg-inv-60);
}
.dev-feature svg {
  color: var(--mint);
  flex-shrink: 0;
}

.developers .btn-primary {
  background: var(--fg-inv);
  color: var(--bg);
}
/* Was an inline margin on the button itself. */
.dev-cta {
  margin-top: 24px;
}

/* Code window */
.code-window {
  background: var(--surface-dark);
  border: 1px solid var(--fg-inv-10);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.code-window-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--fg-inv-10);
}
.code-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--fg-inv-10);
}
.code-dot:nth-child(1) {
  background: #ff5f57;
}
.code-dot:nth-child(2) {
  background: #ffbd2e;
}
.code-dot:nth-child(3) {
  background: #28c840;
}

.code-tabs {
  display: flex;
  gap: 4px;
  margin-left: auto;
}
.code-tab {
  padding: 4px 12px;
  border-radius: var(--r-full);
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.72rem;
  font-weight: 500;
  background: transparent;
  color: var(--fg-inv-40);
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 0.2s;
}
.code-tab:hover {
  color: var(--fg-inv-60);
}
.code-tab.active {
  background: var(--fg-inv-10);
  color: var(--fg-inv);
  border-color: var(--fg-inv-20);
}

.code-block {
  padding: 20px 24px;
  margin: 0;
  overflow-x: auto;
  --scrollbar-thumb: var(--fg-inv-20);
  --scrollbar-thumb-hover: var(--fg-inv-40);
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.82rem;
  line-height: 1.7;
  color: var(--fg-inv-60);
  tab-size: 2;
}
.code-block[hidden] {
  display: none;
}
.ck {
  color: #c792ea;
} /* keywords */
.cf {
  color: #82aaff;
} /* functions */
.cs {
  color: #c3e88d;
} /* strings */
.cc {
  color: rgba(255, 255, 255, 0.25);
}


/* =============================================
   CTA
   ============================================= */
.cta {
  padding: var(--section-y) 0;
  background: var(--bg);
  position: relative;
  overflow: hidden;
}
.cta::before {
  content: "";
  position: absolute;
  width: 500px;
  height: 500px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse, rgba(28, 15, 194, 0.1), transparent 70%);
  pointer-events: none;
}
.cta-content {
  max-width: 580px;
  margin: 0 auto;
  text-align: center;
  position: relative;
}
.cta h2 {
  color: var(--fg-inv);
  margin-bottom: 14px;
}
.cta p {
  color: var(--fg-inv-40);
  margin-bottom: 40px;
  font-size: 1rem;
}

.cta-form {
  display: flex;
  flex-direction: column;
  gap: 10px;

  /* What a field already looks like, flattened: --fg-inv-10 over --bg. The
     autofill rules below paint with an inset shadow, and a shadow cannot be
     translucent without the browser's own colour showing through it, so the
     composite has to be spelled out. Recompute if --bg moves. */
  --autofill-bg: #24232a;
}
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.cta-form input,
.cta-form select,
.cta-form textarea {
  width: 100%;
  padding: 13px 16px;
  border: 1px solid var(--fg-inv-10);
  border-radius: var(--r-sm);
  background: var(--fg-inv-10);
  color: var(--fg-inv);
  font-family: inherit;
  font-size: 0.86rem;
  outline: none;
  transition: border-color 0.2s;
}
.cta-form input::placeholder,
.cta-form textarea::placeholder {
  color: var(--fg-inv-40);
}
.cta-form select {
  color: var(--fg-inv-40);
  padding-right: 38px;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath fill='rgba(255,255,255,0.3)' d='M6 8L0 0h12z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  cursor: pointer;
}
.cta-form select:has(option:checked:not([value=""])) {
  color: var(--fg-inv);
}
.cta-form select option {
  color: var(--fg);
  background: var(--surface);
}
.cta-form input:focus,
.cta-form select:focus,
.cta-form textarea:focus {
  border-color: var(--accent-light);
}

/* ── Autofill ────────────────────────────────────────────────────────────────
   A filled-in field wears the browser's own colours — Chrome's pale blue,
   Safari's, Firefox's yellow tint — with near-black text, which on this dark
   panel reads as a lit block in the middle of the form and, worse, as text on
   a background nobody chose. None of it answers to `background`: the UA sheet
   outranks anything an author writes there. So each engine is met on its own
   terms — WebKit/Blink paint over the colour with an inset shadow wide enough
   to cover the field and set the glyphs through -webkit-text-fill-color (the
   `color` property is likewise overridden), Firefox tints with a filter that
   only `filter: none` switches off.

   The select is left out on purpose: its arrow is a background-image, and an
   inset shadow paints over the background, so the rule would cost it its
   chevron. Nothing autofills it either — browsers fill a <select> only for
   fields they recognise (country, month, card type), never a list of study
   use cases. */
.cta-form input:-webkit-autofill,
.cta-form input:-webkit-autofill:hover,
.cta-form input:-webkit-autofill:focus,
.cta-form input:-webkit-autofill:active,
.cta-form textarea:-webkit-autofill,
.cta-form textarea:-webkit-autofill:hover,
.cta-form textarea:-webkit-autofill:focus,
.cta-form textarea:-webkit-autofill:active {
  -webkit-box-shadow: inset 0 0 0 100px var(--autofill-bg);
  box-shadow: inset 0 0 0 100px var(--autofill-bg);
  -webkit-text-fill-color: var(--fg-inv);
  caret-color: var(--fg-inv);
}

/* Firefox. Kept in its own rule rather than folded into the list above: a
   selector an engine does not know invalidates the whole rule it sits in, and
   :autofill and :-webkit-autofill are not understood by the same versions. */
.cta-form input:autofill,
.cta-form select:autofill,
.cta-form textarea:autofill {
  filter: none;
}

/* Safari puts a contacts button inside a fillable field and Chrome a
   credentials one, both drawn as a dark mask that vanishes against the field.
   They are recoloured through background-color, not fill. */
.cta-form input::-webkit-contacts-auto-fill-button,
.cta-form input::-webkit-credentials-auto-fill-button {
  background-color: var(--fg-inv-40);
}
.cta-form textarea {
  resize: vertical;
  min-height: 76px;
}
.cta-form .btn-primary {
  margin-top: 8px;
  align-self: center;
  background: var(--fg-inv);
  color: var(--bg);
}
.cta-form .btn-primary:hover {
  opacity: 0.88;
}

/* =============================================
   FOOTER (Hume-style: columns)
   ============================================= */
.footer {
  padding: 60px 0 40px;
  background: var(--bg-warm);
  border-top: 1px solid var(--fg-10);
}
.footer-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 60px;
  padding-bottom: 40px;
  border-bottom: 1px solid var(--fg-10);
}
/* The brand block is a column now — logo over a line of copy — so it needs a
   measure of its own, or the tagline runs the width the columns leave it. */
.footer-brand {
  max-width: 34ch;
}
.footer-logo {
  height: 16px;
  width: auto;
  color: var(--fg-40);
}
/* The company line. Long enough to need a reading measure rather than the
   short statement's larger type, and balanced so the last line is not a
   single word. */
.footer-tagline {
  margin-top: 18px;
  max-width: 42ch;
  font-size: 0.86rem;
  line-height: 1.55;
  text-wrap: pretty;
}
.footer-cols {
  display: grid;
  grid-template-columns: repeat(2, auto);
  gap: 40px 60px;
}
.footer-col {
  display: flex;
  flex-direction: column;
  align-items: start;
  gap: 8px;
}
/* An h3 in the outline — the footer follows the CTA's h2 with nothing between
   — wearing the page's small mono label, which is what a column heading in a
   footer wants to look like. */
.footer-col h3 {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--fg-40);
  font-family: "IBM Plex Mono", monospace;
  font-weight: 500;
  margin-bottom: 4px;
}
.footer-col a {
  font-size: 0.82rem;
  color: var(--fg-60);
  text-decoration: none;
  transition: color 0.2s;
}
.footer-col a:hover {
  color: var(--fg);
}
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
  padding-top: 24px;
}
.footer-bottom p {
  font-size: 0.75rem;
  color: var(--fg-40);
}
/* The sign-off's link: a shade darker than the line it sits in, so it reads as
   a link without shouting over the copyright opposite. */
.footer-bottom a {
  color: var(--fg-60);
  text-decoration: none;
  transition: color 0.2s;
}
.footer-bottom a:hover {
  color: var(--fg);
}

/* =============================================
   RESPONSIVE
   ============================================= */
@media (max-width: 1000px) {
  .dev-layout {
    grid-template-columns: 1fr;
    gap: 40px;
  }
}
@media (max-width: 768px) {
  .hero-container {
    /* The inline 24px is repeated, not inherited: this is the shorthand, so
       dropping it here left the sub-headline 7px from the screen edge at
       320px. Only the vertical values are meant to change. */
    padding: 130px 24px 80px;
  }
  .footer-top {
    flex-direction: column;
    gap: 32px;
  }
  .footer-brand {
    max-width: none;
  }
  .footer-cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 32px 40px;
  }
}
@media (max-width: 600px) {
  .form-row {
    grid-template-columns: 1fr;
  }
  .cta-form input,
  .cta-form select,
  .cta-form textarea {
    font-size: 16px;
  }
  .footer-cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 28px 24px;
  }
}


/* =============================================
   V2 — Deck sections
   ============================================= */

/* =============================================
   PLATFORM TOUR — how it works
   ============================================= */
.tour {
  padding: var(--section-y) 0;
  background: var(--surface);
  /* The section above is white too; a hairline keeps them apart. */
  border-top: 1px solid var(--fg-10);
}

/* Two a row, so four steps are one screenful rather than four. */
.tour-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px 32px;
  list-style: none;
}
.tour-item {
  min-width: 0;
}
/* An odd number of steps leaves the last one alone on its row. Centre it in
   the pair of columns rather than letting it hang off to the left, and keep it
   a column wide so every screenshot in the tour stays the same size. */
.tour-item:last-child:nth-child(odd) {
  grid-column: 1 / -1;
  width: calc(50% - 16px);
  margin-inline: auto;
}
.tour-step {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 22px 0 10px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}
.tour-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--fg-inv);
  font-size: 0.7rem;
  font-weight: 700;
}
.tour-item h3 {
  font-size: 1.25rem;
  margin-bottom: 10px;
}
.tour-item > p {
  font-size: 0.9rem;
}

/* Grid items default to min-width:auto, so the survey scale and the code
   block were each forcing their column wider than the phone viewport. */
.comp-col,
.dev-text,
.dev-code {
  min-width: 0;
}
/* The survey is an artefact, the same as the screen opposite it — so give it
   the same treatment: a white card, hairline and radius matching .comp-shot,
   filling its half of the visual row. Left as bare text on the panel it read as
   a caption next to a product shot rather than the other half of a comparison. */
.comp-survey {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  box-sizing: border-box;
  padding: 22px 20px;
  background: var(--surface);
  border: 1px solid var(--fg-10);
  border-radius: var(--r-sm);
}
.comp-survey-q {
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--fg);
}
/* One grid for the scale and its end labels: nine columns of at most 32px, the
   circles on row 1 and the labels on row 2 pinned to the first and last column.
   The labels are wider than a column and simply overhang it, which is what puts
   "Pleasant" under the 9 rather than out at the card's edge.

   This is a grid rather than two stacked flex rows because a flex item that can
   shrink contributes its *content* width to intrinsic sizing, so a fit-content
   wrapper collapsed to the width of the labels instead of the scale. Columns
   shrink on a narrow card, so the nine never wrap. */
.comp-survey-rating {
  display: grid;
  grid-template-columns: repeat(9, minmax(0, 32px));
  gap: 7px 6px;
  justify-content: start;
}
.comp-survey-scale,
.comp-survey-ends {
  display: contents;
}

/* The ends of the scale, as the phase editor defines them. */
.comp-survey-ends span {
  grid-row: 2;
  white-space: nowrap;
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-40);
}
.comp-survey-ends span:first-child {
  grid-column: 1;
  justify-self: start;
}
.comp-survey-ends span:last-child {
  grid-column: 9;
  justify-self: end;
}
.comp-survey-q--second {
  margin-top: 6px;
}
.comp-survey-words {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.comp-survey-words span {
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 0.78rem;
  color: var(--fg-60);
  background: var(--surface-2);
  border: 1px solid var(--fg-10);
}
.comp-survey-result {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: auto;            /* sits on the card's floor, like a form footer */
  padding-top: 14px;
  border-top: 1px solid var(--fg-10);
}
.comp-survey-label {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-40);
}
.comp-survey-val {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--fg);
}

/* The report widget shown inside the comparison card. */
.comp-shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-sm);
  border: 1px solid var(--fg-10);
}

/* A shot from the app: one 1000×625 browser view, framed only by a hairline
   and a soft shadow. No fake chrome — a drawn URL bar says nothing true. */
.tour-shot {
  display: block;
}
.tour-shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r);
  border: 1px solid var(--fg-10);
  box-shadow: 0 18px 50px rgba(26, 26, 30, 0.1);
}

/* ── What else the platform ships with ── */
/* The hairline grid reads better here than a filled band did. */
.tour-extra {
  margin-top: 80px;
}
.tour-extra .label-mono {
  display: block;
  margin-bottom: 16px;
}
.tour-facts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--fg-10);
  border: 1px solid var(--fg-10);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.tour-fact {
  padding: 28px 24px;
  background: var(--surface);
}
.tour-fact-num {
  display: block;
  font-family: "IBM Plex Mono", monospace;
  font-size: 1.7rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--accent);
  margin-bottom: 10px;
}
/* Same reset .open-stage h4 uses: h4 is this page's mono accent label, and in
   a fact cell the icon or the numeral already carries that job. The title then
   reads like the one in .use — sentence case, body face, black. */
.tour-fact h4 {
  color: var(--fg);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 600;
  text-transform: none;
  letter-spacing: -0.01em;
  margin-bottom: 7px;
}
.tour-fact p {
  font-size: 0.84rem;
  line-height: 1.6;
}

/* An icon takes the numeral's place in a cell, so both groups share a shape.
   The icons are the study wizard's own (fragments icons.js). */
.tour-fact-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-bottom: 14px;
  border-radius: var(--r-sm);
  background: var(--accent-08);
  color: var(--accent);
}
.tour-fact-icon svg {
  width: 21px;
  height: 21px;
}

/* The second group's label needs air above it; the first sits under the
   section's own heading. */
.tour-extra__second {
  margin-top: 40px;
}

.tour-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 44px;
}
.tour-cta p {
  margin-right: 8px;
  font-size: 0.95rem;
  color: var(--fg);
}
/* The chip is a toolbar size elsewhere; here it stands next to a full button. */
.tour-cta .btn-chip {
  padding: 13px 26px;
  font-size: 0.88rem;
}

/* ── Headset (deck p5) ── */
.headset {
  padding: var(--section-y) 0;
  background: var(--bg);
  color: var(--fg-inv);
}

/* Hero — the one-pager's gradient band: copy on the deep blue end, the
   render on the pale end. */
.clip-hero {
  display: grid;
  grid-template-columns: 1fr 0.95fr;
  gap: 32px;
  align-items: center;
  position: relative;
  padding: 56px 56px 56px 60px;
  margin-bottom: 64px;
  border-radius: var(--r-xl);
  background: linear-gradient(
    103deg,
    var(--accent-dark) 0%,
    var(--accent) 34%,
    #8079db 64%,
    #d9d5f3 100%
  );
}
.clip-hero-text .label-mono {
  color: var(--fg-inv-60);
}
.clip-hero-text h3 {
  font-size: clamp(1.9rem, 3.4vw, 2.9rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--fg-inv);
  margin-bottom: 16px;
}
.clip-hero-text > p {
  color: var(--fg-inv-60);
  font-size: 0.95rem;
  max-width: 42ch;
}
.clip-hero-shot {
  display: block;
}
.clip-shot {
  display: block;
  width: 100%;
  height: auto;
  /* The render is cut out and carries its own shadow, so it floats straight
     on the gradient with nothing added. */
}

/* Specs — mirrors the Mental Clip one-pager: three headline figures, two
   spec tables, and the two "industry first" callouts beside them. */
.clip-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 48px;
  margin-top: 36px;
}
.clip-stat-num {
  display: block;
  font-size: 2.1rem;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--fg-inv);
  line-height: 1;
}
.clip-stat-label {
  display: block;
  margin-top: 8px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-inv-40);
}

.clip-grid {
  display: grid;
  grid-template-columns: 1.1fr 1fr 1fr;
  gap: 40px;
  margin-bottom: 32px;
}
.clip-table h4 {
  color: var(--fg-inv-40);
  font-size: 0.7rem;
  padding-bottom: 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--fg-inv-20);
}
/* Each spec is a ruled row: the term reads first, the gloss trails it. */
.clip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 11px 0;
  border-bottom: 1px solid var(--fg-inv-10);
}
.clip-row dt {
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--fg-inv);
}
.clip-row dd {
  font-size: 0.8rem;
  color: var(--fg-inv-40);
}

/* Tooltip — a ? button that opens on hover, on keyboard focus and on a tap.
   Hover alone would hide the note from phones and keyboards entirely. */
.tip {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
  flex-shrink: 0;
}
.tip__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border-radius: 50%;
  font: inherit;
  font-size: 0.66rem;
  font-weight: 600;
  line-height: 1;
  cursor: help;
  color: var(--fg-40);
  background: var(--surface);
  border: 1px solid var(--fg-10);
  transition: all 0.15s var(--ease);
}
.tip__btn:hover,
.tip:focus-within .tip__btn {
  color: var(--accent);
  border-color: var(--accent-30);
}
.tip__bubble {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 9px);
  transform: translate(-50%, 4px);
  width: max-content;
  max-width: min(260px, calc(100vw - 48px));
  padding: 10px 13px;
  border-radius: var(--r-sm);
  background: rgba(12, 11, 18, 0.95);
  color: var(--fg-inv-60);
  font-size: 0.76rem;
  font-weight: 400;
  line-height: 1.5;
  text-align: left;
  box-shadow: 0 10px 30px rgba(12, 11, 18, 0.3);
  /* Purely informational, so it must never swallow a click meant for whatever
     it floats over — an open bubble otherwise blocks the row above it. */
  pointer-events: none;
  /* Hidden but still announced: visibility keeps it off the pointer and out
     of the tab order, opacity carries the fade. */
  opacity: 0;
  visibility: hidden;
  z-index: 5;
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
}
.tip:hover .tip__bubble,
.tip:focus-within .tip__bubble {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}

/* In a pricing row the button sits near the right edge, so a centred bubble
   would hang off the card. Anchor it to the right and let it open leftwards. */
.cfg-opt .tip__bubble {
  left: auto;
  right: -6px;
  transform: translate(0, 4px);
}
.cfg-opt .tip:hover .tip__bubble,
.cfg-opt .tip:focus-within .tip__bubble {
  transform: translate(0, 0);
}

/* The hero's marker: the same tooltip, parked in the corner of the gradient.
   It sits on the pale end, so the glyph is ink rather than white. */
.clip-note {
  position: absolute;
  right: 18px;
  bottom: 16px;
  z-index: 2;
}
.clip-note .tip__btn {
  width: 26px;
  height: 26px;
  font-size: 0.78rem;
  color: rgba(12, 11, 18, 0.5);
  background: rgba(255, 255, 255, 0.45);
  border-color: rgba(12, 11, 18, 0.14);
}
.clip-note .tip__btn:hover,
.clip-note .tip:focus-within .tip__btn {
  color: var(--fg);
  background: rgba(255, 255, 255, 0.85);
  border-color: rgba(12, 11, 18, 0.22);
}
.clip-note .tip__bubble {
  left: auto;
  right: 0;
  transform: translate(0, 4px);
  max-width: min(300px, calc(100vw - 64px));
}
.clip-note .tip:hover .tip__bubble,
.clip-note .tip:focus-within .tip__bubble {
  transform: translate(0, 0);
}

/* ── Case Studies (compact) ── */
/* ── Models — the three behind every study ── */
.models {
  padding: var(--section-y) 0;
  background: var(--surface);
}
.models-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.model-card {
  padding: 32px 26px;
  border-radius: var(--r-lg);
  background: var(--bg-warm);
  border: 1px solid var(--fg-10);
  transition: all 0.3s var(--ease);
}
.model-card:hover {
  border-color: var(--accent-15);
  box-shadow: 0 4px 20px rgba(28, 15, 194, 0.05);
  transform: translateY(-2px);
}
/* The figure that replaced the card's icon. A fixed height is what keeps the
   three headings on one line across the row — the panels differ in shape, and
   without it each card would start its copy at its own altitude. */
.model-viz {
  margin: 0 0 18px;
  height: 190px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.model-viz:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 6px;
  border-radius: 6px;
}
/* The plot draws itself at the pixel size it is given (interactive.js sets the
   viewBox from the measured box), so nothing in it is ever scaled out of
   round — a circumplex that stretches is a circumplex that lies. */
.viz-plot {
  flex: 1;
  min-height: 0;
}
.viz-plot svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.viz-readout {
  font-size: 0.72rem;
  color: var(--fg-60);
  font-variant-numeric: tabular-nums;
  min-height: 1.1em;
}
.viz-readout b {
  color: var(--fg);
  font-weight: 600;
}
.viz-hint {
  margin: 0;
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-40);
  opacity: 0;
  transition: opacity 0.25s var(--ease);
}
/* The hint is a nudge for someone who has not realised the panel answers back,
   so it shows on approach and gets out of the way once they have. */
.model-card:hover .viz-hint,
.model-viz:focus-visible .viz-hint {
  opacity: 1;
}
.model-viz[data-used='1'] .viz-hint {
  opacity: 0;
}
.model-card h3 {
  font-size: 1.05rem;
  margin-bottom: 6px;
}
/* The question the model answers, carrying the weight a subtitle would — it is
   what makes the name mean something to someone who has never met the term. */
.model-q {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent);
  margin-bottom: 12px;
}
.model-desc {
  font-size: 0.84rem;
  line-height: 1.65;
  margin: 0;
}
/* ── No black box — the stages behind the three panels ──
   Ruled columns rather than a fourth card grid: the models above and the
   compliance section below are both cards, and a third set in between would
   read as more of the same instead of as the ground they stand on. */
.models-open {
  margin-top: 56px;
  padding-top: 44px;
  border-top: 1px solid var(--fg-10);
}
.open-head {
  max-width: 620px;
  margin-bottom: 36px;
}
.open-head h3 {
  font-size: 1.6rem;
  line-height: 1.2;
  margin-bottom: 10px;
}
.open-head p {
  font-size: 0.92rem;
  line-height: 1.7;
  color: var(--fg-60);
}
.open-chain {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 28px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.open-stage {
  padding-top: 14px;
  border-top: 1px solid var(--fg-10);
}
.open-num {
  display: block;
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  color: var(--accent);
  margin-bottom: 8px;
}
/* Same reset .tour-fact uses: h4 is this page's mono accent label, and the
   stage number above already carries that job. */
.open-stage h4 {
  color: var(--fg);
  font-family: inherit;
  font-size: 0.95rem;
  text-transform: none;
  letter-spacing: -0.01em;
  margin-bottom: 6px;
}
.open-stage p {
  font-size: 0.82rem;
  line-height: 1.65;
  color: var(--fg-60);
  margin: 0;
}

.models-note {
  margin-top: 28px;
  text-align: center;
  font-size: 0.84rem;
  color: var(--fg-60);
}
/* A secondary link inside a secondary line: at rest the accent alone carries
   it, and the underline arrives on hover. Offset clear of the descenders in
   "see pricing", which a border-bottom would rule straight through, and it
   wraps with the text instead of boxing it. */
.models-note a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-color 0.2s var(--ease);
}
.models-note a:hover {
  text-decoration-color: var(--accent);
}

.cases { padding: var(--section-y) 0; background: var(--bg-warm); }

.cases-compact {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;
}
.case-compact {
    border-radius: var(--r-lg); overflow: hidden;
    background: var(--surface); border: 1px solid var(--fg-10);
    display: flex; flex-direction: column;
    transition: all 0.3s var(--ease);
}
.case-compact:hover { border-color: var(--accent-15); box-shadow: 0 4px 20px rgba(28,15,194,0.05); transform: translateY(-2px); }

.case-compact-img { overflow: hidden; }
.placeholder-media--case-sm {
    min-height: 180px; border-radius: 0;
    background: var(--surface-2); border: none;
}

.case-compact-body { padding: 20px 22px 24px; display: flex; flex-direction: column; flex: 1; }
.case-compact-top { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.case-compact-brand { font-size: 0.95rem; font-weight: 700; color: var(--fg); letter-spacing: -0.01em; }
.case-compact-tag {
    font-family: 'IBM Plex Mono', monospace;
    font-size: 0.6rem; font-weight: 500; text-transform: uppercase;
    letter-spacing: 0.06em; color: var(--accent);
    background: var(--accent-08); padding: 2px 8px; border-radius: var(--r-full);
}
.case-compact-desc { font-size: 0.84rem; line-height: 1.6; margin: 0; }
.case-compact-desc strong { color: var(--fg); }

/* ── Pricing — the configurator ── */
.pricing {
  padding: var(--section-y) 0;
  background: var(--surface);
}
.cfg {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: 24px;
  align-items: start;
}
.cfg-main {
  border: 1px solid var(--fg-10);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.cfg-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 24px;
  padding: 22px 24px;
  border-bottom: 1px solid var(--fg-10);
}
.cfg-row:last-child {
  border-bottom: none;
}
.cfg-row--stack {
  align-items: flex-start;
}
.cfg-row-text {
  flex: 1;
  min-width: 190px;
}
.cfg-row-text h3 {
  font-size: 1rem;
  margin-bottom: 4px;
}
.cfg-row-text p {
  font-size: 0.82rem;
}

/* Quantity stepper */
.cfg-qty {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--fg-10);
  border-radius: var(--r-full);
  background: var(--bg-warm);
}
.cfg-step {
  width: 30px;
  height: 30px;
  border: none;
  border-radius: 50%;
  background: var(--surface);
  color: var(--fg-60);
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  transition: all 0.15s var(--ease);
}
.cfg-step:hover {
  background: var(--accent);
  color: var(--fg-inv);
}
.cfg-qty-input {
  width: 52px;
  border: none;
  background: none;
  text-align: center;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--fg);
  -moz-appearance: textfield;
  appearance: textfield;
}
.cfg-qty-input::-webkit-outer-spin-button,
.cfg-qty-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.cfg-unit {
  text-align: right;
  min-width: 96px;
  /* The price is the right-hand column of every row in the configurator, and
     .cfg-row-text's flex:1 is what puts it there — until the row wraps under
     ~430px and the text takes a line of its own. The stepper and the price
     then share a line with the slack trailing behind them, leaving the price
     floating 33px inside an edge it is supposed to sit on. auto absorbs that
     slack ahead of the price instead, and does nothing at any width where
     flex:1 already had. */
  margin-left: auto;
}
.cfg-unit b {
  display: block;
  font-size: 1rem;
  font-weight: 600;
  color: var(--fg);
}
.cfg-unit span {
  font-size: 0.72rem;
  color: var(--fg-40);
}

/* Billing term — two selectable cards */
.cfg-terms {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  flex: 1.2;
  min-width: 260px;
}
.cfg-term {
  cursor: pointer;
}
.cfg-term input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.cfg-term-body {
  display: block;
  padding: 12px 14px;
  border: 1px solid var(--fg-10);
  border-radius: var(--r-sm);
  background: var(--bg-warm);
  transition: all 0.15s var(--ease);
}
.cfg-term-body b {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--fg);
}
.cfg-term-body span {
  font-size: 0.72rem;
  color: var(--fg-40);
  /* "195 €" and "/device/month" are adjacent with no whitespace between them,
     so the price line was a single 155px atom with nowhere to break: in the
     two bands where these tracks are narrowest — 601-720px, and again at
     1001-1150px where the configurator returns to two columns and this row
     narrows with it — the line simply ran out through the card's right edge.
     An inline-block is a box the line can be broken before, which drops the
     card's min-content from 155px to 113px and lets the unit fall to its own
     line. Nothing changes where there is room: max-content is still 155px, so
     every width that set the line on one line still does. */
  display: inline-block;
}
.cfg-term-body em {
  display: block;
  margin-top: 4px;
  font-style: normal;
  font-size: 0.75rem;
  color: var(--fg-60);
}
.cfg-term input:checked + .cfg-term-body {
  border-color: var(--accent);
  background: var(--accent-08);
  box-shadow: 0 0 0 3px var(--accent-08);
}
.cfg-term input:focus-visible + .cfg-term-body {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Add-ons and services */
.cfg-opts {
  display: grid;
  gap: 6px;
  flex: 1.2;
  min-width: 260px;
}
.cfg-opts--quote {
  grid-template-columns: 1fr;
}
.cfg-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--fg-10);
  border-radius: var(--r-sm);
  background: var(--bg-warm);
  cursor: pointer;
  transition: all 0.15s var(--ease);
}
.cfg-opt:hover {
  border-color: var(--accent-15);
}
.cfg-opt input {
  width: 15px;
  height: 15px;
  accent-color: var(--accent);
  cursor: pointer;
  flex-shrink: 0;
}
.cfg-opt-main {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  cursor: pointer;
}
.cfg-opt-name {
  flex: 1;
  font-size: 0.86rem;
  color: var(--fg);
}
.cfg-opt-price {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--fg-40);
}
.cfg-opt:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-08);
}
.cfg-opt:has(input:checked) .cfg-opt-price {
  color: var(--accent);
}

/* Running total */
.cfg-sum {
  position: sticky;
  top: 104px;
  padding: 24px;
  border-radius: var(--r-lg);
  background: var(--bg);
  color: var(--fg-inv);
}
.cfg-sum-title {
  font-size: 0.7rem;
  font-family: "IBM Plex Mono", monospace;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-inv-40);
  margin-bottom: 18px;
}
.cfg-lines {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--fg-inv-10);
}
.cfg-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.86rem;
}
/* An author `display` beats the UA's [hidden] rule, so the attribute alone
   would never hide this row. */
.cfg-line[hidden] {
  display: none;
}
.cfg-line dt {
  color: var(--fg-inv-60);
}
.cfg-line dt em {
  font-style: normal;
  color: var(--fg-inv-40);
  font-size: 0.78rem;
}
.cfg-line dd {
  color: var(--fg-inv);
  white-space: nowrap;
}
.cfg-total {
  margin-top: 18px;
}
.cfg-total-label {
  display: block;
  font-size: 0.78rem;
  color: var(--fg-inv-60);
  margin-bottom: 2px;
}
.cfg-total-value {
  display: block;
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--fg-inv);
  white-space: nowrap;
}
.cfg-total--first .cfg-total-value {
  font-size: 1.05rem;
  color: var(--fg-inv-60);
}
.cfg-note {
  margin-top: 18px;
  font-size: 0.74rem;
  line-height: 1.55;
  color: var(--fg-inv-40);
}
.cfg-cta {
  width: 100%;
  margin-top: 16px;
  background: var(--fg-inv);
  color: var(--bg);
}

/* ── Sliding Logo Bar (inside hero) ── */
.logo-bar {
  position: relative;
  z-index: 2;
  padding: 0 0 24px;
  width: 100%;
  margin-top: auto;
}
.logo-bar-title {
  text-align: center;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--fg-inv-20) !important;
  letter-spacing: 0.04em;
  margin-bottom: 16px;
}

.logo-track {
  width: 100%;
  overflow: hidden;
  mask-image: linear-gradient(
    90deg,
    transparent,
    black 10%,
    black 90%,
    transparent
  );
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    black 10%,
    black 90%,
    transparent
  );
}

.logo-slide {
  display: flex;
  gap: 10px;
  width: max-content;
  animation: logoScroll 40s linear infinite;
}

.logo-slide span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 16px;
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--fg-inv-20);
  white-space: nowrap;
  flex-shrink: 0;
  transition:
    color 0.2s,
    border-color 0.2s,
    background 0.2s;
}
.logo-slide span:hover {
  color: var(--fg-inv-60);
  border-color: rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.08);
}

@keyframes logoScroll {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}

.logo-track:hover .logo-slide {
  animation-play-state: paused;
}

/* ── Headset section ── */
.headset .section-header .label-mono {
  color: var(--accent-on-dark);
}
.headset .section-header h2 {
  color: var(--fg-inv);
}
.headset .section-header p {
  color: var(--fg-inv-60);
}

/* The form-factor range, as the grid's third column. */
.clip-fit {
  padding-top: 11px;
  font-size: 0.88rem;
  line-height: 1.7;
  color: var(--fg-inv-60);
}

/* ── Before/After Comparison ── */
.comparison {
  padding: var(--section-y) 0;
  background: var(--surface);
}
.comparison-cards {
  display: grid;
  /* Two panels either side of the arrow. The rows are declared here — a tag, a
     visual, then one row per facing pair — and each panel adopts them with
     `subgrid`, so the two sides stay locked to the same lines however long
     either one's text runs. Without subgrid the panels simply flow, which is
     the old look rather than a broken one. */
  grid-template-columns: 1fr auto 1fr;
  grid-template-rows: auto auto repeat(4, auto);
  align-items: stretch;
  gap: 0;
}
.comp-col {
  grid-row: 1 / -1;
  display: grid;
  grid-template-rows: subgrid;
  align-content: stretch;
  border-radius: var(--r-lg);
  overflow: hidden;
}
.comp-col--before {
  background: var(--bg-warm);
  border: 1px solid var(--fg-10);
}
.comp-col--after {
  background: var(--accent);
  color: var(--fg-inv);
  border: 1px solid var(--accent);
}
.comp-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  grid-row: 1 / -1;
  align-self: center;
  padding: 0 18px;
  color: var(--fg-40);
}

.comp-card-tag {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 24px 26px 0;
}
.comp-col--before .comp-card-tag {
  color: var(--fg-40);
}
.comp-col--after .comp-card-tag {
  color: var(--fg-inv-60);
}

/* The two visuals share a row, so they are the same height whatever they hold.
   A survey yields one number and a screen of analysis does not — centring the
   small one states that rather than padding it out. */
.comp-card-visual {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 20px 26px 24px;
  min-width: 0;
}

/* Facing pairs. One row each, so the limitation and the answer to it line up. */
.comp-point {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 11px 26px;
  font-size: 0.82rem;
  line-height: 1.45;
  border-top: 1px solid var(--fg-10);
}
.comp-col--after .comp-point {
  border-top-color: var(--fg-inv-10);
}
.comp-point:last-child {
  padding-bottom: 22px;
}
.comp-point-icon {
  display: inline-flex;
  flex-shrink: 0;
  margin-top: 1px;
}
.comp-point--limit {
  color: var(--fg-60);
}
.comp-point--limit .comp-point-icon {
  color: var(--red);
}
.comp-point--benefit {
  color: var(--fg-inv-60);
}
.comp-point--benefit .comp-point-icon {
  color: var(--mint);
}

/* Survey visual */
/* The circles themselves; the grid above places them. The span centres its
   digit with flex, so line-height only sets a floor on the height — leave it at
   1 or the circles go oval once the columns shrink below it. */
.comp-survey-scale span {
  aspect-ratio: 1;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  font-size: min(0.78rem, 2.6vw);
  font-weight: 600;
  color: var(--fg-40);
  /* Not --surface: that is the card these now sit on. */
  background: var(--surface-2);
  border: 1px solid var(--fg-10);
}
.comp-survey-selected {
  background: var(--fg) !important;
  color: var(--fg-inv) !important;
  border-color: var(--fg) !important;
}

/* EMOS timeline visual */


/* ── Compliance ── */
.compliance {
  padding: var(--section-y) 0;
  background: var(--bg-warm);
}
.compliance-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.compliance-card {
  padding: 28px 24px;
  border-radius: var(--r-lg);
  background: var(--surface);
  border: 1px solid var(--fg-10);
  transition: all 0.3s var(--ease);
}
.compliance-card:hover {
  border-color: var(--accent-15);
  box-shadow: 0 4px 20px rgba(28, 15, 194, 0.05);
}
.compliance-icon {
  width: 40px;
  height: 40px;
  margin-bottom: 14px;
  color: var(--accent);
}
.compliance-icon svg {
  width: 100%;
  height: 100%;
}
.compliance-card h3 {
  font-size: 1rem;
  margin-bottom: 8px;
}
.compliance-card p {
  font-size: 0.84rem;
  line-height: 1.65;
}

/* ── FAQ ── */
.faq {
  padding: var(--section-y) 0;
  background: var(--surface);
}
.faq-layout {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 60px;
  align-items: start;
}
.faq-header h2 {
  position: sticky;
  top: 100px;
}
.faq-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.faq-item {
  border-bottom: 1px solid var(--fg-10);
}
.faq-item summary {
  padding: 18px 0;
  cursor: pointer;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--fg);
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: color 0.2s;
}
.faq-item summary::-webkit-details-marker {
  display: none;
}
.faq-item summary::after {
  content: "+";
  font-size: 1.2rem;
  font-weight: 400;
  color: var(--fg-40);
  transition: transform 0.2s;
}
.faq-item[open] summary::after {
  content: "−";
}
.faq-item summary:hover {
  color: var(--accent);
}
.faq-item p {
  padding: 0 0 18px;
  font-size: 0.86rem;
  line-height: 1.7;
}

/* ── Resources ── */
.resources {
  padding: 100px 0;
  background: var(--bg-warm);
}
.resources-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.resource-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 28px 24px;
  border-radius: var(--r-lg);
  background: var(--surface);
  border: 1px solid var(--fg-10);
  text-decoration: none;
  transition: all 0.3s var(--ease);
}
.resource-card:hover {
  border-color: var(--accent-15);
  box-shadow: 0 4px 20px rgba(28, 15, 194, 0.05);
  transform: translateY(-2px);
}
.resource-type {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  background: var(--accent-08);
  padding: 3px 10px;
  border-radius: var(--r-full);
  align-self: flex-start;
}
.resource-card h3 {
  font-size: 1rem;
  color: var(--fg);
}
.resource-card p {
  font-size: 0.82rem;
  color: var(--fg-60);
  flex: 1;
}
.resource-link {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent);
}

/* ── Nav hide/show on scroll ── */
.nav.nav-hidden .nav-island {
  transform: translateY(-80px);
  opacity: 0;
  pointer-events: none;
}
.nav-island {
  transition: all 0.4s var(--ease);
}

/* ── V2 Responsive ── */
@media (max-width: 1000px) {
  .nav-island {
    display: none;
  }
  /* The bar has no plate under it any more, and 16px of gap read as stuck to
     the edge of the screen. Both the fade band and the dropdown hang off where
     the bar lands, so the offset is a token rather than three numbers to keep
     in step. The scrolled state still tightens, just not to the desktop 10px. */
  :root {
    --nav-top: 26px;
    --nav-top-scrolled: 18px;
    --nav-drop: 72px;
  }
  .nav {
    padding: var(--nav-top) 24px;
  }
  .nav.scrolled {
    padding: var(--nav-top-scrolled) 24px;
  }
  .nav-lang {
    display: none;
  }
  .nav-mobile {
    display: flex;
  }
  /* Text scrolling under the mark used to tangle with it: the mark reads its
     own backdrop per pixel, and a heading crossing the wordmark is part of
     that backdrop. Blur is the one operation that drops the glyph detail while
     keeping the tone, so this band smears whatever passes beneath into a
     smooth wash and the mark above thresholds to a single flat colour.

     Blurring the mark itself does not work: the strokes are ~2px, so a
     backdrop blur over them samples mostly outside the mask and washes the
     wordmark to a transparent grey. The blur has to sit under it, not on it.

     No colour, no border, no radius — it is masked to fade out downward, so
     there is no edge anywhere for it to read as a plate. It hangs off .nav
     rather than .nav-mobile because .nav-hidden puts a transform on the bar,
     and a transformed ancestor would re-anchor a fixed child mid-fade. */
  .nav::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 86px;
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    -webkit-mask: linear-gradient(to bottom, #000 58%, transparent);
    mask: linear-gradient(to bottom, #000 58%, transparent);
    pointer-events: none;
    transition: opacity 0.4s var(--ease);
  }
  .nav.nav-hidden::before {
    opacity: 0;
  }
  .nav-toggle {
    display: block;
  }
  .cfg {
    grid-template-columns: 1fr;
  }
  .cfg-sum {
    position: static;
  }
  .tour-grid {
    grid-template-columns: 1fr;
    gap: 48px;
  }
  /* One column: nothing is orphaned, so the centring above has to go. */
  .tour-item:last-child:nth-child(odd) {
    width: auto;
  }
  .tour-facts,
  .uses-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .clip-hero {
    grid-template-columns: 1fr;
    gap: 8px;
    padding: 40px;
  }
  .clip-hero-text > p {
    max-width: none;
  }
  .clip-grid {
    grid-template-columns: 1fr 1fr;
  }
  .cases-compact {
    grid-template-columns: 1fr;
  }
  .compliance-grid,
  .models-grid,
  .open-chain {
    grid-template-columns: repeat(2, 1fr);
  }
  /* Stacked: each panel keeps its own rows, so drop the shared row track and
     the subgrid with it — there is nothing left to face across. */
  .comparison-cards {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    gap: 20px;
  }
  .comp-col {
    grid-row: auto;
    grid-template-rows: none;
  }
  .comp-arrow {
    grid-row: auto;
    transform: rotate(90deg);
    padding: 12px 0;
  }
  .faq-layout {
    grid-template-columns: 1fr;
    gap: 24px;
  }
  .faq-header h2 {
    position: static;
  }
  .resources-grid {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 600px) {
  .cfg-terms {
    grid-template-columns: 1fr;
  }
  .tour-facts,
  .uses-grid {
    grid-template-columns: 1fr;
  }
  .compliance-grid,
  .models-grid,
  .open-chain {
    grid-template-columns: 1fr;
  }
  .clip-hero {
    padding: 28px 24px;
  }
  .clip-grid {
    grid-template-columns: 1fr;
    gap: 28px;
  }
  .clip-stats {
    gap: 32px;
  }
  .nav-links {
    display: none;
    position: fixed;
    top: var(--nav-drop, 60px);
    left: 16px;
    right: 16px;
    background: var(--surface);
    border-radius: var(--r-lg);
    flex-direction: column;
    padding: 16px 20px;
    gap: 12px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
    border: 1px solid var(--fg-10);
    pointer-events: auto;
  }
  .nav-links.open {
    display: flex;
  }
  .nav-links > a {
    color: var(--fg-60) !important;
    font-size: 0.88rem;
  }
}

/* ── Phones — rhythm and type floors ───────────────────────────────────────
   Everything above this point is written for a desktop column and then has its
   grids collapsed for narrow screens. Two things never collapsed with them.

   The rhythm: a dozen sections carry the same band above and below, and 120px
   of it on either side of a 375px screen is 240px of nothing between one idea
   and the next — it stood the page at 21,010px, some twenty-six screenfuls.
   The token is the only thing that has to move.

   The type: the mono eyebrow labels, the table heads and the configurator's
   asides are all set in the 0.6–0.78rem range, which reads as considered at a
   desk and as fine print on a phone — 11.2px at 0.1em of tracking for the very
   labels that open each section. These lift the smallest of them to ~12–13px
   and leave every wider screen exactly as it was.

   Deliberately NOT lifted: .comp-survey-* and .tour-num. The survey card is a
   picture of a questionnaire rather than copy to read, and the step number is
   a glyph fitted to its 22px disc — both would distort rather than clarify. */
@media (max-width: 600px) {
  :root {
    --section-y: 72px;
  }
  .section-header {
    margin-bottom: 40px;
  }
  .reveal-also {
    margin-top: 48px;
  }
  .hero-container {
    padding: 112px 24px 56px;
  }

  /* Eyebrows and headings */
  .label-mono {
    font-size: 0.76rem;
  }
  h4 {
    font-size: 0.8rem;
  }
  h5,
  .tour-step,
  .footer-col h3,
  .code-tab {
    font-size: 0.78rem;
  }
  .open-num,
  .comp-card-tag {
    font-size: 0.74rem;
  }

  /* Captions and asides */
  .viz-readout {
    font-size: 0.78rem;
  }
  .viz-hint {
    font-size: 0.7rem;
  }
  .footer-bottom p {
    font-size: 0.8rem;
  }
  .clip-stat-label,
  .clip-table h4 {
    font-size: 0.76rem;
  }

  /* Configurator — the prices carry the page's one real decision, so its
     small print is the last place to save a pixel. */
  .cfg-sum-title {
    font-size: 0.76rem;
  }
  .cfg-unit span,
  .cfg-term-body span {
    font-size: 0.78rem;
  }
  .cfg-note,
  .cfg-term-body em {
    font-size: 0.8rem;
  }
  .cfg-line dt em,
  .cfg-total-label {
    font-size: 0.82rem;
  }

  /* A pricing row is barely wider than the 260px bubble here, so there is no
     longer room to open beside the button: the Emotion row's ? sits further in
     than its neighbours', which hung its bubble 20px off the left edge at
     320px. Anchor to the row rather than to the button and let the bubble take
     the full width of it — then there is no direction left to hang off. */
  .cfg-opt {
    position: relative;
  }
  .cfg-opt .tip {
    position: static;
  }
  .cfg-opt .tip__bubble {
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    transform: translateY(4px);
  }
  .cfg-opt .tip:hover .tip__bubble,
  .cfg-opt .tip:focus-within .tip__bubble {
    transform: translateY(0);
  }

  /* The tooltip opens on a tap here — an 18px disc is under any thumb-sized
     target, so it grows with its glyph. */
  .tip__btn {
    width: 24px;
    height: 24px;
    font-size: 0.78rem;
  }
  .tip__bubble {
    font-size: 0.8rem;
  }
}

/* ── Motion, opted out of ──────────────────────────────────────────────────
   Three things on this page move without being asked to: .fade-in holds 54
   elements at opacity 0 until an observer reveals them, the client logo strip
   scrolls forever, and anchor jumps animate. The infinite marquee is the one
   that actually makes some people ill, so this is not cosmetic.

   The .fade-in rule earns its place twice over: opacity 0 with no fallback
   means any client that never runs the observer sees a blank page. That case
   is covered by the <noscript> block in index.php — this one covers the
   visitor whose JavaScript works fine and who has simply asked for less. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .fade-in {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .logo-slide {
    animation: none;
  }
}
