/* ==========================================================================
   kryptoswap — the yellow, the pills, and the instrument underneath.

   This brand already exists. It runs on the platform build at
   kryptoswap.exchange (monease/platform, app/clients/kryptoswap), and that
   site is a React/Tailwind landing page: pure black ground, one saturated
   yellow, everything rounded to 24-32px or to a pill, uppercase headings, and
   a soft yellow bloom sitting behind the first screen and between the bands.

   None of that markup can be carried across — this binary renders Go
   templates and serves this file raw, uncompiled — so what follows is the
   look rebuilt, not the code ported. The line is the same one expeer's
   overlay draws:

     The atmosphere is reproduced.  The black ground, the bloom, the yellow,
     the pill chrome and the round cards are what anyone would name if asked
     what Krypto Swap looks like, and a version of this page without them is
     a different site wearing the same logotype.

     The instrument is not touched.  The wizard, the rate board, the chips,
     the flow and the order panel are the base's and stay the base's, wearing
     this brand's tokens. A landing page can afford an ambient wash; a page
     where someone is about to send money to an address they cannot recall it
     from cannot.

   Everything is scoped under body.ks, which the brand's layout override sets
   on every non-admin page. /admin renders without it and keeps the base
   instrument exactly: the operator's tool is not brand surface.

   Raw CSS served after the compiled app.css; unlayered, so it wins over the
   base's @layer rules. The .ks prefix is scoping, not weight. There is no
   `--spacing()` and no `@theme` available in this file — Tailwind never sees
   it — so every figure is written out, taken off the base's 4px scale.

   Content-Security-Policy here is `style-src 'self'; script-src 'self'`.
   No rule may be moved into a style attribute and no behaviour into an
   inline script; both are silently dropped. This overlay ships no script at
   all — the two things that travel are CSS animations and the two disclosure
   controls are <details> and a checkbox.
   ========================================================================== */

