/* ═══════════════════════════════════════════════════════════════════════════
   LANDING — "One desk".
   The public page now uses the same material as the product: an ambient wash
   with layered glass panes floating on it. Someone who sees this page and
   signs up finds the same surfaces waiting, which is the point.
   Scoped to body.desk-landing and loaded after landing.css so it governs.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The default 8px body margin was letting the html background show as thin
   strips down both edges — the page looked inset rather than full-bleed.
   The html element takes the same background so nothing can peek through. */
html:has(body.desk-landing) {
  overflow-x: clip;
  background: #070a10;
  margin: 0;
  padding: 0;
}

body.desk-landing {
  margin: 0;
  padding: 0;
  --dk-bg: #070a10;
  --dk-ink: #e6ebf5;
  --dk-mute: #9aa5ba;
  --dk-dim: #6f7b91;
  --dk-line: rgba(255, 255, 255, 0.11);
  --dk-accent: #6366f1;
  background: var(--dk-bg);
  color: var(--dk-ink);
  font-family: 'Inter', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  /* `clip` not `hidden`. Both stop sideways scroll, but `hidden` makes the
     body a scroll container, and that silently disables `position: sticky`
     everywhere inside it — it had been killing the sticky input panel on the
     calculators for as long as that panel has existed. */
  overflow-x: clip;
}

body.desk-landing::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(1100px 620px at 82% 6%, rgba(99, 102, 241, 0.26), transparent 62%),
    radial-gradient(900px 560px at 6% 88%, rgba(45, 212, 191, 0.13), transparent 66%);
}
body.desk-landing > * { position: relative; z-index: 1; }

body.desk-landing .dk-wrap { max-width: 1260px; margin: 0 auto; padding: 0 44px; }

/* ── nav ──────────────────────────────────────────────────────────────────── */
body.desk-landing .dk-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24px 0;
}
/* The wordmark carries the brand — a typed-out name does not. Same asset the
   app navbar uses, so the page and the product sign themselves identically. */
body.desk-landing .dk-logo { display: inline-flex; align-items: center; text-decoration: none; }
body.desk-landing .dk-logo img {
  height: 26px;
  width: auto;
  display: block;
}
body.desk-landing .dk-flogo {
  height: 22px;
  width: auto;
  display: block;
  opacity: 0.85;
  margin-bottom: 4px;
}
body.desk-landing .dk-navlinks { display: flex; gap: 28px; }
body.desk-landing .dk-navlinks a {
  font-size: 13.5px;
  color: #96a0b5;
  text-decoration: none;
  transition: color 0.14s ease;
}
body.desk-landing .dk-navlinks a:hover { color: var(--dk-ink); }
body.desk-landing .dk-navcta {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--dk-line);
  padding: 9px 18px;
  border-radius: 10px;
  font-size: 13.5px;
  color: var(--dk-ink);
  text-decoration: none;
  backdrop-filter: blur(12px);
}
body.desk-landing .dk-navcta:hover { background: rgba(255, 255, 255, 0.13); }

/* ── hero ─────────────────────────────────────────────────────────────────── */
body.desk-landing .dk-hero { text-align: center; padding: 64px 0 0; }
body.desk-landing .dk-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #a5b0c4;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  padding: 7px 14px;
  border-radius: 999px;
  backdrop-filter: blur(12px);
}
body.desk-landing .dk-eyebrow i {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #4ade80;
  display: inline-block;
}
body.desk-landing h1.dk-h1 {
  font-family: 'Bricolage Grotesque', var(--font-family);
  font-weight: 700;
  font-size: clamp(38px, 5.2vw, 64px);
  line-height: 1.05;
  letter-spacing: -0.03em;
  margin: 26px 0 0;
  color: var(--dk-ink);
}
body.desk-landing .dk-sub {
  margin: 20px auto 0;
  font-size: 17px;
  line-height: 1.6;
  color: var(--dk-mute);
  max-width: 620px;
}
body.desk-landing .dk-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin-top: 32px;
  flex-wrap: wrap;
}
body.desk-landing .dk-btn1 {
  background: #fff;
  color: #0b0e15;
  padding: 13px 26px;
  border-radius: 11px;
  font-weight: 600;
  font-size: 14.5px;
  text-decoration: none;
}
body.desk-landing .dk-btn1:hover { background: #e9ecf3; }
body.desk-landing .dk-btn2 {
  border: 1px solid rgba(255, 255, 255, 0.16);
  padding: 13px 24px;
  border-radius: 11px;
  font-size: 14.5px;
  color: var(--dk-ink);
  text-decoration: none;
  backdrop-filter: blur(12px);
}
body.desk-landing .dk-btn2:hover { border-color: rgba(255, 255, 255, 0.3); }

/* ── the desk: layered glass panes ────────────────────────────────────────── */
body.desk-landing .dk-desk {
  position: relative;
  height: 470px;
  margin-top: 56px;
}
/* The wave sits UNDER the panes as the desk's substrate — the same
   relationship the app has, where the wave runs beneath the pulse cards
   rather than sitting in a box of its own. */
/* The wave has to reach both edges of the SCREEN, not both edges of the
   container. It used to be 112% of .dk-wrap, which is capped at 1260px — fine
   at a 1400px window, but on a 1920px screen it stopped ~250px short on each
   side and read as a graphic sitting in a box. Anchored to the viewport
   instead; .dk-hero clips the overhang so the bleed cannot create a
   horizontal scrollbar.

   The clip has to sit on the body, not on .dk-hero: the hero lives inside
   .dk-wrap and is therefore only ~1348px wide itself, so clipping there cut
   off the very bleed it was meant to contain.

   The bleed is contained by `.landing-page { overflow-x: clip }` in
   landing.css, which every page here carries. */
body.desk-landing .dk-desk-wave {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: -14px;
  width: 100vw;
  height: 260px;
  z-index: 0;
  pointer-events: none;
}
body.desk-landing .dk-deskcap {
  margin: 22px 0 0;
  font-family: var(--font-family-mono);
  font-size: 10.5px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: #5f6b80;
}
body.desk-landing .dk-pane {
  position: absolute;
  border-radius: 16px;
  border: 1px solid var(--dk-line);
  background: linear-gradient(150deg, rgba(255, 255, 255, 0.10), rgba(255, 255, 255, 0.03));
  backdrop-filter: blur(22px) saturate(1.2);
  -webkit-backdrop-filter: blur(22px) saturate(1.2);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.5);
  padding: 0;
  margin: 0;
  overflow: hidden;
  animation: dkRise 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) backwards;
}
body.desk-landing .dk-pane img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left top;
}
body.desk-landing .dk-pane::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.10), transparent 30%);
  pointer-events: none;
}
@keyframes dkRise { from { opacity: 0; transform: translateY(26px) var(--tilt, ); } }
/* ── the dial ─────────────────────────────────────────────────────────────────
   The panes used to be three fixed boxes at three fixed sizes. They are now
   five identical boxes whose position is entirely a transform, so a pane can
   TRAVEL between positions — left to centre, centre to right — instead of its
   picture being swapped underneath it.

   Identical geometry is what makes that possible: animating width and height
   would relayout on every frame, while transform and opacity composite on the
   GPU. The two outermost slots sit off to the sides at zero opacity, so a
   screen fades in as it arrives and fades out as it leaves, and the image
   behind it is exchanged only while it is invisible. */
body.desk-landing .dk-pane {
  left: 50%;
  top: 0;
  width: min(820px, 84vw);
  height: 430px;
  transform-origin: 50% 50%;
  transform:
    translateX(calc(-50% + var(--dx, 0%)))
    translateY(var(--dy, 0px))
    scale(var(--ds, 1))
    rotate(var(--dr, 0deg));
  transition:
    transform 0.62s cubic-bezier(0.22, 0.85, 0.26, 1),
    opacity 0.46s ease;
}

