/* ============================================================
   JOPH UI — design system
   Namespace: --jx-* / .jx-*. Import once, compose pages from blocks.
   Architecture: :root holds the raw palette. A .jx-plane
   re-binds --jx-bg / --jx-fg / --jx-muted / --jx-line /
   --jx-solid so every component is authored once and inherits
   a guaranteed-contrast pair from the plane it sits on.
   ============================================================ */

/* ---- 1. Typefaces ------------------------------------------------ */

@font-face {
  font-family: 'JOPH Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/fraunces-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JOPH Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/fraunces-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: 'JOPH Sans';
  font-style: normal;
  font-weight: 100 1000;
  font-display: swap;
  src: url('fonts/dm-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JOPH Sans';
  font-style: normal;
  font-weight: 100 1000;
  font-display: swap;
  src: url('fonts/dm-sans-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;
}

/* ---- 2. Tokens --------------------------------------------------- */

:root {
  /* Raw palette — extracted from the shipped JOPH stylesheet */
  --jx-paper: oklch(97.3% 0.012 94);
  --jx-paper-soft: oklch(94% 0.023 94);
  --jx-bright: oklch(99.5% 0.003 95);
  --jx-card: oklch(100% 0 0);
  --jx-ink: oklch(14% 0.018 275);
  --jx-ink-2: oklch(44% 0.014 270);

  --jx-cobalt: oklch(54% 0.27 264);
  --jx-cobalt-deep: oklch(48% 0.27 264);
  --jx-cobalt-press: oklch(43% 0.26 264);
  --jx-on-cobalt: oklch(99% 0.002 95);

  --jx-sun: oklch(91% 0.17 99);
  --jx-on-sun: oklch(20% 0.03 264);

  --jx-magenta: oklch(58% 0.24 9);
  /* Magenta carries exactly ONE text tier, and this is it. Sweeping L from
     60% to 100%, only 98%-100% L clears 4.5:1 (4.50-4.76:1) — a 1.9-point
     band. A dimmer secondary step is impossible because the plane itself
     sits at 58% L, so hierarchy on magenta comes from size and weight
     rather than from a paler colour. */
  --jx-on-magenta: oklch(99% 0.002 95);

  /* Shipped as oklch(57.7% .245 27.325). Darkened to 54% L on purpose: the
     shipped value only reaches 4.41:1 as .jx-error copy on a light plane,
     which fails AA. At 54% it measures 4.91:1 on paper and 5.15:1 under
     --jx-on-danger. Hue and chroma are untouched. */
  --jx-danger: oklch(54% 0.245 27.325);
  --jx-on-danger: oklch(99% 0.002 95);

  --jx-line: oklch(88% 0.018 92);
  --jx-line-strong: oklch(25% 0.022 272);
  --jx-line-on-ink: oklch(34% 0.02 272);
  --jx-line-on-ink-strong: oklch(78% 0.02 270);
  --jx-field: oklch(92.9% 0.013 255.508);

  /* Foregrounds verified against each plane (WCAG 2.1) */
  --jx-on-ink: oklch(97.3% 0.012 94);
  --jx-on-ink-2: oklch(79.3% 0.012 250);
  --jx-focus: oklch(48% 0.27 264);
  --jx-focus-on-dark: oklch(91% 0.17 99);

  /* Type */
  --jx-font-display: 'JOPH Fraunces', Georgia, 'Times New Roman', serif;
  --jx-font-sans: 'JOPH Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* Numerals, indices and metadata. The brand ships no mono, so this resolves
     to the platform's own monospace instead of adding a third webfont. This
     token was referenced four times before it existed, which made those
     font-family declarations invalid at computed-value time and silently
     dropped them back to the body face. */
  --jx-num: ui-monospace, 'SF Mono', 'Cascadia Mono', 'Segoe UI Mono',
    Consolas, 'Liberation Mono', monospace;
  /* Display scale. Every heading token was cut 20% on 2026-10-05: the caps
     read as poster type at desktop width and pushed the copy below them into
     a single short column per section. Caps are now 6.6 / 5 / 3.7 / 2.1rem
     and each fluid term tracks its own cap, so the ramp is unchanged in shape
     and 20% smaller in absolute terms.

     Floors are set from measured fit, not taste, and they scale with the
     caps. The longest word in the hero is "Smarter" (3.10em); at the 2.1rem
     floor that needs 105px of the 280px a 320px viewport offers, and 6.7vw
     only overtakes the floor above 501px. A floor set for a retired word is
     how a phone headline ends up visibly under-scaled, so the floor follows
     the current copy rather than the reverse. See brand-spec note 11. */
  --jx-fs-h1: clamp(2.1rem, 6.7vw, 6.6rem);
  --jx-fs-h2: clamp(1.8rem, 5vw, 5rem);
  --jx-fs-h2s: clamp(1.75rem, 4.65vw, 5rem);
  --jx-fs-h3: clamp(1.5rem, 3.2vw, 3.7rem);
  --jx-fs-h4: clamp(1.2rem, 2.1vw, 2.1rem);
  --jx-fs-h5: 1.25rem;
  --jx-fs-lead: clamp(1rem, 1.4vw, 1.25rem);
  --jx-fs-body: 1rem;
  --jx-fs-sm: 0.875rem;
  --jx-fs-xs: 0.8rem;
  --jx-fs-eyebrow: 0.72rem;
  --jx-lh-display: 0.98;
  --jx-lh-heading: 1.06;
  --jx-lh-body: 1.5;
  --jx-track-eyebrow: 0.12em;

  /* Space — 4px base */
  --jx-1: 0.25rem;
  --jx-2: 0.5rem;
  --jx-3: 0.75rem;
  --jx-4: 1rem;
  --jx-5: 1.5rem;
  --jx-6: 2rem;
  --jx-7: 3rem;
  --jx-8: 4rem;
  --jx-9: 6rem;
  --jx-10: 8rem;
  --jx-section-y: clamp(3.5rem, 8vw, 8rem);
  --jx-gutter: clamp(1.25rem, 4vw, 2.5rem);
  --jx-measure: 34rem;

  /* Form */
  --jx-radius: 0.75rem;
  --jx-radius-lg: 1.5rem;
  --jx-radius-pill: 999px;
  --jx-bezel: 8px;
  --jx-device-radius: 2.2rem;
  --jx-shadow: 0 10px 28px color-mix(in oklab, var(--jx-ink) 14%, transparent);
  --jx-shadow-lift: 0 22px 48px color-mix(in oklab, var(--jx-ink) 20%, transparent);
  --jx-target: 44px;
  --jx-dur: 240ms;
  --jx-ease: cubic-bezier(0.2, 0.7, 0.3, 1);

  /* Layout */
  --jx-max: 1240px;
  --jx-max-wide: 1480px;
  --jx-max-read: 46rem;
}

/* ---- 3. Base ----------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--jx-paper);
  color: var(--jx-ink);
  font-family: var(--jx-font-sans);
  font-size: var(--jx-fs-body);
  line-height: var(--jx-lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

h1,
h2,
h3,
h4,
h5,
p,
figure,
blockquote,
dl,
dd {
  margin: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

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

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 3px solid var(--jx-focus, var(--jx-cobalt));
  outline-offset: 3px;
  border-radius: var(--jx-radius-pill);
}

.jx-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.jx-skip {
  position: absolute;
  top: var(--jx-2);
  left: var(--jx-2);
  z-index: 90;
  padding: 0.7rem 1.1rem;
  border-radius: var(--jx-radius-pill);
  background: var(--jx-ink);
  color: var(--jx-on-ink);
  transform: translateY(-200%);
}
.jx-skip:focus {
  transform: translateY(0);
}

/* ---- 4. Layout primitives ---------------------------------------- */

.jx-container {
  width: 100%;
  max-width: var(--jx-max);
  margin-inline: auto;
  padding-inline: var(--jx-gutter);
}
.jx-container--wide {
  max-width: var(--jx-max-wide);
}
.jx-container--read {
  max-width: var(--jx-max-read);
}

.jx-grid {
  display: grid;
  gap: var(--jx-6);
}
.jx-grid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.jx-grid--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.jx-grid--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.jx-grid--2-1 {
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
}
.jx-grid--1-2 {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
}

.jx-stack {
  display: flex;
  flex-direction: column;
  gap: var(--jx-5);
}
.jx-stack--tight {
  gap: var(--jx-3);
}
.jx-stack--loose {
  gap: var(--jx-7);
}

.jx-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--jx-3);
}
.jx-row--between {
  justify-content: space-between;
}
.jx-row--end {
  justify-content: flex-end;
}