/* Inter, vendored under /static/fonts (SIL OFL, see fonts/README.txt), latin
   and cyrillic: the site serves en, ru and uk and the face has to speak all
   three. The platform build sets `font-inter` on this brand's landing layout,
   so this is the face the source names rather than a stand-in. */
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/inter-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  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: "Inter";
  src: url("/static/fonts/inter-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  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: "Inter";
  src: url("/static/fonts/inter-cyrillic.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/inter-cyrillic-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F,
    U+FE2E-FE2F;
}

/* --------------------------------------------------------------------------
   Tokens. Set on body.ks so they beat the base's :root values inside the page
   while leaving the unbranded admin alone.

   Declared in full rather than leaning on the base's dark block, because that
   block sits behind `prefers-color-scheme: dark`. This brand is black whatever
   the visitor's OS says — the platform build hard-sets data-theme="dark" on
   its landing layout — and a half-applied ramp would put the base's *light*
   status colours on a black page.
   -------------------------------------------------------------------------- */

body.ks {
  color-scheme: dark;

  /* Off theme.ts and colors.css:
       #FFE01A  the yellow      — hsl(52 100% 55%), daisyUI --p
       #000000  the ground      — what the landing layout actually sets
       #0D0D0D  the card        — every panel in the source
       #191919  the card raised — the source's hover, and theme.ts dark surface
       #EDEDED  the ink         — theme.ts dark secondary

     Measured on the ground / on the card:
       ink   17.9 / 16.6   ink-2 12.0 / 11.1   ink-3 6.7 / 6.2
       yellow 15.9 / 14.7  and it carries a black label at 15.9:1. */
  --color-paper: #000000;
  --color-surface: #0d0d0d;
  --color-surface-2: #191919;
  --color-ink: #ededed;
  --color-ink-2: #c4c4c4;
  --color-ink-3: #9ca3af;

  --color-rule: #232323;
  --color-rule-strong: #333333;
  /* Control boundaries, held to WCAG 1.4.11's 3:1 against the surfaces this
     brand draws controls on: 3.8:1 on the card, 3.5:1 on the raised card. */
  --color-control: #6e6e6e;
  --color-control-hover: #949494;

  /* The graph paper, stated rather than inherited. It is drawn on body from
     --grid-line, which the base declares on :root with a dark-scheme override
     behind prefers-color-scheme — so a visitor whose OS is set to light got
     the *light* line, which is a near-black line on a black page and no
     texture at all. Half this brand's audience would have seen a different
     page from the other half for no reason either of them could name. Set to
     the dark value on both. */
  --grid-line: rgb(237 237 237 / 0.018);

  /* The one accent, and the whole brand. It is bright enough that its label
     has to be near-black rather than white — 15.9:1 against black, 1.3:1
     against white — so nothing here ever sets white on the yellow. */
  --color-signal: #ffe01a;
  --color-signal-ink: #000000;
  --color-signal-wash: rgb(255 224 26 / 0.13);

  /* Status keeps the semantic four, lifted for a black ground — except warn.
     The base's amber (#fbbf24, hue 43) sits nine degrees from this brand's
     yellow (hue 52), and a "verifying" badge that is the same colour as the
     brand accent is the one collision the base's status doctrine will not
     have. Warn moves to orange, which is 25 degrees clear of the signal and
     still reads as caution beside the red. The dot and the written word carry
     it as they always did; only the hue changed. */
  --color-ok: #4ade80;
  --color-ok-wash: rgb(74 222 128 / 0.13);
  --color-warn: #fb923c;
  --color-warn-wash: rgb(251 146 60 / 0.13);
  --color-bad: #f87171;
  --color-bad-wash: rgb(248 113 113 / 0.14);
  --color-busy: #7dd3fc;
  --color-busy-wash: rgb(125 211 252 / 0.14);

  /* Round. The source draws rounded-3xl cards, rounded-4xl tiles and pills
     for every button and both chrome bars; the base is 3px and 2px because it
     is drawing an instrument. This pair of numbers is the single largest
     reason the two look different at a glance. --radius-coin stays the base's:
     an asset's mark belongs to the asset, not to the site trading it. */
  --radius-plane: 24px;
  --radius-control: 12px;
  --ks-pill: 999px;
  --ks-ease: cubic-bezier(0.16, 1, 0.3, 1);

  font-family: "Inter", var(--font-sans);
  /* The bloom is wider than the viewport by design. Clipped rather than
     hidden: `hidden` would make this the scroll container and break
     `position: sticky` inside it. */
  overflow-x: clip;
}

/* --------------------------------------------------------------------------
   Type: one grotesk voice; mono only where digits have to align.

   The base sets everything structural in --font-mono because it is drawing an
   instrument. This brand is not a monospaced brand, so headings, labels,
   prose and controls move to the grotesk — but the complete figure family
   stays in the mono. An amount, a rate, a pair, an address, a hash, an order
   reference and a countdown are each read a character at a time and compared
   against something on another screen; a proportional face makes that harder
   and buys nothing.
   -------------------------------------------------------------------------- */

body.ks :is(h1, h2, h3, h4, h5, h6),
body.ks :is(.btn, button, .badge, .label, .section-title, .chips li),
body.ks :is(input, select, textarea) {
  font-family: "Inter", var(--font-sans);
}
body.ks :is(.num, .quote-value, .address, .mono, code, kbd, samp),
body.ks .board :is(b, .num) {
  font-family: var(--font-mono);
}

body.ks h1 { letter-spacing: -0.02em; }

/* The source uppercases nearly every heading, and that is the loudest single
   thing about its type. It is carried, with the tracking opened a touch —
   uppercase Cyrillic at -0.02em closes up on itself. */
.ks-display {
  margin: 0 0 14px;
  font-size: clamp(2rem, 4.6vw, 3.25rem);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  text-wrap: balance;
}
.ks-heading {
  margin: 0 0 10px;
  font-size: clamp(1.5rem, 2.8vw, 2.15rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  text-wrap: balance;
}
/* TMark's <b class="hl"> is already the signal colour in the base; here it is
   also the only place the yellow appears in running text. */
.ks-display .hl,
.ks-heading .hl { font-weight: inherit; }

.ks-lede {
  margin: 0;
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--color-ink-2);
  max-inline-size: 60ch;
  text-wrap: pretty;
}
.ks-sub {
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--color-ink-3);
  max-inline-size: 62ch;
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   The bloom.

   The source stacks three absolutely-positioned divs with `blur-[184px]` over
   `#fff29d` and `#f4da3a`. A 184px gaussian across most of the viewport is an
   expensive way to draw a soft ellipse, and it is repainted on every scroll on
   the pages that carry two of them. This is the same picture as one radial
   gradient with a short blur on top of it, which composites once.

   isolation: isolate on the container is load-bearing: it makes the container
   a stacking context, so the bloom's z-index of -1 puts it behind the
   container's own content and nowhere near the page background.
   -------------------------------------------------------------------------- */

.ks-hero,
.ks-page-head,
.ks-section,
.ks-cta,
.ks-team { position: relative; isolation: isolate; }

.ks-bloom {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  inset-block-end: -7rem;
  inset-inline: -25%;
  block-size: 24rem;
  background: radial-gradient(
    closest-side,
    rgb(244 218 58 / 0.34) 0%,
    rgb(244 218 58 / 0.16) 46%,
    rgb(244 218 58 / 0) 76%
  );
  filter: blur(34px);
}
/* Anchored to the bottom of its container rather than the top, which is where
   the source puts it: its blooms live in their own divs *between* two
   sections, so the bright core lands in the gap and the pages either side of
   it stay black. Pinned to the top instead, the core sits under the headline
   and the whole first screen goes the colour of weak tea — the first version
   of this did exactly that. Anything that has to sit over the core takes the
   quiet variant below. */
.ks-bloom-low {
  inset-block-end: -11rem;
  block-size: 20rem;
  background: radial-gradient(
    closest-side,
    rgb(244 218 58 / 0.44) 0%,
    rgb(244 218 58 / 0.2) 44%,
    rgb(244 218 58 / 0) 74%
  );
}

/* --------------------------------------------------------------------------
   Chrome: the AML strip, then the header pill, then the footer pill.
   -------------------------------------------------------------------------- */

.ks-strip {
  background: linear-gradient(90deg, var(--color-signal), #f6cf00);
  color: var(--color-signal-ink);
}
.ks-strip-inner {
  max-inline-size: 70rem;
  margin-inline: auto;
  padding: 7px max(16px, env(safe-area-inset-right)) 7px
           max(16px, env(safe-area-inset-left));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px 10px;
  font-size: 0.8125rem;
  font-weight: 500;
  text-align: center;
}
.ks-strip p { margin: 0; color: inherit; }
.ks-strip a {
  color: inherit;
  font-weight: 700;
  white-space: nowrap;
  text-underline-offset: 3px;
}

/* The header keeps the base's sticky behaviour and drops its rule and glass:
   the bar is a floating pill on the page, not a band across it. */
body.ks .site-header { border-bottom: 0; }
body.ks .site-header::after { content: none; }
body.ks .site-header .wrap {
  display: block;
  padding-block: 12px;
}
/* Sticky over a page that scrolls a bloom past it: without a ground of its
   own the pill would sit on whatever happened to be underneath. The plate is
   a pseudo-element rather than the header's background so the phone menu
   sheet, which is a descendant, still blurs the page rather than this. */
body.ks .site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: color-mix(in oklch, var(--color-paper) 82%, transparent);
  backdrop-filter: blur(14px);
}

.ks-bar {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 8px 10px 8px 18px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--ks-pill);
}
body.ks .brand-logo img { block-size: 24px; }
/* Nothing here touches which of the two logotype slots is shown. The platform
   ships logo.svg, logo-light.svg and logo-dark.svg as one byte-identical
   yellow mark, and both slots in this overlay carry that same file, so the
   base's scheme switch resolves to the same picture either way. Overriding it
   would only be a rule that has to be kept in step with the base's four. */

