/* ============================================================================
   dominenta.com — the tenant domain's front door.
   ============================================================================

   Design register follows the luxury layer already shipped on orkastor.com and
   the Console (kubegraf.io/apps/orkastor/src/console.css): one accent at ~5% of
   pixels, machined radii (never pills), a single grain overlay, one radial glow
   per section, asymmetric easing, and all metadata in neutral mono. Anti-patterns
   deliberately avoided: multiple coloured glows, gradient text everywhere, emoji
   icons, scale-up hovers, second-long fades.

   THREE HARD CONSTRAINTS THAT SHAPED THIS FILE.

   1. NO COOKIES. NONE. Not analytics, not preferences, not a consent banner.
      This page is served from dominenta.com, and until that domain is on the
      Public Suffix List a cookie set here is scoped to the registrable domain —
      which means every tenant environment at <env>-<slug>-<hash>.apps.dominenta.com
      would receive it, and could set one back. A marketing cookie on this host is
      a cross-tenant channel. There is no third-party script on this page for the
      same reason, and no webfont fetch.

   2. NO CLAIM THAT OUTRUNS THE BUILD. gates §2.5 of the design docs: marketing
      copy is updated to match what exists, and NOT before it exists. So: no
      pricing (the rates are unmeasured and an earlier published set was 21% below
      cost), no uptime or SLA, no customer logos, no benchmark numbers, no latency
      figures. Every status string, tier name, region and lifecycle state on this
      page is one the Console actually renders.

   3. THE CSP FORBIDS INLINE STYLE. The nginx policy in this same manifest is
      `style-src 'self'` with no 'unsafe-inline', which blocks BOTH inline <style>
      blocks AND style="" attributes. The previous revision of this page used
      `style="margin-top:14px"` in nine places; every one of them was silently
      dropped by the browser and the spacing it was meant to create never
      appeared in production. There are no inline styles anywhere now — spacing
      is a class, always. If you add one it will not work, and it will not warn.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   1. TOKENS
   ------------------------------------------------------------------------- */
:root {
  color-scheme: dark;
  /* Surfaces, lightest to deepest. A warm bone ground with paper cards on it —
     the page is dark-on-light now, so every rule below that used to lift a
     surface with a white film instead settles it onto paper. */
  --ink: #0f0e0d;          /* the page ground */
  --ink-sunken: #191817;   /* recessed: the metal strip, the substrate boxes */
  --ink-raised: #fafaf9;   /* the alternating band — paper, and it inverts
                              every token inside it. See section 21. */
  --ink-card: #171614;     /* card fill */
  /* The one hue in an otherwise two-colour register, reserved for the single
     link that leaves this site. A monochrome page has no way to mark a
     cross-product link as different in KIND rather than in importance, and
     weight alone reads as 'more important', which this is not. Teal because
     it is cool against warm neutrals and does not collide with --ok or
     --warn. NOTE: this is a design choice, not KubeGraf's brand colour —
     I do not know that it has one. If it does, these four are the change. */
  --kg: #48cbcb;
  --kg-text: #7fdbdb;
  --kg-soft: rgba(72, 203, 203, 0.1);
  --kg-line: rgba(72, 203, 203, 0.34);

  --ink-hover: #262322;    /* card fill under the pointer. --ink-sunken was
                              the obvious reuse and it is two steps per
                              channel off --ink-card: measured, a luminance
                              delta of 0.001, which is no hover state at
                              all. This is a step you can actually see. */

  /* Type. Warm near-black, not grey — a neutral grey on a warm bone ground
     reads as a rendering fault rather than as a colour. */
  --text: #fafaf9;
  --text-dim: #a9a29c;
  /* Metadata tone. #6f6863 measures 4.94:1 on the bone ground; the lighter
     #857e79 it was first set to came in at 3.61:1, under AA for body sizes.
     This is the same correction the dark revision had to make, in reverse. */
  --meta: #938b84;

  /* lines */
  --hairline: rgba(250, 250, 249, 0.12);
  --hairline-bright: rgba(250, 250, 249, 0.2);
  --hairline-strong: rgba(250, 250, 249, 0.34);

  /* The one accent, a deep indigo where this page used to run orange. It
     carries the CTAs, the eyebrows and the boundary and nothing else — the
     same ~5% of pixels the register has always asked for. */
  --accent: #fafaf9;
  --accent-lift: #ffffff;
  --accent-text: #fafaf9;
  --accent-soft: rgba(250, 250, 249, 0.08);
  --accent-line: rgba(250, 250, 249, 0.22);
  --accent-wash: rgba(250, 250, 249, 0.04);

  /* The two decorative washes — the only colours on the page doing no
     information work. They are the soft gradient fields behind the hero and
     the closing band, drawn in CSS because the CSP forbids fetching art. */
  --lavender: rgba(250, 250, 249, 0.05);
  --peach: rgba(250, 250, 249, 0.035);

  /* Status tones, re-picked for a light ground. On dark these read by being
     brighter than the surface; here they have to read by being darker and
     more saturated than it, or they turn into pastel noise. */
  --ok: #4ade80;
  --ok-soft: rgba(74, 222, 128, 0.14);
  --ok-line: rgba(74, 222, 128, 0.32);
  --warn: #fbbf24;
  --warn-soft: rgba(251, 191, 36, 0.14);
  --warn-line: rgba(251, 191, 36, 0.32);

  /* The brand mark keeps its own navy-to-teal gradient — a narrow, deliberate
     exception scoped to the glyph alone. Its stops are written into the three
     inline SVGs rather than kept as tokens here: an SVG stop-color that
     resolves through a custom property loses its colour wherever that fails.

     There is deliberately no `--ease-out`. The register calls for asymmetric
     easing, exits on a different curve from entrances — but nothing on this
     page exits. Add the token with the first thing that does. */
  --ease-in: cubic-bezier(0.16, 1, 0.3, 1); /* entrances */

  --measure: 66ch;
  /* Softer than the machined radii this page used to carry, and a true pill
     for anything that can be pressed — see section 21. */
  --radius-sm: 0px;
  --radius: 0px;
  --radius-lg: 0px;
  --radius-pill: 0px;

  /* NO WEBFONT, and this is not an oversight. The CSP in this manifest is
     `default-src 'none'` with no font-src at all, so a fetched face is blocked
     whether it comes from a CDN or from this origin — self-hosting does not
     get around it, only editing the policy would. The pairing is therefore
     built from faces the platform already has.

     `ui-serif` is the one that matters. It resolves to New York on Apple
     platforms — a contemporary, high-contrast serif — which is why the display
     face reads as a choice rather than as a fallback to Times. */
  --display: var(--sans);
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --shell: 1120px;
  --gutter: 28px;
}

@media (max-width: 560px) {
  :root {
    --gutter: 20px;
  }
}

/* ----------------------------------------------------------------------------
   2. RESET & BASE
   ------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* the sticky header is 60px; anchors must not land underneath it */
  scroll-padding-top: 84px;
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: var(--sans);
  font-feature-settings: "cv01" 1, "ss03" 1, "zero" 1;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

::selection {
  background: var(--accent);
  color: var(--ink);
} /* the accent's one ambient use */

img,
svg {
  max-width: 100%;
}

/* One grain overlay for the whole page — felt, not seen. It also de-bands the
   radial glows, which is the real reason it is here. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* multiply, not overlay: on a light ground overlay lightens the grain into
     nothing at all, and the de-banding it exists for stops happening. */
  opacity: 0.028;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

.wrap {
  position: relative;
  z-index: 2;
}

.container {
  width: 100%;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* Visually hidden but read aloud. Used for the textual equivalent of every
   diagram — no information on this page exists only as a picture. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--ink);
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: none;
  transition: top 180ms var(--ease-in);
}
.skip-link:focus {
  top: 12px;
}

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

/* ----------------------------------------------------------------------------
   3. TYPE
   ------------------------------------------------------------------------- */
