/* ═══════════════════════════════════════════════════════════════════════════
   TOKENS - the whole design system is this file plus components.css
   No framework. No build step. No CSS-in-JS. Two font families, one accent.

   Every value here is a decision, documented where it is not obvious.
   Change a token, the whole site changes. That is the point.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── GROUND ────────────────────────────────────────────────────────────
     Near-black, biased cool. Not #000: pure black makes the accent vibrate
     and makes long reading harsh on OLED phones, which is where this
     audience actually reads. #0A0B0D keeps a hair of blue so the lime sits
     on a complementary ground instead of a neutral one.                    */
  --ground:      #0A0B0D;
  --surface:     #111316;   /* raised: tables, code, cards           */
  --surface-2:   #171A1E;   /* raised twice: nav on scroll, inputs   */
  --line:        #242830;   /* visible rule                          */
  --line-soft:   #1A1E24;   /* internal table rules                  */

  /* ── TEXT ──────────────────────────────────────────────────────────────
     Never pure white. #E8EAED at 17px on #0A0B0D is ~15:1 - well past AA
     without the glare of #FFF, which at this size reads as a light source
     rather than as text.                                                   */
  --text:        #E8EAED;
  --text-2:      #B6BCC4;   /* secondary prose, table cells          */
  --muted:       #8A8F98;   /* metadata, labels, captions            */

  /* ── ACCENT ────────────────────────────────────────────────────────────
     #D7FF3E. Colour theory for conversion, in three parts:

     1. HIGHEST LUMINANCE CONTRAST OF ANY HUE against a near-black ground.
        Yellow-green sits at the peak of human photopic sensitivity (~555nm),
        so it draws the eye harder than red, blue or violet at equal chroma.
        The eye lands on it before it lands on anything else.

     2. NOT A WARNING COLOUR. Red and amber are pre-loaded with loss for a
        trading audience. A red CTA on a page about losing money to fees is
        working against you. Lime is "go", "filled", "in profit" - the same
        semantics every terminal this audience uses already trained into them.

     3. SCARCITY IS THE MECHANISM. The accent appears in exactly four places:
        the primary CTA, the single hero number, the active nav state, and
        the route-line motif. Nowhere else, ever. An accent used on every
        card is not an accent, it is a background - and then nothing tells
        the reader where to click.                                          */
  --accent:      #D7FF3E;
  --accent-dim:  #A8C82F;   /* hover / visited - never a second hue  */
  --accent-ink:  #0A0B0D;   /* text ON the accent                    */
  --accent-wash: rgba(215, 255, 62, .08);

  /* ── SEMANTIC ──────────────────────────────────────────────────────────
     Separate from the accent, and never used for actions.                  */
  --alert:       #FF5C5C;   /* the error string, the failed tx       */
  --alert-wash:  rgba(255, 92, 92, .09);
  --caution:     #F0A93B;   /* "checked 41 days ago"                 */
  --caution-wash:rgba(240, 169, 59, .09);
  --good:        #6FD08C;   /* confirmed, resolved. Deliberately     */
                            /* desaturated so it never competes with */
                            /* the accent for the eye.               */

  /* ── TYPE ──────────────────────────────────────────────────────────────
     Two families. Not three, not five.

     ARCHIVO - display and prose. A grotesk drawn for both, so one family
     carries headings at 800 and body at 400 without a second load. Tight
     apertures, slightly condensed. Reads as infrastructure, not as a
     startup landing page.

     JETBRAINS MONO - ALL chrome and ALL data. Nav, labels, metadata,
     addresses, fees, error strings, timestamps. This is the one real
     opinion in the type system: the interface is mono, the prose is
     grotesk. That is how every terminal this audience uses is built, so
     it reads as native rather than as a blog about trading.                */
  --font-display: Archivo, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body:    Archivo, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Base is 17px, not 16. Crypto Twitter reads on a phone, fast, usually
     one-handed. 16px is a documentation default; 17 is a reading default. */
  --fs-base:   17px;
  --fs-xs:     0.735rem;   /* mono labels, uppercase, letterspaced   */
  --fs-sm:     0.845rem;   /* captions, table meta                   */
  --fs-md:     0.94rem;    /* table cells, nav                       */
  --fs-lg:     1.125rem;   /* the answer block - bigger than body    */
  --fs-h3:     1.22rem;
  --fs-h2:     clamp(1.4rem,  3.2vw, 1.78rem);
  --fs-h1:     clamp(1.95rem, 5.4vw, 2.85rem);
  --fs-hero:   clamp(2.6rem,  9vw,   4rem);   /* the one number      */

  --lh-tight:  1.08;
  --lh-head:   1.16;
  --lh-body:   1.62;

  --track-tight: -0.028em;  /* headings                             */
  --track-label:  0.13em;   /* uppercase mono labels                */

  /* Measure. 68ch at 17px is ~62 characters of Archivo - the top of the
     comfortable band. Wider and the eye loses the line return on mobile.  */
  --measure: 68ch;
  --measure-art: 640px;   /* editorial art cap, see DESIGN.md      */

  /* ── SPACE ─────────────────────────────────────────────────────────────
     A 4px base scale. Sibling groups use flex/grid + gap, never margins,
     so nothing collapses or doubles silently.                             */
  --s1: 4px;  --s2: 8px;   --s3: 12px;  --s4: 16px;
  --s5: 24px; --s6: 32px;  --s7: 48px;  --s8: 64px;  --s9: 96px;

  /* ── FORM ──────────────────────────────────────────────────────────────
     4px radius, everywhere. Not 12px, not "rounded-2xl". Soft corners read
     as consumer app; this is a tool. The one exception is the pill on
     status chips, where the shape carries meaning.                        */
  --r:      4px;
  --r-pill: 999px;

  --border: 1px solid var(--line);

  /* No large ambient shadows - they read as glassmorphism and they do not
     exist on a dark ground anyway. Elevation is done with surface steps.  */
  --shadow: 0 1px 0 rgba(255,255,255,.02) inset;

  --nav-h: 52px;
  --dur:   160ms;
  --ease:  cubic-bezier(.22, 1, .36, 1);   /* expo.out - the house curve */
}