body.ks .nav { gap: 18px; margin-inline-start: auto; }
body.ks .nav :is(a, button) {
  font-size: 0.8125rem;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
  border-bottom: 0;
  padding: 6px 10px;
  border-radius: var(--ks-pill);
  transition: color 0.15s var(--ks-ease), background-color 0.15s var(--ks-ease);
}
body.ks .nav :is(a, button):hover {
  color: var(--color-ink);
  background: var(--color-surface-2);
  border-bottom-color: transparent;
}
body.ks .nav a[aria-current="page"] {
  color: var(--color-signal);
  border-bottom-color: transparent;
}
/* The one filled control in the chrome. Flat yellow, not a gradient: the strip
   above it is the only gradient on the page and a second one on a button is
   how a brand talks itself into looking like every other exchange. */
body.ks .nav a.ks-nav-cta {
  color: var(--color-signal-ink);
  background: var(--color-signal);
  font-weight: 600;
}
body.ks .nav a.ks-nav-cta:hover { filter: brightness(1.08); color: var(--color-signal-ink); }

body.ks .site-footer {
  border-top: 0;
  margin-top: 96px;
}
.ks-footer .wrap { display: grid; gap: 18px; justify-items: center; }
.ks-footer-bar {
  inline-size: 100%;
  justify-content: space-between;
  padding: 14px 24px;
  background: #0d0d0d;
}
.ks-footer-nav,
.ks-footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 26px;
  justify-content: center;
}
.ks-footer-nav a,
.ks-footer-legal a {
  font-size: 0.8125rem;
  color: var(--color-ink-2);
  text-decoration: none;
  padding: 4px 2px;
}
.ks-footer-nav a:hover,
.ks-footer-legal a:hover { color: var(--color-signal); }
.ks-footer-legal a { color: var(--color-ink-3); }
body.ks .footer-end {
  inline-size: 100%;
  justify-content: center;
  gap: 12px 24px;
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   The hero: headline left, calculator right, bloom behind both.

   The source centres a very large uppercase headline over the wizard, which
   spends the whole width of the screen on a short measure and then puts the
   one control the page exists to get pressed underneath it. The split keeps
   every bit of the atmosphere and stops the two competing for the same
   vertical run.
   -------------------------------------------------------------------------- */

.ks-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(21rem, 27rem);
  gap: 40px;
  align-items: start;
  margin-block-end: 64px;
}
.ks-hero-copy { align-self: center; }
.ks-hero-sub {
  display: flex;
  align-items: center;
  gap: 18px;
  margin: 0;
  font-size: 1.0625rem;
  color: var(--color-ink-2);
}
/* The arrow the source draws beside its subtitle. It is a rule with a head on
   it, so it takes the remaining width rather than a fixed one. */