.jx-rule {
  height: 1px;
  border: 0;
  background: var(--jx-line);
}
.jx-rule--strong {
  background: var(--jx-line-strong);
}

/* ---- 5. Planes --------------------------------------------------- */

.jx-plane {
  --jx-bg: var(--jx-paper);
  --jx-fg: var(--jx-ink);
  --jx-muted: var(--jx-ink-2);
  --jx-solid: var(--jx-cobalt);
  --jx-solid-fg: var(--jx-on-cobalt);
  --jx-solid-hover: var(--jx-cobalt-deep);
  /* --jx-line, --jx-line-strong and --jx-focus are deliberately NOT restated
     here. They used to be written as `--jx-line: var(--jx-line)`, which is a
     self-reference: a custom property whose value cycles back to itself is
     invalid at computed-value time, so every hairline border inside a plane
     could resolve to `unset` and inherit currentColor. They are inherited
     from :root instead, and the dark planes below override them with the
     on-ink / on-cobalt pairs. */
  position: relative;
  background: var(--jx-bg);
  color: var(--jx-fg);
}
.jx-plane--soft {
  --jx-bg: var(--jx-paper-soft);
}
.jx-plane--bright {
  --jx-bg: var(--jx-bright);
}
.jx-plane--card {
  --jx-bg: var(--jx-card);
}
.jx-plane--ink {
  --jx-bg: var(--jx-ink);
  --jx-fg: var(--jx-on-ink);
  --jx-muted: var(--jx-on-ink-2);
  --jx-line: var(--jx-line-on-ink);
  --jx-line-strong: var(--jx-line-on-ink-strong);
--jx-solid: var(--jx-sun);
  --jx-solid-fg: var(--jx-on-sun);
  --jx-solid-hover: oklch(84% 0.17 99);
  --jx-focus: var(--jx-focus-on-dark);
}
.jx-plane--cobalt {
  --jx-bg: var(--jx-cobalt);
  --jx-fg: var(--jx-on-cobalt);
  --jx-muted: oklch(95% 0.025 264);
  --jx-line: color-mix(in oklab, var(--jx-on-cobalt) 34%, transparent);
  --jx-line-strong: var(--jx-on-cobalt);
  --jx-solid: var(--jx-ink);
  --jx-solid-fg: var(--jx-on-ink);
  --jx-solid-hover: oklch(20% 0.018 275);
  --jx-focus: var(--jx-on-cobalt);
}
.jx-plane--sun {
  --jx-bg: var(--jx-sun);
  --jx-fg: var(--jx-on-sun);
  --jx-muted: oklch(38% 0.06 264);
  --jx-line: color-mix(in oklab, var(--jx-on-sun) 30%, transparent);
  --jx-line-strong: var(--jx-on-sun);
  --jx-solid: var(--jx-ink);
  --jx-solid-fg: var(--jx-on-ink);
  --jx-solid-hover: oklch(22% 0.018 275);
  --jx-focus: var(--jx-on-sun);
}
/* Magenta is the tightest plane in the system. Its only compliant text
   colour is 99% L at 4.63:1, so --jx-muted deliberately reuses that same
   tier instead of inventing a failing one. Keep this plane to short
   statements rather than long paragraphs. */