/* ── LIGHT ─────────────────────────────────────────────────────────────────
   Dark is the default and the design is built for it. Light exists because
   some readers force it, and a broken light mode looks careless. The accent
   inverts role: on light it is a FILL behind dark text, never text itself -
   #D7FF3E on white is ~1.4:1 and illegible.                                */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --ground:      #F6F7F1;
    --surface:     #FFFFFF;
    --surface-2:   #EEF0E7;
    --line:        #DBDECF;
    --line-soft:   #E7E9DE;
    --text:        #12141A;
    --text-2:      #444A52;
    --muted:       #676D75;
    --accent:      #4E6300;   /* darkened for text/rules on light      */
    --accent-dim:  #3A4A00;
    --accent-ink:  #12141A;   /* dark text on the lime fill            */
    --accent-wash: rgba(215, 255, 62, .38);
    --alert:       #C21E1E;
    --alert-wash:  rgba(194, 30, 30, .08);
    --caution:     #8A5A00;
    --caution-wash:rgba(138, 90, 0, .10);
    --good:        #2E7D4F;
  }
}
:root[data-theme="light"] {
  --ground:#F6F7F1; --surface:#FFFFFF; --surface-2:#EEF0E7;
  --line:#DBDECF; --line-soft:#E7E9DE;
  --text:#12141A; --text-2:#444A52; --muted:#676D75;
  --accent:#4E6300; --accent-dim:#3A4A00; --accent-ink:#12141A;
  --accent-wash:rgba(215,255,62,.38);
  --alert:#C21E1E; --alert-wash:rgba(194,30,30,.08);
  --caution:#8A5A00; --caution-wash:rgba(138,90,0,.10); --good:#2E7D4F;
}

/* On light, the lime survives only as a fill. Components use this token for
   any surface that must stay brand-lime in both themes (the CTA button).   */
