:root {
  --brand-1: #f1a006;
  --brand-2: #8269eb;
  --brand-3: #10b981;
  --ink: #1b2844;
  --ink-darker: #131d30;
  --ink-darkerer: #0e1625;
  --ink-darkererer:rgb(14, 23, 39);
  --ink-darkest: #070c15;
  --on-brand: #1b2844;
  --on-brand-muted: #1b2844de;
  --toy-edge: var(--ink);
  --ink-subtle: #1b284476;
  /* The header's rules: --ink-subtle as it shows over white, made solid so it
     reads the same over the white bar and the grey drawer. */
  --rule: #969ca9;
  --body: "Inter", "Inter Fallback", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --bg: #e2e2e2;
  --panel: #ffffff;
  --muted: #59647d;
  --display: "Mozilla Text", "Mozilla Text Fallback", "Inter", system-ui, -apple-system, sans-serif;
  --shadow: 4px 4px 0 var(--toy-edge);
  /* The side gutter, and so the page's width. The content is at most
     --page-max wide and centred: up to a 2000px window the gutter is 10vw, as
     it always was, and past it the gutter takes every extra pixel, so the
     columns keep their layout instead of drifting apart. Everything that sits
     between the gutters, and the hero's grounds that reach back across them,
     read this one value. */
  --page-max: 1600px;
  --padding: max(10vw, (100vw - var(--page-max)) / 2);
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Mozilla Text';
  font-style: normal;
  font-weight: 200 700;
  font-display: swap;
  src: url('/fonts/mozilla-text-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Tinos';
  font-style: italic;
  font-weight: 700;
  font-display: block;
  src: url('/fonts/tinos-italic-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  font-weight: 300;
  line-height: 1.6;
}

a {
  color: inherit;
  text-decoration: none;
}

.announcement {
  padding: 9px 5vw;
  text-align: center;
  font-size: 12px;
  font-weight: 500;
  border-bottom: 2px solid var(--ink);
  background: var(--panel);
  color: var(--ink);
}
.announcement b {
  margin-left: 5px;
  font-weight: 600;
}
.announcement a {
  margin-left: 12px;
  text-decoration: underline;
  text-decoration-color: var(--brand-1);
}

/* The header is the bar and, under it, the nav drawer. It is sticky, and a
   sticky element keeps its place in the flow: when the drawer grows, the
   header grows with it and pushes the page down. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--panel);
  border-bottom: 2px solid transparent;
  transition: border-color 0.15s ease;
}

.site-header-bar {
  height: 72px;
  display: flex;
  align-items: center;
  gap: 0;
  padding: 0 var(--padding);
  border-bottom: 2px solid transparent;
}

/* The header has one rule, a faint one, and only once the page has scrolled
   under it; the drawer opens below the bar with no line of its own. */
.site-header.scrolled {
  border-bottom-color: rgba(15, 23, 42, 0.08);
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin-top: -10px;
}

.brand .title {
  font-family: 'Tinos', serif;
  font-weight: 700;
  font-style: italic;
  font-size: 2.6rem;
  line-height: 1;
  color: var(--ink);
  letter-spacing: normal;
}

.brand .title .lg {
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 3px;
}
.brand .title .lg-1 { text-decoration-color: var(--brand-1); }
.brand .title .lg-2 { text-decoration-color: var(--brand-2); }
.brand .title .lg-3 { text-decoration-color: var(--brand-3); }
.brand .title .lg-4,
.brand .title .lg-5 { text-decoration-color: var(--ink); }

/* ── Main nav layout ─────────────────────────────────────────── */
.nav-main {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: 1;
  padding-left: 24px;
}

/* navmenu list */
.navmenu {
  display: flex;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
.navmenu-item {
  height: 72px;
  display: flex;
  align-items: center;
}

/* Triggers and plain links share the same look */
.navmenu-trigger,
.navmenu-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 14px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 400;
  color: var(--ink);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: none;
  transition: color 0.12s ease;
  white-space: nowrap;
  font-family: var(--display);
}
.navmenu-trigger:hover,
.navmenu-trigger[aria-expanded="true"],
.navmenu-link:hover { color: var(--brand-1); }

/* Chevron */
.navmenu-trigger svg {
  width: 10px;
  height: 10px;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}
.navmenu-trigger[aria-expanded="true"] svg { transform: rotate(180deg); }

/* ── Nav drawer ─────────────────────────────────────────────────
   Opening a trigger grows the drawer from nothing to its content's height,
   and the page below moves down with it. The panel is pinned to the drawer's
   top, so the page's edge slides off it rather than the panel sliding in: it
   reads as having been underneath all along. */
.nav-drawer {
  display: grid;
  grid-template-rows: 0fr;
  background: var(--bg);
  transition: grid-template-rows 0.36s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.nav-drawer.open { grid-template-rows: 1fr; }
.nav-drawer-inner {
  min-height: 0;
  overflow: hidden;
}
.nav-drawer-panel {
  padding: 32px var(--padding) 0;
  animation: viewFadeIn 0.2s ease forwards;
}
.nav-drawer-panel[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .nav-drawer,
  .nav-drawer.open { transition: none; }
  .nav-drawer-panel { animation: none; }
}

/* Columns: a small label over plain, large links. No icons, no blurbs: the
   link's own words carry it. */
.nd-cols {
  display: grid;
  grid-template-columns: repeat(3, max-content);
  gap: 24px 80px;
  padding-bottom: 32px;
}
.nd-col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}
.nd-label {
  margin: 0 0 10px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
}
.nd-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
  transition: text-decoration-color 0.12s ease;
}
.nd-link:hover,
.nd-link:focus-visible { text-decoration-color: var(--brand-1); }
.nd-ext {
  font-size: 14px;
  color: var(--muted);
}

/* A pillar's colour, as the small square the rest of the page uses for it. */
.nd-mark {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border: 1.5px solid var(--ink);
}
.nd-mark-orange { background: var(--brand-1); }
.nd-mark-purple { background: var(--brand-2); }
.nd-mark-green  { background: var(--brand-3); }
.nd-mark-ink    { background: var(--ink); }
.nd-mark-white  { background: var(--panel); }

/* The strip along the drawer's foot: the tools, and the way into the docs. */
.nd-strip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 28px;
  padding: 14px 0 16px;
  border-top: 1px solid var(--rule);
}
.nd-tool {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 400;
  color: var(--ink);
  transition: color 0.12s ease;
}
.nd-tool:hover,
.nd-tool:focus-visible { color: var(--brand-1); }
.nd-tool-icon {
  min-width: 26px;
  height: 26px;
  padding: 0 4px;
  display: grid;
  place-items: center;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--ink);
  background: var(--panel);
  border: 1.5px solid var(--ink);
}
.nd-strip-end {
  margin-left: auto;
  font-family: var(--display);
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--brand-1);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.nd-strip-end:hover,
.nd-strip-end:focus-visible { color: var(--brand-1); }

/* Right-side nav actions (Sovereignty link + CTA) */
.nav-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-shrink: 0;
}
.nav-link-plain {
  font-size: 14px;
  font-weight: 400;
  color: var(--ink);
  text-decoration: none;
  transition: color 0.12s ease;
}
.nav-link-plain:hover { color: var(--brand-1); }
.nav-cta {
  font-size: 13px;
  padding: 8px 16px;
  transform: none;
  box-shadow: 3px 3px 0 var(--ink);
}
.nav-cta:hover {
  transform: translateY(-2px);
  box-shadow: 3px 5px 0 var(--ink);
}

.hero {
  /* The side-by-side layout's numbers, which the map's sizing reads too. */
  --hero-gap: 20px;    /* between the copy's column and the map's */
  --copy-max: 650px;   /* the copy at its widest */
  --copy-fade: 80px;   /* the copy's white ground, fading out past its edge */
  min-height: 550px;
  padding: 56px var(--padding) 48px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  background: var(--panel);
  border-bottom: 2px solid var(--ink);
}

.hero:before {
  content: "";
  position: absolute;
  width: 520px;
  height: 420px;
  left: -180px;
  top: 10px;
  background: radial-gradient(circle, rgba(241,160,6,.14), transparent 68%);
}

.hero-top-row {
  display: grid;
  grid-template-columns: 1.02fr .98fr;
  align-items: center;
  gap: var(--hero-gap);
  position: relative;
  z-index: 2;
  width: 100%;
}

.hero-copy {
  position: relative;
  z-index: 4;
  max-width: var(--copy-max);
}

/* Side by side, the copy sits on a white ground: from the hero's top and
   left edges to the copy's own right edge, and down to the strip of
   reasons. The copy is as wide as its column (the columns split 1.02 :
   0.98 round the gap) up to --copy-max, so on a wide screen the ground
   stops short of the column's edge. Past the copy's edge it fades out over
   --copy-fade, where the map's land begins, so nothing of the map is ever
   under the copy. Between the map (2) and the copy (4) in the row's own
   stacking. The hero's orange glow (.hero:before, which it covers) is
   painted into it, where it was. */
@media (min-width: 851px) {
  .hero-top-row::before {
    content: "";
    position: absolute;
    z-index: 3;
    top: -56px;
    bottom: -64px;
    left: calc(-1 * var(--padding));
    width: calc(var(--padding) + min(var(--copy-max), (100% - var(--hero-gap)) * 0.51) + var(--copy-fade));
    background:
      radial-gradient(circle 334px at 80px 220px, rgba(241, 160, 6, .14), transparent 68%),
      linear-gradient(to right, var(--panel) calc(100% - var(--copy-fade)), rgb(255 255 255 / 0));
  }
}

.eyebrow {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .18em;
  font-weight: 800;
  color: var(--brand-1);
  margin: 0 0 18px;
}

h1 {
  font-family: var(--display);
  font-size: clamp(40px, 5.2vw, 70px);
  line-height: .92;
  letter-spacing: -.07em;
  margin: 0 0 24px;
  font-weight: 500;
  color: var(--ink);
}
h1 strong {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--brand-3);
  text-underline-offset: 6px;
  text-decoration-thickness: 4px;
}
h1 em {
  font-style: normal;
  font-size: 48px;
  padding-top: 0.45em;
  display: block;
  font-weight: 300;
}

@keyframes hero-blink {
  0%, 49%  { opacity: 1; }
  50%, 100% { opacity: 0; }
}
.hero-caret {
  animation: hero-blink 1s step-end infinite;
  font-style: normal;
}
/* Hide caret once typing is done */
.hero-caret.done { animation: none; opacity: 0; }

.lede {
  font-size: 18px;
  line-height: 1.55;
  color: var(--muted);
  max-width: 540px;
  margin: 0 0 30px;
  font-weight: 300;
}

.lede-second {
  font-size: 18px;
  line-height: 1.55;
  color: var(--muted);
  max-width: 540px;
  margin: 0 0 30px;
  font-weight: 300;
  margin-top: -14px;
  padding-top: 14px;
  border-top: 1px solid var(--bg);
}

.actions {
  display: flex;
  gap: 18px;
}

/* Hero Highlights Sub-block */
.hero-highlights {
  margin-top: 64px;
  text-align: left;
  position: relative;
  z-index: 3;
  width: 100%;
}
/* The strip sits over the map too (the globe's edge runs down past it), on
   a white ground across the whole hero, from a little above the strip to
   the hero's foot. */
.hero-highlights::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -16px;
  bottom: -48px;
  left: calc(-1 * var(--padding));
  right: calc(-1 * var(--padding));
  background: var(--panel);
}