.jx-plane--magenta {
  --jx-bg: var(--jx-magenta);
  --jx-fg: var(--jx-on-magenta);
  --jx-muted: var(--jx-on-magenta);
  --jx-line: color-mix(in oklab, var(--jx-on-magenta) 34%, transparent);
  --jx-line-strong: var(--jx-on-magenta);
  --jx-solid: var(--jx-ink);
  --jx-solid-fg: var(--jx-on-ink);
  --jx-solid-hover: oklch(22% 0.018 275);
  --jx-focus: var(--jx-on-magenta);
}

.jx-band {
  padding-block: var(--jx-section-y);
}
.jx-band--tight {
  padding-block: clamp(2.5rem, 5vw, 4.5rem);
}

/* ---- 6. Typography ----------------------------------------------- */

.jx-h1,
.jx-h2,
.jx-h3,
.jx-h4,
.jx-h5 {
  font-family: var(--jx-font-display);
  font-weight: 700;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 100, 'WONK' 1;
  letter-spacing: 0;
  text-wrap: balance;
  /* Backstop only: a display word wider than its column must break rather
     than push the page into a horizontal scroll. */
  overflow-wrap: break-word;
  color: var(--jx-fg);
}

.jx-h1 {
  font-size: var(--jx-fs-h1);
  line-height: var(--jx-lh-display);
  max-width: 18ch;
}
.jx-h2 {
  font-size: var(--jx-fs-h2);
  line-height: var(--jx-lh-display);
  max-width: 20ch;
}
.jx-h3 {
  font-size: var(--jx-fs-h3);
  line-height: var(--jx-lh-heading);
  max-width: 22ch;
}
.jx-h4 {
  font-size: var(--jx-fs-h4);
  line-height: var(--jx-lh-heading);
  max-width: 26ch;
}
.jx-h5 {
  font-size: var(--jx-fs-h5);
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.jx-h1 em,
.jx-h2 em,
.jx-h3 em,
.jx-h4 em {
  font-style: normal;
  color: var(--jx-em, var(--jx-cobalt));
}

.jx-lead {
  font-size: var(--jx-fs-lead);
  line-height: 1.55;
  max-width: var(--jx-measure);
  color: var(--jx-muted);
  text-wrap: pretty;
}

.jx-body {
  font-size: var(--jx-fs-body);
  max-width: var(--jx-measure);
  color: var(--jx-fg);
  text-wrap: pretty;
}
.jx-body + .jx-body {
  margin-top: var(--jx-3);
}

.jx-meta {
  font-size: var(--jx-fs-xs);
  color: var(--jx-muted);
}

.jx-num {
  font-family: var(--jx-font-sans);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  letter-spacing: -0.01em;
}

.jx-eyebrow {
  font-size: var(--jx-fs-eyebrow);
  font-weight: 800;
  letter-spacing: var(--jx-track-eyebrow);
  text-transform: uppercase;
  line-height: 1;
  color: var(--jx-eyebrow, var(--jx-cobalt));
}

.jx-label {
  display: block;
  font-size: var(--jx-fs-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--jx-muted);
}

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

.jx-btn {
  --btn-bg: transparent;
  --btn-fg: var(--jx-fg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  min-height: var(--jx-target);
  padding: 0.75rem 1.6rem;
  border: 0;
  border-radius: var(--jx-radius-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--jx-fs-body);
  font-weight: 700;
  line-height: 1.1;
  text-align: center;
  cursor: pointer;
  transition: background-color var(--jx-dur) var(--jx-ease),
    color var(--jx-dur) var(--jx-ease), transform var(--jx-dur) var(--jx-ease),
    box-shadow var(--jx-dur) var(--jx-ease);
}

.jx-btn--primary {
  --btn-bg: var(--jx-solid);
  --btn-fg: var(--jx-solid-fg);
  box-shadow: var(--jx-shadow);
}
.jx-btn--primary:hover {
  --btn-bg: var(--jx-solid-hover);
  transform: translateY(-0.5px);
  box-shadow: var(--jx-shadow-lift);
}
.jx-btn--primary:active {
  transform: translateY(0);
  box-shadow: var(--jx-shadow);
}

.jx-btn--ghost {
  border: 1.5px solid currentColor;
}
.jx-btn--ghost:hover {
  background: color-mix(in oklab, currentColor 12%, transparent);
}

.jx-btn--quiet {
  --btn-fg: var(--jx-fg);
  padding-inline: 0.9rem;
}
.jx-btn--quiet:hover {
  background: color-mix(in oklab, currentColor 10%, transparent);
}

.jx-btn--outline {
  /* The fill is derived from the plane's own foreground, not from a fixed
     near-white. A --jx-bright fill is invisible against paper and puts
     near-white label text on a near-white surface on a dark plane - the same
     inherited-token trap as a card on a dark plane. Mixing from --jx-fg makes
     the variant correct on every plane without a per-plane override. */
  --btn-fg: var(--jx-fg);
  border: 1.5px solid var(--jx-line-strong);
  background: color-mix(in oklab, var(--jx-fg) 6%, transparent);
}
.jx-btn--outline:hover {
  border-color: var(--jx-fg);
  background: color-mix(in oklab, var(--jx-fg) 8%, var(--jx-bright));
}

.jx-btn--danger {
  --btn-bg: var(--jx-danger);
  --btn-fg: var(--jx-on-danger);
}
.jx-btn--danger:hover {
  --btn-bg: oklch(47% 0.23 27.325);
}

.jx-btn--lg {
  min-height: 3.5rem;
  padding: 1.05rem 2.1rem;
  font-size: 1.0625rem;
}
/* Small still clears the 44px target — compact, not tiny. */
.jx-btn--sm {
  min-height: var(--jx-target);
  padding: 0.5rem 1.1rem;
  font-size: var(--jx-fs-sm);
}

.jx-btn--arrow::after {
  content: '\2192';
  font-family: var(--jx-font-sans);
  transition: transform var(--jx-dur) var(--jx-ease);
}
.jx-btn--arrow:hover::after {
  transform: translateX(3px);
}

.jx-btn:disabled,
.jx-btn[aria-disabled='true'] {
  cursor: not-allowed;
  --btn-bg: color-mix(in oklab, var(--jx-fg) 10%, var(--jx-bg));
  --btn-fg: color-mix(in oklab, var(--jx-fg) 42%, var(--jx-bg));
  box-shadow: none;
  transform: none;
}
.jx-btn--ghost:disabled,
.jx-btn--quiet:disabled,
.jx-btn--outline:disabled {
  border-color: color-mix(in oklab, var(--jx-fg) 26%, transparent);
  background: transparent;
}

.jx-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--jx-3);
}