.ks-rule {
  flex: 1 1 auto;
  min-inline-size: 0;
  max-inline-size: 8rem;
  block-size: 15px;
  color: var(--color-signal);
}
body.ks .ks-hero-form .panel { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Sections and heads.
   -------------------------------------------------------------------------- */

.ks-section { margin-block-end: 88px; }
.ks-head {
  margin-block-end: 32px;
  display: grid;
  gap: 8px;
}
/* The source centres every section head. Kept, because a run of six centred
   heads down a landing page is a rhythm, and losing it makes the page read as
   a documentation site with yellow in it. */
.ks-section > .ks-head { justify-items: center; text-align: center; }
.ks-section > .ks-head .ks-sub { text-align: center; }

.ks-page-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 24rem);
  gap: 40px;
  align-items: center;
  margin-block-end: 72px;
}
.ks-page-head-plain { grid-template-columns: minmax(0, 1fr); }
.ks-head-art { inline-size: 100%; block-size: auto; }

/* --------------------------------------------------------------------------
   The card, and the four things it becomes.

   One vocabulary — a black plane on a hairline, 24px round, answering a hover
   by moving its border and lifting its ground to #191919, which is exactly
   what the source's `bg-[#0D0D0D] hover:bg-[#191919] border border-surface
   hover:border-primary/30` does. There are no shadows in this world and the
   overlay adds none; the source's `shadow-md hover:shadow-lg` on its pair
   tiles is the specific thing not ported.
   -------------------------------------------------------------------------- */

.ks-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 16px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.ks-card {
  display: flex;
  gap: 18px;
  padding: 20px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-plane);
  transition: background-color 0.3s var(--ks-ease),
              border-color 0.3s var(--ks-ease);
}
.ks-card:hover {
  background: var(--color-surface-2);
  border-color: rgb(255 224 26 / 0.3);
}
.ks-cards-tall .ks-card { flex-direction: column; align-items: flex-start; }
.ks-card h2,
.ks-card h3 {
  margin: 0 0 8px;
  font-size: 1.0625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--color-signal);
}
.ks-card p {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.65;
  color: var(--color-ink-3);
}
.ks-card:hover p { color: var(--color-ink-2); }
.ks-card .channel-value { display: block; margin-block-end: 8px; }

/* The icon plate. 12px round on a 52px box, the source's `rounded-lg
   bg-surface` with the mark in the brand yellow. */
.ks-card-mark {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 52px;
  block-size: 52px;
  border-radius: var(--radius-control);
  background: var(--color-surface-2);
  color: var(--color-signal);
  transition: background-color 0.3s var(--ks-ease);
}
.ks-card:hover .ks-card-mark { background: var(--color-signal-wash); }
.ks-card-mark .icon { inline-size: 26px; block-size: 26px; }

.ks-card-lead { align-self: stretch; }

/* The picture tiles: the source's "we offer the best" grid, where each cell is
   a 32px-round plane with a square art plate above the words. Its own layout
   is a 4+1+2 arrangement whose tallest cell is a 500px picture of a coin with
   no caption at all; here every cell carries its caption, because a cell that
   says nothing is a cell that could be left out. */
.ks-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 16px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.ks-tile {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 24px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: 32px;
  transition: background-color 0.3s var(--ks-ease),
              border-color 0.3s var(--ks-ease);
}
.ks-tile:hover {
  background: var(--color-surface-2);
  border-color: rgb(255 224 26 / 0.3);
}
.ks-tile-art {
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 11;
  border-radius: 16px;
  background: var(--color-surface-2);
  overflow: hidden;
}
.ks-tile-art img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
  padding: 12px;
}
.ks-tile h3 {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--color-signal);
}
.ks-tile p {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.65;
  color: var(--color-ink-3);
}