h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 500;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.45rem, 5.6vw, 4.1rem);
  line-height: 1.03;
  letter-spacing: -0.04em;
}
/* ── the hero headline on a phone ──────────────────────────────────────
   The clamp above floors at 2.45rem, and that floor binds everywhere below
   700px. At 39.2px the headline's second line, "GitHub and production.",
   sets 385px against 280px of container at 320px and 350px at 390px, so it
   wrapped and the deliberate two-line break came out as a ragged three.

   Retuned for the grotesque. These numbers were first worked out while
   --display was still a serif; the register retired that, and the sans sets
   the same string at 4% narrower with a different curve across sizes, so the
   old 10vw - 4px was 3px over at 375px and the 1.85rem floor was 12px over
   at 320px. Measured across SF Pro, Helvetica and Arial — the three the
   stack resolves to — 9.8vw - 4px clears every width from 320px up with the
   tightest margin at 390px.

   The 2.45rem ceiling hands back to the global rule at 442px, where the two
   expressions meet exactly, so there is no step at the boundary. */
@media (max-width: 441.98px) {
  .hero h1 {
    font-size: clamp(1.7rem, 9.8vw - 4px, 2.45rem);
  }
}
h2 {
  font-size: clamp(1.7rem, 3.2vw, 2.4rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
}
h3 {
  font-size: 1.02rem;
  line-height: 1.35;
  letter-spacing: -0.015em;
}
h4 {
  font-size: 0.9rem;
  line-height: 1.4;
  letter-spacing: -0.01em;
}

p {
  margin: 0;
  max-width: var(--measure);
}

/* dl/dd and pre carry UA margins that would break the deflist and code rhythm */
dl,
dd,
pre,
figure {
  margin: 0;
}

.lede {
  font-size: clamp(1.04rem, 1.6vw, 1.2rem);
  color: var(--text-dim);
  line-height: 1.62;
}

.note {
  font-size: 0.93rem;
  color: var(--text-dim);
}

.eyebrow {
  display: block;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--meta);
}

code,
.mono {
  font-family: var(--mono);
  font-size: 0.88em;
  letter-spacing: -0.01em;
}

a {
  color: inherit;
}

/* deliberate, reusable spacing — the CSP blocks style="" so every gap is a class */
.mt-sm {
  margin-top: 14px;
}
.mt-md {
  margin-top: 18px;
}
.mt-lg {
  margin-top: 26px;
}
.mt-xl {
  margin-top: 40px;
}

/* ----------------------------------------------------------------------------
   4. SECTION SHELL
   ------------------------------------------------------------------------- */
section {
  padding: clamp(72px, 10vw, 116px) 0;
  position: relative;
}

.rule {
  height: 1px;
  background: var(--hairline);
  border: 0;
  margin: 0;
}

/* One radial glow per section, one hue, low and wide. */
.glow::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: 0;
  /* 100%, not a vw figure. At 112vw the glow hung 19-22px past the viewport on
     a phone; body's overflow-x propagates to the viewport, so nothing clipped it
     and every page below 560px had a sideways scroll of exactly that overhang. */
  width: min(920px, 100%);
  height: 460px;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 0%, var(--lavender), transparent 70%);
  opacity: 0.45;
  pointer-events: none;
}

.section-head {
  max-width: 680px;
}

/* ----------------------------------------------------------------------------
   5. HEADER
   ------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  padding: 18px 0;
  border-bottom: 1px solid transparent;
  transition: background-color 260ms var(--ease-in), border-color 260ms var(--ease-in),
    padding 260ms var(--ease-in);
}

/* set by app.js past 24px of scroll — the header earns its background */
.site-header.is-stuck {
  padding: 11px 0;
  background: rgba(15, 14, 13, 0.86);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: var(--hairline);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 24px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  flex: none;
}
/* The wordmark. ONE text node, and now a SOLID colour. The approved artwork
   sets the logotype solid, so the split gradient this used to carry is retired
   (brand spec, "Wordmark"). There is no background-clip left to feature-detect,
   so the @supports block that used to clear `color` is gone with it.

   This page is dark ink, so the foreground is the near-white --text. On a light
   surface the same rule takes navy #0B2A4A instead. */
.brand-word {
  font-size: 0.92rem;
  font-weight: 700;
  /* Positive tracking, matching the approved artwork. The old -0.02em was
     tuned for mixed case; caps at negative tracking close into a block. The
     size drops from 1rem because caps set to the same number read larger. */
  letter-spacing: 0.09em;
  color: var(--text);
}

/* "Cloud" is the product, not part of the logotype — set in the dim tone and
   held apart. It stays its own element because it takes a different colour from
   the wordmark, and because the footer scales .brand-word alone. This is a
   space-separated word, so keeping it in a second element breaks no shaping
   run across the boundary. */
.brand-product {
  /* 0.32em minus the 0.09em of trailing letter-space the wordmark now emits
     after its final R, so the optical gap is unchanged. */
  margin-left: 0.23em;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  margin-right: -0.09em;
  color: var(--text-dim);
}

/* The mark. Monochrome, and it takes its colour from here rather than from
   the fill attribute on the SVG: the supplied artwork is near-black on
   white, which is right on this bone ground and wrong the moment the ground
   moves. The attribute stays as the no-CSS fallback and this rule beats it,
   since any stylesheet declaration outranks a presentation attribute. It
   has to be a rule and not style="" — the CSP forbids inline styles.

   `fill` inherits, so setting it on the <svg> reaches the path and every
   rect without naming them. */
.brand-mark {
  fill: var(--text);
  flex: none;
}
/* In the console mock the mark is chrome next to a title, not the brand
   signing the page, so it sits at the dim tone the crumb beside it uses. */
.console-head .brand-mark {
  fill: var(--text-dim);
}

.header-nav {
  display: none;
  align-items: center;
  gap: 26px;
  /* the lockup now ends in a word, not a mark, so the nav needs clear air or
     "Cloud" reads as the first nav item rather than as part of the brand */
  margin-left: 22px;
}
.header-nav a {
  font-size: 0.87rem;
  color: var(--text-dim);
  text-decoration: none;
  transition: color 200ms var(--ease-in);
}
.header-nav a:hover {
  color: var(--text);
}
@media (min-width: 860px) {
  .header-nav {
    display: flex;
  }
}

.header-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
}
.header-signin {
  padding: 8px 16px;
  font-size: 0.87rem;
}
@media (max-width: 560px) {
  .btn.header-signin {
    display: none;
  }
}

/* mobile menu — a disclosure, not a drawer. No overlay, no scroll lock, no
   focus trap to get wrong: the panel is in flow directly under the header. */
.menu-toggle {
  display: inline-flex;
  /* column, or the three bars lay out in a row and render as one long line */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid var(--hairline-bright);
  border-radius: var(--radius-sm);
  background: var(--ink-card);
  color: var(--text);
  cursor: pointer;
}
@media (min-width: 860px) {
  .menu-toggle {
    display: none;
  }
}
.menu-toggle .bar {
  display: block;
  width: 15px;
  height: 1.5px;
  background: currentColor;
  border-radius: 2px;
  transition: transform 220ms var(--ease-in), opacity 160ms var(--ease-in);
}
.menu-toggle .bar + .bar {
  margin-top: 4px;
}
.menu-toggle[aria-expanded="true"] .bar:nth-child(1) {
  transform: translateY(5.5px) rotate(45deg);
}
.menu-toggle[aria-expanded="true"] .bar:nth-child(2) {
  opacity: 0;
}
.menu-toggle[aria-expanded="true"] .bar:nth-child(3) {
  transform: translateY(-5.5px) rotate(-45deg);
}