.why-drift-heading {
  font-family: var(--display);
  font-size: 24px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.brand-wordmark {
  font-family: 'Tinos', serif;
  font-weight: 700;
  font-style: italic;
  font-size: 1.85rem;
  line-height: 1;
  color: var(--ink);
  display: inline-flex;
}
.brand-wordmark .lg {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 2.5px;
}
.brand-wordmark .lg-1 { text-decoration-color: var(--brand-1); }
.brand-wordmark .lg-2 { text-decoration-color: var(--brand-2); }
.brand-wordmark .lg-3 { text-decoration-color: var(--brand-3); }
.brand-wordmark .lg-4,
.brand-wordmark .lg-5 { text-decoration-color: var(--ink); }

.button {
  padding: 12px 22px;
  font-size: 14px;
  font-weight: 600;
  border: 2px solid var(--toy-edge);
  cursor: pointer;
  display: inline-block;
  text-decoration: none;
  transform: translateY(-4px);
  box-shadow: 0 6px 0 var(--toy-edge);
  transition: transform .07s cubic-bezier(.34, 1.56, .64, 1),
              box-shadow .07s cubic-bezier(.34, 1.56, .64, 1),
              background .08s ease, color .08s ease;
}
.button:hover {
  transform: translateY(-5px);
  box-shadow: 0 7px 0 var(--toy-edge);
}
.button:active {
  transform: translateY(0);
  box-shadow: 0 0 0 var(--toy-edge);
}

.primary {
  background: var(--brand-1);
  color: var(--on-brand);
}
.secondary {
  background: var(--panel);
  color: var(--ink);
}
.secondary b {
  margin-left: 8px;
}

.hero-art {
  min-height: 480px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Terminal Container Rig */
.terminal-rig {
  position: relative;
  width: 100%;
  max-width: 580px;
  margin: 20px 0;
  z-index: 2;
  overflow: visible;
}

/* Stepped Underlay Plates — Crisp paper-cutout elevation */
.plate-underlay {
  position: absolute;
  inset: 0;
  border: 2px solid var(--ink);
  pointer-events: none;
  overflow: visible;
  animation-duration: 0.65s;
  animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
  animation-fill-mode: both;
}
/* Stack offset: each plate sits 7px further right+down than the one above it.
   orange=7px, green=14px, purple=21px, ink=28px */
@keyframes fanOutOrange {
  0%   { transform: translate(0, 0);     opacity: 0; }
  100% { transform: translate(7px, 7px); opacity: 1; }
}
@keyframes fanOutGreen {
  0%   { transform: translate(0, 0);       opacity: 0; }
  100% { transform: translate(14px, 14px); opacity: 1; }
}
@keyframes fanOutPurple {
  0%   { transform: translate(0, 0);       opacity: 0; }
  100% { transform: translate(21px, 21px); opacity: 1; }
}
@keyframes fanOutInk {
  0%   { transform: translate(0, 0);       opacity: 0; }
  100% { transform: translate(28px, 28px); opacity: 1; }
}

.plate-orange {
  background: var(--brand-1);
  z-index: -1;
  animation-name: fanOutOrange;
  animation-delay: 0.05s;
}
.plate-green {
  background: var(--brand-3);
  z-index: -2;
  animation-name: fanOutGreen;
  animation-delay: 0.12s;
}
.plate-purple {
  background: var(--brand-2);
  z-index: -3;
  animation-name: fanOutPurple;
  animation-delay: 0.19s;
}
.plate-ink {
  background: var(--ink);
  z-index: -4;
  animation-name: fanOutInk;
  animation-delay: 0.26s;
}

@media (prefers-reduced-motion: reduce) {
  .plate-underlay { animation: none !important; }
  .plate-orange { transform: translate(7px,  7px);  opacity: 1; }
  .plate-green  { transform: translate(14px, 14px); opacity: 1; }
  .plate-purple { transform: translate(21px, 21px); opacity: 1; }
  .plate-ink    { transform: translate(28px, 28px); opacity: 1; }
}

/* Architectural Rig Tabs */
.rig-tab {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 6px;
  border: 2px solid var(--ink);
  background: var(--panel);
  font-family: var(--display);
  font-size: 11px;
  font-weight: 700;
  color: var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  cursor: default;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
  z-index: 5;
}
.rig-tab:hover {
  transform: translateY(-2px);
  box-shadow: 4px 4px 0 var(--ink);
}

.tab-chip {
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border: 1.5px solid var(--ink);
  font-size: 11px;
  font-weight: 900;
}

/* Top left: Atomic */
.rig-tab-atomic { top: -24px; left: 28px; }
.rig-tab-atomic .tab-chip { background: var(--brand-1); color: var(--on-brand); }

/* Top right: Backbone */
.rig-tab-backbone { top: -24px; right: 28px; }
.rig-tab-backbone .tab-chip { background: var(--brand-2); color: #ffffff; }

/* Bottom left: Canvas */
.rig-tab-canvas { bottom: -22px; left: 28px; }
.rig-tab-canvas .tab-chip { background: var(--brand-3); color: var(--on-brand); }

/* Bottom right: Deed */
.rig-tab-deed { bottom: -22px; right: 28px; }
.rig-tab-deed .tab-chip { background: var(--ink); color: #ffffff; }

.terminal {
  position: relative;
  z-index: 2;
  width: 100%;
  border: 2px solid var(--ink);
  background: #1b2844;
  color: #f1f1f1;
  overflow: hidden;
}

.terminal-bar {
  height: 40px;
  background: #16203a;
  border-bottom: 2px solid #2b3a5c;
  display: flex;
  align-items: center;
  padding: 0 16px;
  gap: 8px;
}
.terminal-bar span:nth-child(1) { width: 9px; height: 9px; border-radius: 50%; background: var(--brand-1); }
.terminal-bar span:nth-child(2) { width: 9px; height: 9px; border-radius: 50%; background: var(--brand-2); }
.terminal-bar span:nth-child(3) { width: 9px; height: 9px; border-radius: 50%; background: var(--brand-3); }
.terminal-bar b {
  margin-left: 10px;
  font-size: 13px;
  font-family: var(--mono);
  font-weight: 600;
  color: #b8bbc2;
}

.terminal-body {
  padding: 18px 22px 20px;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.6;
}
.terminal-body small {
  color: var(--brand-1);
  margin-right: 8px;
  font-weight: 600;
}

.muted {
  color: #8ea0c4;
  margin: 0;
}

.check {
  margin: 0;
}
.check span {
  color: var(--brand-3);
  margin-right: 9px;
  font-weight: 600;
}
.check i {
  font-style: normal;
  color: #b9c4dc;
  margin-left: 10px;
}

.check-hdr {
  font-weight: 600;
  margin-top: 8px;
}
.check-hdr-a { color: var(--brand-1); }
.check-hdr-b { color: var(--brand-2); }
.check-hdr-c { color: var(--brand-3); }

.done {
  color: #8ea0c4;
}
.done strong {
  color: var(--brand-3);
}

.dot-grid {
  position: absolute;
  width: 92px;
  height: 72px;
  opacity: .45;
  background-image: radial-gradient(var(--ink) 1.5px, transparent 1.5px);
  background-size: 12px 12px;
}
.dots-a { right: 0; top: 5%; }
.dots-b { left: 2%; bottom: 14%; }

/* ── The hero map ──────────────────────────────────────────────
   Europe without Russia on the curve of the Earth, as a satellite over the
   Sahara sees it looking north (europe-outline.svg, which hero.js loads
   into the map), played once .is-on is set. The Earth's surface fades in
   and the bands rise off its horizon, which runs on past the picture as
   the edge of the globe, across the whole hero (the hero's overflow keeps
   it in). Pens then draw the coastline in two relays, Fennoscandia and then
   the continent, each stroke starting at its --at and running for its
   --span (fractions of --draw, from the generator), and each island draws
   itself as a pen passes it. At --fill-at of the draw, hero.js sweeps a
   scan line south over the globe (a parallel of latitude, projected each
   frame with the map's own camera) for --fill, filling in the land north
   of it. The plates then fan out under it, and hero.js sprouts the blocks
   at --blocks-at. hero.js reads all of these timings from here. */
.eu-map {
  --draw-start: 0.45s;
  --draw: 3.2s;
  --fill-at: 0.8;
  --fill-start: calc(var(--draw-start) + var(--draw) * var(--fill-at));
  --fill: 1.4s;
  --plates-start: calc(var(--fill-start) + var(--fill) - 0.1s);
  --blocks-at: 4.8s;
  z-index: 2;
  container-type: inline-size;
  aspect-ratio: 1058 / 791;
  /* Side by side with the copy, the map is out of the layout, centred on
     the hero's row, which it overflows without ever setting its height, so
     the strip of reasons stays where it is. It is sized and placed by its
     land, so that all of it shows beside all of the copy, as large as the
     room between them allows:
     - its easternmost point, the tip of Cyprus, 0.95841 of the way across
       the picture (tools/europe.py prints it), lands on this column's right
       edge, which is the line the page's right padding draws;
     - its westernmost, Portugal's coast, lands where the copy's white
       ground has faded out (--land-from, from this column's left edge).
       The land spans 0.94518 of the picture (14 to 1014 of its 1058
       units). The copy's column is 1.02/0.98 as wide as this one, so its
       edge is --hero-gap left of here, and further by however much that
       column is wider than --copy-max; the fade adds --copy-fade.
     Past 820px wide, the horizon's bands would leave the hero's top and the
     Aegean would reach the strip, so it stops growing there. */
  --land-from: calc(var(--copy-fade) - var(--hero-gap) - max(0px, 100% * 1.040816 - var(--copy-max)));
  --map-w: min(820px, (100% - var(--land-from)) / 0.94518);
  position: absolute;
  top: 50%;
  left: calc(100% - var(--map-w) * 0.95841);
  width: var(--map-w);
  transform: translateY(-50%);
  /* It reaches across into the copy's column, whose links stay clickable. */
  pointer-events: none;
}
@media (max-width: 850px) {
  .eu-map {
    position: relative;
    left: auto;
    top: auto;
    width: 100%;
    max-width: none;
    transform: none;
  }
}

/* The Earth: its near side in the picture, fading out at the picture's
   sides and foot; its graticule; and its edge, the horizon, ink with the
   brand's three bands stepped off it, as the hero's plates are. */
.eu-earth { fill: #eef0f4; }
.eu-graticule {
  fill: none;
  stroke: #d3d7df;
  stroke-width: 1px;
}
.eu-rim {
  fill: none;
  stroke: var(--ink);
  stroke-width: 2px;
}
.eu-band {
  fill: none;
  stroke-width: 3.5px;
}
.eu-band-orange { stroke: var(--brand-1); }
.eu-band-green  { stroke: var(--brand-3); }
.eu-band-purple { stroke: var(--brand-2); }
.eu-earth, .eu-graticule, .eu-rim, .eu-band { opacity: 0; }

.eu-map.is-on .eu-earth,
.eu-map.is-on .eu-graticule,
.eu-map.is-on .eu-rim {
  animation: eu-appear 0.6s ease-out both;
}
.eu-map.is-on .eu-band { animation: eu-rise 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both; }
.eu-map.is-on .eu-band-orange { animation-delay: 0.15s; }
.eu-map.is-on .eu-band-green  { animation-delay: 0.23s; }
.eu-map.is-on .eu-band-purple { animation-delay: 0.31s; }

@keyframes eu-appear {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes eu-rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
/* The picture paints past its box (the horizon crosses the whole hero),
   so it must not take the clicks meant for what it passes over. */
.eu-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

/* The strokes have pathLength=1, so a dash offset from 1 to 0 draws each
   one from its start to its end. Their width is in map units and scales
   with the map: a non-scaling stroke would dash in screen units instead. */
.eu-trace path {
  fill: none;
  stroke: var(--ink);
  stroke-width: 2.6;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
.eu-pen {
  fill: var(--brand-1);
  stroke: var(--ink);
  stroke-width: 2.5;
  offset-rotate: 0deg;
  opacity: 0;
}
.eu-land-fill { fill: var(--ink); }
.eu-land-dots { fill: url(#eu-dots); }

/* The plates: the large landmasses, cut out in the brand's colours and
   stepped down and right under the land, as the hero's plates always were. */
.eu-plate {
  stroke: var(--ink);
  stroke-width: 1.5px;
  opacity: 0;
}
.eu-plate-orange { fill: var(--brand-1); --to: 6px; }
.eu-plate-green  { fill: var(--brand-3); --to: 12px; }
.eu-plate-purple { fill: var(--brand-2); --to: 18px; }

/* The scan line, a parallel on the globe, and its band of glow just north
   of it; hero.js redraws both each frame and fades them in and out. */
.eu-scan { opacity: 0; }
.eu-scan-line {
  fill: none;
  stroke: var(--brand-1);
  stroke-width: 3px;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.eu-scan-glow { fill: url(#eu-scan-glow); }

.eu-map.is-on .eu-trace .eu-trace-main,
.eu-map.is-on .eu-pen {
  animation-duration: calc(var(--span) * var(--draw));
  animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
  animation-delay: calc(var(--draw-start) + var(--at) * var(--draw));
  animation-fill-mode: both;
}
.eu-map.is-on .eu-trace .eu-trace-main { animation-name: eu-draw; }
.eu-map.is-on .eu-pen { animation-name: eu-pen; }
.eu-map.is-on .eu-trace path:not(.eu-trace-main) {
  animation: eu-draw 0.6s cubic-bezier(0.2, 0.7, 0.3, 1) calc(var(--draw-start) + var(--at, 0) * var(--draw)) both;
}
.eu-map.is-on .eu-plate {
  animation: eu-plate 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.eu-map.is-on .eu-plate-orange { animation-delay: var(--plates-start); }
.eu-map.is-on .eu-plate-green  { animation-delay: calc(var(--plates-start) + 0.08s); }
.eu-map.is-on .eu-plate-purple { animation-delay: calc(var(--plates-start) + 0.16s); }

@keyframes eu-draw {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}
@keyframes eu-pen {
  0%   { offset-distance: 0%; opacity: 0; }
  4%   { opacity: 1; }
  94%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0; }
}
@keyframes eu-plate {
  from { transform: translate(0, 0); opacity: 0; }
  to   { transform: translate(var(--to), var(--to)); opacity: 1; }
}

/* The blocks: a tile on its city, and a tag naming what it is. They size
   with the map (cqw, within bounds), and the tags go once it is too small
   to hold them. hero.js sets .is-up to sprout one and .is-leaving to sink
   it back. */
.eu-blocks {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.eu-block {
  --tile: clamp(16px, 4.3cqw, 26px);
  position: absolute;
  display: flex;
  align-items: center;
  gap: clamp(4px, 1cqw, 7px);
  transform: translate(calc(var(--tile) / -2), -50%);
  visibility: hidden;
}
.eu-block.is-up,
.eu-block.is-leaving { visibility: visible; }
.eu-block-tile {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--tile);
  height: var(--tile);
  color: var(--tone-ink);
  background: var(--tone);
  border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink-darkest);
  transform-origin: 50% 100%;
}
.eu-block-tile svg {
  width: 64%;
  height: 64%;
}
/* The square shock where a block breaks ground. */
.eu-block::before {
  content: "";
  position: absolute;
  left: calc(var(--tile) / 2);
  top: 50%;
  width: calc(var(--tile) * 2.4);
  height: calc(var(--tile) * 2.4);
  border: 2px solid var(--tone);
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
}
.eu-block-tag {
  font-family: var(--mono);
  font-size: clamp(8.5px, 1.9cqw, 11px);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink);
  background: var(--panel);
  border: 1.5px solid var(--ink);
  box-shadow: 2px 2px 0 var(--ink-darkest);
  padding: 0.45em 0.6em;
}

.eu-block.is-up .eu-block-tile { animation: eu-sprout 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both; }
.eu-block.is-up::before { animation: eu-shock 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) 0.12s both; }
.eu-block.is-up .eu-block-tag { animation: eu-tag-in 0.35s cubic-bezier(0.2, 0.7, 0.3, 1) 0.3s both; }
.eu-block.is-leaving .eu-block-tag { animation: eu-tag-out 0.18s ease-in both; }
.eu-block.is-leaving .eu-block-tile { animation: eu-sink 0.3s cubic-bezier(0.5, 0, 0.75, 0) 0.1s both; }

@keyframes eu-sprout {
  from { transform: scale(0); }
  to   { transform: scale(1); }
}
@keyframes eu-sink {
  from { transform: scale(1); }
  to   { transform: scale(0); }
}
@keyframes eu-shock {
  from { transform: translate(-50%, -50%) scale(0.3); opacity: 0.9; }
  to   { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}
@keyframes eu-tag-in {
  from { clip-path: inset(-4px 100% -4px 0); }
  to   { clip-path: inset(-4px -4px -4px 0); }
}
@keyframes eu-tag-out {
  from { clip-path: inset(-4px -4px -4px 0); }
  to   { clip-path: inset(-4px 100% -4px 0); }
}

@container (max-width: 440px) {
  .eu-block-tag { display: none; }
}

/* Without motion, the map is simply there, and so are the first blocks. */
@media (prefers-reduced-motion: reduce) {
  .eu-land { clip-path: none; }
  .eu-trace path { stroke-dashoffset: 0; }
  .eu-scan, .eu-pen { display: none; }
  .eu-plate { opacity: 1; transform: translate(var(--to), var(--to)); }
  .eu-earth, .eu-graticule, .eu-rim, .eu-band { opacity: 1; }
  .eu-map .eu-earth,
  .eu-map .eu-graticule,
  .eu-map .eu-rim,
  .eu-map .eu-band,
  .eu-map .eu-trace path,
  .eu-map .eu-plate,
  .eu-block .eu-block-tile,
  .eu-block .eu-block-tag,
  .eu-block::before { animation: none !important; }
}

/* Container utility & Common Section Layouts */
.container {
  padding: 0 var(--padding);
  width: 100%;
}

.section-band {
  padding: 64px 0;
  border-bottom: 2px solid var(--ink);
}
.bg-panel { background: var(--panel); }
.bg-light { background: #fafafa; }
.bg-desk  { background: var(--bg); }
.bg-ink   { background: var(--ink); }
.bg-ink-darker { background: var(--ink-darker); }
.bg-ink-darkerer { background: var(--ink-darkerer); }
.bg-ink-darkererer { background: var(--ink-darkererer); }
.bg-ink-darkest { background: var(--ink-darkest); }

/* Left-aligned Split Layout for modern two-column narrative */
.split-layout {
  display: grid;
  grid-template-columns: minmax(320px, 1fr) minmax(400px, 1.35fr);
  gap: clamp(36px, 5vw, 64px);
  align-items: start;
}

.split-layout.reverse {
  grid-template-columns: minmax(400px, 1.35fr) minmax(320px, 1fr);
}

#polyglot .split-layout.reverse {
  align-items: start;
}

/* Europe section: stretch both columns so left can push group to bottom */
#europe .split-layout {
  align-items: stretch;
}
#europe .split-left {
  justify-content: space-between;
}
.eu-bottom-group {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ── Europe section: a light band, on the desk ────────────────
   The first of the three bands for the buyer (sovereignty, portability,
   price). Its cards are the page's white toy cards, as the pillar deck's
   are, and the ring of twelve stars behind them is drawn in the brand's
   orange so it shows on the desk. */
#europe {
  position: relative;
}
.eu-stars-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}
.eu-stars-bg g {
  fill: var(--brand-1);
  opacity: 0.3;
}
#europe .container {
  position: relative;
  z-index: 1;
}

.split-left {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.split-right {
  width: 100%;
}

.section-head {
  max-width: 100%;
  margin: 0 0 28px;
  text-align: left;
}

.section-label {
  display: inline-block;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink);
  background: #ffedd5;
  border: 1.5px solid var(--ink);
  padding: 4px 10px;
  box-shadow: 2px 2px 0 var(--ink);
  margin-bottom: 16px;
}

.section-head h2 {
  font-family: var(--display);
  font-size: clamp(30px, 3.6vw, 40px);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 1.12;
  color: var(--ink);
  margin: 0 0 16px;
}
.section-sub {
  font-size: clamp(15.5px, 1.6vw, 18px);
  color: var(--muted);
  line-height: 1.55;
  margin: 0;
  max-width: 520px;
}

/* Side Notes in Left Columns */
.eu-side-note,
.port-side-note {
  border-left: 3px solid var(--ink);
  padding-left: 14px;
  margin-top: 8px;
}
.eu-side-note p,
.port-side-note p {
  font-size: 14px;
  color: var(--muted);
  line-height: 1.5;
  margin: 0;
}

/* Lede Stack in Left Column */
.lede-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 8px;
}

/* Highlights Strip embedded under Hero Copy */
.service-strip {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 28px 28px;
  /* max-width: 1200px; */
  margin: 0;
  padding: 0;
  background: transparent;
}
.strip-item {
  display: flex;
  gap: 16px;
  align-items: center;
  background: transparent;
}

.strip-item-link::hover {
  background: var(--ink);
}

.hero.highlights > a{
  text-decoration: none;
}
.hero-highlights > a::hover{
  text-decoration: underline;
}

.service-icon {
  width: 60px;
  height: 60px;
  border: 2px solid var(--ink);
  display: grid;
  place-items: center;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 800;
  flex-shrink: 0;
  box-shadow: 3px 3px 0 var(--ink);
}
.icon-pill-orange { background: var(--brand-1); color: var(--on-brand); }
.icon-pill-purple { background: var(--brand-2); color: #fff; }
.icon-pill-green { background: var(--brand-3); color: var(--on-brand); }
.icon-pill-ink { background: var(--ink); color: #fff; }
.icon-pill-white { background: white; color: var(--ink); }

.strip-item b {
  display: block;
  font-family: var(--display);
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.25;
}
.strip-item small {
  display: block;
  color: var(--muted);
  font-size: 13.5px;
  margin-top: 3px;
  line-height: 1.35;
}

/* Lede Grid: 2 Philosophy Cards */
.lede-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-bottom: 40px;
}
.lede-card {
  display: flex;
  align-items: flex-start;
  gap: 18px;
  background: #ffffff;
  border: 2px solid var(--ink);
  padding: 20px 22px;
  box-shadow: 4px 4px 0 var(--ink);
  text-align: left;
  cursor: pointer;
  width: 100%;
  font-family: inherit;
  transform: translateY(-2px);
  transition: transform .08s cubic-bezier(.34, 1.56, .64, 1),
              box-shadow .08s cubic-bezier(.34, 1.56, .64, 1),
              background .12s ease, border-color .12s ease;
}
.lede-card:hover {
  transform: translateY(-4px);
  box-shadow: 6px 6px 0 var(--ink);
}
.lede-card:active {
  transform: translateY(0);
  box-shadow: 1px 1px 0 var(--ink);
}
.lede-card.active {
  background: #ffffff;
  border-color: var(--brand-1);
  transform: translateY(0);
  box-shadow: 4px 4px 0 var(--brand-1);
}
.lede-icon {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  background: #f4f4f6;
  border: 2px solid var(--ink);
  display: grid;
  place-items: center;
  box-shadow: 2px 2px 0 var(--ink);
  transition: background 0.15s ease, color 0.15s ease;
}
.lede-card.active .lede-icon {
  background: var(--brand-1);
}
.lede-card.active .lede-icon svg {
  stroke: var(--on-brand);
}
.lede-icon svg { width: 22px; height: 22px; stroke: var(--ink); }

.lede-text {
  flex: 1;
}
.lede-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}
.lede-card h3 {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
}
.lede-badge {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  background: #f4f4f6;
  border: 1px solid var(--ink);
  color: var(--ink);
}
.lede-card.active .lede-badge {
  background: var(--ink);
  color: #ffffff;
}
.lede-card p {
  font-size: 14px;
  line-height: 1.45;
  color: var(--muted);
  margin: 0;
}

/* Architecture Views (The Primitives vs The Wiring) */
#primitives .split-right {
  display: flex;
  flex-direction: column;
}
.arch-view {
  display: none;
  animation: viewFadeIn 0.2s ease forwards;
}
.arch-view.active {
  display: flex;
  flex-direction: column;
}

/* ── The secure-by-default graph ───────────────────────────────
   The slice at the hub, three defaults that live inside it on the left,
   three that guard its edges on the right. hero.js draws a wire from the
   hub to each node and runs a packet along it; the chosen node's wire is
   solid and its description sits in the box below. */
.tone-a { --tone: var(--brand-1); --tone-ink: var(--on-brand); }
.tone-b { --tone: var(--brand-2); --tone-ink: #ffffff; }
.tone-c { --tone: var(--brand-3); --tone-ink: var(--on-brand); }
.tone-d { --tone: var(--ink);     --tone-ink: #ffffff; }
.tone-e { --tone: var(--panel);   --tone-ink: var(--ink); }

.mesh {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  column-gap: 48px;
  padding: 8px 0;
}
.mesh-wires {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
.mesh-col {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  gap: 18px;
  height: 100%;
}

.mesh-node {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  font-family: var(--display);
  font-size: 14px;
  font-weight: 700;
  line-height: 1.25;
  text-align: left;
  color: var(--ink);
  background: var(--panel);
  border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
  transition:
    transform 0.08s cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 0.08s cubic-bezier(0.34, 1.56, 0.64, 1),
    background 0.15s ease, color 0.15s ease;
}
.mesh-node:hover {
  transform: translate(-1px, -1px);
  box-shadow: 4px 4px 0 var(--ink);
}
.mesh-node:focus-visible {
  outline: 2px solid var(--brand-1);
  outline-offset: 3px;
}
/* Chosen: pressed flat and filled with its colour. */
.mesh-node[aria-pressed="true"] {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--ink);
  background: var(--tone);
  color: var(--tone-ink);
}
.mesh-node-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  color: var(--tone-ink);
  background: var(--tone);
  border: 1.5px solid var(--ink);
}
.mesh-node[aria-pressed="true"] .mesh-node-icon { background: var(--panel); color: var(--ink); }
.mesh-node-icon svg { width: 16px; height: 16px; }
.mesh-node-desc { display: none; }

/* The hub: an ink tile on the hero's stepped plates. */
.mesh-hub {
  position: relative;
  z-index: 1;
  width: 136px;
  height: 136px;
  margin-right: 15px;
  margin-bottom: 15px;
}
.mesh-hub::before,
.mesh-hub::after,
.mesh-hub-plate {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--ink);
}
.mesh-hub::before { z-index: 2; background: var(--brand-1); transform: translate(5px, 5px); }
.mesh-hub::after  { z-index: 1; background: var(--brand-3); transform: translate(10px, 10px); }
.mesh-hub-plate   { z-index: 0; background: var(--brand-2); transform: translate(15px, 15px); }
.mesh-hub-face {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  background: var(--ink);
  border: 2px solid var(--ink);
}
.mesh-hub-name {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  line-height: 1.1;
  color: #ffffff;
}
.mesh-hub-sub {
  font-family: var(--mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #8ea0c4;
}

/* Wires: a dashed rule each; the chosen one solid ink, flowing outwards. */
.mesh-wire path {
  fill: none;
  stroke: var(--rule);
  stroke-width: 1.5;
  stroke-dasharray: 4 5;
}
.mesh-wire circle {
  fill: var(--panel);
  stroke: var(--ink);
  stroke-width: 1.5;
}
.mesh-wire.active path {
  stroke: var(--ink);
  stroke-width: 2;
  animation: mesh-flow 0.5s linear infinite;
}
.mesh-wire.active circle { fill: var(--tone); }
@keyframes mesh-flow {
  to { stroke-dashoffset: -9; }
}

.mesh-detail {
  margin-top: 20px;
  padding: 16px 20px;
  background: var(--panel);
  border: 2px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
}
.mesh-detail-name {
  margin: 0 0 4px;
  font-family: var(--display);
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
}
.mesh-detail-desc {
  margin: 0;
  min-height: 3em;
  font-size: 15px;
  line-height: 1.5;
  color: var(--muted);
}
.mesh-detail-note {
  margin: 14px 0 0;
  padding-top: 12px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--muted);
  border-top: 1px dashed var(--rule);
}

@media (prefers-reduced-motion: reduce) {
  .mesh-wire.active path { animation: none; }
  .mesh-node { transition: none; }
}

/* Side by side, the left column alone sets the section's height:
   `contain: size` gives the right column no height of its own, so the grid
   row is as tall as the left, and the right stretches to it. Each view then
   fills that height, which puts its bottom border on the line of the last
   card's on the left. */
@media (min-width: 961px) {
  #primitives .split-layout { align-items: stretch; }
  #primitives .split-right { contain: size; }
  /* A resting card sits 2px up (translateY(-2px)); a chosen one sits flat.
     While the last card rests, the views end 2px higher to meet it. */
  #primitives .split-layout:has(.lede-card:last-child:not(.active)) .split-right {
    margin-bottom: 2px;
  }
  #primitives .arch-view.active {
    flex: 1;
    min-height: 0;
  }
  #primitives .pillar-deck {
    flex: 1;
    display: flex;
    flex-direction: column;
    margin-bottom: 0;
  }
  #primitives .pillar-sheet { flex: 1; }
  #primitives .wiring-console {
    flex: 1;
    height: auto;
    min-height: 0;
  }
  #primitives .mesh { flex: 1; min-height: 0; }
}