/* ---- 8. Chips, badges, tags -------------------------------------- */

.jx-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  min-height: 2rem;
  padding: 0.3rem 0.85rem;
  border: 1px solid var(--jx-line);
  border-radius: var(--jx-radius-pill);
  background: var(--jx-bright);
  color: var(--jx-fg);
  font-size: var(--jx-fs-xs);
  font-weight: 600;
  white-space: nowrap;
}
.jx-chip--solid {
  border-color: transparent;
  background: var(--jx-solid);
  color: var(--jx-solid-fg);
}
.jx-chip--sun {
  border-color: transparent;
  background: var(--jx-sun);
  color: var(--jx-on-sun);
}
.jx-chip--magenta {
  border-color: transparent;
  background: var(--jx-magenta);
  color: var(--jx-on-magenta);
}

.jx-tag {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: var(--jx-radius);
  background: color-mix(in oklab, var(--jx-fg) 8%, transparent);
  color: var(--jx-muted);
  font-size: var(--jx-fs-xs);
  font-weight: 600;
}

.jx-dot {
  width: 0.5rem;
  height: 0.5rem;
  flex: none;
  border-radius: var(--jx-radius-pill);
  background: var(--jx-muted);
}
.jx-dot--live {
  background: var(--jx-solid);
}
.jx-chip .jx-dot {
  background: currentColor;
}