/* The wide plates on the about page: picture beside the words rather than
   above them, which is how the source draws its security and partnership
   pair. */
.ks-plates {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr));
  gap: 16px;
  list-style: none;
  margin: 0 0 88px;
  padding: 0;
}
.ks-plate {
  display: flex;
  gap: 20px;
  padding: 18px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-plane);
  transition: background-color 0.3s var(--ks-ease),
              border-color 0.3s var(--ks-ease);
}
.ks-plate:hover {
  background: var(--color-surface-2);
  border-color: rgb(255 224 26 / 0.3);
}
.ks-plate-art {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 9.5rem;
  border-radius: 16px;
  background: var(--color-surface-2);
  overflow: hidden;
}
.ks-plate-art img { inline-size: 100%; block-size: auto; }
.ks-plate h2 {
  margin: 0 0 8px;
  font-size: 1.0625rem;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--color-signal);
}
.ks-plate p {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.65;
  color: var(--color-ink-3);
}

/* --------------------------------------------------------------------------
   Steps, figures, countries.
   -------------------------------------------------------------------------- */

/* 14rem, so the four steps of an exchange sit on one row at the full measure
   rather than three-and-an-orphan. */
.ks-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 16px;
  list-style: none;
  margin: 0 0 88px;
  padding: 0;
  counter-reset: none;
}
/* Number and mark on one line, the words on the next. Three columns fitted the
   full measure but left about seven rems for the text, which wrapped a
   two-clause sentence over seven lines — four columns of that is a wall of
   verse, not four steps. */
.ks-step {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding: 20px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-plane);
}
.ks-step > div { flex: 1 0 100%; }
/* Without an icon there is nothing to fold, so the number stays beside the
   words as the source draws it. */
.ks-steps-flat .ks-step { flex-wrap: nowrap; align-items: flex-start; }
.ks-steps-flat .ks-step > div { flex: 1 1 auto; }
.ks-step-index {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-signal);
}
.ks-steps-flat .ks-step-index {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 52px;
  block-size: 52px;
  border-radius: var(--radius-control);
  background: var(--color-surface-2);
}
.ks-step h2,
.ks-step h3 {
  margin: 0 0 8px;
  font-size: 1.0625rem;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--color-signal);
}
.ks-step p {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.65;
  color: var(--color-ink-3);
}

/* Measured figures, not claims: every one of these comes from the live
   catalogue or the feed, and the block is omitted where neither answered. */
.ks-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1px;
  margin: 0;
  background: var(--color-rule);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-plane);
  overflow: hidden;
}
.ks-figures > div {
  padding: 22px 24px;
  background: var(--color-surface);
}
.ks-figures dt {
  margin: 0 0 6px;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-ink-3);
}
.ks-figures dd {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--color-ink);
}
.ks-figures dd.hl { color: var(--color-signal); }
.ks-figures-example { margin-block-end: 72px; max-inline-size: 34rem; }

/* The world list. The source lays this out in five hand-sliced columns over a
   dotted map, which drops any country whose index falls in one of the two gaps
   its slicing leaves. Here it is one grid over the whole set, and the map is
   the ground behind it rather than a layer to be positioned around. */
.ks-world { padding-block: 8px; }
.ks-world::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset-block: 2rem auto;
  inset-inline: -12%;
  aspect-ratio: 1440 / 798;
  background: url("/static/img/world-map.svg") center / contain no-repeat;
  opacity: 0.5;
  pointer-events: none;
}
/* Columns rather than a grid: one country's city list is twenty-six entries
   long and the rest are one or two, and grid rows size to their tallest cell —
   which left a column of white space beside Ukraine as tall as Ukraine. Column
   flow packs them, and break-inside keeps a country whole. */
.ks-countries {
  columns: 4 15rem;
  column-gap: 32px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.ks-countries li {
  break-inside: avoid;
  margin-block-end: 22px;
}
.ks-countries h3 {
  margin: 0 0 6px;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-signal);
}
.ks-countries p {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--color-ink-2);
}

/* --------------------------------------------------------------------------
   The marquee, twice: the partner row and the reviews.

   The source runs both on JavaScript — one on a copied component, one on a
   setInterval that scrolls a container. Here the travel is a CSS animation on
   a track carrying its row twice, so the loop closes with no script. It stops
   on hover, on focus inside, when the hold is ticked, and under reduced
   motion, which is more than either source component offers.

   The distance is -50% of the track, which is exactly one copy of the row —
   that is the whole reason the row is duplicated rather than merely long.
   -------------------------------------------------------------------------- */