/* centre — the one being read */
body.desk-landing .dk-slot0  { --dx: 0%;    --dy: 0px;  --ds: 1;    --dr: 0deg;   z-index: 5; opacity: 1; }
/* the two shoulders */
body.desk-landing .dk-slotL1 { --dx: -63%;  --dy: 44px; --ds: 0.52; --dr: -7deg;  z-index: 3; opacity: 0.95; }
body.desk-landing .dk-slotR1 { --dx: 63%;   --dy: 40px; --ds: 0.52; --dr: 6deg;   z-index: 3; opacity: 0.95; }
/* the wings: parked out of sight, where images are exchanged unseen */
body.desk-landing .dk-slotL2 { --dx: -104%; --dy: 74px; --ds: 0.34; --dr: -11deg; z-index: 1; opacity: 0; }
body.desk-landing .dk-slotR2 { --dx: 104%;  --dy: 70px; --ds: 0.34; --dr: 10deg;  z-index: 1; opacity: 0; }

/* Only the centre is worth the room on a phone. */
@media (max-width: 900px) {
  body.desk-landing .dk-slotL1,
  body.desk-landing .dk-slotR1,
  body.desk-landing .dk-slotL2,
  body.desk-landing .dk-slotR2 { opacity: 0; pointer-events: none; }
}

/* Nothing travels for someone who has asked for less motion; the dial simply
   holds its opening position. */
@media (prefers-reduced-motion: reduce) {
  body.desk-landing .dk-pane { transition: none; }
}
body.desk-landing .dk-ph {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-family-mono);
  font-size: 9.5px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: #a5b0c4;
  margin-bottom: 12px;
}
body.desk-landing .dk-dot { width: 7px; height: 7px; border-radius: 50%; }
body.desk-landing .dk-ln { height: 9px; border-radius: 5px; background: rgba(255, 255, 255, 0.10); margin-bottom: 9px; }
body.desk-landing .dk-ln.hi { background: rgba(255, 255, 255, 0.21); }
body.desk-landing .dk-bars { display: flex; align-items: flex-end; gap: 7px; height: 92px; margin-top: 14px; }
body.desk-landing .dk-bars i { flex: 1; border-radius: 4px 4px 0 0; background: linear-gradient(180deg, #6366f1, rgba(99, 102, 241, 0.25)); }
body.desk-landing .dk-kpi { font-family: var(--font-family-mono); font-size: 26px; margin-bottom: 4px; }
body.desk-landing .dk-kpil {
  font-family: var(--font-family-mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #8b96ab;
}

/* ── shared section furniture ─────────────────────────────────────────────── */
body.desk-landing .dk-section { padding: 96px 0; }
body.desk-landing .dk-kicker {
  font-family: var(--font-family-mono);
  font-size: 10.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--dk-accent);
  margin-bottom: 16px;
}
body.desk-landing h2.dk-h2 {
  font-family: 'Bricolage Grotesque', var(--font-family);
  font-weight: 700;
  font-size: clamp(28px, 3.4vw, 40px);
  line-height: 1.1;
  letter-spacing: -0.025em;
  margin: 0;
  color: var(--dk-ink);
}
body.desk-landing .dk-lede { margin-top: 16px; font-size: 16px; line-height: 1.62; color: var(--dk-mute); max-width: 620px; }

/* ── product grid ─────────────────────────────────────────────────────────── */
body.desk-landing .dk-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
  gap: 12px;
  margin-top: 40px;
}
body.desk-landing .dk-card {
  display: block;
  padding: 20px;
  border-radius: 15px;
  border: 1px solid var(--dk-line);
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.02));
  backdrop-filter: blur(16px) saturate(1.15);
  -webkit-backdrop-filter: blur(16px) saturate(1.15);
  text-decoration: none;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
body.desk-landing .dk-card:hover { transform: translateY(-2px); border-color: rgba(255, 255, 255, 0.24); }
body.desk-landing .dk-card .ic {
  width: 34px; height: 34px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  margin-bottom: 14px;
}
body.desk-landing .dk-card .ic svg { width: 17px; height: 17px; fill: none; stroke-width: 2; }
body.desk-landing .dk-card h3 {
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 6px;
  color: var(--dk-ink);
}
body.desk-landing .dk-card p { font-size: 13px; line-height: 1.55; color: var(--dk-dim); margin: 0; }

/* ── the thread (proof) ───────────────────────────────────────────────────── */
body.desk-landing .dk-thread {
  margin-top: 40px;
  border-radius: 16px;
  border: 1px solid var(--dk-line);
  background: rgba(255, 255, 255, 0.035);
  backdrop-filter: blur(18px) saturate(1.15);
  -webkit-backdrop-filter: blur(18px) saturate(1.15);
  overflow: hidden;
}
body.desk-landing .dk-trow {
  display: grid;
  grid-template-columns: 66px 1fr auto;
  gap: 16px;
  align-items: baseline;
  padding: 15px 20px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}
body.desk-landing .dk-trow:last-child { border-bottom: none; }
body.desk-landing .dk-tt { font-family: var(--font-family-mono); font-size: 11.5px; color: var(--dk-dim); }
body.desk-landing .dk-tw { font-size: 14px; color: var(--dk-ink); }
body.desk-landing .dk-tw b { font-weight: 600; }
body.desk-landing .dk-tsrc {
  display: block;
  margin-top: 3px;
  font-family: var(--font-family-mono);
  font-size: 9.5px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--dk-accent);
}
body.desk-landing .dk-ta { font-family: var(--font-family-mono); font-size: 13.5px; color: var(--dk-ink); white-space: nowrap; }
body.desk-landing .dk-tfoot {
  display: flex;
  justify-content: space-between;
  padding: 14px 20px;
  background: rgba(255, 255, 255, 0.04);
  font-family: var(--font-family-mono);
  font-size: 11.5px;
  color: var(--dk-mute);
}

/* ── differentiators ──────────────────────────────────────────────────────── */
body.desk-landing .dk-three {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 32px;
  margin-top: 44px;
}
body.desk-landing .dk-three h3 {
  font-family: 'Bricolage Grotesque', var(--font-family);
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 10px;
  color: var(--dk-ink);
}
body.desk-landing .dk-three p { font-size: 14px; line-height: 1.62; color: var(--dk-mute); margin: 0; }
body.desk-landing .dk-three .num {
  font-family: var(--font-family-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--dk-accent);
  display: block;
  margin-bottom: 12px;
}

/* ── FAQ ──────────────────────────────────────────────────────────────────────
   Shared by every product page. A landing page can only carry so many claims
   before it stops being readable, and the ones it drops tend to be the
   foundational ones a buyer assumes are missing precisely because nobody says
   them out loud. This is where those go. */
