/* Graphite design system. Shared by the React homepage and the static
   /domains page. Changing a value here changes both surfaces. */
.kx {
  --bg: #16181C;
  --surf: #1E2126;
  --txt: #E6E8EB;
  --dim: #8B929B;
  --acc: #6EE7FF;
  --acc-ink: #0A1418;
  --edge: rgba(255, 255, 255, .10);
  --edge2: rgba(110, 231, 255, .35);
  --live: #5EEAD4;
  --build: #FCD34D;
  --disp: 'Space Grotesk', system-ui, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, monospace;
  background: var(--bg);
  color: var(--txt);
  font-family: var(--disp);
  position: relative;
  overflow: hidden;
}
.kx * { box-sizing: border-box; }

.kx-pad { padding: 36px 40px; }
.kx-h { font-family: var(--disp); font-weight: 700; letter-spacing: -.02em;
  line-height: 1.02; font-size: clamp(28px, 4vw, 40px); margin: 0 0 8px; }
.kx-sub { color: var(--dim); font-size: 14.5px; margin: 0; max-width: 560px; line-height: 1.5; }
.kx-eye { font-family: var(--mono); font-size: 10.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--acc); margin: 0 0 12px;
  display: flex; align-items: center; gap: 8px; }
.kx-eye::after { content: ""; flex: 1; height: 1px; background: var(--edge); }

.kx-counts { display: flex; gap: 24px; flex-wrap: wrap; align-items: baseline; margin-top: 16px; }
.kx-count { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; color: var(--dim); }
.kx-count b { font-family: var(--disp); font-size: 26px; font-weight: 700; color: var(--txt);
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; }

/* mark */
.kx-mark { flex: 0 0 auto; border-radius: 999px; overflow: hidden; display: flex;
  align-items: center; justify-content: center; background: var(--surf);
  border: 1px solid var(--edge); width: 28px; height: 28px; }
.kx-mark img { width: 74%; height: 74%; object-fit: contain; display: block; }
.kx-mark .mono { font-weight: 700; font-size: 11px; color: var(--txt); font-family: var(--disp); }
.kx-mark.nomark { border-style: dashed; border-color: var(--acc); }

/* status */
.kx-dot { width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto;
  display: inline-block; background: var(--dim); }
.kx-dot.live { background: var(--live); animation: kxPulseLive 2.2s ease-in-out infinite; }
.kx-dot.building { background: var(--build); animation: kxPulseBuild 2.6s ease-in-out infinite; }
@keyframes kxPulseLive {
  0% { box-shadow: 0 0 0 0 rgba(94,234,212,.5); }
  70% { box-shadow: 0 0 0 6px rgba(94,234,212,0); }
  100% { box-shadow: 0 0 0 0 rgba(94,234,212,0); }
}
@keyframes kxPulseBuild {
  0% { box-shadow: 0 0 0 0 rgba(252,211,77,.45); }
  70% { box-shadow: 0 0 0 5px rgba(252,211,77,0); }
  100% { box-shadow: 0 0 0 0 rgba(252,211,77,0); }
}

/* ticker */
.kx-tick { position: relative; border-top: 1px solid var(--edge);
  border-bottom: 1px solid var(--edge); padding: 16px 0; overflow: hidden; user-select: none; }
.kx-tick::before, .kx-tick::after { content: ""; position: absolute; top: 0; bottom: 0;
  width: 90px; z-index: 4; pointer-events: none; }
.kx-tick::before { left: 0; background: linear-gradient(90deg, var(--bg), transparent); }
.kx-tick::after { right: 0; background: linear-gradient(270deg, var(--bg), transparent); }
.kx-sweep { position: absolute; top: 0; bottom: 0; left: 0; width: 170px; z-index: 3;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(110,231,255,.11), transparent);
  animation: kxSweep 6.5s ease-in-out infinite; }
@keyframes kxSweep {
  0% { transform: translateX(-200px); opacity: 0; }
  12% { opacity: 1; } 88% { opacity: 1; }
  100% { transform: translateX(100vw); opacity: 0; }
}
.kx-track { display: flex; gap: 8px; width: max-content; will-change: transform; }