:root { --accent-solid: #D7FF3E; --accent-solid-ink: #0A0B0D; }

/* Same rule for the one caution surface that must stay amber in both themes:
   the preview-build draft banner. Near-black on amber is ~10:1 either way. */
:root { --caution-solid: #F0A93B; --caution-solid-ink: #0A0B0D; }

/* ═══════════════════════════════════════════════════════════════════════════
   COMPONENTS - reusable assets. Every one of these is used on more than one
   page type; anything used once lives in the page, not here.

   Rule enforced throughout: the interface chrome is mono, the prose is
   grotesk, the numbers are mono. If you can copy it, it is mono.
   ═══════════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

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

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

/* ── NAV ───────────────────────────────────────────────────────────────────
   One row, 52px, mono, sticky. The nav IS the entity architecture: the
   platform hubs are the primary items, because "axiom" is the thing a
   search engine and a reader both need us to be an authority on.
   No hamburger holding twelve links. On mobile the hubs scroll sideways -
   a trader swiping a row of tickers is a familiar object.                   */
.nav {
  position: sticky; top: 0; z-index: 50;
  height: var(--nav-h);
  display: flex; align-items: center; gap: var(--s5);
  padding: 0 var(--s5);
  background: color-mix(in srgb, var(--ground) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: var(--border);
  font-family: var(--font-mono);
  font-size: var(--fs-md);
}
.nav__mark {
  font-weight: 700; letter-spacing: -.02em; color: var(--text);
  text-decoration: none; white-space: nowrap; flex: 0 0 auto;
}
.nav__mark::after { content: ""; display: inline-block; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); margin-left: 6px; vertical-align: 2px; }
.nav__hubs {
  display: flex; gap: var(--s5); align-items: center;
  overflow-x: auto; scrollbar-width: none; flex: 1 1 auto;
  -webkit-overflow-scrolling: touch;
  /* Fade the right edge. Without it the last hub clips mid-word straight into
     the links group and the two read as one broken word ("bull links") on a
     narrow phone. The fade says "this scrolls" and removes the collision. */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  scroll-snap-type: x proximity;
}
.nav__hubs > a { scroll-snap-align: start; }
.nav__hubs::-webkit-scrollbar { display: none; }
.nav a {
  color: var(--muted); text-decoration: none; white-space: nowrap;
  transition: color var(--dur) var(--ease);
  /* Fill the bar's height. As inline elements these anchors were 15px tall
     inside a 52px bar, so the tap target was a third of what it looked like -
     invisible on desktop, and the whole audience is on a phone. */
  display: inline-flex; align-items: center; min-height: 44px;
}
.nav a:hover { color: var(--text); }
.nav a[aria-current="page"] { color: var(--accent); }
.nav__links {
  flex: 0 0 auto; display: flex; gap: var(--s4); align-items: center;
  font-size: var(--fs-sm);
  padding-left: var(--s4);
  border-left: 1px solid var(--line);
  background: var(--ground);            /* opaque, so nothing bleeds under it */
}
@media (max-width: 720px) { .nav__links .is-optional { display: none; } }
/* No hubs built (the public build before anything ships): drop the divider,
   or it rules off an empty row. */
.nav__hubs:not(:has(a)) + .nav__links { border-left: 0; padding-left: 0; }

/* ── DRAFT BANNER ──────────────────────────────────────────────────────────
   Preview builds only. Solid caution, full bleed, and it sticks under the
   nav: a draft is mostly judged from a scrolled screenshot, so the banner
   has to be in every one. Amber, never lime - lime means go.               */
.draft-banner {
  position: sticky; top: var(--nav-h); z-index: 40;
  padding: var(--s2) var(--s5);
  background: var(--caution-solid); color: var(--caution-solid-ink);
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; line-height: 1.5;
}

/* ── PAGE ──────────────────────────────────────────────────────────────────
   One screen, one purpose. No sidebar competing with the body for attention,
   no related-posts rail, no newsletter interrupt. A page that is trying to
   do two things does neither, and the second thing is always the one that
   eats the conversion.                                                      */
.page { max-width: 780px; margin: 0 auto; padding: var(--s7) var(--s5) var(--s9); }
.page > * { max-width: var(--measure); }
.page > .full { max-width: none; }

/* ── META STRIP ────────────────────────────────────────────────────────────
   Above the H1. Platform · type · checked date. All mono, all small. This
   is the first thing that says "this is maintained", which is the entire
   differentiator against a 2024 blog post that still ranks.                */
.meta {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); align-items: center;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--muted); margin-bottom: var(--s4);
}
.meta__dot { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }

/* ── HEADINGS ──────────────────────────────────────────────────────────────
   H1 is the query, verbatim. Not a keyword variant, not a clever title.
   If someone typed "i cant find where to deposit on axiom", the H1 is as
   close to that string as English allows.                                   */
h1 {
  font-family: var(--font-display); font-weight: 800;
  font-size: var(--fs-h1); line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  margin: 0 0 var(--s5); text-wrap: balance;
}
h2 {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-h2); line-height: var(--lh-head);
  letter-spacing: var(--track-tight);
  margin: var(--s8) 0 var(--s3); text-wrap: balance;
}
h3 {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--fs-h3); line-height: var(--lh-head);
  letter-spacing: -.014em;
  margin: var(--s6) 0 var(--s2); text-wrap: balance;
}
h2 + h3 { margin-top: var(--s4); }

p { margin: 0 0 var(--s4); }
ul, ol { margin: 0 0 var(--s4); padding-left: 1.3em; }
li { margin-bottom: var(--s2); }
li::marker { color: var(--muted); }
strong { font-weight: 700; color: var(--text); }
hr { border: 0; height: 1px; background: var(--line); margin: var(--s7) 0; }