body.desk-landing .dk-faq {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 30px 44px;
  margin-top: 40px;
}
body.desk-landing .dk-faq h3 {
  font-family: 'Bricolage Grotesque', var(--font-family);
  font-size: 16.5px;
  font-weight: 600;
  margin: 0 0 8px;
  color: var(--dk-ink);
}
body.desk-landing .dk-faq p { margin: 0; font-size: 14px; line-height: 1.62; color: var(--dk-mute); }
body.desk-landing .dk-faq p + p { margin-top: 9px; }
body.desk-landing .dk-faq b { color: var(--dk-ink); font-weight: 600; }
body.desk-landing .dk-faq code {
  font-family: var(--font-family-mono);
  font-size: 12.5px;
  color: var(--dk-ink);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--dk-line);
  border-radius: 5px;
  padding: 1px 5px;
}
body.desk-landing .dk-faq .q {
  display: block;
  font-family: var(--font-family-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  color: var(--dk-accent);
  margin-bottom: 10px;
}

/* ── close ────────────────────────────────────────────────────────────────── */
body.desk-landing .dk-close {
  text-align: center;
  padding: 90px 44px;
  border-radius: 20px;
  border: 1px solid var(--dk-line);
  background: linear-gradient(160deg, rgba(99, 102, 241, 0.16), rgba(255, 255, 255, 0.03));
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  margin-bottom: 90px;
}
body.desk-landing .dk-close p { margin: 16px auto 0; color: var(--dk-mute); font-size: 16px; max-width: 520px; }
body.desk-landing .dk-close .dk-actions { margin-top: 30px; }

/* ── footer ───────────────────────────────────────────────────────────────── */
body.desk-landing .dk-foot {
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding: 42px 0 60px;
  display: flex;
  justify-content: space-between;
  gap: 30px;
  flex-wrap: wrap;
}
body.desk-landing .dk-foot a { color: var(--dk-dim); text-decoration: none; font-size: 13px; }
body.desk-landing .dk-foot a:hover { color: var(--dk-ink); }
body.desk-landing .dk-fcol { display: flex; flex-direction: column; gap: 9px; }
body.desk-landing .dk-fcol strong {
  font-family: var(--font-family-mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #5f6b80;
  font-weight: 400;
  margin-bottom: 3px;
}
body.desk-landing .dk-fnote { font-size: 12px; color: #5f6b80; max-width: 280px; line-height: 1.6; }

@media (max-width: 900px) {
  body.desk-landing .dk-navlinks { display: none; }
  body.desk-landing .dk-desk { height: 300px; }
  body.desk-landing .dk-pane { width: 92vw; height: 290px; }
  body.desk-landing .dk-section { padding: 64px 0; }
  body.desk-landing .dk-wrap { padding: 0 22px; }
}
@media (prefers-reduced-motion: reduce) {
  body.desk-landing .dk-pane { animation: none; }
}

/* ── pulse band ───────────────────────────────────────────────────────────────
   The wave is the product's signature: every dashboard opens on one. Putting it
   on the landing page means the page and the app speak the same visual language
   rather than the marketing site inventing its own. */
body.desk-landing .dk-pulse {
  padding: 30px 0 96px;
}
body.desk-landing .dk-pulse-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 36px;
  flex-wrap: wrap;
}
body.desk-landing .dk-pulse-chips { display: flex; gap: 10px; flex-wrap: wrap; }
body.desk-landing .dk-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid var(--dk-line);
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(14px);
  white-space: nowrap;
}
body.desk-landing .dk-chip b {
  font-family: var(--font-family-mono);
  font-size: 16px;
  color: var(--dk-ink);
  font-variant-numeric: tabular-nums;
}
body.desk-landing .dk-chip span { font-size: 12px; color: var(--dk-dim); }

body.desk-landing .dk-wave {
  position: relative;
  margin-top: 30px;
  border-radius: 16px;
  border: 1px solid var(--dk-line);
  background: rgba(255, 255, 255, 0.03);
  backdrop-filter: blur(16px) saturate(1.12);
  -webkit-backdrop-filter: blur(16px) saturate(1.12);
  overflow: hidden;
  height: 168px;
}
body.desk-landing .dk-wave svg { width: 100%; height: 100%; display: block; }
body.desk-landing .dk-wavecap {
  position: absolute;
  right: 18px;
  top: 14px;
  font-family: var(--font-family-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dk-dim);
}

/* ── product shots ────────────────────────────────────────────────────────── */
body.desk-landing .dk-shots {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  margin-top: 40px;
}
body.desk-landing .dk-shot {
  margin: 0;
  border-radius: 16px;
  border: 1px solid var(--dk-line);
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(16px) saturate(1.15);
  -webkit-backdrop-filter: blur(16px) saturate(1.15);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  overflow: hidden;
}
body.desk-landing .dk-shot-wide { grid-column: 1 / -1; }
body.desk-landing .dk-shot img {
  display: block;
  width: 100%;
  height: auto;
  border-bottom: 1px solid var(--dk-line);
}
body.desk-landing .dk-shot figcaption {
  padding: 14px 18px;
  font-size: 13px;
  color: var(--dk-dim);
}
body.desk-landing .dk-shot figcaption b { color: var(--dk-ink); font-weight: 600; }

@media (max-width: 900px) {
  body.desk-landing .dk-shots { grid-template-columns: 1fr; }
  body.desk-landing .dk-wave { height: 130px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LIFT — three things, not decoration.
   1. The thread was the best idea on the page and read as a plain table.
   2. Every section had the same shape, so the page scanned as a list.
   3. Nothing moved, so it felt like a document rather than a product.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. the thread, made literal ──────────────────────────────────────────────
   A spine runs through the rows with a node per step, lit in the accent of
   whichever product handled it — so the hand-off between products is the
   thing you see, which is the whole claim. */
body.desk-landing .dk-trow {
  position: relative;
  grid-template-columns: 66px 26px 1fr auto;
  transition: background 0.18s ease;
}
body.desk-landing .dk-trow:hover { background: rgba(255, 255, 255, 0.03); }
body.desk-landing .dk-node {
  position: relative;
  align-self: stretch;
  display: block;
  width: 26px;
}
/* the spine */
body.desk-landing .dk-node::before {
  content: '';
  position: absolute;
  left: 50%;
  top: -16px;
  bottom: -16px;
  width: 2px;
  transform: translateX(-50%);
  background: linear-gradient(180deg, transparent, var(--c) 18%, var(--c) 82%, transparent);
  opacity: 0.45;
}
body.desk-landing .dk-trow:first-child .dk-node::before { top: 12px; }
body.desk-landing .dk-trow:last-of-type .dk-node::before { bottom: 12px; }
/* the node */
body.desk-landing .dk-node::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 7px;
  width: 9px;
  height: 9px;
  margin-left: -4.5px;
  border-radius: 50%;
  background: var(--c);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--c) 22%, transparent),
              0 0 18px color-mix(in srgb, var(--c) 55%, transparent);
}
body.desk-landing .dk-tsrc { color: var(--c); }

/* ── 2. a numbers strip — the page gave the reader nothing to hold on to ─── */
body.desk-landing .dk-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px;
  margin: 8px 0 0;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--dk-line);
  background: var(--dk-line);
}
body.desk-landing .dk-strip > div {
  background: rgba(10, 14, 22, 0.72);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  padding: 26px 24px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
body.desk-landing .dk-strip b {
  font-family: 'Bricolage Grotesque', var(--font-family);
  font-size: 40px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--dk-ink);
}
body.desk-landing .dk-strip span { font-size: 13px; color: var(--dk-dim); }

/* ── 3. arrival ───────────────────────────────────────────────────────────── */
body.desk-landing .dk-reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s cubic-bezier(0.2, 0.8, 0.2, 1), transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}
body.desk-landing .dk-reveal.is-in { opacity: 1; transform: none; }

/* product cards pick up their own accent on hover, so the grid stops reading
   as eight identical tiles */
body.desk-landing .dk-card { position: relative; overflow: hidden; }
body.desk-landing .dk-card::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.18s ease;
  background: radial-gradient(320px 130px at 22% -10%, var(--accent, #6366f1), transparent 70%);
  pointer-events: none;
}
body.desk-landing .dk-card:hover::after { opacity: 0.13; }

@media (prefers-reduced-motion: reduce) {
  body.desk-landing .dk-reveal { opacity: 1; transform: none; transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOTION — every effect here answers something. Nothing moves decoratively.
   All of it is disabled under prefers-reduced-motion, both in CSS and in JS.
   ═══════════════════════════════════════════════════════════════════════════ */

/* the desk panes are driven by JS on pointermove, so they must not fight it
   with their own transition on transform */
body.desk-landing .dk-pane { will-change: transform; }
/* the shadow lift on hover must not clobber the dial's transform transition */
body.desk-landing .dk-desk:hover .dk-pane { box-shadow: 0 36px 90px rgba(0, 0, 0, 0.58); }
body.desk-landing .dk-desk:hover .dk-pane { box-shadow: 0 36px 90px rgba(0, 0, 0, 0.58); }

/* spotlight follows the cursor across a card rather than sitting in a corner */
body.desk-landing .dk-card::after {
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 0%), var(--accent, #6366f1), transparent 68%);
}

/* staggered arrival for grid children — the parent section still fades, but
   its contents assemble, which reads as considered rather than abrupt */
body.desk-landing .dk-card,
body.desk-landing .dk-strip > div,
body.desk-landing .dk-lrow,
body.desk-landing .dk-trow {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s cubic-bezier(0.2, 0.8, 0.2, 1), transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),
              background 0.18s ease, border-color 0.15s ease;
}
body.desk-landing .dk-card.is-in,
body.desk-landing .dk-strip > div.is-in,
body.desk-landing .dk-lrow.is-in,
body.desk-landing .dk-trow.is-in { opacity: 1; transform: none; }

/* the thread's nodes breathe in sequence — the eye follows the hand-off from
   one product to the next, which is the section's whole argument */
body.desk-landing .dk-trow.is-in .dk-node::after { animation: dkNode 3.4s ease-in-out infinite; }
body.desk-landing .dk-trow:nth-of-type(2) .dk-node::after { animation-delay: 0.34s; }
body.desk-landing .dk-trow:nth-of-type(3) .dk-node::after { animation-delay: 0.68s; }
body.desk-landing .dk-trow:nth-of-type(4) .dk-node::after { animation-delay: 1.02s; }
body.desk-landing .dk-trow:nth-of-type(5) .dk-node::after { animation-delay: 1.36s; }
@keyframes dkNode {
  0%, 68%, 100% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--c) 20%, transparent), 0 0 14px color-mix(in srgb, var(--c) 45%, transparent); }
  16%           { box-shadow: 0 0 0 7px color-mix(in srgb, var(--c) 26%, transparent), 0 0 28px color-mix(in srgb, var(--c) 85%, transparent); }
}