.kx-item { display: flex; align-items: center; gap: 8px; padding: 8px 16px 8px 8px;
  border: 1px solid var(--edge); border-radius: 999px; background: var(--surf);
  white-space: nowrap; cursor: pointer; text-decoration: none; color: inherit; position: relative;
  transition: border-color 200ms ease, background 200ms ease, box-shadow 260ms ease,
    transform 260ms cubic-bezier(.16,1,.3,1);
  animation: kxRiseIn 620ms cubic-bezier(.16,1,.3,1) backwards; }
.kx-item .nm { font-size: 14px; font-weight: 600; letter-spacing: -.015em; }
.kx-item .badge { font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; padding: 4px 8px; border-radius: 4px;
  background: var(--acc); color: var(--acc-ink); font-weight: 600; }
.kx-item:hover, .kx-item:focus-visible { border-color: var(--edge2); transform: translateY(-3px);
  box-shadow: 0 8px 26px rgba(0,0,0,.42), 0 0 0 1px var(--edge2); }
.kx-item:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
@keyframes kxRiseIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }

.kx-hint { font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim); padding: 8px 40px 0;
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.kx-hint b { color: var(--acc); font-weight: 500; }
.kx-ontouch { display: none; }
@media (hover: none) {
  .kx-onhover { display: none; }
  .kx-ontouch { display: inline; }
}

/* wipe panel.
   Sized with the grid 0fr -> 1fr technique rather than a fixed pixel height.
   A fixed height clipped the preview by 21px the moment the content was
   measured, and would silently clip again on any copy change. This tracks the
   content exactly and still transitions.

   minmax(0, 0fr) rather than plain 0fr: a bare 0fr row cannot shrink below its
   content's automatic minimum, so the child's 32px of vertical padding left a
   visible empty sliver under the strip when the panel was closed. */
.kx-wipe { display: grid; grid-template-rows: minmax(0, 0fr);
  transition: grid-template-rows 320ms cubic-bezier(.16,1,.3,1);
  border-bottom: 1px solid transparent;
  /* The panel needs its own overflow clip, not just the child's. The child
     keeps 32px of padding even when the row is 0, so without this it escapes
     the collapsed panel and sits on top of the hint text below. */
  overflow: hidden; }
.kx-wipe > * { overflow: hidden; min-height: 0; }
.kx-wipe.open { grid-template-rows: minmax(0, 1fr); border-bottom-color: var(--edge); }
.kx-wipe-in { display: flex; gap: 16px; padding: 16px 40px; align-items: center; }
.kx-wipe-shot { width: 280px; aspect-ratio: 16/10; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--edge); background: var(--surf); flex: 0 0 auto; position: relative; }
.kx-wipe-shot img { width: 100%; height: 100%; object-fit: cover; object-position: top center;
  display: block; transition: transform 400ms cubic-bezier(.16,1,.3,1); }
.kx-wipe-shot canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.kx-wipe-txt h4 { font-family: var(--disp); font-size: 24px; font-weight: 700;
  letter-spacing: -.02em; margin: 0 0 4px; }
.kx-wipe-txt p { color: var(--dim); font-size: 14px; margin: 0; max-width: 420px; line-height: 1.45; }
.kx-wipe-txt .dm { font-family: var(--mono); font-size: 11.5px; color: var(--acc); margin-top: 8px; }

/* split panel */
.kx-split { display: grid; grid-template-columns: 330px 1fr; gap: 24px; align-items: start; }
.kx-splitlist { border: 1px solid var(--edge); border-radius: 10px; overflow: hidden;
  background: var(--surf); max-height: 520px; overflow-y: auto; }
.kx-si { display: flex; align-items: center; gap: 8px; padding: 8px 12px; cursor: pointer;
  border-bottom: 1px solid var(--edge); position: relative; width: 100%; text-align: left;
  background: none; border-left: 0; border-right: 0; border-top: 0; color: inherit;
  font-family: inherit;
  transition: background 200ms ease, padding-left 260ms cubic-bezier(.16,1,.3,1); }