.mobile-nav {
  display: none;
  border-top: 1px solid var(--hairline);
  background: rgba(15, 14, 13, 0.97);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.mobile-nav.is-open {
  display: block;
}
@media (min-width: 860px) {
  .mobile-nav.is-open {
    display: none;
  }
}
.mobile-nav a {
  display: block;
  padding: 14px 0;
  border-bottom: 1px solid var(--hairline);
  color: var(--text-dim);
  text-decoration: none;
  font-size: 0.95rem;
}
.mobile-nav a:last-child {
  border-bottom: 0;
  color: var(--accent-text);
}

/* ----------------------------------------------------------------------------
   6. BUTTONS & CHIPS
   ------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 19px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font: inherit;
  font-size: 0.93rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: transform 160ms var(--ease-in), background-color 200ms var(--ease-in),
    border-color 200ms var(--ease-in), color 200ms var(--ease-in);
}
.btn:hover {
  transform: translateY(-1px);
}
.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--accent);
  color: var(--ink);
}
.btn-primary:hover {
  background: var(--accent-lift);
}

.btn-ghost {
  color: var(--text);
  border-color: var(--hairline-bright);
  background: var(--ink-card);
}
.btn-ghost:hover {
  border-color: var(--hairline-strong);
} /* brighten, never glow */

.btn .arrow {
  transition: transform 220ms var(--ease-in);
}
.btn:hover .arrow {
  transform: translateX(2px);
}
.btn .arrow-down {
  transition: transform 220ms var(--ease-in);
}
.btn:hover .arrow-down {
  transform: translateY(2px);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 34px;
}

/* status chip. Machined, not a pill. */
.status {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 13px;
  border: 1px solid var(--hairline-bright);
  border-radius: var(--radius-pill);
  background: var(--ink-card);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}

.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: none;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.dot-ok {
  background: var(--ok);
  box-shadow: 0 0 0 3px var(--ok-soft);
}
.dot-warn {
  background: var(--warn);
  box-shadow: 0 0 0 3px var(--warn-soft);
}
.dot-muted {
  background: var(--meta);
  box-shadow: none;
}

/* the one looping animation on the page: a running environment is running */
.dot-live {
  animation: breathe 2.6s var(--ease-in) infinite;
}
@keyframes breathe {
  0%,
  100% {
    box-shadow: 0 0 0 3px var(--ok-soft);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(15, 107, 53, 0.06);
  }
}

/* ----------------------------------------------------------------------------
   7. CARDS & GRIDS
   ------------------------------------------------------------------------- */
.grid {
  display: grid;
  gap: 14px;
  margin-top: 38px;
}
.grid > * {
  min-width: 0;
}
@media (min-width: 700px) {
  .grid.cols-2,
  .grid.cols-3,
  .grid.cols-4 {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 900px) {
  .grid.cols-3 {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (min-width: 1000px) {
  .grid.cols-4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

.card {
  position: relative;
  padding: 22px;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: var(--ink-card);
  transition: border-color 220ms var(--ease-in), background-color 220ms var(--ease-in);
}
.card:hover {
  border-color: var(--hairline-bright);
  background: var(--ink-card);
}
.card h3 {
  margin-bottom: 9px;
}
.card p {
  font-size: 0.93rem;
  color: var(--text-dim);
}
.card .card-index {
  display: block;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  color: var(--meta);
  margin-bottom: 14px;
}

/* ----------------------------------------------------------------------------
   8. PANEL — the shared chrome for every figure on the page
   ------------------------------------------------------------------------- */
.panel {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--ink-card);
  overflow: hidden;
}

.panel-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--hairline);
  background: var(--ink-card);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--meta);
}
.panel-bar .spacer {
  margin-left: auto;
}
.panel-body {
  padding: 20px 18px;
}

/* the small technical annotations that live beside things */
.meta {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--meta);
}
.meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  align-items: baseline;
}
.meta-row b {
  font-weight: inherit;
  color: var(--text-dim);
}

/* ----------------------------------------------------------------------------
   9. HERO
   ------------------------------------------------------------------------- */
.hero {
  padding-top: clamp(56px, 8vw, 92px);
  padding-bottom: clamp(64px, 9vw, 104px);
}
.hero-grid {
  display: grid;
  gap: 48px;
  align-items: center;
}
.hero-grid > * {
  min-width: 0;
}
@media (min-width: 1000px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
    gap: 56px;
    align-items: center;
  }
  /* Its own ceiling, lower than the global h1: this column is ~520px wide, and
     the 4.1rem global maximum wraps "Ephemeral environments" onto two lines. */
  .hero h1 {
    font-size: clamp(2.2rem, 3.1vw, 2.95rem);
  }
}
.hero h1 {
  margin-top: 22px;
}
.hero .lede {
  margin-top: 22px;
  max-width: 52ch;
}
.hero-foot {
  margin-top: 30px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
}

/* ----------------------------------------------------------------------------
   10. THE BOUNDARY FIGURE — hero visual, and the page's one big idea
   ------------------------------------------------------------------------- */
.boundary-fig {
  --env-line: var(--hairline-bright);
  position: relative;
}

.env-box {
  position: relative;
  border: 1px solid var(--env-line);
  border-radius: var(--radius-lg);
  background: var(--ink-card);
  box-shadow: 0 20px 48px -32px rgba(27, 24, 24, 0.45);
  overflow: hidden;
  transition: border-color 300ms var(--ease-in);
}

.env-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 15px;
  border-bottom: 1px solid var(--hairline);
  font-family: var(--mono);
  font-size: 0.71rem;
  color: var(--meta);
}
.env-head .env-id {
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.env-head .env-state {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  flex: none;
}

.env-url {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 15px;
  border-bottom: 1px solid var(--hairline);
  background: var(--accent-wash);
  font-family: var(--mono);
  font-size: 0.73rem;
  color: var(--accent-text);
  overflow: hidden;
}
.env-url .u {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.env-services {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  padding: 16px 15px;
}
.svc {
  padding: 12px 11px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  background: var(--ink-card);
  transition: border-color 240ms var(--ease-in), background-color 240ms var(--ease-in);
}
.svc .svc-name {
  display: block;
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--text);
  letter-spacing: -0.01em;
}
.svc .svc-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 7px;
  font-family: var(--mono);
  font-size: 0.63rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--meta);
}
/* lit as the request walks the path — set by app.js, and by :hover for a
   visitor who would rather drive it than watch it */
.svc.is-hot,
.svc:hover {
  border-color: var(--accent-line);
  background: var(--accent-wash);
}

.env-kernel {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 15px;
  border-top: 1px dashed var(--hairline-bright);
  background: var(--ink-card);
  font-size: 0.83rem;
  color: var(--text-dim);
  transition: background-color 300ms var(--ease-in), color 300ms var(--ease-in);
}
.env-kernel .k-name {
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--text);
}
.env-kernel .k-note {
  margin-left: auto;
  text-align: right;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  color: var(--meta);
}

/* the boundary itself — the only element on the page allowed to be loud */
.boundary-band {
  position: relative;
  margin: 0;
  padding: 15px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
}
.boundary-band .b-label {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-text);
  white-space: nowrap;
}
.boundary-band .b-line {
  flex: 1;
  height: 1px;
  min-width: 12px;
  background: linear-gradient(90deg, transparent, var(--accent-line), transparent);
  position: relative;
  overflow: hidden;
}
/* a slow sweep along the boundary — 6s, low contrast, easy to ignore */
.boundary-band .b-line::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(47, 47, 143, 0.85), transparent);
  transform: translateX(-100%);
  animation: sweep 6s var(--ease-in) infinite;
}
.boundary-band .b-line.rev::after {
  animation-direction: reverse;
}
@keyframes sweep {
  0% {
    transform: translateX(-100%);
  }
  55%,
  100% {
    transform: translateX(200%);
  }
}

.metal-box {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--ink-sunken);
  font-size: 0.86rem;
  color: var(--text-dim);
}
.metal-box .m-name {
  color: var(--text);
}
.metal-box .m-note {
  margin-left: auto;
  text-align: right;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  color: var(--meta);
}

/* the request travelling in from HTTPS, drawn above the box */
.ingress {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 12px;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--meta);
}
.ingress .i-line {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--hairline), transparent);
}

/* hovering a layer explains it, in text, below the figure */
.fig-caption {
  margin-top: 14px;
  min-height: 2.6em;
  font-size: 0.84rem;
  color: var(--text-dim);
  transition: opacity 200ms var(--ease-in);
}
.fig-caption .fc-key {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-right: 8px;
}

/* ----------------------------------------------------------------------------
   11. TOGGLE — shared kernel vs Orkastor
   ------------------------------------------------------------------------- */
.switch {
  display: inline-flex;
  padding: 4px;
  gap: 4px;
  border: 1px solid var(--hairline-bright);
  border-radius: var(--radius-pill);
  background: var(--ink-card);
}
.switch button {
  padding: 9px 16px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--text-dim);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  transition: background-color 200ms var(--ease-in), color 200ms var(--ease-in);
}
.switch button:hover {
  color: var(--text);
}
.switch button[aria-selected="true"] {
  background: var(--accent);
  color: var(--ink);
}

.compare-stage {
  margin-top: 26px;
}
.compare-panel[hidden] {
  display: none;
}
.compare-panel {
  /* No `both`. A backwards fill holds the keyframe's opacity: 0 whenever the
     animation has not run — which is exactly the failure the .js reveal gate
     exists to prevent, reintroduced by a different route. With no fill mode the
     element's own style is the visible one, and the animation is decoration on
     top of it. There is no flash: the active phase starts on the same frame. */
  animation: panel-in 420ms var(--ease-in);
}
@keyframes panel-in {
  from {
    opacity: 0;
    transform: translateY(10px);
    filter: blur(4px);
  }
}