a { color: var(--text); text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 3px; text-decoration-thickness: 1px; transition: text-decoration-color var(--dur) var(--ease); }
a:hover { text-decoration-color: var(--accent); }

/* Inline code is mono because it is copyable. That is the whole rule. */
code {
  font-family: var(--font-mono); font-size: .855em;
  background: var(--surface); border: 1px solid var(--line-soft);
  padding: .1em .36em; border-radius: 3px; word-break: break-word;
}
pre {
  font-family: var(--font-mono); font-size: var(--fs-sm); line-height: 1.6;
  background: var(--surface); border: var(--border); border-radius: var(--r);
  padding: var(--s4) var(--s5); overflow-x: auto; margin: 0 0 var(--s5);
  color: var(--text-2);
}
pre code { background: none; border: 0; padding: 0; font-size: inherit; }

/* ── ANSWER ────────────────────────────────────────────────────────────────
   The single highest-value element on the site. It is what a featured
   snippet lifts, what an AI answer paraphrases, and what a reader with
   funds stuck reads before deciding whether to stay.

   Rules: 40-60 words, answer in sentence one, the number in mono, no
   preamble. Set LARGER than body so it reads as the answer and not as an
   intro paragraph.                                                          */
.answer {
  font-size: var(--fs-lg); line-height: 1.52; color: var(--text);
  border-left: 2px solid var(--accent);
  background: var(--accent-wash);
  padding: var(--s5) var(--s5) var(--s4);
  border-radius: 0 var(--r) var(--r) 0;
  margin: 0 0 var(--s6);
}
.answer > :last-child { margin-bottom: 0; }
.answer strong { color: var(--text); }
.answer .num { font-family: var(--font-mono); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ── HERO NUMBER ───────────────────────────────────────────────────────────
   One per page, maximum. The frame people screenshot.                       */
.hero-num {
  font-family: var(--font-mono); font-weight: 700;
  font-size: var(--fs-hero); line-height: .9; letter-spacing: -.045em;
  color: var(--accent); font-variant-numeric: tabular-nums;
  margin: var(--s5) 0 var(--s2);
}
.hero-num + .hero-cap { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--muted); margin-bottom: var(--s6); }

/* ── TABLE ─────────────────────────────────────────────────────────────────
   Numerals are mono and tabular so columns align on the decimal. A fee
   table where the digits do not line up is unreadable and reads as amateur
   to people who stare at order books all day.                              */
.tw { overflow-x: auto; margin: 0 0 var(--s5); border: var(--border); border-radius: var(--r); background: var(--surface); }
table { border-collapse: collapse; width: 100%; font-size: var(--fs-md); min-width: 460px; }
th {
  text-align: left; font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--muted); font-weight: 500; white-space: nowrap;
  padding: var(--s3) var(--s4); border-bottom: var(--border); background: var(--surface-2);
}
td { padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line-soft); color: var(--text-2); vertical-align: top; }
tbody tr:last-child td { border-bottom: 0; }
td:first-child { color: var(--text); font-weight: 500; }
/* any cell that is a number gets mono + tabular, automatically at build time */
td.num, th.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text); }
tr.is-best td { background: var(--accent-wash); }
tr.is-best td:first-child { box-shadow: inset 2px 0 0 var(--accent); }

/* ── STEP ──────────────────────────────────────────────────────────────────
   Numbered, with room for the capture. One action per step, exact settings
   in mono. The number is a real ordinal - steps are a sequence, so the
   numbering carries information.                                            */
.steps { list-style: none; padding: 0; margin: 0 0 var(--s6); counter-reset: step; }
.step { counter-increment: step; display: grid; grid-template-columns: 30px minmax(0,1fr); gap: var(--s4); margin-bottom: var(--s5); }
.step::before {
  content: counter(step);
  font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: 700;
  color: var(--accent-ink); background: var(--accent-solid);
  width: 26px; height: 26px; border-radius: var(--r);
  display: grid; place-items: center; margin-top: 2px;
}
.step > div > :last-child { margin-bottom: 0; }
.step .setting { font-family: var(--font-mono); color: var(--text); background: var(--surface); border: 1px solid var(--line); padding: .1em .4em; border-radius: 3px; }

/* ── FIGURE ────────────────────────────────────────────────────────────────
   MP4 loop, not GIF. Everything except a README embed takes video and looks
   better for it at a fifteenth of the bytes.

   aspect-ratio from the width/height attributes reserves the box BEFORE the
   file arrives. Without it the page reflows when each clip loads, which on a
   phone means the paragraph you were reading jumps off screen - the single
   most common way a media-heavy guide feels broken.                          */