.kx-si:last-child { border-bottom: 0; }
.kx-si::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--acc); transform: scaleY(0);
  transition: transform 300ms cubic-bezier(.16,1,.3,1); }
.kx-si:hover { background: rgba(127,127,127,.08); }
.kx-si[aria-selected="true"]::before { transform: scaleY(1); }
.kx-si[aria-selected="true"] { padding-left: 16px; background: rgba(127,127,127,.10); }
.kx-si .nm { font-size: 13px; font-weight: 600; letter-spacing: -.01em; display: block;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kx-si .dm { font-family: var(--mono); font-size: 10.5px; color: var(--dim); display: block;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kx-splitpane { border: 1px solid var(--edge); border-radius: 10px; overflow: hidden;
  background: var(--surf); }
.kx-shotwrap { position: relative; aspect-ratio: 16/9.3; overflow: hidden; background: var(--bg); }
.kx-shotwrap img, .kx-shotwrap canvas { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: top center; display: block; }
.kx-shotwrap img { animation: kxWipeIn 520ms cubic-bezier(.16,1,.3,1); }
@keyframes kxWipeIn {
  from { clip-path: inset(0 100% 0 0); transform: scale(1.04); }
  to { clip-path: inset(0 0 0 0); transform: scale(1); }
}
.kx-splitbody { padding: 16px 16px 16px; }
.kx-splitbody h3 { font-family: var(--disp); font-size: 26px; font-weight: 700;
  letter-spacing: -.02em; margin: 0 0 4px; }
.kx-splitbody p { color: var(--dim); font-size: 14px; margin: 0; line-height: 1.45; }
.kx-splitbody .dm { font-family: var(--mono); font-size: 11.5px; color: var(--acc); margin-top: 8px; }

/* filter chips */
.kx-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.kx-fchip { font-family: var(--mono); font-size: 11px; letter-spacing: .06em;
  /* 5px 11px is the locked DCJ .btn--sm token, deliberately off the 4px
     grid. The polish auditor's grid check flagged it; the locked design
     system wins over that heuristic for control padding. */
  text-transform: uppercase; padding: 5px 11px; border-radius: 999px;
  border: 1px solid var(--edge); background: transparent; color: var(--dim);
  cursor: pointer; font-weight: 500; transition: all 180ms ease; }
.kx-fchip:hover { border-color: var(--edge2); color: var(--txt); }
.kx-fchip[aria-pressed="true"] { background: var(--acc); border-color: var(--acc); color: var(--acc-ink); }

/* empty state badge */
.kx-esbadge { position: absolute; top: 12px; left: 12px; z-index: 6; font-family: var(--mono);
  font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; padding: 4px 8px;
  border-radius: 5px; background: rgba(0,0,0,.42); border: 1px solid var(--edge);
  color: var(--dim); backdrop-filter: blur(4px); }

.kx-more { font-family: var(--disp); font-size: 15px; font-weight: 600; color: var(--acc);
  text-decoration: none; border-bottom: 1px solid currentColor; padding-bottom: 4px; }

@media (max-width: 900px) {
  .kx-split { grid-template-columns: 1fr; }
  .kx-splitlist { max-height: none; }
  .kx-pad { padding: 28px 20px; }
  .kx-wipe-in { padding: 16px 20px; gap: 12px; }
  .kx-wipe-shot { width: 150px; }
  .kx-wipe-txt h4 { font-size: 19px; }
  .kx-wipe-txt p { font-size: 13px; }
  .kx-hint { padding: 8px 20px 0; }
  .kx-counts { gap: 16px; }
  .kx-count b { font-size: 22px; }
}

/* The safety valve. Stops only the two things that trigger vestibular symptoms:
   continuous translation and parallax drift. Everything else is unchanged. */
@media (prefers-reduced-motion: reduce) {
  .kx-track { transform: none !important; }
  .kx-tick { overflow-x: auto; }
  .kx-wipe-shot img { transform: none !important; }
}

/* ============================================================
   Specificity guard.

   The homepage wraps its tree in .cal-root, whose legacy cream-theme reset
   `.cal-root * { color: inherit; -webkit-text-fill-color: currentColor }`
   sits later in the bundle at the same (0,1,0) specificity as the rules above,
   so it wins and forces every colour in this section to #0F0F0F on #16181C.
   That measured at a 1.1:1 contrast ratio, which is invisible.

   These re-assert the Graphite palette at (0,2,0) so they beat that reset
   without editing the legacy stylesheet. -webkit-text-fill-color has to be
   restated too, because the reset pins it to currentColor.
   ============================================================ */
.kx.kx { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-h, .kx h2, .kx h3, .kx h4 { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-sub, .kx .kx-count, .kx .kx-hint, .kx .kx-esbadge { color: var(--dim); -webkit-text-fill-color: currentColor; }
.kx .kx-eye, .kx .kx-hint b, .kx .kx-more { color: var(--acc); -webkit-text-fill-color: currentColor; }
.kx .kx-count b { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-item { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-item .nm { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-item .badge { color: var(--acc-ink); -webkit-text-fill-color: currentColor; }
.kx .kx-mark .mono { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-wipe-txt h4 { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-wipe-txt p { color: var(--dim); -webkit-text-fill-color: currentColor; }
.kx .kx-wipe-txt .dm { color: var(--acc); -webkit-text-fill-color: currentColor; }
.kx .kx-si { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-si .nm, .kx .kx-si h3, .kx .kx-si h3 a { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-si .dm, .kx .kx-si .cat { color: var(--dim); -webkit-text-fill-color: currentColor; }
.kx .kx-splitbody h3 { color: var(--txt); -webkit-text-fill-color: currentColor; }
.kx .kx-splitbody p { color: var(--dim); -webkit-text-fill-color: currentColor; }
.kx .kx-splitbody .dm { color: var(--acc); -webkit-text-fill-color: currentColor; }
.kx .kx-fchip { color: var(--dim); -webkit-text-fill-color: currentColor; }
.kx .kx-fchip[aria-pressed="true"] { color: var(--acc-ink); -webkit-text-fill-color: currentColor; }

/* Main's inline-link style `.cal-root a:not(.cal-pill)` paints a 2px bronze
   underline on every anchor at specificity (0,2,1), which beat the guard above
   and put a gold rule under every venture name inside the pills. These are not
   inline prose links: the pill and the border already carry the affordance.
   Matched at (0,3,1) so it wins without touching the legacy rule. */
.kx a { text-decoration: none; }
.cal-root .kx a:not(.cal-pill) {
  text-decoration: none;
  color: var(--txt);
  -webkit-text-fill-color: currentColor;
}
.cal-root .kx a.kx-more:not(.cal-pill),
.kx a.kx-more {
  color: var(--acc);
  -webkit-text-fill-color: currentColor;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

/* ============================================================
   Mobile flow fixes from the polish pass.
   ============================================================ */
@media (max-width: 900px) {
  /* The split collapses to one column on mobile. Source order put the 47-row
     list first, so tapping a row updated a preview pane the user could not see
     without scrolling past every remaining row. Show the preview first.

     align-items MUST be restated: the desktop grid rule sets `start`, and in a
     column flex container that shrinks each child to its content width instead
     of stretching, which rendered the list ~230px wide inside a 393px phone. */
  .kx-split { display: flex; flex-direction: column; align-items: stretch; }
  .kx-splitpane { order: 1; }
  .kx-splitlist { order: 2; width: 100%; }

  /* The list is long on a phone, so it gets its own scroll rather than pushing
     the page to 47 rows. Not sticky: a sticky pane inside a short flex column
     just scrolls away with its containing block, which looked broken. */
  .kx-splitlist { max-height: 58vh; overflow-y: auto; -webkit-overflow-scrolling: touch; }
}

/* A row scrolled to by a deep link must not land under the translucent sticky
   nav. scroll-margin moves the anchor stop, it does not add visible space. */
.kx-si { scroll-margin-top: 76px; }

/* The [hidden] attribute sets display:none only in the UA stylesheet, so any
   authored `display` on the same element silently wins. .kx-filters sets
   display:flex, so `hidden` did nothing and the duplicate chip row stayed
   visible on the live site. */
.kx-filters[hidden] { display: none; }