/* Idle placeholder shown when no card is selected */
.view-idle {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 280px;
  height: 100%;
  border: 2px dashed var(--ink);
  opacity: 0.35;
  transition: opacity 0.2s ease;
}
.view-idle.hidden {
  display: none;
}
.view-idle-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  color: var(--ink);
}
.view-idle-inner p {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin: 0;
}
@keyframes viewFadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Wiring Console Blueprint */
.wiring-console {
  background: #1b2844;
  border: 2px solid var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
  color: #f1f5f9;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}
.wiring-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  background: #151f33;
  border-bottom: 2px solid #2d3f66;
  gap: 12px;
}
.wiring-title-bar {
  display: flex;
  align-items: center;
  gap: 10px;
}
.wiring-tab-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--brand-1);
  color: var(--on-brand);
  border: 1.5px solid var(--ink);
  padding: 4px 10px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  box-shadow: 2px 2px 0 var(--ink);
}
.wiring-subtitle {
  font-family: var(--mono);
  font-size: 11px;
  color: #8aa0c8;
}
.wiring-meta {
  display: flex;
  align-items: center;
}
.wiring-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 11px;
  color: #b9c4dc;
}
/* Two-pane split: sidebar + code */
.wiring-body-split {
  display: grid;
  grid-template-columns: 11rem minmax(0, 1fr);
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

/* File explorer sidebar */
.wiring-files {
  background: #16203a;
  border-right: 2px solid #2b3a5c;
  padding: 14px 10px 14px 14px;
  overflow-y: auto;
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.85;
}

.wf-tree,
.wf-tree ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.wf-tree ul { padding-left: 0.85rem; }

.wf-node {
  display: block;
  color: #8aa0c8;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wf-dir        { color: #f1f5f9; font-weight: 600; }
.wf-atomic     { color: var(--brand-1); }
.wf-backbone   { color: var(--brand-2); }
.wf-canvas     { color: var(--brand-3); }
.wf-driftfile  { color: #569cd6; font-weight: 600; }

.wiring-code-wrap {
  padding: 18px 22px;
  background: #1b2844;
  overflow-y: auto;
}
.wiring-code {
  margin: 0;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.55;
  color: #f1f5f9;
  white-space: pre;
}
.syn-key { color: var(--brand-1); font-weight: 700; }
.syn-prop { color: #93c5fd; }
.syn-val { color: #facc15; }
.syn-str { color: #a7f3d0; }
.syn-cmt { color: #64748b; font-style: italic; }
.syn-pillar {
  display: inline-block;
  font-weight: 700;
  margin-top: 10px;
  margin-bottom: 2px;
  padding: 2px 6px;
  border-left: 3px solid currentColor;
}
.syn-atomic { color: var(--brand-1); background: rgba(241,160,6,0.12); }
.syn-backbone { color: #a78bfa; background: rgba(130,105,235,0.14); }
.syn-canvas { color: #34d399; background: rgba(16,185,129,0.12); }

.wiring-footer {
  padding: 14px 20px;
  background: #151f33;
  border-top: 2px solid #2d3f66;
}
.wiring-callout {
  font-size: 13px;
  line-height: 1.45;
  color: #cbd5e1;
}
.wiring-callout b {
  color: #ffffff;
}

/* ── The pillar deck ────────────────────────────────────────────
   Five folder tabs over one white sheet. The selected tab is the sheet's
   own paper: it is white, it drops over the sheet's top rule, and it wears
   its pillar's colour as a band along its top. Under the sheet sits one
   cut-out plate in that colour, as the hero's plates do. */
[data-grp="a"] { --key-fill: var(--brand-1); --key-ink: var(--on-brand); }
[data-grp="b"] { --key-fill: var(--brand-2); --key-ink: #ffffff; }
[data-grp="c"] { --key-fill: var(--brand-3); --key-ink: var(--on-brand); }
[data-grp="d"] { --key-fill: var(--ink);     --key-ink: #ffffff; }
[data-grp="e"] { --key-fill: var(--panel);   --key-ink: var(--ink); }

.pillar-deck {
  position: relative;
  isolation: isolate;
  margin: 0 10px 10px 0;
}

.pillar-tabs {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 6px;
  align-items: end;
  padding: 0 14px;
}
.pillar-tab {
  position: relative;
  display: block;
  min-width: 0;
  padding: 10px 4px 9px;
  font-family: inherit;
  text-align: center;
  color: var(--ink);
  background: #f1f1f1;
  border: 2px solid var(--ink);
  border-bottom: 0;
  cursor: pointer;
  /* Rising back: the tab first, then its colour drains and its label returns. */
  transition:
    background 0.12s ease,
    transform 0.26s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.pillar-tab:hover { background: #fafafa; }
.pillar-tab:focus-visible {
  outline: 2px solid var(--brand-1);
  outline-offset: 2px;
}
/* The tab's colour: drains up out of an unchosen tab, and pours down to
   fill a chosen one once its label has sunk away. */
.pillar-tab::before {
  content: "";
  position: absolute;
  left: -2px;
  right: -2px;
  top: -2px;
  bottom: 0;
  background: var(--key-fill);
  border: 2px solid var(--ink);
  border-bottom: 0;
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.18s cubic-bezier(0.5, 0, 0.75, 0) 0.12s;
}
.pillar-tab[aria-selected="true"]::before {
  transform: scaleY(1);
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1) 0.12s;
}

/* Picking a tab presses it in: once its label has sunk and its colour has
   filled it, the whole tab slides down behind the sheet (which comes later
   in the markup, so it paints over it), leaving a coloured lip showing. */
.pillar-tab[aria-selected="true"] {
  transform: translateY(calc(100% - 10px));
  cursor: default;
  transition:
    background 0.12s ease,
    transform 0.3s cubic-bezier(0.5, 0, 0.3, 1) 0.4s;
}

/* The chosen tab hands its label to the sheet: the icon and name sink out
   through the tab's foot, and the same pair slides into the panel's title
   from the left (.pillar-title, below). Unchosen, they rise back. */
.pillar-tab-clip {
  display: block;
  overflow: hidden;
}
.pillar-tab-face {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  transition:
    transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1) 0.24s,
    opacity 0.3s ease-out 0.24s;
}
.pillar-tab[aria-selected="true"] .pillar-tab-face {
  transform: translateY(110%);
  opacity: 0;
  transition:
    transform 0.22s cubic-bezier(0.5, 0, 0.75, 0),
    opacity 0.22s ease-in;
}

.pillar-tab-icon {
  flex: none;
  width: 22px;
  height: 22px;
}
.pillar-tab-icon svg {
  display: block;
  width: 100%;
  height: 100%;
}
.pillar-tab-name {
  font-family: var(--display);
  font-size: 14px;
  font-weight: 700;
  line-height: 1.15;
}

/* The panel's title: the chosen tab's icon and name, arrived from the left
   edge of the head. The clip is what they emerge from. */
.pillar-title {
  overflow: hidden;
  margin: 0 0 12px;
}
.pillar-title-face {
  display: flex;
  align-items: center;
  gap: 10px;
}
.pillar-title-icon {
  flex: none;
  width: 34px;
  height: 34px;
  color: var(--ink);
}
.pillar-title-icon svg {
  display: block;
  width: 100%;
  height: 100%;
}
.pillar-title-name {
  font-family: var(--display);
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
}
.pillar-title-role {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
}
.pillar-title-role::before {
  content: "·";
  margin-right: 10px;
}
@keyframes pillar-title-in {
  from { transform: translateX(-105%); }
  to   { transform: none; }
}

.pillar-sheet {
  position: relative;
  display: grid;
  background: var(--panel);
  border: 2px solid var(--ink);
}
.pillar-sheet::after {
  content: "";
  position: absolute;
  inset: -2px;
  z-index: -1;
  transform: translate(10px, 10px);
  background: var(--key-fill);
  border: 2px solid var(--ink);
  transition: background 0.2s ease;
}

/* Every panel sits in the same cell; the hidden ones keep their height. */
.pillar-panel {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  padding: 26px 28px 0;
  visibility: hidden;
}
.pillar-panel.active { visibility: visible; }

.pillar-head h3 {
  margin: 0 0 10px;
  font-family: var(--display);
  font-size: 28px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--ink);
}
.pillar-head p {
  margin: 0;
  max-width: 60ch;
  font-size: 16.5px;
  line-height: 1.5;
  color: var(--muted);
}
.pillar-head code {
  font-family: var(--mono);
  font-size: 0.88em;
  padding: 1px 5px;
  background: #f1f5f9;
  border: 1px solid var(--ink);
  color: var(--ink);
}

/* The blocks: two columns of ruled rows, each a name over one line. */
.pillar-blocks {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 28px;
  border-top: 1px solid var(--rule);
}
.pillar-blocks li { border-bottom: 1px solid var(--rule); }
.pillar-block {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  height: 100%;
  padding: 12px 22px 12px 18px;
  color: var(--ink);
}
.pillar-block::before {
  content: "";
  position: absolute;
  left: 0;
  top: 18px;
  width: 8px;
  height: 8px;
  background: var(--key-fill);
  border: 1.5px solid var(--ink);
}
.pillar-block b {
  font-family: var(--display);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
}
.pillar-block span {
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--muted);
}
a.pillar-block::after {
  content: "→";
  position: absolute;
  right: 2px;
  top: 12px;
  font-size: 14px;
  color: var(--muted);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.12s ease, transform 0.12s ease;
}
a.pillar-block:hover::after,
a.pillar-block:focus-visible::after {
  opacity: 1;
  transform: none;
}
a.pillar-block:hover b,
a.pillar-block:focus-visible b {
  text-decoration: underline;
  text-decoration-color: var(--brand-1);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

.pillar-foot {
  margin-top: auto;
  padding: 18px 0 20px;
}
.pillar-foot a {
  font-family: var(--display);
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--brand-1);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.pillar-foot a:hover { color: var(--brand-1); }

.badge {
  display: inline-block;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border: 1.5px solid var(--ink);
  box-shadow: 2px 2px 0 var(--ink);
  margin-bottom: 10px;
}
.badge-atomic { background: var(--brand-1); color: var(--on-brand); }
.badge-backbone { background: var(--brand-2); color: #fff; }
.badge-canvas { background: var(--brand-3); color: var(--on-brand); }
.badge-deed { background: #facc15; color: var(--on-brand); }
.badge-edge { background: #38bdf8; color: var(--on-brand); }

.blocks-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* A pillar's head, then its rows, arrive in turn each time its tab is
   chosen: .active is re-added, which restarts the animations. */
@keyframes block-arrive {
  0%   { opacity: 0; transform: translateY(8px); }
  100% { opacity: 1; transform: translateY(0); }
}
.pillar-panel.active .pillar-title-face {
  animation: pillar-title-in 380ms cubic-bezier(0.2, 0.7, 0.3, 1) 0.2s backwards;
}
.pillar-panel.active .pillar-head h3,
.pillar-panel.active .pillar-head p,
.pillar-panel.active .pillar-blocks li {
  animation: block-arrive 300ms cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}
.pillar-panel.active .pillar-blocks li:nth-child(1) { animation-delay: 0.04s; }
.pillar-panel.active .pillar-blocks li:nth-child(2) { animation-delay: 0.08s; }
.pillar-panel.active .pillar-blocks li:nth-child(3) { animation-delay: 0.12s; }
.pillar-panel.active .pillar-blocks li:nth-child(4) { animation-delay: 0.16s; }
.pillar-panel.active .pillar-blocks li:nth-child(5) { animation-delay: 0.20s; }
.pillar-panel.active .pillar-blocks li:nth-child(6) { animation-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
  .pillar-panel.active .pillar-title-face,
  .pillar-panel.active .pillar-head h3,
  .pillar-panel.active .pillar-head p,
  .pillar-panel.active .pillar-blocks li { animation: none; }
  .pillar-tab, .pillar-tab::before, .pillar-tab-face, .pillar-sheet::after { transition: none; }
}

.block-card {
  background: #f8fafc;
  border: 1.5px solid var(--ink);
  padding: 16px;
  box-shadow: 3px 3px 0 var(--ink);
}
.block-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  font-family: var(--display);
  font-size: 15px;
  color: var(--ink);
}
.block-dot {
  width: 8px;
  height: 8px;
  border: 1px solid var(--ink);
}
.dot-atomic { background: var(--brand-1); }
.dot-backbone { background: var(--brand-2); }
.dot-canvas { background: var(--brand-3); }
.dot-deed { background: var(--ink); }
.dot-edge { background: white; }
.block-card p {
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--muted);
  margin: 0;
}

/* DevExcellence Interactive Views */
#polyglot .split-left {
  height: 100%;
}
.devex-view {
  display: none;
  height: 100%;
  animation: viewFadeIn 0.2s ease forwards;
}
.devex-view.active {
  display: flex;
  flex-direction: column;
}

/* DevExcellence Selector Buttons on the Right */
.devex-pillars {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 10px;
}
.devex-tile {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  background: #ffffff;
  border: 2px solid var(--ink);
  padding: 18px 20px;
  box-shadow: 4px 4px 0 var(--ink);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  width: 100%;
  transform: translateY(-2px);
  transition: transform .08s cubic-bezier(.34, 1.56, .64, 1),
              box-shadow .08s cubic-bezier(.34, 1.56, .64, 1),
              background .12s ease, border-color .12s ease;
}
.devex-tile:hover {
  transform: translateY(-4px);
  box-shadow: 6px 6px 0 var(--ink);
}
.devex-tile:active {
  transform: translateY(0);
  box-shadow: 1px 1px 0 var(--ink);
}
.devex-tile.active {
  background: #ffffff;
  border-color: var(--brand-2);
  transform: translateY(0);
  box-shadow: 4px 4px 0 var(--brand-2);
}
.devex-icon-box {
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  background: #f4f4f6;
  color: var(--ink);
  border: 2px solid var(--ink);
  display: grid;
  place-items: center;
  box-shadow: 2px 2px 0 var(--ink);
  transition: background 0.15s ease, color 0.15s ease,
              border-color 0.15s ease, box-shadow 0.15s ease;
}
/* Colour classes are overridden to neutral until the tile is active */
.devex-icon-box.orange,
.devex-icon-box.purple,
.devex-icon-box.green {
  background: #f4f4f6;
  color: var(--ink);
}
.devex-tile.active .devex-icon-box {
  background: var(--brand-2);
  color: #ffffff;
  border-color: var(--brand-2);
  box-shadow: 2px 2px 0 var(--brand-2);
}
.devex-icon-box svg { width: 20px; height: 20px; }

.devex-meta {
  flex: 1;
}
.devex-meta-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}
.devex-meta h4 {
  font-family: var(--display);
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
}
.devex-chip {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  background: #f4f4f6;
  border: 1px solid var(--ink);
  color: var(--ink);
}
.devex-tile.active .devex-chip {
  background: var(--ink);
  color: #ffffff;
}
.devex-meta p {
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--muted);
  margin: 0;
}

/* CLI Console Styling */
.cli-console {
  background: #1b2844;
  border: 2px solid var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.cli-console-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px;
  background: #131d30;
  border-bottom: 2px solid #2d3f66;
  flex-shrink: 0;
}
.cli-header-left {
  display: flex;
  align-items: center;
  gap: 10px;
}
.cli-tab-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--brand-2);
  color: #ffffff;
  border: 1.5px solid var(--ink);
  padding: 4px 10px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  box-shadow: 2px 2px 0 var(--ink);
}
.cli-header-sub {
  font-family: var(--mono);
  font-size: 11px;
  color: #8aa0c8;
}
.cli-mode-tag {
  font-family: var(--mono);
  font-size: 11px;
  color: #cbd5e1;
}
.cli-snippet-box {
  padding: 20px 24px;
  background: #1b2844;
  flex: 1;
  overflow-y: auto;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.6;
}
.cli-cmd-block {
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px dashed rgba(255,255,255,0.1);
}
.cli-cmd-block:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}
.cli-cmd-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: #f1f5f9;
}
.cli-prompt {
  color: var(--brand-1);
  font-weight: 700;
}
.cli-cmd-text {
  font-weight: 700;
  color: #ffffff;
}
.cli-cmt-inline {
  color: #64748b;
  font-size: 12px;
  font-style: italic;
  margin-left: 6px;
}
.cli-output-row {
  margin-top: 4px;
  padding-left: 16px;
  color: #cbd5e1;
  font-size: 12.5px;
}
.cli-ok {
  color: var(--brand-3);
  font-weight: 700;
  margin-right: 4px;
}
.cli-arrow {
  color: var(--brand-1);
  font-weight: 700;
  margin-right: 4px;
}
.cli-url {
  color: #93c5fd;
  text-decoration: underline;
}
.cli-output-row.log {
  background: #151f33;
  padding: 4px 8px;
  border-left: 2px solid var(--brand-3);
  margin-top: 6px;
  font-size: 12px;
}
.log-dim { color: #64748b; }
.log-info { color: #34d399; font-weight: 600; }
/* Two plain notes, set apart by the room between them. */
.cli-footer {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 28px;
  padding: 12px 20px;
  background: #151f33;
  border-top: 1px solid #253658;
  flex-shrink: 0;
}
.cli-footer-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: #cbd5e1;
}

/* Flow Console Styling */
.flow-console {
  background: #1b2844;
  border: 2px solid var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.flow-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px;
  background: #131d30;
  border-bottom: 2px solid #2d3f66;
  flex-shrink: 0;
}
.flow-header-left {
  display: flex;
  align-items: center;
  gap: 10px;
}
.flow-tab-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--brand-3);
  color: var(--on-brand);
  border: 1.5px solid var(--ink);
  padding: 4px 10px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  box-shadow: 2px 2px 0 var(--ink);
}
.flow-header-sub {
  font-family: var(--mono);
  font-size: 11px;
  color: #8aa0c8;
}
.flow-tag {
  font-family: var(--mono);
  font-size: 11px;
  color: #a7f3d0;
  background: rgba(16,185,129,0.15);
  border: 1px solid rgba(16,185,129,0.3);
  padding: 2px 8px;
}
.flow-steps-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  padding: 18px;
  background: #1b2844;
  flex: 1;
  align-content: stretch;
}
.flow-step-card {
  display: flex;
  gap: 12px;
  background: #151f33;
  border: 1.5px solid #2d3f66;
  padding: 14px;
}
.flow-step-num {
  font-family: var(--mono);
  font-size: 18px;
  font-weight: 800;
  color: var(--brand-3);
  line-height: 1;
}
.flow-step-body h5 {
  font-family: var(--display);
  font-size: 14.5px;
  font-weight: 700;
  color: #ffffff;
  margin: 0 0 4px;
}
.flow-step-body p {
  font-size: 12.5px;
  line-height: 1.45;
  color: #94a3b8;
  margin: 0;
}
.flow-step-body code {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--brand-1);
  background: #1e2c46;
  padding: 1px 4px;
}
.flow-footer {
  padding: 12px 20px;
  background: #131d30;
  border-top: 1px solid #253658;
  flex-shrink: 0;
}
.flow-footer-item {
  font-size: 12.5px;
  color: #cbd5e1;
}
.flow-footer-item b {
  color: #ffffff;
}

/* ---- CLI console entrance animation ----------------------------------------
   Header slides in from the top. Each cmd-block then cascades down the
   terminal one by one, simulating a live session running. Footer arrives last. */
@keyframes cli-header-drop {
  0%   { opacity: 0; transform: translateY(-10px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes cli-block-in {
  0%   { opacity: 0; transform: translateX(-8px); }
  60%  { transform: translateX(2px); }
  100% { opacity: 1; transform: translateX(0); }
}
@keyframes cli-footer-in {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

.devex-view.active .cli-console-header {
  animation: cli-header-drop 300ms cubic-bezier(0.2, 0.7, 0.3, 1) 0.04s backwards;
}
.devex-view.active .cli-cmd-block {
  animation: cli-block-in 340ms cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}
.devex-view.active .cli-cmd-block:nth-child(1) { animation-delay: 0.18s; }
.devex-view.active .cli-cmd-block:nth-child(2) { animation-delay: 0.34s; }
.devex-view.active .cli-cmd-block:nth-child(3) { animation-delay: 0.50s; }
.devex-view.active .cli-cmd-block:nth-child(4) { animation-delay: 0.66s; }
.devex-view.active .cli-footer {
  animation: cli-footer-in 280ms ease 0.84s backwards;
}

@media (prefers-reduced-motion: reduce) {
  .devex-view.active .cli-console-header,
  .devex-view.active .cli-cmd-block,
  .devex-view.active .cli-footer { animation: none; }
}

/* ---- Flow console entrance animation ----------------------------------------
   Header slides down. Step cards arrive in reading order (left→right, top→bottom)
   with a punch-up feel. The step number briefly brightens on arrival.
   Footer fades in after all cards are down. */
@keyframes flow-header-in {
  0%   { opacity: 0; transform: translateY(-8px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes flow-card-in {
  0%   { opacity: 0; transform: translateY(14px); }
  55%  { transform: translateY(-5px); }
  80%  { transform: translateY(1px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes flow-num-flash {
  0%   { color: #ffffff; }
  100% { color: var(--brand-3); }
}

.devex-view.active .flow-header {
  animation: flow-header-in 280ms cubic-bezier(0.2, 0.7, 0.3, 1) 0.04s backwards;
}
.devex-view.active .flow-step-card {
  animation: flow-card-in 380ms cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}
.devex-view.active .flow-step-card:nth-child(1) { animation-delay: 0.16s; }
.devex-view.active .flow-step-card:nth-child(2) { animation-delay: 0.26s; }
.devex-view.active .flow-step-card:nth-child(3) { animation-delay: 0.36s; }
.devex-view.active .flow-step-card:nth-child(4) { animation-delay: 0.46s; }
/* Step numbers flash bright white → green after their card arrives */
.devex-view.active .flow-step-card:nth-child(1) .flow-step-num { animation: flow-num-flash 400ms ease 0.46s both; }
.devex-view.active .flow-step-card:nth-child(2) .flow-step-num { animation: flow-num-flash 400ms ease 0.56s both; }
.devex-view.active .flow-step-card:nth-child(3) .flow-step-num { animation: flow-num-flash 400ms ease 0.66s both; }
.devex-view.active .flow-step-card:nth-child(4) .flow-step-num { animation: flow-num-flash 400ms ease 0.76s both; }
.devex-view.active .flow-footer {
  animation: cli-footer-in 280ms ease 0.72s backwards;
}

@media (prefers-reduced-motion: reduce) {
  .devex-view.active .flow-header,
  .devex-view.active .flow-step-card,
  .devex-view.active .flow-step-card .flow-step-num,
  .devex-view.active .flow-footer { animation: none; }
}

/* DevExcellence Polyglot Workbench Console */
.poly-console {
  background: #1b2844;
  border: 2px solid var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
}
/* The rows arrive one after another as the view opens, then the handler
   under them. Scoped to .devex-view.active, so it replays each time. */
@keyframes poly-row-in {
  0%   { opacity: 0; transform: translateX(-10px); }
  100% { opacity: 1; transform: none; }
}
@keyframes poly-code-in {
  0%   { opacity: 0; transform: translateY(8px); }
  100% { opacity: 1; transform: translateY(0); }
}

.devex-view.active .poly-row {
  animation: poly-row-in 300ms cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}
.devex-view.active .poly-row:nth-child(1) { animation-delay: 0.00s; }
.devex-view.active .poly-row:nth-child(2) { animation-delay: 0.06s; }
.devex-view.active .poly-row:nth-child(3) { animation-delay: 0.12s; }
.devex-view.active .poly-row:nth-child(4) { animation-delay: 0.18s; }
.devex-view.active .poly-row:nth-child(5) { animation-delay: 0.24s; }
.devex-view.active .poly-row:nth-child(6) { animation-delay: 0.30s; }
.devex-view.active .poly-code-box {
  animation: poly-code-in 380ms cubic-bezier(0.2, 0.7, 0.3, 1) 0.36s backwards;
}
.devex-view.active .poly-footer {
  animation: poly-code-in 280ms ease 0.5s backwards;
}

@media (prefers-reduced-motion: reduce) {
  .devex-view.active .poly-row,
  .devex-view.active .poly-code-box,
  .devex-view.active .poly-footer { animation: none; }
}

.poly-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 14px;
  padding: 12px 18px;
  background: #131d30;
  border-bottom: 1px solid #2d3f66;
}
.poly-route {
  padding: 3px 9px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--on-brand);
  background: var(--brand-1);
}
.poly-head-note {
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #94a3b8;
}

/* A row: the language, its runtime, and the one line that reads the cache.
   The calls share a column, so their get("menu") line up down the rows. */
.poly-rows {
  display: flex;
  flex-direction: column;
  padding: 8px 0;
  background: #151f33;
  border-bottom: 2px solid #2d3f66;
}
.poly-row {
  display: grid;
  grid-template-columns: 34px 92px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  padding: 7px 18px 7px 15px;
  font: inherit;
  text-align: left;
  color: #94a3b8;
  background: transparent;
  border: 0;
  border-left: 3px solid transparent;
  cursor: pointer;
  transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
}
.poly-row:hover { color: #f1f5f9; background: #1c2b47; }
.poly-row:focus-visible { outline: 2px solid var(--brand-1); outline-offset: -2px; }
.poly-row.active {
  color: #ffffff;
  background: #1b2844;
  border-left-color: var(--brand-1);
}
.poly-row .poly-lang-badge { justify-self: start; }
.poly-row-runtime {
  font-family: var(--mono);
  font-size: 11.5px;
  white-space: nowrap;
}
.poly-row-call {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 13px;
  color: #cbd5e1;
}
.poly-row-call b { font-weight: 600; color: #6ee7b7; }
.poly-row.active .poly-row-call { color: #ffffff; }
.poly-row.active .poly-row-call b { color: var(--brand-3); }
/* On a phone the runtime drops out; the code box under the rows names it. */
@media (max-width: 580px) {
  .poly-row { grid-template-columns: 34px minmax(0, 1fr); padding-right: 12px; }
  .poly-row-runtime { display: none; }
  .poly-row-call { font-size: 12px; }
}

.poly-lang-badge {
  font-size: 10px;
  font-weight: 800;
  padding: 2px 5px;
  border-radius: 2px;
  text-transform: uppercase;
  color: #ffffff;
}
.bg-go { background: #00acd7; }
.bg-py { background: #3776ab; }
.bg-ts { background: #3178c6; }
.bg-rb { background: #cc342d; }
.bg-rs { background: #dea584; color: #1b2844; }
.bg-php { background: #777bb4; }

.poly-code-box {
  background: #1b2844;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.poly-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px;
  background: #131d30;
  border-bottom: 1px solid #253658;
  flex-shrink: 0;
}
.poly-file-info {
  display: flex;
  align-items: center;
  gap: 8px;
}
.poly-filename {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  color: #c9d7f0;
}
.poly-bar-tools {
  display: flex;
  align-items: center;
  gap: 12px;
}
.poly-runtime-tag {
  font-family: var(--mono);
  font-size: 11px;
  color: #8aa0c8;
  background: #1e2c46;
  border: 1px solid #2d3f66;
  padding: 2px 8px;
}
.poly-copy-btn {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 10px;
  background: var(--ink);
  color: #ffffff;
  border: 1px solid var(--muted);
  cursor: pointer;
  transition: all 0.1s ease;
}
.poly-copy-btn:hover {
  background: var(--brand-1);
  color: var(--on-brand);
  border-color: var(--brand-1);
}
.poly-copy-btn.copied {
  background: var(--brand-3);
  color: var(--on-brand);
  border-color: var(--brand-3);
}

.poly-snippet-view {
  padding: 20px 24px;
  flex: 1;
  overflow-y: auto;
}
.poly-code {
  margin: 0;
  font-family: var(--mono);
  font-size: 13.5px;
  line-height: 1.6;
  color: #f1f5f9;
  white-space: pre;
}

/* Syntax Highlighting Tokens */
.poly-code .kw { color: #f1a006; font-weight: 600; }
.poly-code .str { color: #6ee7b7; }
.poly-code .cmt { color: #64748b; font-style: italic; }
.poly-code .fn { color: #93c5fd; }
.poly-code .num { color: #f472b6; }

.poly-footer {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  padding: 12px 20px;
  background: #151f33;
  border-top: 1px solid #253658;
  flex-shrink: 0;
}
.poly-feature-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: #cbd5e1;
}
.poly-feature-pill svg {
  color: var(--brand-3);
}

/* Sovereignty Section */
.eu-stat-plaque {
  background: #ffffff;
  border: 2px solid var(--ink);
  padding: 18px 20px;
  box-shadow: 4px 4px 0 var(--ink);
}
.stat-highlight {
  display: flex;
  align-items: center;
  gap: 16px;
}
.stat-digit {
  font-family: var(--display);
  font-size: 44px;
  font-weight: 800;
  line-height: 1;
  color: var(--brand-1);
}
.stat-caption {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
}

.eu-side-note,
.port-side-note {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted);
  border-left: 3px solid var(--brand-1);
  padding-left: 14px;
}

.sovereignty-box {
  padding: clamp(24px, 3.5vw, 36px);
}
.seal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 16px;
  margin-bottom: 20px;
}
.seal-header-left {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.seal-badge {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  background: #dbeafe;
  border: 1.5px solid var(--ink);
  padding: 4px 10px;
  color: var(--ink);
  box-shadow: 2px 2px 0 var(--ink);
  display: inline-block;
  align-self: flex-start;
}
.seal-meta {
  font-size: 12px;
  color: var(--muted);
}
.seal-indicator {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
}

.eu-fact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 4px;
}
.eu-fact-card {
  background: white;
  border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.eu-fact-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  background: var(--ink);
  color: #fff;
  flex-shrink: 0;
  margin-bottom: 2px;
}
.eu-fact-q {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin: 0;
  line-height: 1.35;
}
.eu-fact-a {
  font-family: var(--display);
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
  line-height: 1.4;
}

.eu-outside-callout {
  margin-top: 20px;
  padding: 16px;
  background: #f8fafc;
  border: 1.5px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
}
.callout-badge {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--brand-1);
  margin-bottom: 6px;
}
.eu-outside-callout p {
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
  margin: 0;
}

/* ── European Disclosure Cards (left column) ─────────────────── */
.eu-disc-stack {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
}

.eu-disc-card {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  background: var(--panel);
  border: 2px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  width: 100%;
  padding: 18px 20px;
  transform: translateY(-2px);
  transition: transform .08s cubic-bezier(.34, 1.56, .64, 1),
              box-shadow .08s cubic-bezier(.34, 1.56, .64, 1),
              border-color .12s ease;
}
.eu-disc-card:hover {
  transform: translateY(-4px);
  box-shadow: 6px 6px 0 var(--ink);
}
.eu-disc-card:active {
  transform: translateY(0);
  box-shadow: 1px 1px 0 var(--ink);
}
.eu-disc-card.active {
  border-color: var(--brand-1);
  box-shadow: 4px 4px 0 var(--brand-1);
  transform: translateY(0);
}

.eu-disc-icon-box {
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  background: #f4f4f6;
  border: 2px solid var(--ink);
  display: grid;
  place-items: center;
  color: var(--ink);
  box-shadow: 2px 2px 0 var(--ink);
  transition: background .15s ease, color .15s ease,
              border-color .15s ease, box-shadow .15s ease;
}
.eu-disc-card.active .eu-disc-icon-box {
  background: var(--brand-1);
  color: var(--on-brand);
}

.eu-disc-meta {
  flex: 1;
  min-width: 0;
}
.eu-disc-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}
.eu-disc-card h3 {
  font-family: var(--display);
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
  line-height: 1.2;
}
.eu-disc-chip {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  background: #f4f4f6;
  border: 1px solid var(--ink);
  color: var(--ink);
  white-space: nowrap;
  flex-shrink: 0;
}
.eu-disc-card.active .eu-disc-chip {
  background: var(--ink);
  color: #ffffff;
}
.eu-disc-meta p {
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--muted);
  margin: 0;
}

/* ── European Disclosure Panels (right column) ───────────────── */
#europe .split-right {
  display: flex;
  flex-direction: column;
}

.eu-disc-idle {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-height: 280px;
  border: 2px dashed var(--ink);
  opacity: 0.35;
  transition: opacity 0.2s ease;
}
.eu-disc-idle.hidden { display: none; }

.eu-disc-panel {
  display: none;
  flex: 1;
}
.eu-disc-panel.active {
  display: flex;
  flex-direction: column;
}

/* Card entrance — punch up, staggered in reading order */
@keyframes euCardArrive {
  0%   { opacity: 0; transform: translateY(14px); }
  55%  { transform: translateY(-4px); }
  80%  { transform: translateY(1px); }
  100% { opacity: 1; transform: translateY(0); }
}

.eu-disc-panel.active .eu-disc-fact-card {
  animation: euCardArrive 360ms cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}
.eu-disc-panel.active .eu-disc-fact-card:nth-child(1) { animation-delay: 0.04s; }
.eu-disc-panel.active .eu-disc-fact-card:nth-child(2) { animation-delay: 0.12s; }
.eu-disc-panel.active .eu-disc-fact-card:nth-child(3) { animation-delay: 0.20s; }
.eu-disc-panel.active .eu-disc-fact-card:nth-child(4) { animation-delay: 0.28s; }

@media (prefers-reduced-motion: reduce) {
  .eu-disc-panel.active .eu-disc-fact-card { animation: none; }
}

/* Fact-card grid inside panels */
.eu-disc-cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: 1fr 1fr;
  gap: 12px;
  flex: 1;
}
/* Two cards across need room for their text; on a phone they stack. */
@media (max-width: 700px) {
  .eu-disc-cards {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
  }
}

.eu-disc-fact-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--panel);
  border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  padding: 22px 20px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.eu-disc-fact-card--caution {
  border-color: var(--brand-1);
  box-shadow: 3px 3px 0 var(--brand-1);
}

/* Icon + title/subtitle in a horizontal row */
.eu-disc-fact-header {
  display: flex;
  align-items: center;
  gap: 14px;
}

.eu-disc-fact-icon {
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  background: var(--ink);
  border: 2px solid var(--ink);
  color: #ffffff;
}
.eu-disc-fact-card--caution .eu-disc-fact-icon {
  background: var(--brand-1);
  border-color: var(--ink);
  color: var(--on-brand);
}

.eu-disc-fact-heading {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.eu-disc-fact-title {
  font-family: var(--display);
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.25;
  margin: 0;
}
.eu-disc-fact-sub {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  line-height: 1.2;
  margin: 0;
}
.eu-disc-fact-card p {
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
  margin: 0;
  flex: 1;
}
.eu-disc-fact-card p a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--brand-1);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.eu-disc-fact-card p a:hover { color: var(--brand-1); }

/* ── EU Interstitial CTA ─────────────────────────────────────── */
.eu-interstitial {
  background: var(--brand-1);
  border-top: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
  padding: 24px;
}

.eu-int-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
}

.eu-int-eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--on-brand);
  opacity: 0.55;
  margin: 0;
}

.eu-int-btn {
  margin-top: 4px;
}

/* ── Portability Section ─────────────────────────────────────── */
/* A light band on white. The export is a white packing list on the brand's
   stepped plates. */
#portability .section-sub strong { color: var(--ink); font-weight: 600; }
.port-split { align-items: stretch; }
.port-copy-col {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.port-bottom-bundle {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.port-stat-card {
  background: #ffffff;
  border: 2px solid var(--ink);
  padding: 14px 20px;
  box-shadow: 4px 4px 0 var(--ink);
}
.term-p { color: var(--brand-1); font-weight: 700; margin-right: 6px; }

/* The export, as a packing list: a white sheet on the brand's three stepped
   plates. The stage leaves room for the plates' step. */
.port-stage {
  position: relative;
  isolation: isolate;
  margin: 0 24px 24px 0;
}
.port-plate {
  position: absolute;
  inset: 0;
  z-index: 0;
  border: 2px solid var(--ink);
}
.port-plate-orange { background: var(--brand-1); transform: translate(8px, 8px); }
.port-plate-green  { background: var(--brand-3); transform: translate(16px, 16px); }
.port-plate-purple { background: var(--brand-2); transform: translate(24px, 24px); }

.port-console {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border: 2px solid var(--ink);
  display: flex;
  flex-direction: column;
  height: 100%;
}
.port-console-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  border-bottom: 2px solid var(--ink);
  flex-shrink: 0;
}
.port-console-label {
  flex: none;
  padding: 3px 8px;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--on-brand);
  background: var(--brand-1);
  border: 1.5px solid var(--ink);
}
.port-console-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
}
.port-console-kind {
  margin-left: auto;
  flex: none;
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
}
.port-console-body {
  flex: 1;
  padding: 18px 18px 16px;
  display: flex;
  flex-direction: column;
}

/* Each line is hidden until hero.js reveals it. */
.port-con-line {
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 0.22s ease, transform 0.22s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.port-con-line.port-line-in {
  opacity: 1;
  transform: none;
}

/* The two commands, on a grey strip each; a long one scrolls in its strip. */
.port-con-cmd {
  margin-bottom: 6px;
  padding: 7px 12px;
  overflow-x: auto;
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
  background: #f4f4f6;
  border: 1px solid var(--rule);
}
.port-con-prompt { color: var(--brand-1); font-weight: 700; margin-right: 10px; }

.port-con-head {
  margin: 14px 0 4px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
}

/* The contents: the pillar's square, the path, and what it holds. */
.port-con-items {
  list-style: none;
  margin: 0;
  padding: 0;
}
.port-con-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 12px;
  padding: 8px 0;
  border-bottom: 1px dashed var(--rule);
}
.port-con-fname {
  min-width: 0;
  overflow-wrap: anywhere;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
}
.port-con-what {
  font-size: 13px;
  color: var(--muted);
  text-align: right;
}

/* The seal. */
.port-con-done {
  margin: 14px 0 0;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--ink);
}
.port-con-ok {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  margin-right: 10px;
  font-size: 12px;
  font-weight: 700;
  color: var(--on-brand);
  background: var(--brand-3);
  border: 1.5px solid var(--ink);
  vertical-align: -3px;
}

.port-console-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 18px;
  background: #f4f4f6;
  border-top: 2px solid var(--ink);
  flex-shrink: 0;
}
.port-con-badge-law {
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--muted);
}
.port-con-badge-date {
  font-weight: 700;
  color: var(--ink);
}
/* The copy button is light on the packing list and dark on the free slice's
   command, which shares it. */
#portability .port-copy-btn {
  background: var(--panel);
  color: var(--ink);
  border: 1.5px solid var(--ink);
}
.port-copy-btn {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 4px 10px;
  background: #1b2844;
  color: #e2e8f0;
  border: 1px solid #2d3f66;
  cursor: pointer;
  transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
  flex-shrink: 0;
}
.port-copy-btn:hover {
  background: var(--brand-1);
  color: var(--on-brand);
  border-color: var(--brand-1);
}
.port-copy-btn.copied {
  background: var(--brand-3);
  color: var(--on-brand);
  border-color: var(--brand-3);
}
#portability .port-copy-btn:hover {
  background: var(--brand-1);
  color: var(--on-brand);
}
#portability .port-copy-btn.copied {
  background: var(--brand-3);
  color: var(--on-brand);
}

@media (prefers-reduced-motion: reduce) {
  .port-con-line { opacity: 1 !important; transform: none !important; transition: none !important; }
}
@media (max-width: 580px) {
  .port-stage { margin: 0 16px 16px 0; }
  .port-plate-orange { transform: translate(5px, 5px); }
  .port-plate-green  { transform: translate(10px, 10px); }
  .port-plate-purple { transform: translate(16px, 16px); }
  .port-console-kind { display: none; }
  .port-con-item { grid-template-columns: auto minmax(0, 1fr); }
  .port-con-what { grid-column: 2; text-align: left; }
  .port-console-footer { flex-wrap: wrap; }
}

/* ── Price ─────────────────────────────────────────────────────
   The third light band, on the desk. Four unit prices on a card, then four
   shapes priced from them, each a receipt: what the shape holds, the
   arithmetic line by line, and the month's total on an ink strip. A unit's
   square wears the colour of the pillar that owns it (functions and jobs are
   Atomic, realtime is Backbone), and storage wears all three, as it bills on
   three lines. */
.price-top { align-items: start; }
.price-top .section-head { margin-bottom: 0; }

.price-rates {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--panel);
  border: 2px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
}
.price-rate {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name cost" "unit cost";
  column-gap: 16px;
  align-items: center;
  padding: 14px 20px;
  border-bottom: 1px solid var(--rule);
}
.price-rate:nth-last-child(2) { border-bottom: 0; }
.price-rate-name {
  grid-area: name;
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
}
.price-rate-unit {
  grid-area: unit;
  padding-left: 20px;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--muted);
}
.price-rate-cost {
  grid-area: cost;
  font-family: var(--display);
  font-size: 28px;
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
  white-space: nowrap;
}
.price-rates-foot {
  margin: 0;
  padding: 12px 20px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--muted);
  border-top: 2px solid var(--ink);
  background: #f4f4f6;
}

.price-marks {
  display: inline-flex;
  flex: none;
  gap: 3px;
}
.price-marks i {
  display: block;
  width: 10px;
  height: 10px;
  background: var(--tone);
  border: 1.5px solid var(--ink);
}

.price-cases {
  list-style: none;
  margin: 56px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 32px;
}
.price-case {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--panel);
  border: 2px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
}
.price-case-head {
  padding: 20px 22px 18px;
  border-bottom: 2px solid var(--ink);
}
.price-case-kind {
  margin: 0 0 6px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
}
.price-case h3 {
  margin: 0 0 8px;
  font-family: var(--display);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.price-case-for {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--muted);
}
.price-shape {
  list-style: none;
  margin: 0;
  padding: 16px 22px;
  display: grid;
  gap: 8px;
  border-bottom: 1px dashed var(--rule);
}
/* A row: the pillar's squares, then what the shape holds as a short lead
   (the quantity, the figure the receipt prices) over what it is for. */
.price-shape li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  color: var(--ink);
}
.price-shape .price-marks { margin-top: 5px; }
.price-shape-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.price-shape-text b {
  font-family: var(--display);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
}
.price-shape-text span {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted);
}
.price-receipt {
  list-style: none;
  margin: 0;
  padding: 6px 22px 14px;
  flex: 1;
}
.price-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name amount" "calc amount";
  column-gap: 16px;
  align-items: baseline;
  padding: 10px 0;
  border-bottom: 1px solid var(--rule);
}
.price-line:last-child { border-bottom: 0; }
.price-line-name {
  grid-area: name;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}