.fig { margin: 0 0 var(--s5); }
.fig video, .fig img {
  width: 100%; height: auto; display: block;
  aspect-ratio: attr(width type(<number>), 16) / attr(height type(<number>), 9);
  border: var(--border); border-radius: var(--r); background: var(--surface);
}
/* attr() with a type is not everywhere yet; this is the floor that always
   applies, and the rule above sharpens it where supported. */
@supports not (aspect-ratio: attr(width type(<number>), 16) / 9) {
  .fig video, .fig img { aspect-ratio: 16 / 9; }
}
.fig video[controls] { aspect-ratio: auto; }
.fig figcaption, .editorial-art figcaption { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted); margin-top: var(--s2); letter-spacing: .02em; max-width: var(--measure); }

/* Nothing overflows its container, ever. This is the backstop, not the plan -
   the plan is that every wide thing has its own scroll container.            */
img, video, svg, canvas, iframe { max-width: 100%; }

/* ── CALLOUT ───────────────────────────────────────────────────────────────
   Three, and only three. note / warn / error. A fourth would dilute all of
   them.                                                                     */
.note { border: var(--border); border-left: 2px solid var(--accent); background: var(--surface); padding: var(--s4) var(--s5); border-radius: 0 var(--r) var(--r) 0; margin: 0 0 var(--s5); }
.note--warn  { border-left-color: var(--caution); background: var(--caution-wash); }
.note--error { border-left-color: var(--alert);  background: var(--alert-wash); }
.note > :last-child { margin-bottom: 0; }
.note__label { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted); display: block; margin-bottom: var(--s2); }

/* The error string itself, rendered as the error. Its own component because
   it is an entire page type and it is the highest-intent moment we get. */
.errstr {
  font-family: var(--font-mono); font-size: var(--fs-md);
  color: var(--alert); background: var(--alert-wash);
  border: 1px solid color-mix(in srgb, var(--alert) 28%, transparent);
  border-radius: var(--r); padding: var(--s3) var(--s4);
  margin: 0 0 var(--s5); overflow-x: auto; white-space: pre;
}

/* ── CTA ───────────────────────────────────────────────────────────────────
   One per page, after the resolution, never before. The code sits beside
   the button in plain text so the reader can read it, check it against the
   clipboard and type it on any venue that shows a code field, without
   having to trust the button.

   The button is the only solid-accent surface on the page. That is what
   makes it the obvious next action without any of the usual tricks.        */
.cta { border: var(--border); background: var(--surface); border-radius: var(--r); padding: var(--s5); margin: var(--s7) 0 var(--s5); display: grid; gap: var(--s4); }
.cta__row { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }
.cta__btn {
  font-family: var(--font-mono); font-weight: 700; font-size: var(--fs-md);
  letter-spacing: .01em; text-decoration: none;
  background: var(--accent-solid); color: var(--accent-solid-ink);
  padding: var(--s3) var(--s5); border-radius: var(--r);
  display: inline-flex; align-items: center; gap: var(--s2);
  transition: transform var(--dur) var(--ease), filter var(--dur) var(--ease);
}
.cta__btn:hover { filter: brightness(1.06); transform: translateY(-1px); }
.cta__code {
  font-family: var(--font-mono); font-size: var(--fs-md);
  border: 1px dashed var(--line); border-radius: var(--r);
  padding: var(--s3) var(--s4); color: var(--text);
  display: inline-flex; align-items: center; gap: var(--s3);
}
.cta__code b { color: var(--accent); letter-spacing: .08em; }
.cta__copy { font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: var(--track-label); background: none; border: 0; color: var(--muted); cursor: pointer; padding: 0; }
.cta__copy:hover { color: var(--accent); }
.cta__note { font-size: var(--fs-sm); color: var(--muted); margin: 0; }
.cta__note b { font-family: var(--font-mono); color: var(--text); letter-spacing: .06em; }
/* Pressing the button copies the code before it navigates, because the code is
   what attaches and the reader is about to be in another app. The tick is the
   only confirmation there is room for on the way out. */
.cta__btn::after { content: ""; }
.cta__btn.is-copied::after { content: " \2713"; }

/* ── SOURCES ───────────────────────────────────────────────────────────────
   "How we know." This block is the moat rendered as UI: a competitor can
   copy the prose in an afternoon and cannot copy a maintained claim ledger.
   So it gets designed, not hidden in a footer.                             */