/* shared-kernel model: two tenants, one kernel underneath */
.tenants {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr 1fr;
}
.tenant {
  padding: 14px 15px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--ink-card);
}
.tenant .t-who {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--meta);
}
.tenant .t-what {
  display: block;
  margin-top: 8px;
  font-size: 0.93rem;
  color: var(--text);
}
.tenant .t-note {
  display: block;
  margin-top: 4px;
  font-size: 0.8rem;
  color: var(--text-dim);
}

.shared-kernel {
  margin-top: 12px;
  padding: 16px;
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--radius);
  background: repeating-linear-gradient(
    -45deg,
    rgba(27, 24, 24, 0.05),
    rgba(27, 24, 24, 0.05) 6px,
    transparent 6px,
    transparent 12px
  );
  text-align: center;
}
.shared-kernel .sk-name {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--text);
}
.shared-kernel .sk-note {
  display: block;
  margin-top: 6px;
  font-size: 0.82rem;
  color: var(--text-dim);
}

.arrows-down {
  display: grid;
  grid-template-columns: 1fr 1fr;
  color: var(--hairline-strong);
  text-align: center;
  font-family: var(--mono);
  font-size: 1.05rem;
  line-height: 1;
  padding: 10px 0;
}

/* orkastor model: two environments, each with its own kernel */
.envs-two {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr 1fr;
}
.mini-env {
  border: 1px solid var(--hairline-bright);
  border-radius: var(--radius);
  background: var(--ink-card);
  overflow: hidden;
}
.mini-env .me-head {
  padding: 9px 13px;
  border-bottom: 1px solid var(--hairline);
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--meta);
}
.mini-env .me-row {
  padding: 11px 13px;
  font-size: 0.87rem;
  color: var(--text);
  border-bottom: 1px solid var(--hairline);
}
.mini-env .me-row .rn {
  display: block;
  font-size: 0.76rem;
  color: var(--text-dim);
  margin-top: 2px;
}
.mini-env .me-kernel {
  padding: 11px 13px;
  background: var(--accent-soft);
  border-bottom: 1px solid var(--accent-line);
  border-top: 1px solid var(--accent-line);
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--accent-text);
}
.mini-env .me-foot {
  padding: 10px 13px;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--meta);
}

.metal-strip {
  margin-top: 12px;
  padding: 13px 16px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--ink-sunken);
  text-align: center;
  font-size: 0.86rem;
  color: var(--text-dim);
}

@media (max-width: 620px) {
  .tenants,
  .envs-two,
  .arrows-down {
    grid-template-columns: 1fr;
  }
}

/* ----------------------------------------------------------------------------
   12. CONSOLE MOCK
   ------------------------------------------------------------------------- */
.console {
  font-family: var(--mono);
}
.console-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--hairline);
  background: var(--ink-card);
}
.console-head .ch-title {
  font-size: 0.74rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.console-head .ch-crumb {
  font-size: 0.72rem;
  color: var(--meta);
}

.env-table {
  width: 100%;
  overflow-x: auto;
}
.env-table table {
  width: 100%;
  min-width: 620px;
  border-collapse: collapse;
}
.env-table th {
  padding: 10px 14px;
  text-align: left;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.63rem;
  font-weight: 650;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--meta);
  white-space: nowrap;
}
.env-table td {
  padding: 13px 14px;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.77rem;
  color: var(--text-dim);
  vertical-align: middle;
  white-space: nowrap;
}
.env-table tbody tr:last-child td {
  border-bottom: 0;
}
.env-table tbody tr {
  transition: background-color 200ms var(--ease-in);
}
.env-table tbody tr:hover {
  background: var(--ink-card);
}
.env-table .n {
  color: var(--text);
}
.env-table .u {
  color: var(--accent-text);
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;
  vertical-align: bottom;
}
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border: 1px solid var(--hairline-bright);
  border-radius: 6px;
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--ink-card);
}
.pill-ok {
  border-color: var(--ok-line);
  color: var(--ok);
  background: var(--ok-soft);
}
.pill-warn {
  border-color: var(--warn-line);
  color: var(--warn);
  background: var(--warn-soft);
}

/* ----------------------------------------------------------------------------
   15. LISTS — limits, workflow, comparison
   ------------------------------------------------------------------------- */
.deflist {
  margin-top: 32px;
  border-top: 1px solid var(--hairline);
}
.deflist > div {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  align-items: baseline;
  padding: 15px 2px;
  border-bottom: 1px solid var(--hairline);
}
.deflist .item {
  font-size: 0.95rem;
  min-width: 210px;
  flex: none;
  font-weight: 400;
}
.deflist .why {
  font-size: 0.9rem;
  color: var(--text-dim);
  flex: 1 1 260px;
  max-width: none;
}

.steps {
  margin-top: 40px;
  display: grid;
  gap: 0;
  border-top: 1px solid var(--hairline);
}
@media (min-width: 900px) {
  .steps {
    grid-template-columns: repeat(4, 1fr);
    border-top: 0;
  }
}
/* #order has three steps, not four. Left on the shared rule the row set as
   three columns of a four-column grid with a hole where the fourth would
   be. */
@media (min-width: 900px) {
  #order .steps {
    grid-template-columns: repeat(3, 1fr);
  }
}
.step {
  padding: 22px 0;
  border-bottom: 1px solid var(--hairline);
  position: relative;
}
@media (min-width: 900px) {
  .step {
    padding: 24px 22px 24px 0;
    border-bottom: 0;
    border-top: 1px solid var(--hairline);
  }
  .step::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 0;
    width: 0;
    height: 1px;
    background: var(--accent);
    transition: width 700ms var(--ease-in);
  }
  .step.in::before {
    width: 40px;
  }
}
.step .s-n {
  display: block;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  color: var(--meta);
}
.step h3 {
  margin-top: 12px;
}
.step p {
  margin-top: 8px;
  font-size: 0.89rem;
  color: var(--text-dim);
}

.cmp {
  margin-top: 36px;
  width: 100%;
  overflow-x: auto;
}
.cmp table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
}
.cmp th,
.cmp td {
  padding: 14px 16px;
  text-align: left;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.88rem;
}
.cmp thead th {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--meta);
  border-bottom-color: var(--hairline-bright);
}
.cmp thead th.ours {
  color: var(--accent-text);
}
.cmp tbody th {
  font-weight: 400;
  color: var(--text-dim);
  width: 34%;
}
.cmp td {
  color: var(--text-dim);
}
.cmp td.ours {
  color: var(--text);
  background: var(--accent-wash);
}
.cmp tbody tr:last-child th,
.cmp tbody tr:last-child td {
  border-bottom: 0;
}

/* ----------------------------------------------------------------------------
   16. STATUS PANEL
   ------------------------------------------------------------------------- */
.status-grid {
  display: grid;
  gap: 0;
}
@media (min-width: 760px) {
  .status-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
.status-cell {
  padding: 20px 18px;
  border-bottom: 1px solid var(--hairline);
}
@media (min-width: 760px) {
  .status-cell {
    border-bottom: 0;
    border-right: 1px solid var(--hairline);
  }
  .status-cell:last-child {
    border-right: 0;
  }
}
.status-cell:last-child {
  border-bottom: 0;
}
.status-cell .sc-k {
  display: block;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--meta);
}
.status-cell .sc-v {
  display: block;
  margin-top: 10px;
  font-size: 0.95rem;
  color: var(--text);
}
.status-cell .sc-n {
  display: block;
  margin-top: 6px;
  font-size: 0.85rem;
  color: var(--text-dim);
}

/* ----------------------------------------------------------------------------
   17. FINAL CTA + FOOTER
   ------------------------------------------------------------------------- */
.final h2 {
  font-size: clamp(2.1rem, 4.6vw, 3.2rem);
  line-height: 1.05;
  letter-spacing: -0.035em;
}
.final .cadence {
  margin-top: 24px;
  font-family: var(--mono);
  font-size: 0.9rem;
  color: var(--text-dim);
  line-height: 2;
}