.price-line-calc {
  grid-area: calc;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}
.price-line-amount {
  grid-area: amount;
  align-self: center;
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}
.price-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  padding: 14px 22px 16px;
  color: #ffffff;
  background: var(--ink);
}
.price-total-label {
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #c8d6ef;
}
.price-total-sum {
  font-family: var(--display);
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
}

/* The picker: a button per shape with its total. hero.js shows it and sets
   .is-picking on the receipts, which hides them all but the one opened. The
   opened receipt lies flat under the buttons: its shape on the left, the
   arithmetic and the total on the right. */
.price-picker {
  margin-top: 56px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px;
}
.price-picker[hidden] { display: none; }
.price-pick {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 16px 44px 16px 18px;
  font: inherit;
  text-align: left;
  color: var(--ink);
  background: var(--panel);
  border: 2px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.price-pick:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--ink);
}
.price-pick:focus-visible {
  outline: 3px solid var(--brand-1);
  outline-offset: 3px;
}
.price-pick[aria-expanded="true"] {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--brand-1);
}
.price-pick .price-case-kind { margin: 0; }
.price-pick-title {
  flex: 1;
  font-family: var(--display);
  font-size: 17px;
  font-weight: 700;
  line-height: 1.25;
}
.price-pick-sum {
  margin-top: 10px;
  font-family: var(--display);
  font-size: 28px;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
}
.price-pick-sum small {
  margin-left: 4px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
}
.price-pick-cue {
  position: absolute;
  top: 14px;
  right: 14px;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--ink);
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
}
.price-pick-cue::before { content: "+"; }
.price-pick[aria-expanded="true"] .price-pick-cue {
  color: var(--on-brand);
  background: var(--brand-1);
}
.price-pick[aria-expanded="true"] .price-pick-cue::before { content: "\2212"; }