.ks-marquee {
  margin-block-end: 88px;
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.ks-marquee-track {
  display: flex;
  inline-size: max-content;
  animation: ks-travel 42s linear infinite;
}
.ks-marquee-track ul {
  display: flex;
  align-items: center;
  gap: 56px;
  list-style: none;
  margin: 0;
  padding: 0 28px;
}
.ks-marquee:hover .ks-marquee-track,
.ks-marquee:focus-within .ks-marquee-track { animation-play-state: paused; }
.ks-marquee-track a { display: block; }
/* Black is a hostile ground for third-party marks, and half of these are
   full-colour. Greyed at rest so a row of six logos does not outrank
   everything the page says, restored on hover: these are places to check us
   against, not claims. */
.ks-marquee-track img {
  block-size: auto;
  inline-size: auto;
  max-block-size: 28px;
  /* Same reason as the wall: without a width cap the widest wordmark runs to
     340px and takes a third of the visible row on its own. */
  max-inline-size: 11rem;
  filter: grayscale(1) brightness(1.7);
  opacity: 0.6;
  transition: filter 0.25s var(--ks-ease), opacity 0.25s var(--ks-ease);
}
.ks-marquee-track a:hover img,
.ks-marquee-track a:focus-visible img { filter: none; opacity: 1; }
.ks-listing-name {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-ink-3);
  white-space: nowrap;
}
.ks-marquee-track a:hover .ks-listing-name { color: var(--color-signal); }

@keyframes ks-travel {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

.ks-reviews-marquee { margin-block-end: 0; }
.ks-reviews-marquee .ks-marquee-track { animation-duration: 90s; }
.ks-reviews-marquee ul { align-items: stretch; gap: 20px; padding: 0 10px; }
.ks-quote {
  display: flex;
  flex-direction: column;
  gap: 20px;
  inline-size: 22rem;
  padding: 26px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-plane);
}
.ks-quote-when {
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-signal);
}
.ks-quote blockquote {
  flex: 1;
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--color-ink-2);
}
.ks-quote blockquote::before { content: "\201C"; }
.ks-quote blockquote::after { content: "\201D"; }
.ks-quote figcaption {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 0.9375rem;
  color: var(--color-signal);
}
.ks-quote-mark {
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  flex: none;
  border-radius: 50%;
  background: var(--color-signal-wash);
}

/* The hold. A checkbox rather than a button because there is no script here,
   and the state has to survive without one. */
.ks-hold {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-block-end: 16px;
  padding: 6px 14px;
  font-size: 0.8125rem;
  color: var(--color-ink-3);
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--ks-pill);
  cursor: pointer;
}
.ks-hold:hover { color: var(--color-ink); border-color: var(--color-control); }
#reviews-paused:focus-visible + .ks-hold { outline: 2px solid var(--color-signal); outline-offset: 2px; }
#reviews-paused:checked + .ks-hold { color: var(--color-signal); border-color: var(--color-signal); }
#reviews-paused:checked ~ .ks-marquee .ks-marquee-track { animation-play-state: paused; }

/* --------------------------------------------------------------------------
   FAQ, notes, calls to action, the partner wall.
   -------------------------------------------------------------------------- */

/* The base sets the FAQ group label beside its questions above 64rem, keyed on
   `.section:has(.faq)`. These sections carry a centred head instead, so that
   grid is switched off and the split is stated where the page wants one. */
body.ks .section:has(.faq) { display: block; }
body.ks .faq {
  max-inline-size: none;
  border-block-start: 1px solid var(--color-rule);
}
.ks-faq-split {
  display: grid;
  grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
  gap: 32px;
  align-items: start;
}
.ks-faq-aside { margin: 0; }
body.ks .faq-item summary {
  font-size: 1rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.01em;
}
body.ks .faq-item[open] summary { color: var(--color-signal); }
body.ks .faq-item p { color: var(--color-ink-2); }
/* The dedicated FAQ page has no second column to fill, so the list keeps a
   reading measure and centres in the frame. Left at full width the +/- marker
   trails a four-word question across half a screen of empty rule, which is the
   thing the base's own 72ch cap exists to prevent. */
.ks-faq-full { max-inline-size: 78ch; margin-inline: auto; }