footer {
  padding: 56px 0 48px;
  border-top: 1px solid var(--hairline);
}
.foot-grid {
  display: grid;
  gap: 34px;
}
@media (min-width: 760px) {
  .foot-grid {
    grid-template-columns: 1.4fr repeat(3, 1fr);
    gap: 28px;
  }
}
.foot-col h3 {
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--meta);
}
.foot-col ul {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
}
.foot-col li + li {
  margin-top: 9px;
}
.foot-col a {
  color: var(--text-dim);
  text-decoration: none;
  font-size: 0.88rem;
  transition: color 200ms var(--ease-in);
}
.foot-col a:hover {
  color: var(--text);
}
.foot-blurb {
  margin-top: 14px;
  font-size: 0.86rem;
  color: var(--text-dim);
  max-width: 34ch;
}
.foot-lockup .brand-lg {
  gap: 12px;
}
/* The footer sets the lockup larger than the header. It scales BOTH words,
   not just .brand-word: leaving .brand-product at the base size split the
   lockup across two type sizes once the wordmark went to caps, and the pair
   then overran the column by a couple of pixels. 1.04rem rather than the
   old 1.12rem because letterspaced caps set wider than mixed case at the
   same size. */
.foot-lockup .brand-lg .brand-word,
.foot-lockup .brand-lg .brand-product {
  font-size: 1.04rem;
}

/* The watermark. Set in the page's own display face at a size the columns
   cannot reach, at an opacity where it reads as a texture rather than a word —
   the point is the shape of the name closing the page, not another thing to
   read. `clamp` keeps it from overflowing on a phone, `overflow: hidden` keeps
   a long descender from adding page height, and it is inert to selection and
   the pointer so it never behaves like content. */
.foot-watermark {
  margin-top: 44px;
  /* Centred, and re-sized for the word rather than for the old wording. The
     previous clamp was tuned to "Dominenta" — 23 characters,
     roughly 12em set — so 8.4vw filled the container. "Dominenta" is 9
     characters and measures 4.18em in New York, 4.14em in Times and 4.67em
     in Georgia. --display is the grotesque now, where the same word sets
     4.54em in SF Pro and 4.52em in Helvetica and Arial — narrower, so the
     old numbers could not overflow, they just under-filled. Re-tuned to the
     sans below (there is still no webfont: the CSP blocks font-src outright).

     The numbers below are computed against the widest face in the stack,
     so the word cannot overflow on a machine that falls back to it. That
     matters more than it used to: the text is centred now, so an overflow
     would be clipped at BOTH ends by the `overflow: hidden` below — losing
     the D and the final a rather than just a tail, which is a worse failure
     than the one this comment used to describe. 18vw against 4.665em fills
     about 96% of the container from 320px up, and the 14rem cap lands
     where the container stops growing at --shell. */
  font-size: clamp(3.4rem, 18.5vw, 14rem);
  text-align: center;
  line-height: 0.85;
  font-weight: 500;
  letter-spacing: -0.055em;
  color: rgba(250, 250, 249, 0.055);
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
  overflow: hidden;
  white-space: nowrap;
}

.foot-bottom {
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  align-items: center;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--meta);
}

/* ----------------------------------------------------------------------------
   18. SCROLL REVEAL
   ------------------------------------------------------------------------

   Gated on `.js` — a class app.js sets on <html> as its very first statement,
   before the body is parsed. If the script 404s, fails to parse, or is blocked,
   the class is never set and nothing is ever hidden. The previous revision hid
   .reveal unconditionally in CSS, so a broken script meant a blank page.
   ------------------------------------------------------------------------- */
.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  filter: blur(6px);
  transition: opacity 560ms var(--ease-in), transform 560ms var(--ease-in), filter 560ms var(--ease-in);
}
.js .reveal.in {
  opacity: 1;
  transform: none;
  filter: none;
}
/* stagger children of a revealed group by index, set as a custom property */
.js .reveal[data-i="1"] {
  transition-delay: 60ms;
}
.js .reveal[data-i="2"] {
  transition-delay: 120ms;
}
.js .reveal[data-i="3"] {
  transition-delay: 180ms;
}

/* ----------------------------------------------------------------------------
   18b. NO JAVASCRIPT
   ----------------------------------------------------------------------------

   app.js swaps `no-js` for `js` on <html> as its first statement, so this block
   applies only when the script never ran — disabled, blocked, or broken.

   Two things need saying explicitly. The isolation toggle is a control that
   cannot work, so it is hidden and BOTH diagrams are shown stacked instead;
   without this the shared-kernel half of the page's central argument would be
   unreachable. And Replay is hidden for the same reason — the log itself is in
   the markup, so it reads fine, but the button would do nothing.
   ------------------------------------------------------------------------- */
.no-js .switch,
.no-js .menu-toggle {
  display: none;
}

/* Without the toggle there would be no navigation at all below 860px — and
   below 560px not even the Console button. Put the mobile nav permanently in
   flow instead of behind a control that cannot open it. */
.no-js .mobile-nav {
  display: block;
}
.no-js .btn.header-signin {
  display: inline-flex;
}
.no-js .compare-panel[hidden] {
  display: block;
}
.no-js .compare-panel + .compare-panel {
  margin-top: 14px;
}

/* ----------------------------------------------------------------------------
   19. REDUCED MOTION
   ------------------------------------------------------------------------

   Everything that moves is turned off here, including the two ambient loops
   (the boundary sweep and the status breathe) and the terminal's typing, which
   app.js also checks so it prints its output at once instead of animating it.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  /* The blanket first, exactly as the Console does it, so nothing new anyone
     adds to this file can escape the preference by being forgotten below.
     The named rules that follow are not redundant: they restore the correct
     STATIC state (a revealed element, an unblinking cursor), which a
     near-zero duration alone would not. */
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  html {
    scroll-behavior: auto;
  }
  .js .reveal {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }
  .btn,
  .btn .arrow,
  .btn .arrow-down,
  .site-header,
  .compare-panel {
    transition: none;
    animation: none;
  }
  .btn:hover,
  .btn:active {
    transform: none;
  }
  .boundary-band .b-line::after,
  .dot-live,
  .step::before {
    animation: none;
  }
  .boundary-band .b-line::after {
    display: none;
  }
  .step.in::before {
    transition: none;
  }
}

/* ----------------------------------------------------------------------------
   20. NARROW TABLES
   ----------------------------------------------------------------------------

   Two shapes, not one shrunk. Below 860px both tables stop being tables and
   become stacked cards, each cell naming its own column from `data-label`.

   The alternative — leaving the 620px table inside its `overflow-x: auto`
   wrapper — means a phone visitor has to discover a sideways scroll to find out
   that an environment has a status, a countdown and a URL. The Console itself
   makes exactly this switch, and 860px is the breakpoint it already uses for
   its desktop/mobile pair — so this is the product's own answer at the product's
   own breakpoint, not a new one. It is also where this page's own primary nav
   collapses, which keeps the page down to two shapes rather than three.

   The markup stays a real <table> with a real <caption> and real <th scope>, so
   the semantics a screen reader gets do not change with the viewport.
   ------------------------------------------------------------------------- */
@media (max-width: 859px) {
  .env-table table,
  .cmp table {
    min-width: 0;
    display: block;
  }
  .env-table thead,
  .cmp thead {
    /* clip rather than `display: none`: the header text stays in the
       accessibility tree, so the table is still announced with its columns */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .env-table tbody,
  .cmp tbody {
    display: block;
  }
  .env-table tbody tr,
  .cmp tbody tr {
    display: block;
    padding: 14px 0;
    border-bottom: 1px solid var(--hairline);
  }
  .env-table tbody tr:last-child,
  .cmp tbody tr:last-child {
    border-bottom: 0;
  }

  .env-table td,
  .cmp td,
  .cmp tbody th {
    display: flex;
    align-items: baseline;
    gap: 14px;
    width: auto;
    padding: 5px 14px;
    border-bottom: 0;
    white-space: normal;
  }
  .env-table td::before,
  .cmp td::before {
    content: attr(data-label);
    flex: none;
    min-width: 104px;
    font-family: var(--mono);
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--meta);
  }
  .env-table .u {
    max-width: none;
    white-space: normal;
    word-break: break-all;
  }

  /* the first cell of each row is the row's name — it leads, without a label */
  .env-table td:first-child {
    padding-bottom: 9px;
    font-size: 0.86rem;
  }
  .env-table td:first-child::before {
    display: none;
  }
  /* the property being compared leads the card. Neutral, not accent — it is
     metadata, and the accent belongs to the Orkastor value below it. */
  .cmp tbody th {
    font-family: var(--mono);
    font-size: 0.66rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--meta);
    padding-bottom: 9px;
  }
  /* a 2px left rule, which is a line and not a filled block */
  .cmp td.ours {
    background: transparent;
    border-left: 2px solid var(--accent-line);
    color: var(--text);
  }
  .cmp td.ours::before {
    color: var(--accent-text);
  }
}