/* the ambient wash drifts very slowly — 40s, so it is felt rather than seen */
body.desk-landing::after { animation: dkDrift 40s ease-in-out infinite alternate; }
@keyframes dkDrift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-2.5%, 1.5%, 0) scale(1.06); }
}

/* buttons acknowledge the pointer */
body.desk-landing .dk-btn1,
body.desk-landing .dk-btn2,
body.desk-landing .dk-navcta { transition: transform 0.16s ease, background 0.16s ease, border-color 0.16s ease; }
body.desk-landing .dk-btn1:hover,
body.desk-landing .dk-btn2:hover { transform: translateY(-1px); }
body.desk-landing .dk-btn1:active,
body.desk-landing .dk-btn2:active { transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  body.desk-landing .dk-card,
  body.desk-landing .dk-strip > div,
  body.desk-landing .dk-trow { opacity: 1; transform: none; transition: none; }
  body.desk-landing .dk-trow .dk-node::after,
  body.desk-landing::after { animation: none; }
  body.desk-landing .dk-pane { animation: none; }
}

/* The closing note on every module page: this is one module of the OS, not a
   point tool. Set quieter than the closing line above it — it is a
   qualification, not a second pitch. */
body.desk-landing .dk-osnote {
  max-width: 62ch;
  margin: 14px auto 0;
  font-size: 14px;
  line-height: 1.62;
  color: var(--dk-dim);
}

/* ── the category, defined ────────────────────────────────────────────────────
   Three panels: what an ERP covers, what a productivity suite covers, and the
   claim that we are both. Each panel states what it HAS and, in muted red,
   what it does not — because the whole argument is the missing half, and a
   panel that only lists strengths would not make it. */