.sources { border-top: var(--border); margin-top: var(--s8); padding-top: var(--s5); }
.sources__h { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted); margin: 0 0 var(--s4); }
.sources ol { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s3); }
.sources li { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: var(--s3); align-items: baseline; font-size: var(--fs-sm); color: var(--text-2); margin: 0; padding-bottom: var(--s3); border-bottom: 1px solid var(--line-soft); }
.sources li:last-child { border-bottom: 0; }
.sources .val { font-family: var(--font-mono); color: var(--text); font-weight: 500; }
.sources .when { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }

/* ── CHIPS ─────────────────────────────────────────────────────────────────
   Pill shape here is deliberate and is the only place it appears: the shape
   itself encodes "status", distinct from every rectangular element.        */
.chip { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 500; letter-spacing: var(--track-label); text-transform: uppercase; padding: 3px 10px; border-radius: var(--r-pill); border: 1px solid; }
.chip::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.chip--fresh { color: var(--good);    border-color: color-mix(in srgb, var(--good) 32%, transparent); }
.chip--stale { color: var(--caution); border-color: color-mix(in srgb, var(--caution) 32%, transparent); }
.chip--dead  { color: var(--alert);   border-color: color-mix(in srgb, var(--alert) 32%, transparent); }

/* ── HUB GRID ──────────────────────────────────────────────────────────────
   The platform hubs. Entity architecture made navigable: to be the answer
   for "axiom deposit", we have to be an authority on "axiom", which means
   covering the whole entity surface and linking it together.               */
.hubs { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1px; background: var(--line); border: var(--border); border-radius: var(--r); overflow: hidden; margin: 0 0 var(--s6); }
.hub { background: var(--surface); padding: var(--s5); text-decoration: none; display: grid; gap: var(--s2); transition: background var(--dur) var(--ease); }
.hub:hover { background: var(--surface-2); }
.hub__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h3); color: var(--text); letter-spacing: -.02em; }
.hub__fee { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--accent); font-variant-numeric: tabular-nums; }
.hub__n { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted); letter-spacing: .04em; }
/* Nothing built yet. The box stays, so the slot reads as a venue picker with
   nothing in it and not as a page with a hole in it. */
.hubs--empty > p { margin: 0; padding: var(--s5); background: var(--surface); color: var(--text-2); }

/* ── FAQ ───────────────────────────────────────────────────────────────────
   Question-shaped headings matching real queries, answered in 40-60 words.
   This block is disproportionately what AI answers lift.                   */
.faq { display: grid; gap: var(--s5); margin: 0 0 var(--s6); }
.faq__q { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h3); letter-spacing: -.014em; margin: 0 0 var(--s2); }
.faq__a { margin: 0; color: var(--text-2); }

/* ── FOOTER ────────────────────────────────────────────────────────────────
   Small, mono, honest. The disclosure lives here AND inline at the CTA.    */
.foot { border-top: var(--border); margin-top: var(--s9); padding: var(--s5) var(--s5) var(--s8); font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--muted); }
.foot__in { max-width: 780px; margin: 0 auto; display: grid; gap: var(--s4); }
.foot a { color: var(--muted); }
.foot a:hover { color: var(--text); }
.foot__links { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); }
.foot__links a { display: inline-flex; align-items: center; min-height: 44px; }
.foot__disc { max-width: var(--measure); line-height: 1.55; }

/* ── ROUTE LINE ────────────────────────────────────────────────────────────
   The signature motif. Same colour, same weight, same easing, every asset -
   site, card, video. One motif used consistently is how a reader recognises
   us at 0.4 seconds in a feed; five effects used once is how nobody does.  */
.route { display: block; width: 100%; height: auto; opacity: .13; margin: var(--s6) 0; }
.route path { stroke: var(--accent); stroke-width: 2; fill: none; stroke-linecap: round; }

/* ── SKIP ──────────────────────────────────────────────────────────────── */
.skip { position: absolute; left: -9999px; }
.skip:focus { left: var(--s4); top: var(--s2); z-index: 100; background: var(--accent-solid); color: var(--accent-solid-ink); padding: var(--s2) var(--s4); border-radius: var(--r); font-family: var(--font-mono); font-size: var(--fs-sm); min-height: 44px; display: inline-flex; align-items: center; }


/* ══════════════════════════════════════════════════════════════════════════
   MOBILE
   Not a separate stylesheet and not an afterthought - this audience reads on
   a phone, one-handed, usually while something is going wrong.
   ══════════════════════════════════════════════════════════════════════════ */

/* Long unbroken strings are everywhere in this niche: contract addresses,
   error codes, transaction signatures. Any one of them will push a phone
   layout sideways if it is allowed to. */
p, li, td, th, .answer, .faq__a, .sources li { overflow-wrap: anywhere; }
h1, h2, h3 { overflow-wrap: break-word; }