/* ----------------------------------------------------------------------------
   21. THE LIGHT REGISTER
   ----------------------------------------------------------------------------

   Everything above is the page's original structure with its surfaces inverted
   at the token layer. This section is the part a token cannot carry: a display
   serif against a grotesque, pressed things as true pills, alternating grounds
   so the page has a rhythm instead of one flat field, and two soft gradient
   fields that give the bone somewhere to breathe.

   The one rule that governs all of it: the accent stays at roughly 5% of
   pixels. Indigo is on the CTAs, the eyebrows, the boundary and the Orkastor
   column of the comparison. It is on nothing else. A light ground makes it very
   easy to spend colour everywhere and end up with a page that has no emphasis
   left to give.
   ------------------------------------------------------------------------- */

/* ── display face ──────────────────────────────────────────────────────────
   One grotesque for everything, which is the reference's arrangement and the
   reason its pages read as flat and engineered rather than composed. The
   serif that used to carry the headlines is retired: --display now resolves
   to the same platform sans as --sans, so this rule is what remains of the
   pairing — it holds the weight and the tracking headlines take, not a
   second family.

   Measured off the reference: 60px at weight 500 with -1.2px of tracking,
   which is -0.02em, the value already set below. Weight goes to 600 because
   SF Pro at 500 sets lighter than Manrope at 500 and the headline lost its
   authority at display size. */
h1,
h2,
.final h2,
.card h3,
.step h3,
.foot-watermark {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -0.02em;
}
h1 {
  letter-spacing: -0.025em;
}
.card h3,
.step h3 {
  font-size: 1.14rem;
  letter-spacing: -0.01em;
}
/* The deflist term and the comparison's row headers stay sans — they are
   labels in a data structure, not headings. */

/* ── eyebrows ──────────────────────────────────────────────────────────────
   Indigo rather than the metadata tone, and this is the one place metadata
   takes the accent. An eyebrow is the only label on the page that exists to be
   found rather than read, and on a bone ground the neutral simply sank. */
.eyebrow {
  /* Was indigo, on the argument that an eyebrow is the one label meant to be
     found rather than read. There is no hue left to spend, so the finding is
     done by the mono face, the upper case and the 0.14em tracking the base
     rule in section 4 already sets — this only has to hand back the colour.
     Dim rather than full strength: at that size and tracking, --text made it
     compete with the h2 directly under it. */
  color: var(--text-dim);
  font-weight: 500;
}

/* ── pressed things are pills ───────────────────────────────────────────── */
.btn,
.skip-link {
  border-radius: var(--radius-pill);
}
.btn-primary {
  /* Flat paper on ink, square, and no shadow — the reference's primary is a
     solid rectangle of the page's own light and nothing else. The gradient
     and the coloured drop that used to sit here were both doing the job of
     separating an indigo fill from a bone ground, and there is no indigo and
     no bone any more. Hover lifts to pure white rather than shifting hue. */
  background-image: none;
  box-shadow: none;
}
.btn-primary:hover {
  background: var(--accent-lift);
  background-image: none;
}
.pill,
.switch,
.switch button {
  border-radius: var(--radius-pill);
}
.pill {
  padding: 4px 11px;
}

/* The card index was a bare mono number. It becomes the small tinted tile the
   register uses to mark a card, which also gives the top of every card
   something to align to. */
.card .card-index {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 26px;
  height: 26px;
  padding: 0 8px;
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent-text);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
}

/* ── the bands ─────────────────────────────────────────────────────────────
   The reference's whole structure is this: full-bleed sections that alternate
   ink and paper the length of the page, edge to edge, with nothing between
   them. It is what gives it rhythm without spending a single colour.

   A band is not a background swap. Paper under ink-coloured body copy is
   unreadable, so every token inside has to invert — and that is exactly what
   custom properties are for. Re-declaring them on the section flips the text,
   the metadata, the hairlines, the card fill and the status tones together,
   for every descendant, and no component rule below needs to know which band
   it is sitting in. That is the whole mechanism; there is no .band-light
   class to remember to add, because the section ids already say it.

   The `.rule` hairlines between sections are dropped here: two bands of
   different colour meeting IS the divider, and a line across the seam reads
   as a mistake. */