body.desk-landing .dk-osdef {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin-top: 30px;
  background: var(--dk-line);
  border: 1px solid var(--dk-line);
  border-radius: 18px;
  overflow: hidden;
}
body.desk-landing .dk-osdef > div {
  background: var(--dk-bg);
  padding: 26px 26px 24px;
  display: flex;
  flex-direction: column;
}
/* the third panel is the claim, so it is lit rather than left neutral */
body.desk-landing .dk-osdef > div.ours {
  background: linear-gradient(165deg, rgba(99, 102, 241, 0.12), rgba(255, 255, 255, 0.02));
}
body.desk-landing .dk-osdef .k {
  font-family: var(--font-family-mono);
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #5f6b80;
  margin-bottom: 14px;
}
body.desk-landing .dk-osdef > div.ours .k { color: #A5B4FC; }
body.desk-landing .dk-osdef h3 {
  font-family: 'Bricolage Grotesque', var(--font-family);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.26;
  letter-spacing: -0.024em;
  color: var(--dk-ink);
  margin: 0 0 10px;
}
body.desk-landing .dk-osdef p {
  margin: 0 0 18px;
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--dk-mute);
  flex: 1;
}
body.desk-landing .dk-osdef .has,
body.desk-landing .dk-osdef .hasnt {
  font-family: var(--font-family-mono);
  font-size: 11.5px;
  line-height: 1.6;
  letter-spacing: 0.02em;
  padding-top: 10px;
  border-top: 1px solid var(--dk-line);
}
body.desk-landing .dk-osdef .has { color: #7DD3A8; }
body.desk-landing .dk-osdef .hasnt { color: #F79B9B; border-top: 0; padding-top: 4px; }
body.desk-landing .dk-osdef > div.ours .hasnt { color: #5f6b80; }

/* the module pages centre their .dk-osnote inside a centred close panel; this
   one sits under a left-aligned section, so it keeps the section's margin */
body.desk-landing .dk-section > .dk-osnote {
  max-width: 68ch;
  margin: 22px 0 0;
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--dk-dim);
}
body.desk-landing .dk-osnote a { color: #A5B4FC; text-decoration: none; }
body.desk-landing .dk-osnote a:hover { text-decoration: underline; }

@media (max-width: 900px) {
  body.desk-landing .dk-osdef { grid-template-columns: 1fr; }
}



/* ═══════════════════════════════════════════════════════════════════════════
   THE LAUNCHER — the platform section, shaped like the workspace you land in.

   Ten modules in a four-column card grid left a ragged 4+4+2 and, worse, told
   you nothing about how they relate. This is the same object the product opens
   with once you sign in: a label and a sentence on the left, a panel of rows on
   the right, one row per module. Someone evaluating the page is looking at the
   screen they will actually use.

   Two deliberate departures from the app. The app's status column reads
   "Online", which is telemetry a customer has no use for before they buy — it
   carries a single checkable fact about each module instead. And the app groups
   by Money / People / Work / Communication, which would leave one lonely row
   under Money here because only Accounts is sold separately; these group by the
   question a buyer is actually asking.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Trade picker (merch.html #pick) — the "I can make this look like my shop"
   moment, so it sits directly under the hero rather than in the feature list.
   Each tile carries its preset's own primary colour in --mk. */
body.desk-landing .mk-trades {
  margin-top: 40px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 12px;
}
body.desk-landing .mk-trade {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 18px 18px 16px;
  border: 1px solid var(--dk-line);
  border-radius: 14px;
  text-decoration: none;
  background: var(--dk-bg);
  transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
/* the trade's colour, as a spine rather than a wash */
body.desk-landing .mk-trade::before {
  content: "";
  position: absolute;
  left: 0; top: 14px; bottom: 14px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--mk, var(--dk-accent));
}
body.desk-landing .mk-trade:hover {
  border-color: var(--mk, var(--dk-accent));
  transform: translateY(-2px);
  box-shadow: 0 8px 24px -14px rgb(0 0 0 / 0.45);
}
body.desk-landing .mk-trade:focus-visible {
  outline: 2px solid var(--mk, var(--dk-accent));
  outline-offset: 2px;
}
body.desk-landing .mk-tname {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--dk-ink);
}
body.desk-landing .mk-tlooks {
  font-size: 13px;
  line-height: 1.5;
  color: var(--dk-dim);
}
body.desk-landing .mk-tn {
  font-family: var(--font-family-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mk, var(--dk-accent));
}
@media (max-width: 560px) {
  body.desk-landing .mk-trades { grid-template-columns: 1fr; gap: 10px; }
  body.desk-landing .mk-trade { padding: 15px 15px 13px; }
}
@media (prefers-reduced-motion: reduce) {
  body.desk-landing .mk-trade { transition: none; }
  body.desk-landing .mk-trade:hover { transform: none; }
}

/* ── merch-api.html: expandable endpoint reference ──────────────────────────
   <details> rather than JS: it works with no script, is keyboard and screen
   reader accessible for free, and Cmd-F finds text inside a collapsed block in
   modern browsers. */
body.desk-landing .mk-eps { margin-top: 40px; }

body.desk-landing .mk-group { margin: 0 0 34px; }
body.desk-landing .mk-gname {
  margin: 0 0 12px;
  font-family: var(--font-family-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dk-ink);
}
body.desk-landing .mk-gname span { color: var(--dk-dim); margin-left: 8px; }

body.desk-landing .mk-ep {
  border: 1px solid var(--dk-line);
  border-radius: 12px;
  margin-bottom: 8px;
  background: var(--dk-bg);
  overflow: hidden;
}
body.desk-landing .mk-ep[open] { border-color: rgb(255 255 255 / 0.22); }
body.desk-landing .mk-ep > summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 16px;
  cursor: pointer;
  list-style: none;
  transition: background .15s ease;
}
body.desk-landing .mk-ep > summary::-webkit-details-marker { display: none; }
body.desk-landing .mk-ep > summary:hover { background: rgb(255 255 255 / 0.03); }
/* chevron, drawn rather than an asset */
body.desk-landing .mk-ep > summary::after {
  content: "";
  margin-left: auto;
  width: 7px; height: 7px;
  border-right: 1.5px solid var(--dk-dim);
  border-bottom: 1.5px solid var(--dk-dim);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .18s ease;
}
body.desk-landing .mk-ep[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }

body.desk-landing .mk-epbody {
  padding: 2px 16px 18px;
  border-top: 1px solid var(--dk-line);
}
body.desk-landing .mk-desc {
  margin: 14px 0 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--dk-ink);
  max-width: 82ch;      /* the measure the rest of this page reads at */
}
body.desk-landing .mk-note {
  margin: 10px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--dk-dim);
}
body.desk-landing .mk-sub {
  margin: 18px 0 8px;
  font-family: var(--font-family-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dk-dim);
}
body.desk-landing .mk-params { margin: 0; padding: 0; list-style: none; }
body.desk-landing .mk-params li {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 5px 0;
  font-size: 13px;
  border-bottom: 1px solid rgb(255 255 255 / 0.05);
}
body.desk-landing .mk-params li:last-child { border-bottom: 0; }
body.desk-landing .mk-params code { font-size: 12.5px; color: var(--dk-ink); }
body.desk-landing .mk-loc,
body.desk-landing .mk-ty {
  font-family: var(--font-family-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dk-dim);
}
body.desk-landing .mk-params em { font-style: normal; font-size: 10.5px; color: #FCA5A5; }

/* The curl. Given its own treatment rather than reusing .mk-json because it is
   the one block a reader selects and copies, so it should be obvious at a
   glance which one that is. */
body.desk-landing .mk-curl {
  margin: 0;
  padding: 13px 15px;
  border: 1px solid rgb(96 165 250 / 0.28);
  border-radius: 10px;
  background: rgb(96 165 250 / 0.06);
  font-family: var(--font-family-mono);
  font-size: 12.5px;
  line-height: 1.7;
  color: #DCE6F7;
  overflow-x: auto;
  white-space: pre;
  user-select: all;      /* one click selects the whole command */
}

body.desk-landing .mk-json {
  margin: 0;
  padding: 13px 15px;
  border: 1px solid var(--dk-line);
  border-radius: 10px;
  background: rgb(0 0 0 / 0.32);
  font-family: var(--font-family-mono);
  font-size: 12.5px;
  line-height: 1.65;
  color: #C8D3E6;
  overflow-x: auto;      /* long values scroll here, never the page */
  white-space: pre;
}

body.desk-landing .mk-auth {
  font-family: var(--font-family-mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 5px;
  background: rgb(226 232 240 / 0.1);
  color: #CBD5E1;
}

@media (max-width: 560px) {
  body.desk-landing .mk-ep > summary { flex-wrap: wrap; gap: 8px; padding: 12px 13px; }
  body.desk-landing .mk-epbody { padding: 2px 13px 16px; }
}
@media (prefers-reduced-motion: reduce) {
  body.desk-landing .mk-ep > summary,
  body.desk-landing .mk-ep > summary::after { transition: none; }
}

/* Endpoint rows on merch-api.html — a verb chip and a monospace path. Colours
   are the conventional REST ones so a developer reads the list at a glance
   rather than parsing each line. */
body.desk-landing .mk-verb {
  flex: none;
  min-width: 62px;
  padding: 3px 8px;
  border-radius: 6px;
  font-family: var(--font-family-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-align: center;
  align-self: flex-start;
}
body.desk-landing .mk-get    { background: rgb(96 165 250 / 0.16); color: #93C5FD; }
body.desk-landing .mk-post   { background: rgb(74 222 128 / 0.16); color: #86EFAC; }
body.desk-landing .mk-put    { background: rgb(251 146 60 / 0.16); color: #FDBA74; }
body.desk-landing .mk-delete { background: rgb(248 113 113 / 0.16); color: #FCA5A5; }
body.desk-landing .mk-path {
  font-family: var(--font-family-mono);
  font-size: 13px;
  color: var(--dk-ink);
  word-break: break-all;
}

body.desk-landing .dk-launch { margin-top: 44px; }

body.desk-landing .dk-lgroup {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: 42px;
  align-items: start;
  padding: 30px 0;
  border-top: 1px solid var(--dk-line);
}
body.desk-landing .dk-lgroup:first-child { border-top: 0; padding-top: 0; }

body.desk-landing .dk-lhead h3 {
  margin: 0;
  font-family: var(--font-family-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dk-ink);
}
body.desk-landing .dk-lhead p {
  margin: 10px 0 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--dk-dim);
}

/* the panel — the same glass the app's launcher uses */
body.desk-landing .dk-lrows {
  border: 1px solid var(--dk-line);
  border-radius: 16px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.028);
  backdrop-filter: blur(18px) saturate(1.15);
  -webkit-backdrop-filter: blur(18px) saturate(1.15);
}

body.desk-landing .dk-lrow {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 15px 20px;
  border-bottom: 1px solid var(--dk-line);
  text-decoration: none;
  transition: background 0.14s ease;
}
body.desk-landing .dk-lrow:last-child { border-bottom: 0; }
body.desk-landing a.dk-lrow:hover { background: rgba(255, 255, 255, 0.045); }

/* the icon carries the module's colour, exactly as it does in the product */
body.desk-landing .dk-lic {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  flex: none;
  position: relative;
  background: color-mix(in srgb, var(--mod) 14%, transparent);
  color: var(--mod);
}
body.desk-landing .dk-lic svg { width: 18px; height: 18px; position: relative; z-index: 1; }
/* the same soft bloom the live tiles carry */
body.desk-landing .dk-lic::after {
  content: '';
  position: absolute;
  inset: -12px;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--mod) 18%, transparent), transparent 70%);
  pointer-events: none;
}

body.desk-landing .dk-lmid { flex: 1; min-width: 0; }
body.desk-landing .dk-lname {
  display: block;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--dk-ink);
}
body.desk-landing .dk-ldesc {
  display: block;
  margin-top: 3px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--dk-mute);
}

/* where the app shows a status dot, this shows something you can check */
body.desk-landing .dk-lfact {
  flex: none;
  font-family: var(--font-family-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--mod);
  opacity: 0.85;
  text-align: right;
  white-space: nowrap;
}
body.desk-landing .dk-larrow {
  flex: none;
  width: 16px;
  text-align: right;
  font-size: 15px;
  color: var(--mod);
  opacity: 0;
  transition: opacity 0.14s ease;
}
body.desk-landing a.dk-lrow:hover .dk-larrow { opacity: 1; }

@media (max-width: 980px) {
  body.desk-landing .dk-lgroup { grid-template-columns: 1fr; gap: 16px; }
}
@media (max-width: 640px) {
  /* the fact is the first thing to go when the row runs out of room */
  body.desk-landing .dk-lfact { display: none; }
  body.desk-landing .dk-lrow { padding: 14px 16px; gap: 13px; }
}

/* ── the same rows, used as a feature list ────────────────────────────────────
   The module pages carried the same argument as a grid of cards: nine or
   fifteen equal boxes that left a ragged last row and gave the eye nowhere to
   start. They now use the launcher's rows. A feature list is not navigation,
   so these rows are plain elements — no arrow, no hover, no pointer — but the
   icon, the name and the description sit exactly where they do in the product.

   Descriptions here run longer than the launcher's, so the row aligns its icon
   to the top rather than centring it against three lines of text. */
body.desk-landing .dk-list {
  border: 1px solid var(--dk-line);
  border-radius: 16px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.028);
  backdrop-filter: blur(18px) saturate(1.15);
  -webkit-backdrop-filter: blur(18px) saturate(1.15);
  margin-top: 34px;
}
body.desk-landing .dk-list .dk-lrow { align-items: flex-start; padding: 17px 20px; }
body.desk-landing .dk-list .dk-lic { margin-top: 1px; }
body.desk-landing .dk-list .dk-ldesc { white-space: normal; max-width: 88ch; }

/* two abreast once there is room, so a fifteen-row list does not become a
   column of its own */