.price-cases.is-picking {
  grid-template-columns: minmax(0, 1fr);
  margin-top: 24px;
}
.price-cases.is-picking .price-case { display: none; }
.price-cases.is-picking .price-case.is-open {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-areas: "head head" "shape receipt" "shape total";
  grid-template-rows: auto 1fr auto;
}
.price-cases.is-picking .price-case-head { grid-area: head; }
.price-cases.is-picking .price-shape {
  grid-area: shape;
  align-content: start;
  gap: 0;
  padding: 8px 26px 12px 22px;
  border-bottom: 0;
  border-right: 1px dashed var(--rule);
}
.price-cases.is-picking .price-shape li { padding: 12px 0; }
.price-cases.is-picking .price-shape li + li { border-top: 1px solid var(--rule); }
.price-cases.is-picking .price-receipt { grid-area: receipt; }
.price-cases.is-picking .price-total { grid-area: total; }

.price-notes {
  list-style: none;
  margin: 48px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px 40px;
}
.price-notes li {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--muted);
  border-left: 3px solid var(--ink);
  padding-left: 14px;
}
.price-notes code {
  font-family: var(--mono);
  font-size: 0.88em;
  padding: 1px 5px;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--ink);
}
.price-notes b {
  display: block;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 2px;
}
.price-more {
  display: inline-block;
  margin-top: 28px;
  font-family: var(--display);
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--brand-1);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.price-more:hover { color: var(--brand-1); }