.ks-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 22px;
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--color-signal-ink);
  background: var(--color-signal);
  border-radius: var(--ks-pill);
  transition: filter 0.15s var(--ks-ease);
}
.ks-pill:hover { filter: brightness(1.08); color: var(--color-signal-ink); }
.ks-pill .icon { inline-size: 18px; block-size: 18px; }

body.ks .btn { border-radius: var(--ks-pill); text-transform: none; letter-spacing: 0; font-size: 0.875rem; }

.ks-note {
  display: flex;
  gap: 14px;
  padding: 18px 20px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-plane);
}
.ks-note .icon { flex: none; color: var(--color-ink-3); }
.ks-note-warn { border-color: var(--color-warn); }
.ks-note-warn .icon { color: var(--color-warn); }
.ks-note p { margin: 0 0 6px; font-size: 0.875rem; color: var(--color-ink-2); }
.ks-note > div > :last-child { margin-block-end: 0; }
.ks-asides {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 16px;
  margin-block: 32px 88px;
}

.ks-cta {
  display: grid;
  gap: 14px;
  justify-items: center;
  text-align: center;
  padding: 56px 32px;
  margin-block-end: 32px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: 32px;
}
.ks-cta h2 {
  margin: 0;
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  font-weight: 700;
  text-transform: uppercase;
  text-wrap: balance;
}
.ks-cta-lede {
  margin: 0;
  max-inline-size: 58ch;
  color: var(--color-ink-3);
  text-wrap: pretty;
}
.ks-cta-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px 24px;
  margin: 6px 0 0;
}
.ks-cta-aside { font-size: 0.875rem; color: var(--color-ink-3); }

/* The closing panel on the landing page: the source's "our team will help you"
   block, words on the left and the picture bleeding off the right edge of the
   plane. */
.ks-team {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
  align-items: center;
  gap: 24px;
  padding: 8px 8px 8px 0;
  margin-block-end: 32px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: 32px;
  overflow: hidden;
}
.ks-team-say { padding: 40px 8px 40px 48px; }
.ks-team-say p { margin: 0 0 16px; color: var(--color-ink-2); }
/* Matched to `.ks-team-say p` rather than beating it with !important: same
   specificity, stated after, which is all this needs. */
.ks-team-say p.ks-team-tagline { color: var(--color-signal); }
.ks-team-art {
  inline-size: 100%;
  block-size: auto;
  border-radius: 26px;
}

/* The partner wall: the same marks as the marquee, standing still and larger,
   on the page whose whole subject they are. */
/* Three across, not five. These five marks run from 3:1 to 12:1 — CryptoControl
   is a very wide serif wordmark — and in a five-column wall the cell is narrow
   enough that the widest mark is width-limited to about twelve pixels tall,
   beside a BestChange tile at its full height. Wider cells let every mark reach
   the height cap, which is what makes a row of logos read as one row. */
.ks-wall {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 16px;
  list-style: none;
  margin: 0 0 88px;
  padding: 0;
}
.ks-wall a {
  display: grid;
  place-items: center;
  min-block-size: 8rem;
  padding: 24px;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-plane);
  transition: background-color 0.3s var(--ks-ease),
              border-color 0.3s var(--ks-ease);
}
.ks-wall a:hover {
  background: var(--color-surface-2);
  border-color: rgb(255 224 26 / 0.3);
}
/* Capped on both axes rather than set to a fixed height: at a fixed height a
   12:1 wordmark is 480px wide and overruns its cell, and whichever constraint
   binds first should be the one that decides. */
.ks-wall img {
  block-size: auto;
  inline-size: auto;
  max-block-size: 44px;
  max-inline-size: 100%;
  filter: grayscale(1) brightness(1.7);
  opacity: 0.65;
  transition: filter 0.25s var(--ks-ease), opacity 0.25s var(--ks-ease);
}
.ks-wall a:hover img,
.ks-wall a:focus-visible img { filter: none; opacity: 1; }

/* --------------------------------------------------------------------------
   The instrument, wearing this brand's tokens.

   Everything below is the base's component answering the round radii and the
   yellow; none of it is redrawn. The board rows, the flow, the order panel and
   the wizard are untouched beyond what the tokens already do.
   -------------------------------------------------------------------------- */

body.ks .chips li { border-radius: var(--ks-pill); }
body.ks .badge { border-radius: var(--ks-pill); }
body.ks .panel { border-radius: var(--radius-plane); }
/* The panel's corner registration marks are the base instrument's signature
   and they are drawn as square brackets over a 3px corner. On a 24px corner
   they sit outside the curve and read as a misprint, so this brand does not
   take them. What is left is a plain round plane, which is what the source
   draws. */