@media (min-width: 1100px) {
  body.desk-landing .dk-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  body.desk-landing .dk-list .dk-lrow:nth-child(odd) { border-right: 1px solid var(--dk-line); }
  /* the final row of an odd-numbered list spans both columns rather than
     leaving a hole */
  body.desk-landing .dk-list .dk-lrow:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    border-right: 0;
  }
}

/* ── "one module, four products" ──────────────────────────────────────────────
   The answer to "you only have ten apps" has to be near the top of a module
   page, not in the closing note where it originally sat, more than half way
   down. A bordered strip under the subhead: quiet enough not to compete with
   the headline, specific enough to be checkable. */
body.desk-landing .dk-replaces {
  display: inline-block;
  margin: 20px auto 0;
  padding: 10px 16px;
  border: 1px solid var(--dk-line);
  border-left: 2px solid #7DD3A8;
  border-radius: 0 10px 10px 0;
  background: rgba(125, 211, 168, 0.06);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--dk-mute);
  text-align: left;
  max-width: 60ch;
}
body.desk-landing .dk-replaces b { color: var(--dk-ink); font-weight: 600; }

@media (max-width: 640px) {
  body.desk-landing .dk-replaces { display: block; font-size: 13px; }
}

/* ── Merch theme swatches ────────────────────────────────────────────────────
   The chip shows each preset's own primary colour, and nine of the thirty are
   dark-canvas looks whose primary is near-black (#0A0A0A, #111111, #1F2937).
   The launcher's usual treatment tints BOTH the container and the glyph from
   --mod, so for those nine the whole icon area disappeared into the card.

   Fix in two parts, the way a colour picker handles a black swatch:
     1. the container stops taking the colour and sits on a neutral surface,
        so there is always something to see the disc against;
     2. the disc keeps the colour and carries a bright ring, so a near-black
        fill reads as a dark disc that is plainly on purpose.
   `stroke` is a real CSS property on SVG shapes, so no markup changes. */
body.commerce-desk #themes .dk-lic {
  background: rgba(255, 255, 255, 0.07);
  box-shadow: inset 0 0 0 1px var(--dk-line);
}
body.commerce-desk #themes .dk-lic svg {
  width: 22px;
  height: 22px;
}
body.commerce-desk #themes .dk-lic svg circle {
  stroke: var(--dk-ink);
  stroke-width: 1.5;
  stroke-opacity: 0.75;
}
/* Same root cause on the right-hand label, which the launcher also colours
   from --mod: on the near-black presets it was black text on a dark card and
   effectively invisible. The swatch already carries the colour, so the label
   has no reason to repeat it and takes the normal muted text colour instead. */
body.commerce-desk #themes .dk-lfact {
  color: var(--dk-mute);
  opacity: 1;
}

/* Merch API — the two checkout paths. Side by side on purpose: the whole point
   is that a reader sees there are TWO and picks one, which a stacked list hides. */