@media (max-width: 900px) {
  .price-cases { grid-template-columns: minmax(0, 1fr); gap: 28px; margin-top: 40px; }
  .price-notes { grid-template-columns: minmax(0, 1fr); margin-top: 36px; }
  .price-picker { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 40px; }
  .price-cases.is-picking { margin-top: 24px; }
  .price-cases.is-picking .price-case.is-open {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "head" "shape" "receipt" "total";
    grid-template-rows: none;
  }
  .price-cases.is-picking .price-shape {
    border-right: 0;
    border-bottom: 1px dashed var(--rule);
  }
}
@media (max-width: 580px) {
  .price-picker { gap: 14px; }
  .price-pick { padding: 14px 36px 14px 14px; }
  .price-pick-title { font-size: 15px; }
  .price-pick-sum { font-size: 22px; }
  .price-pick-cue { top: 10px; right: 10px; }
  .price-top { gap: 28px; }
  .price-case-head { padding: 18px 18px 16px; }
  .price-shape { padding: 14px 18px; }
  .price-receipt { padding: 4px 18px 12px; }
  .price-total { padding: 12px 18px 14px; }
  .price-total-sum { font-size: 30px; }
  .price-rate { padding: 12px 16px; }
  .price-rate-cost { font-size: 24px; }
}

/* ── The dark bands: three for the developer ────────────────────
   "Stay in the zone", the five pillars and the free slice. Each band is a
   step darker than the one before, and the consoles keep the dark panel's
   own colour, so they stand off the band as objects, outlined in the
   consoles' rule colour as the free slice's tray is. The white cards keep
   their ink edges; on a dark band the edge is a quiet lift. */
#polyglot h2,
#primitives h2 { color: #ffffff; }
#polyglot .section-sub,
#primitives .section-sub { color: #94a3b8; }
#polyglot .view-idle,
#primitives .view-idle { border-color: #2d3f66; opacity: 0.8; }
#polyglot .view-idle-inner,
#primitives .view-idle-inner,
#polyglot .view-idle-inner p,
#primitives .view-idle-inner p { color: #94a3b8; }
#polyglot .poly-console,
#polyglot .cli-console,
#polyglot .flow-console,
#primitives .wiring-console { border-color: #2d3f66; }
/* The chosen wire is solid ink on a light band; here it is light. */
#primitives .mesh-wire.active path { stroke: #f1f5f9; }

/* On these two bands the cards, the pillar deck and the graph are dark too:
   the consoles' panel, edged in their rule colour, lifted by a near-black
   shadow. A chosen card keeps the brand's edge and shadow. The ink key (Deed,
   and the graph's ink node) would vanish into the panel, so here it is slate. */
#primitives [data-grp="d"] { --key-fill: #64748b; }
#primitives .tone-d { --tone: #64748b; }

#primitives .lede-card,
#polyglot .devex-tile {
  background: #1b2844;
  border-color: #2d3f66;
  box-shadow: 4px 4px 0 #0b1220;
}
#primitives .lede-card:hover,
#polyglot .devex-tile:hover { box-shadow: 6px 6px 0 #0b1220; }
#primitives .lede-card:active,
#polyglot .devex-tile:active { box-shadow: 1px 1px 0 #0b1220; }
#primitives .lede-card.active {
  background: #1b2844;
  border-color: var(--brand-1);
  box-shadow: 4px 4px 0 var(--brand-1);
}
#polyglot .devex-tile.active {
  background: #1b2844;
  border-color: var(--brand-2);
  box-shadow: 4px 4px 0 var(--brand-2);
}
#primitives .lede-card h3,
#polyglot .devex-meta h4 { color: #ffffff; }
#primitives .lede-card p,
#polyglot .devex-meta p { color: #94a3b8; }
#primitives .lede-icon,
#polyglot .devex-icon-box,
#polyglot .devex-icon-box.orange,
#polyglot .devex-icon-box.purple,
#polyglot .devex-icon-box.green {
  background: #151f33;
  color: #f1f5f9;
  border-color: #2d3f66;
  box-shadow: 2px 2px 0 #0b1220;
}
#primitives .lede-icon svg { stroke: #f1f5f9; }
#primitives .lede-card.active .lede-icon { background: var(--brand-1); border-color: var(--brand-1); }
#primitives .lede-card.active .lede-icon svg { stroke: var(--on-brand); }
#polyglot .devex-tile.active .devex-icon-box {
  background: var(--brand-2);
  color: #ffffff;
  border-color: var(--brand-2);
  box-shadow: 2px 2px 0 var(--brand-2);
}
#primitives .lede-badge,
#polyglot .devex-chip {
  background: #151f33;
  border-color: #2d3f66;
  color: #cbd5e1;
}
#primitives .lede-card.active .lede-badge {
  background: var(--brand-1);
  border-color: var(--brand-1);
  color: var(--on-brand);
}
#polyglot .devex-tile.active .devex-chip {
  background: var(--brand-2);
  border-color: var(--brand-2);
  color: #ffffff;
}

/* The pillar deck: dark tabs over a dark sheet, its plate still the key. */
#primitives .pillar-tab {
  color: #cbd5e1;
  background: #151f33;
  border-color: #2d3f66;
}
#primitives .pillar-tab:hover { color: #ffffff; background: #1c2b47; }
#primitives .pillar-sheet {
  background: #1b2844;
  border-color: #2d3f66;
}
#primitives .pillar-title-icon,
#primitives .pillar-title-name,
#primitives .pillar-head h3,
#primitives .pillar-block,
#primitives .pillar-foot a { color: #ffffff; }
#primitives .pillar-title-role,
#primitives .pillar-head p,
#primitives .pillar-block span,
#primitives a.pillar-block::after { color: #94a3b8; }
#primitives .pillar-foot a:hover { color: var(--brand-1); }
#primitives .pillar-head code {
  color: #f1f5f9;
  background: #131d30;
  border-color: #2d3f66;
}
#primitives .pillar-blocks,
#primitives .pillar-blocks li { border-color: #2d3f66; }