/* Touch targets. 44px is the floor Apple and Google both publish, and a
   mis-tap on the CTA is a lost referral. */
.cta__btn { min-height: 44px; }
.cta__copy { min-height: 44px; min-width: 56px; display: inline-flex; align-items: center; justify-content: center; }
.foot a { padding: 4px 0; }

@media (max-width: 720px) {
  .nav { padding: 0 var(--s4); gap: var(--s4); }
  .draft-banner { padding-inline: var(--s4); }
  .page { padding: var(--s6) var(--s4) var(--s8); }

  /* Let the hub row bleed to both edges so it reads as a swipeable row of
     tickers rather than a clipped list. */
  .nav__hubs { margin-inline: calc(var(--s2) * -1); padding-inline: var(--s2); }

  /* Tables keep their own scroll container, and get an edge-to-edge bleed so
     the scrollable area is obviously wider than the text column. */
  .tw {
    margin-inline: calc(var(--s4) * -1);
    border-inline: 0; border-radius: 0;
    padding-inline: 0;
  }
  th, td { padding: var(--s3); }

  /* The label column STICKS while the numbers scroll under it.

     Without this, a three-column fee table squeezes the label column to about
     55px and "Base rate, taker both legs" renders one word per line - six rows
     of shredded text with the numbers scrolled off screen. Sticky keeps the
     row label anchored so a value scrolled into view still means something,
     which is the whole point of reading a fee table on a phone. */
  table { min-width: 520px; }
  th:first-child, td:first-child {
    position: sticky; left: 0; z-index: 1;
    min-width: 136px;
    background: var(--surface);
    box-shadow: 1px 0 0 var(--line-soft);
  }
  th:first-child { background: var(--surface-2); }
  tr.is-best td:first-child {
    background: color-mix(in srgb, var(--accent) 8%, var(--surface));
    box-shadow: inset 2px 0 0 var(--accent), 1px 0 0 var(--line-soft);
  }

  /* Sources stack - the date column has nowhere to go at 360px. */
  .sources li { grid-template-columns: minmax(0, 1fr); gap: var(--s1); }
  .sources .when { justify-self: start; }

  .cta { padding: var(--s4); }
  .cta__row { gap: var(--s2); }
  .cta__btn, .cta__code { width: 100%; justify-content: center; }

  .step { grid-template-columns: 26px minmax(0, 1fr); gap: var(--s3); }
  .hubs { grid-template-columns: minmax(0, 1fr); }
  .meta { gap: var(--s1) var(--s3); }
}

@media (max-width: 380px) {
  /* iPhone SE and the small Androids. Nothing may overflow here. */
  .page { padding: var(--s5) var(--s3) var(--s7); }
  .tw { margin-inline: calc(var(--s3) * -1); }
  .nav, .draft-banner { padding-inline: var(--s3); }
  h1 { font-size: 1.72rem; }
}

/* Wide screens: the measure does the work, not a wider column. Long lines are
   harder to read, not more impressive. The page stays 780px and centres. */
@media (min-width: 1600px) {
  .page { padding-top: var(--s8); }
}

/* Landscape phone: the sticky nav eats a third of the viewport. Let it go. */
@media (max-height: 480px) and (orientation: landscape) {
  .nav, .draft-banner { position: static; }
}

/* Print - someone will print an error page while their funds are stuck. */
@media print {
  .nav, .cta__copy { display: none; }
  body { background: #fff; color: #000; }
  .fig video { display: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 10px; }
}

/* ── people also ask ────────────────────────────────────────────────────────
   The reader's next question is another chance for a competitor to win them
   back in search. Answering it here removes that draw. Built on <details> so
   every seeded pair is in the HTML and works with JavaScript off. */
.paa { margin: 56px 0 0; border-top: 1px solid var(--line); padding-top: 28px; }
.paa__h { font-size: var(--fs-h2); letter-spacing: var(--track-tight); margin: 0 0 4px; }
.paa__list { margin-top: 18px; border-top: 1px solid var(--line-soft); }
.paa__q { border-bottom: 1px solid var(--line-soft); }
.paa__q > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 52px; padding: 12px 2px; cursor: pointer; list-style: none;
  font-weight: 500; color: var(--text);
}
.paa__q > summary::-webkit-details-marker { display: none; }
.paa__q > summary::after {
  content: "+"; font-family: var(--font-mono); font-size: 1.1rem;
  color: var(--muted); flex: none;
}
.paa__q[open] > summary::after { content: "\2212"; }
.paa__q > summary:hover { color: var(--accent); }
.paa__q > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.paa__a { padding: 0 2px 18px; color: var(--text-2); max-width: 62ch; }
.paa__a > p { margin: 0; }
.paa__more {
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--accent); text-decoration: none; border-bottom: 1px solid var(--line);
}
.paa__more:hover { border-bottom-color: var(--accent); }