body.ks .panel::before,
body.ks .panel::after { content: none; }

/* --------------------------------------------------------------------------
   Narrow.

   The base folds the header nav into a sheet below 40rem. This brand's nav
   carries six links plus the auth pair, which does not fit a tablet, so the
   fold moves up to 64rem. The sheet's own behaviour — the scrim, the body
   lock, the no-script fallback — is the base's and applies unchanged below
   40rem; what is restated here is only what has to exist in the band between.
   -------------------------------------------------------------------------- */

@media (max-width: 63.999rem) {
  body.ks .nav-toggle { display: flex; margin-inline-start: auto; }
  body.ks .nav {
    position: absolute;
    inset-inline: 0;
    inset-block-start: 100%;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-inline-start: 0;
    padding: 8px max(16px, env(safe-area-inset-right))
             12px max(16px, env(safe-area-inset-left));
    background: var(--color-surface);
    border-block: 1px solid var(--color-rule);
    opacity: 0;
    translate: 0 -0.5rem;
    transition: opacity 0.2s var(--ks-ease), translate 0.2s var(--ks-ease),
                display 0.2s allow-discrete;
  }
  body.ks .site-header:has(.nav-toggle[aria-expanded="true"]) .nav {
    display: flex;
    opacity: 1;
    translate: 0 0;
    @starting-style { opacity: 0; translate: 0 -0.5rem; }
  }
  body.ks .nav :is(a, button) {
    display: block;
    inline-size: 100%;
    text-align: start;
    padding: 12px 10px;
    border-radius: var(--radius-control);
  }
  body.ks .nav a.ks-nav-cta { text-align: center; }
  /* Scripting off: the button is dead, so the sheet stands open as a block of
     links under the identity row. The base does this by letting .site-header
     .wrap wrap; here the flex container is the pill inside it, so the pill is
     what has to wrap — and a pill three hundred pixels tall is a lozenge, so
     it takes the plane radius for as long as it is one. */
  html:not(.js) body.ks .nav-toggle { display: none; }
  html:not(.js) body.ks .ks-bar {
    flex-wrap: wrap;
    border-radius: var(--radius-plane);
    padding: 12px 16px;
  }
  html:not(.js) body.ks .nav {
    position: static;
    display: flex;
    flex-basis: 100%;
    opacity: 1;
    translate: none;
    padding: 8px 0 0;
    background: none;
    border-block: 0;
  }

  .ks-hero,
  .ks-page-head { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  /* On a phone the page opens on the control, with the sentence that explains
     it still read first. Source order stays copy-then-form, because source
     order is also tab order. */
  .ks-hero-copy { order: 1; }
  .ks-hero-form { order: 2; }
  .ks-faq-split { grid-template-columns: minmax(0, 1fr); }
  .ks-team { grid-template-columns: minmax(0, 1fr); padding: 8px; }
  .ks-team-say { padding: 24px 16px 8px; }
}

@media (max-width: 40rem) {
  .ks-section { margin-block-end: 56px; }
  .ks-marquee,
  .ks-plates,
  .ks-steps,
  .ks-wall { margin-block-end: 56px; }
  .ks-hero { margin-block-end: 40px; }
  .ks-card { flex-direction: column; }
  .ks-plate { flex-direction: column; }
  .ks-plate-art { inline-size: 100%; }
  .ks-quote { inline-size: 17rem; }
  /* The arrow rules off the end of a subtitle that has room for it. Wrapped
     onto two lines on a phone it is a line pointing at the edge of the
     screen. */
  .ks-rule { display: none; }
  .ks-cta { padding: 40px 20px; }
  .ks-strip-inner { font-size: 0.75rem; }
  .ks-bar { padding: 8px 10px 8px 14px; gap: 12px; }
}

/* Anything that travels, stops. The marquees are the only continuous motion
   this overlay adds, and neither is reporting anything measured — the base's
   doctrine would not have them at all, and the argument for keeping them is
   that a landing page is not the surface that rule was written for. That
   argument does not extend to a reader who has asked for stillness. */
@media (prefers-reduced-motion: reduce) {
  body.ks .ks-marquee-track { animation: none; }
  body.ks .ks-marquee { mask-image: none; overflow-x: auto; }
}

@media print {
  body.ks .ks-strip,
  body.ks .ks-bloom,
  body.ks .ks-world::before,
  body.ks .ks-hold { display: none; }
  body.ks .ks-marquee { overflow: visible; mask-image: none; }
  body.ks .ks-marquee-track { animation: none; flex-wrap: wrap; }
}