/* The graph: dark nodes and a dark detail box; a chosen node still fills
   with its colour, and the hub keeps its ink face on the brand's plates. */
#primitives .mesh-node {
  color: #f1f5f9;
  background: #1b2844;
  border-color: #2d3f66;
  box-shadow: 3px 3px 0 #0b1220;
}
#primitives .mesh-node:hover { box-shadow: 4px 4px 0 #0b1220; }
#primitives .mesh-node[aria-pressed="true"] {
  color: var(--tone-ink);
  background: var(--tone);
  border-color: var(--tone);
  box-shadow: none;
}
#primitives .mesh-node-icon { border-color: #2d3f66; }
#primitives .mesh-node[aria-pressed="true"] .mesh-node-icon {
  color: #f1f5f9;
  background: #1b2844;
}
#primitives .mesh-hub-face { border-color: #2d3f66; }
#primitives .mesh-wire path { stroke: #2d3f66; }
#primitives .mesh-wire circle { fill: #1b2844; stroke: #94a3b8; }
#primitives .mesh-wire.active circle { fill: var(--tone); }
#primitives .mesh-detail {
  background: #1b2844;
  border-color: #2d3f66;
  box-shadow: 4px 4px 0 #0b1220;
}
#primitives .mesh-detail-name { color: #ffffff; }
#primitives .mesh-detail-desc,
#primitives .mesh-detail-note { color: #94a3b8; }
#primitives .mesh-detail-note { border-color: #2d3f66; }

/* ── The free slice ────────────────────────────────────────────
   On the dark band: the copy, three terms, the command; and the slice
   itself, a tray in the consoles' dark panel on the hero's stepped plates,
   holding the free grant's parts under the placeholder names it ships
   with. hero.js sets .is-on as the section comes into view (the plates fan
   out and the parts arrive), retypes the names into a small app, then sets
   .is-priced (the sticker lands and €0 stamps in). */
#free h2 { color: white; }
#free .section-sub { color: #94a3b8; }

.free-split { align-items: center; }
/* Side by side, the tray takes the larger share of the row and reaches past
   the section's middle. Below 1181px the copy's column would leave it too
   narrow for its tiles, so the two stack, the tray at the copy's full width. */
@media (min-width: 1181px) {
  .free-split { grid-template-columns: minmax(340px, 0.8fr) minmax(0, 1.5fr); }
}
@media (max-width: 1180px) {
  .free-split { grid-template-columns: minmax(0, 1fr); gap: 40px; }
}
.free-copy-col {
  display: flex;
  flex-direction: column;
  gap: 26px;
}
.free-copy-col .section-head { margin-bottom: 0; }

.free-terms {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.free-terms li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 15px;
  line-height: 1.5;
  color: #94a3b8;
}
.free-terms b { color: #ffffff; font-weight: 600; }
.free-term-mark {
  flex: none;
  width: 10px;
  height: 10px;
  margin-top: 7px;
  background: var(--tone);
  outline: 1.5px solid #ffffff;
}

/* The command, in the consoles' dark panel, on a green plate. In a column
   too narrow for the command and its button on one line, the button drops
   to a line of its own, at the right. */
.free-command {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 14px;
  max-width: 470px;
  padding: 10px 10px 10px 16px;
  background: #1b2844;
  border: 2px solid #2d3f66;
  box-shadow: 4px 4px 0 var(--brand-3);
}
.free-command code {
  min-width: 0;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 14px;
  color: #f1f5f9;
  white-space: nowrap;
}
.free-prompt {
  margin-right: 10px;
  color: var(--brand-1);
  font-weight: 700;
}
.free-command .port-copy-btn { margin-left: auto; }
.free-more {
  width: fit-content;
  font-family: var(--display);
  font-size: 14px;
  font-weight: 500;
  color: #ffffff;
  text-decoration: underline;
  text-decoration-color: var(--brand-3);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.free-more:hover { color: var(--brand-3); }

/* The stage leaves room for the sticker's overhang and the plates' step;
   the tray fills the rest of its column. */
.free-stage { padding: 26px 30px 30px 0; }
.free-box {
  position: relative;
  isolation: isolate;
}
.free-plate {
  position: absolute;
  inset: 0;
  z-index: 0;
  border: 2px solid var(--ink);
  transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.free-plate-orange { background: var(--brand-1); }
.free-plate-green  { background: var(--brand-3); }
.free-plate-purple { background: var(--brand-2); }
.free-stage.is-on .free-plate-orange { transform: translate(8px, 8px); }
.free-stage.is-on .free-plate-green  { transform: translate(16px, 16px); transition-delay: 0.08s; }
.free-stage.is-on .free-plate-purple { transform: translate(24px, 24px); transition-delay: 0.16s; }

/* The tray wears the consoles' colours (their panel, bar and rules), as the
   command beside it does, so it sits in the band rather than glaring out of
   it; the plates under it and the sticker on it keep the brand's. */
.free-slice {
  position: relative;
  z-index: 1;
  background: #1b2844;
  border: 2px solid #2d3f66;
}
.free-slice-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  background: #131d30;
  border-bottom: 2px solid #2d3f66;
  font-family: var(--mono);
  font-size: 12px;
  color: #f1f5f9;
}
.free-slice-name { font-weight: 700; }
.free-slice-kind {
  padding: 2px 7px;
  border: 1px solid #3a4f78;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #8aa0c8;
}
.free-slice-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 18px 20px 4px;
}
.free-group-label {
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #8aa0c8;
}
.free-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
  gap: 8px;
}

/* A part of the slice: its pillar's square, its name, what it is. Each
   cell has room for the longest name it is retyped into, so retyping never
   reflows the tray. */
.free-tile {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 7px 10px;
  font-family: var(--mono);
  font-size: 12.5px;
  color: #f1f5f9;
  white-space: nowrap;
  background: #151f33;
  border: 1.5px solid #2d3f66;
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 0.3s ease,
    transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1),
    background 0.3s ease,
    border-color 0.3s ease;
  transition-delay: calc(0.3s + var(--i, 0) * 0.06s), calc(0.3s + var(--i, 0) * 0.06s), 0s, 0s;
}
/* The square is outlined in white, as the terms' marks beside it are. */
.free-tile::before {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  background: var(--tone);
  outline: 1.5px solid #ffffff;
}
.free-stage.is-on .free-tile { opacity: 1; transform: none; }
/* Renamed into the app, a part takes on its pillar's colour. */
.free-tile.is-renamed {
  background: color-mix(in srgb, var(--tone) 18%, #151f33);
  border-color: color-mix(in srgb, var(--tone) 60%, #2d3f66);
}
.free-name { overflow: hidden; text-overflow: clip; }
.free-name.is-typing::after {
  content: "";
  display: inline-block;
  width: 1px;
  height: 1.05em;
  margin-left: 1px;
  vertical-align: -2px;
  background: #f1f5f9;
  animation: hero-blink 0.8s step-end infinite;
}
.free-tile-kind {
  margin-left: auto;
  padding-left: 6px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #8aa0c8;
}

/* What the slice carries besides its named parts. */
.free-slice-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 16px 0 0;
  padding: 12px 20px 14px;
  border-top: 1px dashed #2d3f66;
  font-family: var(--mono);
  font-size: 11.5px;
  color: #8aa0c8;
}
.free-slice-foot b { color: #f1f5f9; font-weight: 700; }

/* The price sticker, slapped on the tray's corner once the parts are
   renamed; €0 stamps onto it as it lands. */
.free-sticker {
  position: absolute;
  z-index: 2;
  top: -24px;
  right: -22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 8px 15px 9px;
  color: var(--ink);
  background: var(--brand-1);
  border: 2px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink-darkest);
  transform: rotate(7deg);
  opacity: 0;
}
.free-sticker-now {
  font-family: var(--display);
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
  opacity: 0;
  transform: scale(1.7);
  transition:
    opacity 0.15s ease 0.25s,
    transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) 0.25s;
}
.free-sticker-per {
  font-family: var(--mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.free-stage.is-priced .free-sticker { animation: free-slap 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both; }
.free-stage.is-priced .free-sticker-now { opacity: 1; transform: none; }
@keyframes free-slap {
  from { opacity: 0; transform: rotate(-16deg) scale(1.8); }
  to   { opacity: 1; transform: rotate(7deg) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .free-plate, .free-tile, .free-sticker-now { transition: none; }
  .free-stage.is-priced .free-sticker { animation: none; opacity: 1; }
}

/* ── The last word ──────────────────────────────────────────────
   On the darkest band, where white is the ink: the keys and the buttons
   wear white edges, as the footer's logo does. The headline is the hero's
   own type, and types itself behind the hero's caret; each word that lands
   lights its day of the weekend below, and the line to that day is drawn
   in the word's colour while the word types. hero.js arms the section
   (.is-armed: the headline blank, the days unlit) and plays it once the
   weekend is in view: .is-going on a day draws the line to it over --go,
   and .is-lit lights it. Unarmed, the whole weekend is lit. */
.ship {
  --toy-edge: #ffffff;
  padding: 88px 0 80px;
}
.ship-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.ship-title {
  position: relative;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(40px, 5.2vw, 72px);
  font-weight: 500;
  line-height: 1.04;
  letter-spacing: -0.05em;
  color: #ffffff;
}
.ship-word { color: var(--tone); }
/* hero.js splits the words into letters, which keep their places while
   hidden, so the centred headline never shifts as it types. */
.ship-ch { opacity: 0; }
.ship-ch.is-typed { opacity: 1; }
/* hero.js sets the caret's box to a letter's, beside it and in its colour,
   so the two share a baseline. */
.ship-caret {
  position: absolute;
  margin-left: 0.06em;
  pointer-events: none;
  animation: hero-blink 1s step-end infinite;
}

.ship-week {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  width: 100%;
  max-width: 860px;
  margin: 52px 0 0;
  padding: 0;
}
.ship-day {
  --key: 52px;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 0 6px;
}
/* The line into a day, from the day before's key to this one's, under both:
   the way still to go as a dashed rule, the way gone as a bar in this day's
   colour. */
.ship-day:not(:first-child)::before,
.ship-day:not(:first-child)::after {
  content: "";
  position: absolute;
  left: -50%;
  width: 100%;
}
.ship-day:not(:first-child)::after {
  z-index: 0;
  top: calc(var(--key) / 2 - 1px);
  border-top: 2px dashed #2d3f66;
}
.ship-day:not(:first-child)::before {
  z-index: 1;
  top: calc(var(--key) / 2 - 2px);
  height: 4px;
  background: var(--tone);
  transform-origin: left;
  transition: transform var(--go, 0.5s) linear;
}

/* A day's key: its colour, edged in white. */
.ship-day-key {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  width: var(--key);
  height: var(--key);
  padding-left: 0.08em;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--tone-ink);
  background: var(--tone);
  border: 2px solid #ffffff;
  box-shadow: 3px 3px 0 #ffffff;
  transition:
    color 0.15s ease,
    background 0.15s ease,
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}
/* Monday's colour is white, the ink here, so its key is drawn in it. */
.ship-day.tone-e .ship-day-key {
  color: #ffffff;
  background: var(--ink-darkest);
}
/* The square shock as a key lights, the one the hero's blocks break
   ground with. */
.ship-day-key::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--key) * 2.1);
  height: calc(var(--key) * 2.1);
  border: 2px solid var(--tone);
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
  pointer-events: none;
}
.ship-day-what {
  font-family: var(--display);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.3;
  color: #f1f5f9;
  transition: color 0.3s ease;
}

.ship.is-armed .ship-day:not(.is-going):not(.is-lit)::before { transform: scaleX(0); }
.ship.is-armed .ship-day:not(.is-lit) .ship-day-key {
  color: #64748b;
  background: #0f1724;
  border-color: #2d3f66;
  box-shadow: 0 0 0 #2d3f66;
}
.ship.is-armed .ship-day:not(.is-lit) .ship-day-what { color: #64748b; }
.ship.is-armed .ship-day.is-lit .ship-day-key { animation: ship-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); }
.ship.is-armed .ship-day.is-lit .ship-day-key::after { animation: eu-shock 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) both; }
@keyframes ship-pop {
  0%   { transform: scale(0.82); }
  55%  { transform: scale(1.12); }
  100% { transform: none; }
}

.ship-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 18px;
  margin-top: 48px;
}
/* The light page's secondary button is white paper; here it is the band's
   own dark, lettered in white. */
.ship .secondary {
  background: var(--ink-darkest);
  color: #ffffff;
}

@media (max-width: 580px) {
  .ship { padding: 64px 0 56px; }
  .ship-week { margin-top: 40px; }
  .ship-day { --key: 44px; gap: 12px; padding: 0 2px; }
  .ship-day-key { font-size: 12px; }
  .ship-day-what { font-size: 13.5px; }
  .ship-actions { margin-top: 40px; }
}

/* Call to Action Terminal Rig */
.cta-terminal-rig {
  background: #1b2844;
  border: 2px solid var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
  overflow: hidden;
}
.terminal-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 16px;
  background: #131d30;
  border-bottom: 1px solid #253658;
}
.term-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #475569;
}
.terminal-title {
  margin-left: 8px;
  font-family: var(--mono);
  font-size: 11px;
  color: #8aa0c8;
}
.cta-terminal {
  background: #1b2844;
  padding: 24px;
  font-family: var(--mono);
  font-size: 13.5px;
  line-height: 1.8;
  color: #f1f5f9;
}
.term-comment { color: #8aa0c8; font-style: italic; }
.term-prompt { color: var(--brand-1); font-weight: 700; margin-right: 6px; }
.cta-terminal-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 18px;
  background: #151f33;
  border-top: 1px solid #253658;
}
.cta-badge {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  color: var(--brand-3);
}
.cta-hint {
  font-family: var(--mono);
  font-size: 11px;
  color: #8aa0c8;
}