.jx-status {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-size: var(--jx-fs-xs);
  font-weight: 700;
  color: var(--jx-muted);
}
.jx-status::before {
  content: '';
  width: 0.55rem;
  height: 0.55rem;
  border-radius: var(--jx-radius-pill);
  background: var(--jx-solid);
}
.jx-status--warn::before {
  background: var(--jx-sun);
}
.jx-status--stop::before {
  background: var(--jx-danger);
}

/* ---- 9. Cards and features --------------------------------------- */

/* A card hard-codes its own foreground and background, so it must also rebind
   the plane's semantic foreground tokens - not just set `color`. Descendants
   do not inherit `color` in every case: every heading rule in this file
   declares `color: var(--jx-fg)` outright, so a card sitting on a dark plane
   painted that plane's near-white heading colour onto the card's own white.
   Rebinding --jx-fg and --jx-muted here fixes every such descendant at once,
   and each variant below pairs its tiers with the foreground it ships.

   The line tokens move to the ink family for the same reason. A card is a
   light object whatever plane it lands on, so it keeps one boundary weight
   everywhere; inheriting the plane's line gave the same card a faint warm
   hairline on paper and a light halo on magenta. */
.jx-card {
  --jx-fg: var(--jx-ink);
  --jx-muted: var(--jx-ink-2);
  --jx-line: var(--jx-line-on-ink);
  --jx-line-strong: var(--jx-line-strong);
  padding: var(--jx-5);
  border: 1px solid var(--jx-line);
  border-radius: var(--jx-radius);
  background: var(--jx-card);
  color: var(--jx-ink);
  transition: transform var(--jx-dur) var(--jx-ease),
    box-shadow var(--jx-dur) var(--jx-ease),
    border-color var(--jx-dur) var(--jx-ease);
}
.jx-card--flat {
  /* The flat variant drops the box, so it also has to drop the foreground
     rebinding above - otherwise a transparent card on a dark plane would
     still carry ink-coloured headings. It cannot read the plane's value back
     (--jx-fg is not declared at :root, and a self-reference is a cycle), so
     this variant restates the light-plane pair and is therefore restricted to
     light planes. Use a bare wrapper instead on a dark plane. */
  --jx-fg: var(--jx-ink);
  --jx-muted: var(--jx-ink-2);
  --jx-line: transparent;
  --jx-line-strong: transparent;
  background: transparent;
  border-color: transparent;
  padding: 0;
}
.jx-card--lift:hover {
  transform: translateY(-2px);
  border-color: var(--jx-line-strong);
  box-shadow: var(--jx-shadow);
}
.jx-card--ink {
  --jx-fg: var(--jx-on-ink);
  --jx-muted: var(--jx-on-ink-2);
  background: var(--jx-ink);
  border-color: var(--jx-ink);
  color: var(--jx-on-ink);
}
.jx-card--sun {
  --jx-fg: var(--jx-on-sun);
  --jx-muted: oklch(38% 0.06 264);
  background: var(--jx-sun);
  border-color: var(--jx-sun);
  color: var(--jx-on-sun);
}
.jx-card--cobalt {
  --jx-fg: var(--jx-on-cobalt);
  --jx-muted: oklch(95% 0.025 264);
  background: var(--jx-cobalt);
  border-color: var(--jx-cobalt);
  color: var(--jx-on-cobalt);
}
.jx-card--magenta {
  --jx-fg: var(--jx-on-magenta);
  --jx-muted: var(--jx-on-magenta);
  background: var(--jx-magenta);
  border-color: var(--jx-magenta);
  color: var(--jx-on-magenta);
}

.jx-feature {
  display: flex;
  flex-direction: column;
  gap: var(--jx-3);
}
.jx-feature .jx-h4,
.jx-feature .jx-h5 {
  margin-top: var(--jx-1);
}
.jx-feature p {
  color: var(--jx-muted);
  max-width: 30ch;
  text-wrap: pretty;
}

.jx-mark {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  flex: none;
  border: 1.5px solid currentColor;
  border-radius: var(--jx-radius);
  color: var(--jx-fg);
}
.jx-mark svg {
  width: 1.35rem;
  height: 1.35rem;
}
.jx-mark--solid {
  border-color: transparent;
  background: var(--jx-solid);
  color: var(--jx-solid-fg);
}

/* ---- 10. Stats ---------------------------------------------------- */

.jx-stat {
  display: flex;
  flex-direction: column;
  gap: var(--jx-2);
  padding-top: var(--jx-4);
  border-top: 2px solid var(--jx-fg);
}
.jx-stat-num {
  font-family: var(--jx-font-display);
  font-weight: 700;
  font-variation-settings: 'SOFT' 100, 'WONK' 1;
  font-size: clamp(2.75rem, 5vw, 4.75rem);
  line-height: 0.94;
  color: var(--jx-fg);
}
.jx-stat-unit {
  font-size: 0.5em;
  color: var(--jx-muted);
}
.jx-stat-label {
  color: var(--jx-muted);
  max-width: 28ch;
  text-wrap: pretty;
}