#platform,
#order,
#boundary,
#how,
#comparison,
#status {
  color-scheme: light;
  --ink: #fafaf9;
  --ink-sunken: #efeeec;
  --ink-raised: #ffffff;
  --ink-card: #ffffff;
  --ink-hover: #f1f0ed;
  --kg: #12706f;
  --kg-text: #12706f;
  --kg-soft: rgba(18, 112, 111, 0.09);
  --kg-line: rgba(18, 112, 111, 0.3);
  --text: #0f0e0d;
  --text-dim: #57534e;
  --meta: #6b6560;
  --hairline: rgba(15, 14, 13, 0.12);
  --hairline-bright: rgba(15, 14, 13, 0.2);
  --hairline-strong: rgba(15, 14, 13, 0.34);
  --accent: #0f0e0d;
  --accent-lift: #292524;
  --accent-text: #0f0e0d;
  --accent-soft: rgba(15, 14, 13, 0.07);
  --accent-line: rgba(15, 14, 13, 0.2);
  --ok: #15803d;
  --ok-soft: rgba(21, 128, 61, 0.12);
  --ok-line: rgba(21, 128, 61, 0.3);
  --warn: #a16207;
  --warn-soft: rgba(161, 98, 7, 0.12);
  --warn-line: rgba(161, 98, 7, 0.3);
  --accent-wash: rgba(15, 14, 13, 0.04);
  background: var(--ink);
  color: var(--text);
}
/* The primary CTA inverts with its band: ink fill, paper text. */
#platform .btn-primary,
#order .btn-primary,
#boundary .btn-primary,
#how .btn-primary,
#comparison .btn-primary,
#status .btn-primary {
  color: #fafaf9;
}
#platform + .rule,
#order + .rule,
#boundary + .rule,
#how + .rule,
#comparison + .rule,
#status + .rule,
.rule:has(+ #platform),
.rule:has(+ #order),
.rule:has(+ #boundary),
.rule:has(+ #how),
.rule:has(+ #comparison),
.rule:has(+ #status) {
  display: none;
}

/* ── the gradient fields ───────────────────────────────────────────────────
   Two of them, both CSS: the CSP forbids fetching art, and a radial-gradient
   is neither an image nor a font. They sit under everything and are inert.

   `.glow` already draws the lavender field per section — see section 4, whose
   width is capped at 100% for the sideways-scroll reason documented there.
   These two are the larger, off-centre ones the hero and the closing band get,
   and they are attached to the section rather than the body so they scroll
   with the content that justifies them. */
.hero::before,
.final::before {
  content: "";
  position: absolute;
  z-index: -2;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(10px);
}
.hero::before {
  top: -160px;
  left: -180px;
  width: min(560px, 72vw);
  height: min(560px, 72vw);
  background: radial-gradient(circle at 50% 50%, var(--peach), transparent 62%);
}
.final {
  position: relative;
  overflow: hidden;
}
.final::before {
  top: 50%;
  right: -220px;
  width: min(620px, 80vw);
  height: min(620px, 80vw);
  transform: translateY(-50%);
  background: radial-gradient(circle at 50% 50%, var(--lavender), transparent 64%);
}

/* ── surfaces that still need a shadow, not a film ─────────────────────────
   On dark, a card lifted by getting lighter than its ground. On light there is
   nowhere lighter to go past white, so the lift has to come from a shadow.
   Kept very soft and very wide: a tight shadow on a bone ground reads as a
   sticker. */
.card,
.panel,
.mini-env,
.metal-box {
  box-shadow: 0 12px 30px -24px rgba(27, 24, 24, 0.5);
}
.card:hover {
  /* Was a dark drop shadow, which is invisible against ink — the hover had
     no visible state at all on three quarters of the page. A fill lift reads
     in both bands: --ink-sunken is one step off the ground in each. */
  background: var(--ink-hover);
  border-color: var(--hairline-bright);
}

/* The header's stuck state loses its border into the bone otherwise. */
.site-header.is-stuck {
  box-shadow: 0 1px 0 rgba(27, 24, 24, 0.06), 0 12px 28px -26px rgba(27, 24, 24, 0.5);
}

/* The footer watermark is the page's name closing it out. On dark it was a
   near-invisible light; here it is a near-invisible dark, and it takes the
   serif with everything else at display size. */
.foot-watermark {
  letter-spacing: -0.035em;
}

/* ── provenance line ───────────────────────────────────────────────────────
   "A product of Orkastor", under the footer lockup.

   It is highlighted twice over, because it is doing two jobs. The line itself
   takes the accent's tint and a pill so it reads as a distinct object in a
   column of plain footer text rather than as another sentence of blurb. The
   company name inside it then takes weight and a real underline, because it is
   the one link on the page that leaves for the company rather than for a
   product surface, and an accent-coloured word with no underline is not a
   link — it is a word that happens to be blue.

   The underline is drawn by text-decoration rather than a border so it skips
   descenders, and it thickens on hover instead of moving, which keeps the
   pill's height fixed. */
.foot-origin,
.foot-explore,
.head-origin {
  /* flex, not inline-flex, with a fit-content width: as an inline box it flowed
     onto the same line as the Sign in button below it, and a tinted pill beside
     a white pill button reads as two buttons, one of which does nothing. Block
     level gives it its own line; fit-content stops it stretching the column. */
  display: flex;
  width: fit-content;
  align-items: baseline;
  gap: 0.34em;
  padding: 8px 15px;
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  font-size: 0.86rem;
  color: var(--accent-text);
  /* the <p> rule sets a 66ch measure; the pill should hug its own words */
  max-width: none;
}
.foot-origin a,
.head-origin a {
  color: var(--accent-text);
  font-weight: 650;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  transition: text-decoration-thickness 160ms var(--ease-in), color 160ms var(--ease-in);
}
.foot-origin a:hover,
.head-origin a:hover {
  color: var(--accent);
  text-decoration-thickness: 2.5px;
}

/* The header's copy of it. Same object, sized down for the bar: the footer's
   0.86rem pill measures 41px tall against an 85px header, which is half the bar
   and turns the lockup into a row of competing chips. At 0.74rem it is 29px.

   Hidden below 1000px rather than allowed to squeeze. Re-measured after the nav
   dropped to three items: the row is brand 200 + pill 151 + nav 240 + Sign in
   116 = 707, and with 112px of gaps and margins that is 819 of the 944px usable
   at 1000 — 125px of slack. It was 1180 when the nav carried five items and the
   same measurement left sixteen pixels, which is not a layout, it is a
   coincidence. At 940 the slack is 65px and at 900 it is 25px; 1000 is the last
   width where a label could be added without this needing to move again.

   Nothing is lost by hiding it: the footer copy is visible at every width, and
   this is the redundant instance of the two. */
.head-origin {
  flex: none;
  /* No left margin now that it lives inside .header-actions — that row has its
     own 10px gap, and the 18px was spacing it off the brand lockup it used to
     follow. */
  padding: 5px 12px;
  font-size: 0.74rem;
  /* The bar's own line-height would make the pill taller than its text needs. */
  line-height: 1.4;
}
.head-origin a {
  font-weight: 600;
  text-decoration-thickness: 1.2px;
  text-underline-offset: 2.5px;
}
@media (max-width: 999.98px) {
  .head-origin {
    display: none;
  }
}

/* ── the footer's two pills ────────────────────────────────────────────────
   A column, and stated as one rather than left to `flex-wrap` to discover.
   The lockup is 1.4fr of the footer's four-column grid, which is about 330px
   at the 1120px shell and 216px at 820. The two pills measure 176 and 169, so
   345px plus a gap: they do not fit side by side at any width this page has,
   and a wrapping row would only ever produce this stack by accident.

   The margin that used to sit on .foot-origin lives here instead. On the
   footer instance it was right; the header instance inherited it from the
   shared skin and sat 8px below the brand and the nav, because a margin-top
   on a flex item in a centred row is not centring, it is an offset. */
.foot-links {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin-top: 16px;
}

/* The whole pill is the link here, rather than one word inside a sentence:
   there is no sentence, and a 176px target beats a 68px one. The name still
   carries the underline, so the pill does not have to look like a button to
   read as a link. */
/* Selected through .foot-col, and it has to be. The footer column's own link
   rule is `.foot-col a { color: var(--text-dim) }` — two classes' worth of
   weight against this pill's one — so the shared skin's accent colour lost to
   it and the pill rendered grey inside an indigo border. The sibling pill was
   unaffected because its accent lives on `.foot-origin a`, which matches that
   rule's weight and wins on order instead. */
.foot-col a.foot-explore {
  color: var(--accent-text);
  font-size: 0.86rem;
  text-decoration: none;
  transition: border-color 180ms var(--ease-in), background-color 180ms var(--ease-in),
    color 180ms var(--ease-in);
}
.foot-explore .fx-name {
  font-weight: 650;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  transition: text-decoration-thickness 160ms var(--ease-in);
}
.foot-explore .arrow {
  margin-left: 0.1em;
  transition: transform 200ms var(--ease-in);
}
.foot-col a.foot-explore:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(47, 47, 143, 0.17);
}
.foot-explore:hover .fx-name {
  text-decoration-thickness: 2.5px;
}
.foot-explore:hover .arrow {
  transform: translateX(2px);
}

/* ── the header's sign-in ──────────────────────────────────────────────────
   Filled, and larger than the nav around it. It was a ghost button at
   0.87rem, which put the one action in the bar at the same weight as the four
   labels beside it and lighter than the provenance pill — the quietest thing
   in a row of quiet things. Filled indigo is the only place the accent appears
   above the fold apart from the eyebrow, so it reads as the action without
   needing size alone to carry it.

   Overrides the 8px/16px the header set on it earlier in this file; that rule
   was sized for the ghost treatment and shrinking a filled button makes it
   look like a chip. */
.btn.header-signin {
  padding: 11px 22px;
  font-size: 0.95rem;
  font-weight: 550;
}

/* ── the connect dialog ────────────────────────────────────────────────────
   A native <dialog>, so the modal semantics, the focus trap, Escape and the
   inertness of the page behind it are the platform's rather than three more
   things to maintain here. Only the skin is ours. */
.connect {
  width: min(560px, calc(100vw - 2 * var(--gutter)));
  max-height: calc(100vh - 2 * var(--gutter));
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  /* --ink-card, NOT --ink-raised. Raised means "the alternating band" and
     resolves to paper, so this panel came up white with white text on it:
     measured 1.00:1, the dialog was a blank rectangle. Card fill means
     "lifted off the current ground", which is what a modal is. */
  background: var(--ink-card);
  color: var(--text);
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.85);
  overflow: hidden;
}
.connect::backdrop {
  /* Warm, not the UA's neutral black: a grey scrim over a bone page reads as
     a screenshot with the lights off. */
  background: rgba(6, 6, 6, 0.72);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.connect-form {
  display: flex;
  flex-direction: column;
  max-height: inherit;
}
/* Any `display` beats the UA stylesheet's `[hidden] { display: none }`, so a
   flex container with the hidden attribute set stays on screen — the property
   reads as hidden and the element is not. Both panels here declare a display,
   so both need this or the swap shows the form and the confirmation at once. */
.connect-form[hidden] {
  display: none;
}

.connect-head {
  position: relative;
  padding: 24px 26px 18px;
  border-bottom: 1px solid var(--hairline);
  background: var(--ink-sunken);
}
.connect-head h2 {
  margin-top: 8px;
  font-size: 1.45rem;
}
.connect-head .note {
  margin-top: 8px;
  max-width: 44ch;
}
.connect-close {
  position: absolute;
  top: 18px;
  right: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  transition: border-color 180ms var(--ease-in), color 180ms var(--ease-in);
}
.connect-close:hover {
  border-color: var(--hairline-strong);
  color: var(--text);
}

/* The fields. Two columns where there is room, because five stacked rows in a
   modal push the submit button under the fold on a laptop. */
.connect-body {
  display: grid;
  gap: 14px;
  padding: 22px 26px;
  overflow-y: auto;
}
@media (min-width: 520px) {
  .connect-body {
    grid-template-columns: 1fr 1fr;
  }
  .field-wide {
    grid-column: 1 / -1;
  }
}
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.field-label {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--meta);
}
.field-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--hairline-bright);
  border-radius: var(--radius-sm);
  background: var(--ground, var(--ink));
  background: var(--ink);
  color: var(--text);
  font: inherit;
  font-size: 0.94rem;
  transition: border-color 160ms var(--ease-in), box-shadow 160ms var(--ease-in);
}
.field-input::placeholder {
  color: var(--ink-faint, #9c938c);
}
.field-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea.field-input {
  resize: vertical;
  min-height: 76px;
}

.connect-foot {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 26px 20px;
  border-top: 1px solid var(--hairline);
  background: var(--ink-sunken);
}
.connect-status {
  flex: 1;
  min-width: 0;
  margin: 0;
}
.connect-foot .btn {
  flex: none;
}

/* ── the hero action row ───────────────────────────────────────────────────
   All three buttons step up together. Enlarging only the KubeGraf one would
   have made the cross-product link the biggest thing in the hero, above the
   action the page exists for — so the row grows as a set and the hierarchy is
   carried by fill, not by size: solid indigo for connect, white for the
   in-page jump, tinted for the link that leaves. */
.hero .actions .btn {
  padding: 14px 26px;
  font-size: 1rem;
}
.hero .actions {
  gap: 14px;
}

/* The cross-product link, and the only coloured thing on the page.

   It was a pale lavender fill drawn to sit beside an indigo accent on a bone
   ground. Both of those are gone, and the rule survived the retheme because
   it paints with `background-image` — the audit that caught the other
   sixteen literals only looked at `background`. The result measured 1.22:1:
   --accent-text, now paper, on a #e3e1fa fill. Invisible.

   Outline-and-tint rather than a fill, so it stays quieter than the paper
   CTA beside it: this is a way out of the site, not the action the hero
   exists for. Hover fills solid and flips the text to the ground. */
.btn-kg {
  color: var(--kg-text);
  border-color: var(--kg-line);
  background: var(--kg-soft);
  background-image: none;
  font-weight: 550;
  box-shadow: none;
}
.btn-kg:hover {
  color: var(--ink);
  border-color: transparent;
  background: var(--kg);
  background-image: none;
  box-shadow: none;
}

/* ── the connect confirmation ──────────────────────────────────────────────
   Centred, and given the room the form was using: the point of this panel is
   that something changed, and a one-line status where the fields used to be
   reads as the form having failed quietly. */
.connect-done {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 44px 34px 38px;
}
.connect-done[hidden] {
  display: none;
}
.connect-done h2 {
  font-size: 1.4rem;
}
.connect-done .note {
  max-width: 38ch;
}
.connect-done .btn {
  margin-top: 10px;
}
/* The tick sits in the green this page already uses for a finished state, not
   in the accent — the accent means "do this", and there is nothing left to do
   here. */
.done-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: var(--radius-pill);
  background: var(--ok-soft);
  color: var(--ok);
}

/* ── mobile ────────────────────────────────────────────────────────────────
   Two things that only show up on a real phone, and neither is about looks.

   1. iOS Safari ZOOMS THE PAGE when a text field with a font-size under 16px
      takes focus, and does not zoom back out. The fields were 0.94rem, so
      tapping "Full name" threw the visitor into a magnified, sideways-scrolling
      page with the dialog half off-screen. 16px exactly is the threshold; this
      is the whole fix and it costs nothing at this size.

   2. The footer's links were 17px tall. That is the text and nothing else — an
      inline anchor has no height of its own to tap. Padding gives them a real
      target, and the list's own gap comes down so the column does not grow by
      the same amount it gained in reach. */
@media (max-width: 760px) {
  .field-input {
    font-size: 16px;
  }
  /* `.foot-col ul a`, not `.foot-col a`. The broader selector also matched the
     two pills in the lockup column — it gave the "Orkastor" link inside one of
     them 20px of vertical padding, which pushed that pill to 61px over three
     lines, and it set `display: inline-block` on .foot-explore, which IS an
     anchor in a .foot-col and whose own `display: flex` it therefore replaced.
     Only the three link lists want this. */
  .foot-col ul a {
    display: inline-block;
    padding: 10px 0;
  }
  .foot-col ul li + li {
    margin-top: 0;
  }
  /* The lockup is a link too, and its mark is 32px of the 32px. */
  .foot-lockup .brand,
  .site-header .brand {
    padding: 5px 0;
  }
}

/* The dialog gets the screen's edges on a phone rather than a 350px card
   floating in the middle of it: the form is the whole task at that point, and
   the gutter it was keeping is 40px that the five fields could use. */
@media (max-width: 520px) {
  .connect {
    width: 100vw;
    max-width: 100vw;
    max-height: 100vh;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }
  .connect-head {
    padding: 20px 20px 16px;
  }
  .connect-body {
    padding: 18px 20px;
  }
  .connect-foot {
    padding: 14px 20px 18px;
  }
  .connect-done {
    padding: 40px 24px 34px;
  }
  /* Full width, because a pill in the corner of a phone is a smaller target
     than the thumb reaching for it.

     The action row stacks rather than sharing: `.connect-status` is flex: 1
     and was holding half the row open even while empty, which left Send at
     half width and pushed to one side. column-reverse keeps the button first
     and lets the status sit under it when there is one.

     `align-self`, not `flex: 1`, on the confirmation's button — its parent is
     a column, so flex-grow there stretches the button's HEIGHT, not its
     width. */
  .connect-foot {
    flex-direction: column-reverse;
    align-items: stretch;
    gap: 8px;
  }
  .connect-foot .btn {
    justify-content: center;
  }
  .connect-status:empty {
    display: none;
  }
  .connect-done .btn {
    align-self: stretch;
    justify-content: center;
  }
}

/* ── the footer pills on a phone ───────────────────────────────────────────
   Full width and centred. They hug their text on a desktop because they sit in
   a 330px column beside three others; on a phone that column is the whole
   screen, and two short pills floating at the left of it read as leftovers
   rather than as a pair. Stretching them makes them deliberate, and it takes
   the tap targets from 176x41 and 169x41 to the full column at 48px — the same
   size as every other button the page offers a thumb. */
@media (max-width: 520px) {
  .foot-links {
    align-self: stretch;
    width: 100%;
  }
  .foot-origin,
  .foot-col a.foot-explore {
    width: 100%;
    justify-content: center;
    padding: 12px 18px;
    font-size: 0.92rem;
  }
  /* The whole pill becomes the target, not just the word in it. "Orkastor" is
     23px of tappable height inside a 50px pill that plainly looks pressable —
     a thumb aimed at the middle of it hits nothing. The overlay carries the
     hit area; the underline stays on the word, so what looks like the link is
     still the link. .foot-explore needs none of this: it is the anchor. */
  .foot-origin {
    position: relative;
  }
  .foot-origin a::after {
    content: "";
    position: absolute;
    inset: 0;
  }
}

/* The nav marks where you are. Weight and colour, not a rule underneath: the
   header has a hairline of its own when stuck and a second one would read as
   an artefact. */
.header-nav a[aria-current="page"],
.mobile-nav a[aria-current="page"],
.foot-col a[aria-current="page"] {
  color: var(--accent-text);
  font-weight: 600;
}

/* ── the header groups to the right ────────────────────────────────────────
   The nav used to sit next to the brand with all the free space after it, so
   the row read as two things at opposite ends with a hole between them. The
   auto margin moves to the nav instead: the space collects before it, and the
   nav, the provenance pill and Sign in end up as one group at the right.

   `.header-actions` keeps its own auto margin as the default and gives it up
   only here, because below 860px the nav is `display: none` — with the margin
   moved unconditionally the actions would fall back against the lockup on
   every phone, which is the one width this rule is not about.

   Two spacings, on purpose: 24px from the nav to the pill, which is the
   header's own gap, and 10px from the pill to the button, which is the
   actions' — so the pill reads as belonging to the button rather than as the
   last item of the nav. */
@media (min-width: 860px) {
  .header-inner .header-nav {
    margin-left: auto;
  }
  .header-inner .header-actions {
    margin-left: 0;
  }
}