body.desk-landing .mk-flows{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:18px;margin:28px 0 20px}
body.desk-landing .mk-flow{border:1px solid var(--dk-line);border-radius:14px;padding:20px 22px;background:rgb(255 255 255 / 0.02)}
body.desk-landing .mk-flowhead{display:flex;align-items:center;gap:10px;font-weight:650;font-size:15px;color:var(--dk-ink);margin-bottom:14px;line-height:1.35}
body.desk-landing .mk-flownum{flex:none;width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
  background:var(--dk-accent);color:#fff;font-size:13px;font-weight:750}
body.desk-landing .mk-steps{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:9px}
/* Parameter tables in the API reference (added with the categories/filtering section). Matches .mk-flow's
   border + radius language so a table inside a flow card does not read as a different component. Scrolls
   inside its own container rather than widening the page: the parameter column can hold long code spans and
   the page must not gain a horizontal scrollbar on a narrow screen. */
body.desk-landing .mk-table{width:100%;border-collapse:collapse;margin:14px 0 0;display:block;overflow-x:auto}
body.desk-landing .mk-table th,body.desk-landing .mk-table td{
  text-align:left;padding:8px 12px;border-bottom:1px solid var(--dk-line);font-size:13.5px;line-height:1.55;vertical-align:top}
body.desk-landing .mk-table th{color:var(--dk-ink);font-weight:600;white-space:nowrap}
body.desk-landing .mk-table td{color:var(--dk-mute)}
body.desk-landing .mk-table tr:last-child td{border-bottom:0}
body.desk-landing .mk-table code{font-size:12.5px;background:rgb(255 255 255 / 0.06);padding:1px 5px;border-radius:5px}
body.desk-landing .mk-table strong{color:var(--dk-ink)}
body.desk-landing .mk-steps li{font-size:14px;line-height:1.6;color:var(--dk-mute)}
body.desk-landing .mk-steps code,body.desk-landing .mk-flownote code{font-size:12.5px;background:rgb(255 255 255 / 0.06);
  border:1px solid var(--dk-line);border-radius:5px;padding:1px 5px;color:var(--dk-ink)}
body.desk-landing .mk-steps strong,body.desk-landing .mk-flownote strong{color:var(--dk-ink)}
body.desk-landing .mk-flownote{margin:14px 0 0;font-size:13.5px;line-height:1.55;color:var(--dk-mute);
  border-top:1px solid var(--dk-line);padding-top:12px}

/* Copy-to-clipboard on every curl block. The button is injected by script, so a
   reader with JS off still gets a clean, selectable <pre> and loses nothing. */
body.desk-landing .mk-curlwrap{position:relative}
body.desk-landing .mk-copy{position:absolute;top:8px;right:8px;z-index:2;
  border:1px solid var(--dk-line);border-radius:7px;background:rgb(255 255 255 / 0.07);
  color:var(--dk-mute);font:600 11.5px/1 'Inter',system-ui,sans-serif;letter-spacing:.02em;
  padding:6px 10px;cursor:pointer;transition:background .15s,color .15s,border-color .15s}
body.desk-landing .mk-copy:hover{background:rgb(255 255 255 / 0.13);color:var(--dk-ink)}
body.desk-landing .mk-copy:focus-visible{outline:2px solid var(--dk-accent);outline-offset:2px}
body.desk-landing .mk-copy.is-done{color:#4ADE80;border-color:rgb(74 222 128 / 0.4)}
/* Keep long commands clear of the button. Wrapping rather than scrolling
   matters here: with horizontal overflow a long line slides UNDERNEATH the
   Copy button and is unreadable (a git clone URL did exactly that). Wrapping
   is safe for copying — the button copies textContent, so the real newlines
   travel regardless of where the text visually breaks. */
body.desk-landing .mk-curlwrap .mk-curl{
  padding-right:76px;
  white-space:pre-wrap;
  overflow-wrap:anywhere;
}

/* ── hero wave ────────────────────────────────────────────────────────────────
   The signature data-wave as the BACKDROP of a hero, for the pages that have
   no product screenshot to open on. Injected by js/landing-hero-wave.js when
   the body carries data-hero-wave; there is no markup for it in the pages.

   Positioning follows .dk-desk-wave above, for the reason documented there:
   the wave must reach both edges of the SCREEN, not both edges of .dk-wrap
   (which caps at 1260px and left the graphic sitting in a box on a wide
   monitor). Anchored to the viewport; the bleed is contained by
   `.landing-page { overflow-x: clip }` in landing.css, which every one of
   these pages carries. */
body.desk-landing .dk-hero { position: relative; }

body.desk-landing .dk-hero-wave {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: -46px;
  width: 100vw;
  height: 300px;
  /* Above `body.desk-landing::after`, which is a FIXED full-viewport glow at
     z-index 0. Generated content paints after the element content at the same
     level, so a wave at z-index 0 is invisible — drawn correctly, sized
     correctly, and completely covered. It cost a while to find because the
     hero's extra padding still applied, so the page looked like the script had
     run and produced nothing. */
  z-index: 1;
  pointer-events: none;
}
body.desk-landing .dk-hero-wave svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* The hero's own content sits above it. Without this the text keeps the
   default z-index and the fill can wash over the sub-copy. */
body.desk-landing .dk-hero > *:not(.dk-hero-wave) {
  position: relative;
  z-index: 2;
}

/* A waved hero needs real room beneath the copy, not a token gap.

   The wave is anchored to the hero's BOTTOM edge, and its line sits in the
   lower part of its own box — so the padding here is what decides whether the
   line passes behind the text or below it. At 78px the line ran straight
   through the closing callout and the accent dots landed on top of words.
   This much clears the copy entirely, and the space is not empty: the wave is
   what fills it. */
body.desk-landing .dk-hero[data-waved] { padding-bottom: 210px; }

@media (max-width: 760px) {
  body.desk-landing .dk-hero-wave { height: 200px; bottom: -30px; }
  body.desk-landing .dk-hero[data-waved] { padding-bottom: 140px; }
}

/* ── prose links ──────────────────────────────────────────────────────────────
   Only .dk-osnote a was ever styled, so an inline link anywhere else in the
   copy fell through to the browser default — near-black-on-black, effectively
   invisible, on a page whose whole background is #070a10. Six of them were
   live across accounts, merch and procurement before anyone noticed.

   Underlined on purpose: colour alone is not enough to mark a link for a
   reader who cannot distinguish it, and these sit mid-sentence where there is
   no other cue. */
body.desk-landing .dk-lede a,
body.desk-landing .dk-sub a,
body.desk-landing .dk-ldesc a,
body.desk-landing .dk-replaces a,
body.desk-landing .dk-faq a,
body.desk-landing .dk-close a:not(.dk-btn1):not(.dk-btn2) {
  color: #A5B4FC;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
body.desk-landing .dk-lede a:hover,
body.desk-landing .dk-sub a:hover,
body.desk-landing .dk-ldesc a:hover,
body.desk-landing .dk-replaces a:hover,
body.desk-landing .dk-faq a:hover { color: #C7D2FE; }

/* ── features mega-menu ───────────────────────────────────────────────────────
   Built at runtime by js/features-menu.js from the "Features" nav link, so
   there is one definition rather than a copy on each of ~123 pages.

   Dense frost on the panel, per the suite's rule for floating surfaces: a
   nested backdrop-filter caps how much the blur can sample, so the opacity
   has to carry readability on its own. */
/* The nav is a flex row of bare <a>s with NO padding at 13.5px. The trigger
   has to match that exactly or it breaks the row two ways at once: it was
   14.5px with 8px of padding, which pushed its own label ~8px below its
   neighbours AND, because the row stretches to its tallest child, made every
   other link's box taller than it should be. Same size, same zero padding. */
body.desk-landing .fx-menu { position: relative; display: inline-flex; align-items: center; }

body.desk-landing .fx-trigger {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: inherit;
  line-height: inherit;
  color: #96a0b5;
  cursor: pointer;
  transition: color 0.14s ease;
}
body.desk-landing .fx-trigger:hover,
body.desk-landing .fx-menu.is-open .fx-trigger { color: var(--dk-ink); }
body.desk-landing .fx-trigger svg {
  width: 13px; height: 13px;
  fill: none; stroke: currentColor; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform .18s ease;
}
body.desk-landing .fx-menu.is-open .fx-trigger svg { transform: rotate(180deg); }

/* THE HIDDEN ATTRIBUTE LOSES TO ANY AUTHOR `display`.

   `[hidden]` is only `display: none` in the UA stylesheet, so the
   `display: grid` below outranked it and the panel was permanently open —
   the toggle set panel.hidden and nothing happened. This exact bug bit the
   Merch reference storefront's cart badge earlier (`display: inline-grid`
   over `hidden`), so it is a house pattern, not a one-off: any element that
   is hidden by attribute AND styled with `display` needs this rule. */
body.desk-landing .fx-panel[hidden] { display: none; }

/* BRIDGE THE GAP BETWEEN TRIGGER AND PANEL.

   The panel sits 16px below the trigger, and that gap was a dead zone: moving
   the pointer down to click an item left the trigger's box before entering
   the panel's, `mouseleave` fired, and the menu closed under the cursor. The
   menu was effectively unusable by mouse.

   This pseudo-element extends the panel's hit area up to meet the trigger, so
   the pointer is never over neither. Invisible, and it only exists while the
   panel is open because [hidden] removes the panel entirely. */
body.desk-landing .fx-panel::before {
  content: '';
  position: absolute;
  top: -18px;
  left: 0;
  right: 0;
  height: 18px;
}

body.desk-landing .fx-panel {
  position: absolute;
  top: calc(100% + 16px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  display: grid;
  grid-template-columns: 244px 380px;
  /* The row too, not just the columns. min-height:0 on the children was not
     enough: the panel was 460px while its IMPLICIT ROW measured 856px, so the
     children filled the row and the panel clipped them. minmax(0, 1fr) is
     what actually forces the row to the container's height and lets the
     children scroll. */
  grid-template-rows: minmax(0, 1fr);
  width: 624px;
  border: 1px solid var(--dk-line);
  border-radius: 14px;
  overflow: hidden;
  background: rgb(9 12 20 / 0.97);
  backdrop-filter: blur(18px) saturate(1.15);
  -webkit-backdrop-filter: blur(18px) saturate(1.15);
  box-shadow: 0 24px 60px rgb(0 0 0 / 0.55);
  /* The CAP BELONGS HERE, not on a column. With max-height on .fx-apps alone
     the grid row still stretched to the tallest column, so Accounts' 22 links
     made a 700px panel with the app list scrolling inside it — two columns of
     visibly different height and a menu nearly as tall as the viewport.
     Capping the panel and letting each column scroll inside it keeps them
     equal whichever app is selected. */
  /* Tall enough that all twelve apps fit without scrolling on a normal
     laptop — the list needs ~570px at 46px a row, and a menu you have to
     scroll to see the last three apps hides them in practice. Still clamped
     to the viewport, so a short window scrolls rather than overflowing. */
  max-height: min(600px, calc(100vh - 120px));
}

body.desk-landing .fx-apps {
  padding: 8px;
  overflow-y: auto;
  border-right: 1px solid var(--dk-line);
  /* A grid child will not shrink below its content height without this, so
     `overflow-y: auto` alone did nothing: the columns grew to 856px inside a
     462px panel and were simply CLIPPED by the panel's overflow:hidden. The
     scrollbar only appears once the item is allowed to be shorter than its
     content. Same reason the detail column carries it. */
  min-height: 0;
}
/* TWO ROWS, NOT THREE.

   The tag carried `grid-column: 1 / -1`, which pushed it out of row one — so
   auto-placement dropped the chevron onto a row of its own and every app read
   as three stacked lines. Each cell is now placed explicitly: name and tag
   stack in column one, and the chevron sits in column two spanning both,
   vertically centred against them. */
body.desk-landing .fx-app {
  display: grid;
  grid-template-columns: 1fr 14px;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 8px;
  row-gap: 1px;
  padding: 7px 10px;
  border-radius: 9px;
  text-decoration: none;
  color: var(--dk-ink);
  transition: background .12s ease;
}
body.desk-landing .fx-app:hover,
body.desk-landing .fx-app.is-on { background: rgb(255 255 255 / 0.07); }

body.desk-landing .fx-appname {
  grid-column: 1;
  grid-row: 1;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.25;
}
body.desk-landing .fx-apptag {
  grid-column: 1;
  grid-row: 2;
  font-size: 11px;
  color: var(--dk-dim);
  line-height: 1.3;
}
body.desk-landing .fx-more {
  grid-column: 2;
  grid-row: 1 / span 2;
  justify-self: end;
  align-self: center;
  color: var(--dk-dim);
  font-size: 15px;
  line-height: 1;
  opacity: .55;
  transition: opacity .12s ease, transform .12s ease;
}
body.desk-landing .fx-app:hover .fx-more,
body.desk-landing .fx-app.is-on .fx-more { opacity: 1; transform: translateX(2px); }

body.desk-landing .fx-detail { padding: 14px 16px; overflow-y: auto; min-height: 0; }
body.desk-landing .fx-dhead {
  margin: 0 0 10px;
  font-family: var(--font-family-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dk-accent);
}
body.desk-landing .fx-dnote { margin: 0; font-size: 13px; line-height: 1.6; color: var(--dk-mute); }
body.desk-landing .fx-dnote a { color: #A5B4FC; text-decoration: underline; text-underline-offset: 2px; }

/* Two columns once there are more than a handful — Accounts has 22, and a
   single column of them is what made the panel unmanageably tall. */
body.desk-landing .fx-dlist {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px 6px;
}
body.desk-landing .fx-dlist.is-short { grid-template-columns: 1fr; }
body.desk-landing .fx-dlist a {
  display: block;
  padding: 6px 8px;
  border-radius: 7px;
  font-size: 13px;
  color: var(--dk-mute);
  text-decoration: none;
}
body.desk-landing .fx-dlist a:hover { background: rgb(255 255 255 / 0.07); color: var(--dk-ink); }

/* NOTE ON SMALL SCREENS. There is deliberately no mobile variant here.
   `.dk-navlinks` is display:none below 900px (see the rule further up), so the
   Features trigger does not exist there at all and a panel style for that
   width would be unreachable code pretending to be a feature.

   Below 900px the routes to the feature pages are the footer's Resources
   column and the in-body drill-down on the module pages, both of which work.
   If a mobile nav is ever added, this menu needs a single-column panel pinned
   to the viewport rather than centred on the trigger — it is 624px wide. */

/* Quiet scrollbars inside the menu. */
body.desk-landing .fx-apps::-webkit-scrollbar,
body.desk-landing .fx-detail::-webkit-scrollbar { width: 8px; }
body.desk-landing .fx-apps::-webkit-scrollbar-thumb,
body.desk-landing .fx-detail::-webkit-scrollbar-thumb {
  background: rgb(255 255 255 / 0.12);
  border-radius: 99px;
}

/* ── Endpoint filter + section nav (merch-api reference) ───────────────────────────────────────────────
   Added because 39 of the 46 endpoint blocks are collapsed by default, putting ~63% of the page's text
   inside closed <details>. Chrome's find-in-page reaches into those; Firefox and Safari do not — so the
   browser's own search cannot see most of this reference for a large share of readers. */
body.desk-landing .mk-find { margin: 22px 0 6px; }
body.desk-landing .mk-find-label {
  display: block; font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dk-dim); margin-bottom: 8px;
}
body.desk-landing .mk-find-row { display: flex; align-items: center; gap: 12px; }
body.desk-landing .mk-find-input {
  flex: 1; min-width: 0; height: 44px; padding: 0 14px;
  border: 1px solid var(--dk-line); border-radius: 11px;
  background: rgb(255 255 255 / 0.04); color: var(--dk-ink);
  font-size: 14.5px; font-family: inherit; outline: none;
  transition: border-color .15s ease, background .15s ease;
}
body.desk-landing .mk-find-input::placeholder { color: var(--dk-dim); }
body.desk-landing .mk-find-input:focus { border-color: rgb(255 255 255 / 0.28); background: rgb(255 255 255 / 0.06); }
/* Tabular figures so "7 of 46" does not jiggle the layout as the reader types. */
body.desk-landing .mk-find-count {
  flex: 0 0 auto; font-size: 13px; color: var(--dk-mute); font-variant-numeric: tabular-nums;
}
body.desk-landing .mk-find-hint { margin: 9px 0 0; font-size: 12.5px; color: var(--dk-dim); }
body.desk-landing .mk-find-hint kbd {
  font-family: inherit; font-size: 11.5px; padding: 1px 6px; border-radius: 5px;
  border: 1px solid var(--dk-line); background: rgb(255 255 255 / 0.06); color: var(--dk-mute);
}
body.desk-landing .mk-find-empty { margin: 12px 0 0; font-size: 13.5px; color: var(--dk-mute); }

/* Section nav. Scrolls rather than wrapping on a narrow screen, so it can never push the page wide. */
body.desk-landing .mk-toc {
  display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; overflow-x: auto;
  margin: 0 auto 6px; padding: 10px 4px; max-width: var(--dk-maxw, 1100px);
  scrollbar-width: none;
}
body.desk-landing .mk-toc::-webkit-scrollbar { display: none; }
body.desk-landing .mk-toc-label {
  flex: 0 0 auto; font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--dk-dim);
  margin-right: 2px;
}
body.desk-landing .mk-toc a {
  flex: 0 0 auto; font-size: 13px; color: var(--dk-mute); text-decoration: none;
  padding: 6px 12px; border: 1px solid var(--dk-line); border-radius: 999px;
  background: rgb(255 255 255 / 0.02); transition: color .15s ease, border-color .15s ease, background .15s ease;
}
body.desk-landing .mk-toc a:hover { color: var(--dk-ink); border-color: rgb(255 255 255 / 0.24); background: rgb(255 255 255 / 0.06); }

/* ── Reading measure on the API reference ──────────────────────────────────────────────────────────────
   `.dk-lede` is capped at 620px site-wide, which at this font is 61 characters. That is a legitimate
   measure — and it is a NARROW one, sitting under a heading and above cards that both span the full
   1260px container. On the marketing pages the gap reads as deliberate whitespace; on this page the
   ledes carry real explanation and the same gap reads as a layout bug.

   Widened HERE ONLY, via the api-docs hook, because .dk-lede is shared by eighteen pages and re-flowing
   the whole marketing site is not a side effect this change should have.

   82ch ~= 81 characters: past the 66 ideal but inside the 45-90 band, and it closes most of the visual
   gap. Deliberately NOT the full 1260px, which would be 125 characters per line — measurably worse to
   read, and the reason "just make it full width" is the wrong fix rather than the obvious one.

   `ch` rather than px so the measure follows the font size instead of drifting from it. */
/* ── the reading measure on the API reference ────────────────────────────────
   Reported twice as "text wraps midway with space left on the right".

   MEASURED, not eyeballed, and the first measurement was WRONG: a probe using
   the `font` shorthand does not always serialize, so it silently fell back to
   the body font and reported .dk-osnote at 52 characters. Copying the font
   properties individually gives the true figure of 68 — INSIDE the 45-75 band,
   i.e. not typographically broken at all.

   The real defect is that this page stacks FOUR different measures in one
   1260px column: .dk-sub 58 chars, .dk-replaces 64, .dk-osnote 68, .dk-lede 82.
   Every paragraph therefore wraps at a different point, and that raggedness is
   what reads as a bug. Unified to one measure rather than widened arbitrarily.

   82ch is the top of the readable band, so it closes most of the gap to the
   1260px container without the 125-character line that full width would give.
   Expressed in `ch` so each block lands at the same CHARACTER count despite
   running at four different font sizes (13.5/14.5/16/17px) — the whole point of
   the unit, and why a px value cannot do this job.

   Scoped to .api-docs on purpose: these are shared `dk-` classes used by 12-17
   marketing pages each, where a narrow centred column is the intended design. */
/* ── endpoint cards: prose one side, code the other ───────────────────────────
   Fourth and final shape for this. The history is worth keeping because each
   attempt failed for a different reason and the reasons are not obvious:

     1. Widened the paragraph — 78 characters was already a good measure, so this
        changed almost nothing.
     2. Widened it to fill the card — ~142 characters per line, worse to read than
        the complaint being fixed.
     3. Paired the description with only its curl example — fixed the horizontal
        gap and created an L-shaped one, because the description is about twice
        the height of that one short example.
     4. Narrowed the whole card to 830px so it matched its contents — the card
        then looked right on its own, and the PAGE became lopsided: an 830px
        column of content against 530px of empty viewport.

   The space is real and the page should use it, but a card only fills its width
   honestly if BOTH columns carry weight. So the split is by kind, not by
   position: every piece of prose (description, notes, the parameter table) goes
   left, every piece of code (curl, request body, response) goes right. Those two
   stacks are of comparable height, which is what none of the earlier attempts
   had. */
@media (min-width: 1180px) {
  body.desk-landing.api-docs .mk-epbody {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 36px;
    align-items: start;
  }
  body.desk-landing.api-docs .mk-col-prose { grid-column: 1; min-width: 0; }
  body.desk-landing.api-docs .mk-col-code  { grid-column: 2; min-width: 0; }
  /* The column is the measure now; the paragraph cap would only reintroduce a
     gap inside a column that is already the right width. */
  body.desk-landing.api-docs .mk-col-prose .mk-desc { max-width: none; }
  body.desk-landing.api-docs .mk-col > :first-child { margin-top: 0; }
}

body.desk-landing.api-docs .dk-lede,
body.desk-landing.api-docs .dk-sub,
body.desk-landing.api-docs .dk-replaces,
body.desk-landing.api-docs .dk-osnote,
body.desk-landing.api-docs .dk-section > .dk-osnote { max-width: 82ch; }