/* ---- 11. Quote ---------------------------------------------------- */

.jx-quote-mark {
  font-family: var(--jx-font-display);
  font-size: 5rem;
  line-height: 0.7;
  color: var(--jx-sun);
}
.jx-quote {
  font-family: var(--jx-font-display);
  font-weight: 700;
  font-variation-settings: 'SOFT' 100, 'WONK' 1;
  font-size: var(--jx-fs-h3);
  line-height: 1.12;
  color: var(--jx-fg);
  text-wrap: pretty;
}
.jx-quote-author {
  margin-top: var(--jx-4);
  font-size: var(--jx-fs-sm);
  font-weight: 600;
  color: var(--jx-muted);
}

/* ---- 12. Log / list rows ------------------------------------------ */

.jx-log-row {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1fr) auto;
  gap: var(--jx-4);
  align-items: start;
  padding-block: var(--jx-5);
  border-top: 1px solid var(--jx-line);
}
.jx-log-row:last-child {
  border-bottom: 1px solid var(--jx-line);
}
.jx-log-row .jx-h5 {
  text-wrap: balance;
}
.jx-log-row p {
  margin-top: var(--jx-1);
  color: var(--jx-muted);
  font-size: var(--jx-fs-sm);
  max-width: 52ch;
  text-wrap: pretty;
}
.jx-log-time {
  font-family: var(--jx-font-sans);
  font-variant-numeric: tabular-nums;
  font-size: var(--jx-fs-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--jx-muted);
}

/* ---- 13. Table ---------------------------------------------------- */

.jx-table-wrap {
  overflow-x: auto;
  border-radius: var(--jx-radius);
}
.jx-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--jx-fs-sm);
}
.jx-table th,
.jx-table td {
  padding: 1rem 1.1rem;
  text-align: left;
  border-bottom: 1px solid var(--jx-line);
}
.jx-table thead th {
  font-size: var(--jx-fs-eyebrow);
  font-weight: 800;
  letter-spacing: var(--jx-track-eyebrow);
  text-transform: uppercase;
  color: var(--jx-muted);
  border-bottom: 1.5px solid var(--jx-line-strong);
  white-space: nowrap;
}
.jx-table tbody tr {
  transition: background-color var(--jx-dur) var(--jx-ease);
}
.jx-table tbody tr:hover {
  background: color-mix(in oklab, var(--jx-fg) 5%, transparent);
}
.jx-table .jx-num-col {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.jx-table tbody tr:last-child td {
  border-bottom: 0;
}

/* ---- 14. Forms ---------------------------------------------------- */

.jx-field {
  display: flex;
  flex-direction: column;
  gap: var(--jx-2);
}
.jx-input,
.jx-select,
.jx-textarea {
  width: 100%;
  min-height: var(--jx-target);
  padding: 0.7rem 1rem;
  border: 1.5px solid var(--jx-line-strong);
  border-radius: var(--jx-radius);
  background: var(--jx-field);
  color: var(--jx-ink);
  transition: border-color var(--jx-dur) var(--jx-ease),
    background-color var(--jx-dur) var(--jx-ease),
    box-shadow var(--jx-dur) var(--jx-ease);
}
.jx-textarea {
  min-height: 7rem;
  resize: vertical;
}
.jx-input::placeholder,
.jx-textarea::placeholder {
  color: var(--jx-ink-2);
}
.jx-input:hover,
.jx-select:hover,
.jx-textarea:hover {
  border-color: var(--jx-ink);
  background: var(--jx-bright);
}
.jx-input:focus,
.jx-select:focus,
.jx-textarea:focus {
  outline: none;
  border-color: var(--jx-cobalt);
  background: var(--jx-bright);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--jx-cobalt) 28%, transparent);
}
.jx-input:focus-visible,
.jx-select:focus-visible,
.jx-textarea:focus-visible {
  outline: none;
}
.jx-input[aria-invalid='true'] {
  border-color: var(--jx-danger);
}
.jx-help {
  font-size: var(--jx-fs-xs);
  color: var(--jx-muted);
}
.jx-error {
  font-size: var(--jx-fs-xs);
  font-weight: 600;
  color: var(--jx-danger);
}

.jx-check {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-height: var(--jx-target);
  padding-block: 0.25rem;
  font-size: var(--jx-fs-sm);
  color: var(--jx-fg);
  cursor: pointer;
}
.jx-check input {
  width: 1.3rem;
  height: 1.3rem;
  flex: none;
  accent-color: var(--jx-cobalt);
  cursor: pointer;
}

.jx-radio-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--jx-3);
}

/* ---- 15. Accordion ------------------------------------------------ */