/* CTA section layout — stretch columns so bundle bottom aligns with terminal bottom */
.cta-split { align-items: stretch; }
.cta-copy-col {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.cta-bottom-bundle {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.cta-actions {
  display: flex;
  gap: 16px;
  margin: 0;
}
.cta-assurance {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
}
.assurance-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}
.assurance-item svg {
  color: var(--brand-3);
}

/* ── The changelog (/changelog/) ────────────────────────────────
   One entry per dated change, newest first: the date in mono on the left,
   what changed beside it, each entry a card on the page's desk. In one
   column on a narrow screen, the date sits over its entry. */
.changelog { min-height: 60vh; }
.changelog .section-sub a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--brand-1);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.changelog .section-sub a:hover { color: var(--brand-1); }
.cl-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 860px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.cl-entry {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 24px;
  padding: 22px 24px;
  background: var(--panel);
  border: 2px solid var(--ink);
  box-shadow: var(--shadow);
}
.cl-date {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  line-height: 1.5;
  color: var(--muted);
  padding-top: 3px;
}
.cl-body h3 {
  margin: 0 0 8px;
  font-family: var(--display);
  font-size: 19px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.cl-body p {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
}
@media (max-width: 580px) {
  .cl-entry { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 18px; }
}

/* Site Footer: white on black throughout, the logo included (its ink, the
   letters and the last two underlines, turns white; the brand colours
   stay). */
.site-footer {
  background: black;
  color: var(--panel);
}

/* Tricolour accent bar — mirrors the ondrift navbar-accent */
.footer-accent {
  display: flex;
  width: 100%;
  height: 4px;
}
.footer-accent span { flex: 1; }
.footer-accent span:nth-child(1) { background: var(--brand-1); }
.footer-accent span:nth-child(2) { background: var(--brand-2); }
.footer-accent span:nth-child(3) { background: var(--brand-3); }

.site-footer .container {
  padding-top: 52px;
  padding-bottom: 36px;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(4, 1fr);
  gap: 32px;
  margin-bottom: 40px;
}

/* Brand column */
.footer-logo {
  display: inline-block;
  font-family: 'Tinos', serif;
  font-weight: 700;
  font-style: italic;
  font-size: 1.9rem;
  line-height: 1;
  color: var(--panel);
  text-decoration: none;
  margin-bottom: 14px;
}
.footer-logo .lg {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 2px;
}
.footer-logo .lg-1 { text-decoration-color: var(--brand-1); }
.footer-logo .lg-2 { text-decoration-color: var(--brand-2); }
.footer-logo .lg-3 { text-decoration-color: var(--brand-3); }
.footer-logo .lg-4,
.footer-logo .lg-5 { text-decoration-color: var(--panel); }

.footer-brand p {
  font-size: 13.5px;
  font-weight: 300;
  line-height: 1.55;
  color: var(--panel);
  margin: 0;
  max-width: 30ch;
}

/* Link columns */
.footer-col {
  display: flex;
  flex-direction: column;
}
.footer-col h4 {
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--panel);
  margin: 0 0 14px;
}
.footer-col a {
  display: block;
  color: var(--panel);
  font-size: 13.5px;
  font-weight: 300;
  text-decoration: none;
  margin-bottom: 9px;
  width: fit-content;
  transition: color 0.12s ease;
  font-family: var(--display);
}
.footer-col a:hover { color: var(--brand-1); }

/* Bottom bar */
.footer-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  border-top: 1px solid rgb(255 255 255 / 0.2);
  padding-top: 20px;
  font-size: 13px;
  font-weight: 300;
  color: var(--panel);
}
.footer-bottom strong { font-weight: 600; color: var(--panel); }
.alpha-tag {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  background: var(--brand-1);
  color: var(--on-brand);
  padding: 2px 7px;
  vertical-align: 1px;
}

/* EU Law Compliance Strip */
.eu-law-strip {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.eu-law-item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--panel);
  border: 2px solid var(--ink);
  box-shadow: 2px 2px 0 var(--ink);
  padding: 7px 12px;
  font-size: 12px;
}
.eu-law-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.eu-law-dot-gdpr  { background: var(--brand-2); }
.eu-law-dot-act   { background: var(--brand-1); }
.eu-law-dot-iso   { background: var(--brand-3); }
.eu-law-name {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 11.5px;
  color: var(--ink);
}
.eu-law-status {
  font-size: 11px;
  color: var(--muted);
  font-weight: 500;
}

/* Portability: promise strip */
.port-promise-strip {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 20px;
}
.port-promise-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  font-weight: 400;
  color: var(--ink);
  line-height: 1.5;
}
.port-promise-item svg {
  color: #ffffff;
  flex-shrink: 0;
  margin-top: 2px;
  padding: 2px;
  width: 20px;
  height: 20px;
  background: var(--ink);
  border: 1.5px solid var(--ink);
}
.port-promise-item code {
  font-family: var(--mono);
  font-size: 12.5px;
  background: #f4f4f6;
  border: 1px solid var(--ink);
  padding: 1px 5px;
  color: var(--ink);
}


/* Idea bullet colour cycling */
.idea-col-orange { color: var(--brand-1); }
.idea-col-purple  { color: var(--brand-2); }
.idea-col-green   { color: var(--brand-3); }

/* CTA terminal output lines */
.term-out {
  padding-left: 2px;
  line-height: 1.5;
}
.term-ok {
  color: var(--brand-3);
  font-weight: 700;
  margin-right: 6px;
}
.term-ver {
  color: var(--brand-2);
}
.term-url {
  color: var(--brand-3);
  text-decoration: underline;
  text-decoration-color: rgba(16,185,129,0.4);
}
.term-gap {
  display: block;
  height: 4px;
}

/* CTA platform pills */
.cta-platform-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 20px;
}
.cta-platform-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--muted);
  background: var(--bg);
  border: 2px solid var(--ink);
  box-shadow: 2px 2px 0 var(--ink);
  padding: 5px 12px;
}
.cta-platform-pill svg { flex-shrink: 0; }
.cta-platform-pill-eu {
  background: #dbeafe;
  color: var(--ink);
}


/* ============================================================
   SCROLL-REVEAL & ENTRANCE ANIMATIONS
   ============================================================ */

/* --- Base reveal state ------------------------------------------
   Every element tagged [data-reveal] starts invisible and slightly
   displaced. The IntersectionObserver in hero.js adds .is-in,
   which plays the entrance. Nothing is ever hidden unless JS runs
   (the class is added by script). */
[data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 0.55s cubic-bezier(0.2, 0.7, 0.3, 1),
    transform 0.55s cubic-bezier(0.2, 0.7, 0.3, 1);
}
[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* --- Stagger: siblings tagged [data-stagger] get nth-child delays ---
   Works for any grid or list of siblings up to 9 items. */
[data-stagger] > *            { transition-delay: 0s; }
[data-stagger] > *:nth-child(1) { transition-delay: 0.00s; }
[data-stagger] > *:nth-child(2) { transition-delay: 0.07s; }
[data-stagger] > *:nth-child(3) { transition-delay: 0.14s; }
[data-stagger] > *:nth-child(4) { transition-delay: 0.21s; }
[data-stagger] > *:nth-child(5) { transition-delay: 0.28s; }
[data-stagger] > *:nth-child(6) { transition-delay: 0.35s; }
[data-stagger] > *:nth-child(7) { transition-delay: 0.42s; }
[data-stagger] > *:nth-child(8) { transition-delay: 0.49s; }
[data-stagger] > *:nth-child(9) { transition-delay: 0.56s; }

/* Stagger children share the parent's [data-reveal] transition but
   start hidden too. They become visible in a cascade once the
   parent's IntersectionObserver fires. */
[data-stagger].is-in > * {
  opacity: 1;
  transform: none;
}
[data-stagger] > * {
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.45s cubic-bezier(0.2, 0.7, 0.3, 1),
    transform 0.45s cubic-bezier(0.2, 0.7, 0.3, 1);
  transition-delay: inherit;
}

/* --- Slide-from-left / right variants for the portability ledger --- */
[data-reveal="left"] {
  transform: translateX(-18px);
}
[data-reveal="right"] {
  transform: translateX(18px);
}
[data-reveal="left"].is-in,
[data-reveal="right"].is-in {
  transform: none;
}

/* --- Punch-through: the free tickets and eu-fact-cards break UP ----
   Borrowed directly from ondrift's prim-key-break: the element
   punches up through the surface it sits on, overshoots, and
   settles. Shadow follows. */
@keyframes punch-up {
  0%   { opacity: 0; transform: translateY(8px);  box-shadow: 0 0 0 var(--ink); }
  22%  { opacity: 1; }
  58%  { transform: translateY(-14px); box-shadow: 0 14px 0 var(--ink); }
  80%  { transform: translateY(-2px);  box-shadow: 0 2px  0 var(--ink); }
  100% { transform: translateY(0);     box-shadow: 2px 2px 0 var(--ink); }
}

/* Pre-animation: hidden via the keyframe's own 0% frame (backwards fill).
   After animation completes, 'both' holds the 100% frame (opacity:1).
   No separate opacity:0 rule — that was fighting the fill-mode. */
.punch-parent:not(.is-in) > [data-punch] { opacity: 0; }
.punch-parent.is-in > [data-punch] {
  animation: punch-up 560ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
.punch-parent.is-in > [data-punch]:nth-child(1) { animation-delay: 0.00s; }
.punch-parent.is-in > [data-punch]:nth-child(2) { animation-delay: 0.06s; }
.punch-parent.is-in > [data-punch]:nth-child(3) { animation-delay: 0.12s; }
.punch-parent.is-in > [data-punch]:nth-child(4) { animation-delay: 0.18s; }
.punch-parent.is-in > [data-punch]:nth-child(5) { animation-delay: 0.24s; }
.punch-parent.is-in > [data-punch]:nth-child(6) { animation-delay: 0.30s; }
.punch-parent.is-in > [data-punch]:nth-child(7) { animation-delay: 0.36s; }
.punch-parent.is-in > [data-punch]:nth-child(8) { animation-delay: 0.42s; }
.punch-parent.is-in > [data-punch]:nth-child(9) { animation-delay: 0.48s; }

/* --- Stat digit counter roll-up --------------------------------
   The number element gets a CSS counter-driven clip animation.
   The actual counting is done in JS; here we just give the
   element a typewriter-style slot: overflow:hidden with a fixed
   height so the digit doesn't reflow as it changes. */
.stat-digit[data-count] {
  display: inline-block;
  min-width: 2ch;
  transition: transform 0.05s ease-out;
}

/* --- Section label pop-in --------------------------------------
   The mono section-label tags stamp in with a quick scale from
   slightly small, like a rubber stamp. */
@keyframes stamp-in {
  0%   { opacity: 0; transform: scale(0.88) rotate(-1deg); }
  60%  { transform: scale(1.04) rotate(0.3deg); }
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
}
.section-label[data-reveal].is-in {
  animation: stamp-in 0.4s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
  /* Override the base translate-only entrance for this element */
  opacity: 1;
  transform: none;
}

/* --- Heading draw-in --------------------------------------------
   h2 elements slide up with a slightly longer arc and a gentle
   blur clearing, giving them more weight on arrival. */
[data-reveal="heading"] {
  opacity: 0;
  transform: translateY(16px);
  filter: blur(2px);
  transition:
    opacity  0.65s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.65s cubic-bezier(0.16, 1, 0.3, 1),
    filter   0.55s ease;
}
[data-reveal="heading"].is-in {
  opacity: 1;
  transform: none;
  filter: none;
}

/* --- Law strip item slide-in -----------------------------------
   The three compliance pills slide in from left with a cascade. */
.eu-law-strip[data-stagger] > .eu-law-item {
  transform: translateX(-12px);
  transition:
    opacity 0.4s cubic-bezier(0.2, 0.7, 0.3, 1),
    transform 0.4s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.eu-law-strip[data-stagger].is-in > .eu-law-item {
  opacity: 1;
  transform: none;
}

/* --- CTA terminal line reveal ----------------------------------
   Lines in the CTA terminal are hidden; JS adds .line-in to each
   in sequence once the section is visible. */
.cta-terminal .term-line,
.cta-terminal .term-out {
  opacity: 0;
  transform: translateX(-6px);
  transition:
    opacity  0.3s ease,
    transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.cta-terminal .term-line.line-in,
.cta-terminal .term-out.line-in {
  opacity: 1;
  transform: none;
}

/* --- Service strip (hero highlights) stagger ---------------------*/
.service-strip[data-stagger] > .strip-item {
  transform: translateY(8px);
}

/* ============================================================
   REDUCED MOTION — everything snaps in instantly
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  [data-reveal="left"],
  [data-reveal="right"],
  [data-reveal="heading"],
  [data-stagger] > *,
  .punch-parent > [data-punch],
  .punch-parent:not(.is-in) > [data-punch],
  .cta-terminal .term-line,
  .cta-terminal .term-out,
  .section-label[data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    animation: none !important;
    transition: none !important;
  }
}

/* Responsive Media Queries */
/* Five reasons in a row need room: below 1240px their captions would wrap
   into slivers, so they go three to a row. */
@media (max-width: 1240px) {
  .service-strip { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 960px) {
  /* minmax(0, …): a plain 1fr column cannot shrink below its widest
     content, and a line of code that does not wrap would stretch it (and
     the page) past the window. The code scrolls in its own box instead. */
  .split-layout,
  .split-layout.reverse { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  #primitives .split-layout,
  #polyglot .split-layout.reverse { align-items: start; }
  #primitives .split-right,
  #polyglot .split-left { height: auto; }
  .split-layout.reverse .split-right { order: 1; }
  .split-layout.reverse .split-left { order: 2; }
  .service-strip { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-brand { grid-column: 1 / -1; }
  .nd-cols { grid-template-columns: repeat(2, max-content); gap: 24px 56px; }
}

@media (max-width: 850px) {
  .hero-top-row { grid-template-columns: 1fr; row-gap: 0; }
  .hero { padding-top: 40px; }
  h1 { font-size: clamp(38px, 9vw, 56px); }
  /* In one column, the map comes between the headline and the rest. The
     copy's box steps aside (display: contents), so its parts sit in the
     column themselves, and take turns with the map by their order: the
     eyebrow, the headline and the typed line, then the map, then the
     sentence and the buttons. */
  .hero-copy { display: contents; }
  .lede { margin-bottom: 0; }
  .hero-art { order: 1; min-height: 0; margin: 8px 0 24px; }
  .lede-second, .actions { order: 2; }
  .lede-second { margin-top: 8px; }
  .actions { margin-bottom: 32px; }
}

@media (max-width: 580px) {
  .announcement { font-size: 11px; flex-direction: column; gap: 4px; text-align: center; }
  .site-header-bar { padding: 0 5vw; }
  /* Three menu items beside the wordmark need less air to fit a 390px window. */
  .nav-main { padding-left: 12px; gap: 0; }
  .navmenu-trigger,
  .navmenu-link { padding: 6px 8px; }
  .nav-drawer-panel { padding: 24px 5vw 0; }
  .nd-cols { grid-template-columns: 1fr; }
  .nd-link { font-size: 18px; }
  .nd-strip-end { margin-left: 0; }
  .hero { padding-left: 5vw; padding-right: 5vw; }
  .container { padding-left: 5vw; padding-right: 5vw; }
  .service-strip { grid-template-columns: 1fr; }
  .pillar-tabs { padding: 0; gap: 4px; }
  .pillar-tab-name { font-size: 12px; }
  .pillar-panel { padding: 20px 18px 0; }
  .pillar-blocks { grid-template-columns: 1fr; }
  .mesh { grid-template-columns: 1fr 1fr; grid-template-areas: "hub hub" "left right"; column-gap: 14px; row-gap: 28px; }
  .mesh-hub { grid-area: hub; justify-self: center; width: 116px; height: 116px; }
  .mesh-col-left { grid-area: left; }
  .mesh-col-right { grid-area: right; }
  .mesh-node { font-size: 12.5px; padding: 8px; gap: 8px; }
  .flow-steps-grid { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; gap: 12px; text-align: center; }
  .cta-actions { flex-direction: column; align-items: stretch; }
  .cta-terminal { font-size: 12px; padding: 18px; }
}

/* The narrowest phones: a smaller wordmark and tighter menu keep the header
   inside the window, and a card's title and its tag may wrap. */
@media (max-width: 400px) {
  .brand .title { font-size: 2.1rem; }
  .nav-main { padding-left: 6px; }
  .navmenu-trigger,
  .navmenu-link { padding: 6px 5px; gap: 3px; }
  .eu-disc-title-row,
  .lede-title-row,
  .devex-meta-title-row { flex-wrap: wrap; }
}