/* The next rail: the last thing on every article, four more questions from the
   same venue, each a page. Question first, the answer's first sentence under it,
   the whole row is the link. "more" only exists with the script running. */
.next { margin: 56px 0 0; border-top: 1px solid var(--line); padding-top: 28px; }
.next__h { font-size: var(--fs-h2); letter-spacing: var(--track-tight); margin: 0 0 18px; }
.next__list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line-soft); counter-reset: next; }
.next__list li { margin: 0; border-bottom: 1px solid var(--line-soft); }
.next__list a {
  display: grid; gap: 4px; min-height: 52px; padding: 14px 2px;
  color: var(--text); text-decoration: none;
}
.next__list a:hover .next__q { color: var(--accent); }
.next__q { font-weight: 500; }
.next__a { font-size: var(--fs-sm); color: var(--text-2); max-width: 62ch; }
.next__more {
  display: inline-flex; align-items: center; min-height: 44px; margin-top: 8px;
  font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--accent); background: none; border: 0;
  border-bottom: 1px solid var(--line); padding: 0; cursor: pointer;
}
.next__more:hover { border-bottom-color: var(--accent); }
.next__more:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* A question opened inside a question. The indent and the rule are the whole
   affordance: the reader has to be able to see at a glance that this branch
   came out of the answer above it, not out of the page. Depth stops at 4, so
   the indent can never walk the text off a 320px screen. */
.paa__a > .paa__list {
  margin: 14px 0 0; border-top: 0;
  border-left: 1px solid var(--line); padding-left: 14px;
}
.paa__a > .paa__list > .paa__q:last-child { border-bottom: 0; }
.paa__a > .paa__list > .paa__q > summary { min-height: 46px; font-size: var(--fs-md); font-weight: 400; }
.paa__up { margin: 18px 0 0; font-family: var(--font-mono); font-size: var(--fs-sm); }
.paa__up a { color: var(--muted); }
.paa__up a:hover { color: var(--text); }

/* ── fee calculator ─────────────────────────────────────────────────────────
   The part of a fees page that cannot be lifted into a search result, because
   the answer depends on a number only the reader has. Server-rendered at a
   default size so it still answers with JavaScript off. */
.calc { margin: 28px 0; border: 1px solid var(--line); background: var(--surface); padding: 20px; }
.calc__in { display: grid; gap: 4px; }
.calc__label, .calc__unit {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted);
}
.calc__field { display: flex; align-items: center; gap: 8px; border-bottom: 1px solid var(--line); }
.calc__field i { font-family: var(--font-mono); color: var(--muted); font-style: normal; }
.calc__field input {
  flex: 1; min-height: 48px; width: 100%; background: none; border: 0; color: var(--text);
  font-family: var(--font-mono); font-size: 1.25rem; font-variant-numeric: tabular-nums;
}
.calc__field input:focus { outline: none; }
.calc__field:focus-within { border-bottom-color: var(--accent); }
.calc__out {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px; margin: 20px 0 0;
}
.calc__out dt {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted);
}
.calc__out dd {
  margin: 4px 0 0; font-family: var(--font-mono); font-size: 1.25rem;
  font-variant-numeric: tabular-nums; color: var(--text);
}
.calc__out .is-good { color: var(--good); }
.calc__out .is-ours { color: var(--caution); }
.calc__note { margin: 18px 0 0; font-size: var(--fs-sm); color: var(--muted); }
@media (max-width: 420px) { .calc__out { grid-template-columns: 1fr; gap: 12px; } }

/* ── page index ─────────────────────────────────────────────────────────────
   The list on a hub, the home page and the error index. One row per page,
   type on the right, because a reader scanning a cluster is looking for a
   shape of answer as often as a subject. */
.idx { list-style: none; margin: 18px 0; padding: 0; border-top: 1px solid var(--line-soft); }
.idx li { border-bottom: 1px solid var(--line-soft); }
.idx a {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 52px; padding: 10px 2px; color: var(--text); text-decoration: none;
}
.idx a:hover { color: var(--accent); }
.idx__t {
  flex: none; font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted);
}
.muted { color: var(--muted); }

/* Detailed editorial compositions below the answer, separate from UI evidence.
   Left-aligned like every other block; the caption is the .fig caption. */
.editorial-art { width: min(100%, var(--measure-art)); margin: var(--s6) 0; }
.editorial-art img { display: block; width: 100%; height: auto; border-radius: var(--r); }