.jx-acc {
  border-top: 1px solid var(--jx-line);
}
.jx-acc:last-of-type {
  border-bottom: 1px solid var(--jx-line);
}
.jx-acc summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--jx-4);
  min-height: var(--jx-target);
  padding-block: var(--jx-4);
  font-family: var(--jx-font-display);
  font-weight: 700;
  font-size: var(--jx-fs-h5);
  color: var(--jx-fg);
  cursor: pointer;
  list-style: none;
}
.jx-acc summary::-webkit-details-marker {
  display: none;
}
.jx-acc summary::after {
  content: '+';
  font-family: var(--jx-font-sans);
  font-size: 1.4rem;
  line-height: 1;
  color: var(--jx-muted);
  transition: transform var(--jx-dur) var(--jx-ease);
}
.jx-acc[open] summary::after {
  content: '\2212';
}
.jx-acc summary:hover {
  color: var(--jx-cobalt);
}
.jx-acc-body {
  padding-bottom: var(--jx-5);
  color: var(--jx-muted);
  max-width: 58ch;
  text-wrap: pretty;
}

/* ---- 16. Device frame and media ----------------------------------- */

.jx-device {
  width: min(100%, 20rem);
  margin-inline: auto;
  padding: var(--jx-bezel);
  border-radius: var(--jx-device-radius);
  background: var(--jx-ink);
  box-shadow: var(--jx-shadow-lift);
  transition: transform var(--jx-dur) var(--jx-ease);
}
.jx-device:hover {
  transform: translateY(-3px);
}
.jx-device--wide {
  width: min(100%, 24rem);
}
.jx-device img,
.jx-device video {
  width: 100%;
  height: auto;
  border-radius: calc(var(--jx-device-radius) - var(--jx-bezel));
  display: block;
}

.jx-device-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(1rem, 3vw, 2.5rem);
}

.jx-shot {
  display: block;
  width: 100%;
  height: auto;
  max-height: 34rem;
  object-fit: contain;
  object-position: left top;
  border-radius: var(--jx-radius);
  background: var(--jx-bright);
}

.jx-logo {
  width: auto;
  height: 2.1rem;
  max-width: 100%;
}

.jx-figure {
  display: flex;
  flex-direction: column;
  gap: var(--jx-3);
}
.jx-figure figcaption {
  font-size: var(--jx-fs-xs);
  color: var(--jx-muted);
}

/* ---- 17. Track / steps ------------------------------------------- */

.jx-track {
  position: relative;
  display: grid;
  gap: var(--jx-5);
  padding-left: 2.25rem;
}
.jx-track::before {
  content: '';
  position: absolute;
  left: 0.6875rem;
  top: 0.5rem;
  bottom: 0.5rem;
  width: 2px;
  background: var(--jx-line);
}
.jx-track-item {
  position: relative;
}
.jx-track-item::before {
  content: '';
  position: absolute;
  left: -2.25rem;
  top: 0.45rem;
  width: 1.375rem;
  height: 1.375rem;
  border: 2px solid var(--jx-line-strong);
  border-radius: var(--jx-radius-pill);
  background: var(--jx-bg);
}
.jx-track-item--done::before {
  background: var(--jx-cobalt);
  border-color: var(--jx-cobalt);
}
.jx-track-item--now::before {
  background: var(--jx-sun);
  border-color: var(--jx-sun);
  box-shadow: 0 0 0 5px color-mix(in oklab, var(--jx-sun) 30%, transparent);
}
.jx-track-item .jx-h5 {
  margin-bottom: var(--jx-1);
}
.jx-track-item p {
  color: var(--jx-muted);
  font-size: var(--jx-fs-sm);
  max-width: 44ch;
  text-wrap: pretty;
}

/* ---- 18. Navigation ----------------------------------------------- */

/* The topnav is sticky at 4.5rem tall. Without this, jumping to #experience
   or #business parks the section heading underneath it. */
:target,
section[id],
main[id] {
  scroll-margin-top: 5.5rem;
}

.jx-topnav {
  position: sticky;
  top: 0;
  z-index: 40;
  border-bottom: 1px solid var(--jx-line);
  background: color-mix(in oklab, var(--jx-bg) 82%, transparent);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
}
.jx-topnav-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--jx-4);
  min-height: 4.5rem;
}
.jx-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  min-height: var(--jx-target);
  font-family: var(--jx-font-display);
  font-weight: 700;
  font-size: 1.35rem;
  letter-spacing: -0.01em;
  color: var(--jx-fg);
}
.jx-brand .jx-logo {
  height: 1.9rem;
}

.jx-nav-toggle {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.jx-burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--jx-target);
  height: var(--jx-target);
  border: 1.5px solid var(--jx-line-strong);
  border-radius: var(--jx-radius);
  color: var(--jx-fg);
  cursor: pointer;
}
.jx-burger span,
.jx-burger span::before,
.jx-burger span::after {
  display: block;
  width: 1.15rem;
  height: 2px;
  background: currentColor;
}
.jx-burger span {
  position: relative;
}
.jx-burger span::before,
.jx-burger span::after {
  content: '';
  position: absolute;
  left: 0;
}
.jx-burger span::before {
  top: -6px;
}
.jx-burger span::after {
  top: 6px;
}

.jx-nav-links {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.75rem);
}
.jx-nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: var(--jx-target);
  padding: 0.5rem 0.25rem;
  font-size: var(--jx-fs-sm);
  font-weight: 600;
  color: var(--jx-fg);
  transition: color var(--jx-dur) var(--jx-ease);
}
.jx-nav-link::after {
  content: '';
  position: absolute;
  left: 0.25rem;
  right: 0.25rem;
  bottom: 0.15rem;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--jx-dur) var(--jx-ease);
}
.jx-nav-link:hover::after,
.jx-nav-link:focus-visible::after,
.jx-nav-link[aria-current='page']::after {
  transform: scaleX(1);
}
.jx-nav-toggle:focus-visible ~ .jx-burger {
  outline: 3px solid var(--jx-focus);
  outline-offset: 3px;
}

/* ---- 19. Notice bar ----------------------------------------------- */

.jx-notice {
  padding-block: var(--jx-2);
  background: var(--jx-ink);
  color: var(--jx-on-ink);
  font-size: var(--jx-fs-xs);
  font-weight: 600;
  text-align: center;
}
.jx-notice a {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.jx-notice a:hover {
  color: var(--jx-sun);
}

/* ---- 20. Footer --------------------------------------------------- */

.jx-foot {
  padding-block: var(--jx-9) var(--jx-6);
}
.jx-foot-grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr));
  gap: var(--jx-6);
}
.jx-foot :is(h3, h4) {
  font-family: var(--jx-font-sans);
  font-size: var(--jx-fs-eyebrow);
  font-weight: 800;
  letter-spacing: var(--jx-track-eyebrow);
  text-transform: uppercase;
  color: var(--jx-muted);
  margin-bottom: var(--jx-3);
}
.jx-foot li + li {
  margin-top: 0.25rem;
}
/* Footer links are a standalone list, not inline prose, so they carry
   their own target size rather than relying on the line box. */
.jx-foot a {
  display: inline-block;
  padding-block: 0.35rem;
  font-size: var(--jx-fs-sm);
  color: var(--jx-fg);
  transition: color var(--jx-dur) var(--jx-ease);
}
.jx-foot a:hover {
  color: var(--jx-cobalt);
}
.jx-foot-base {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--jx-3);
  margin-top: var(--jx-8);
  padding-top: var(--jx-4);
  border-top: 1px solid var(--jx-line);
  font-size: var(--jx-fs-xs);
  color: var(--jx-muted);
}

/* ---- 21. Section headers ------------------------------------------ */

.jx-head {
  display: flex;
  flex-direction: column;
  gap: var(--jx-4);
  max-width: 42rem;
}
.jx-head .jx-eyebrow {
  color: var(--jx-eyebrow, var(--jx-cobalt));
}
.jx-head--center {
  align-items: center;
  text-align: center;
  margin-inline: auto;
}

/* ---- 22. Responsive ----------------------------------------------- */

@media (max-width: 1080px) {
  .jx-grid--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .jx-foot-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 920px) {
  .jx-grid--2,
  .jx-grid--3,
  .jx-grid--2-1,
  .jx-grid--1-2 {
    grid-template-columns: minmax(0, 1fr);
  }
  .jx-log-row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--jx-2);
  }
  .jx-log-row .jx-tag {
    justify-self: start;
  }
  .jx-burger {
    display: inline-flex;
  }
  .jx-nav-panel {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--jx-1);
    padding-block: var(--jx-3) var(--jx-5);
    border-top: 1px solid var(--jx-line);
  }
  .jx-nav-toggle:not(:checked) ~ .jx-nav-panel {
    display: none;
  }
  .jx-nav-links {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }
  .jx-nav-link {
    display: block;
    padding: 0.85rem 0;
    font-size: var(--jx-fs-body);
    border-bottom: 1px solid var(--jx-line);
  }
  .jx-nav-link::after {
    display: none;
  }
  .jx-nav-panel .jx-btn {
    margin-top: var(--jx-3);
  }
}

@media (min-width: 921px) {
  .jx-nav-panel {
    display: flex;
    align-items: center;
    gap: clamp(0.75rem, 2vw, 1.75rem);
  }
}

@media (max-width: 680px) {
  .jx-grid--4 {
    grid-template-columns: minmax(0, 1fr);
  }
  .jx-foot-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .jx-btn {
    width: 100%;
  }
  .jx-btn-row .jx-btn {
    width: auto;
    flex: 1 1 14rem;
  }
  .jx-device {
    width: min(100%, 16rem);
  }
  .jx-shot {
    max-height: 26rem;
  }
  .jx-h1 {
    max-width: 22ch;
  }
  .jx-h2,
  .jx-h3 {
    max-width: 26ch;
  }
}

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

@media print {
  .jx-topnav,
  .jx-burger,
  .jx-nav-toggle {
    display: none !important;
  }
  .jx-band {
    padding-block: 1.5rem;
  }
  body {
    font-size: 12pt;
  }
}