/* ══════════════════════════════════════════════════════════════════════
   soulbound.tools — hub site

   Same family as the build planner (dark, pixel-game, rarity ramp), but a
   content page rather than an app: bigger type, more air, one column of
   reading rather than four panels of controls.

   Colours, type steps and spacing come from /tokens.css, which is generated
   from shared/tokens.css and loaded first. Nothing in this file may declare
   a palette value — tests/design_tokens_test.py exists to catch it.

   No external fonts, no CDN, no JavaScript.
   ══════════════════════════════════════════════════════════════════════ */

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

body {
  margin: 0;
  color: var(--text);
  font: var(--fs-body)/var(--lh-body) var(--sans);
  -webkit-font-smoothing: antialiased;
  background:
    radial-gradient(1100px 620px at 50% -14%, #1a2030 0%, transparent 68%),
    var(--bg);
  background-attachment: fixed;
}

/* 1px scanline wash at 1.4% — reads as CRT, not as texture */
body::before {
  content: ""; position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background: repeating-linear-gradient(
    0deg, rgba(255,255,255,.014) 0 1px, transparent 1px 3px);
}
body > * { position: relative; z-index: 2; }

::selection { background: color-mix(in srgb, var(--accent) 45%, transparent); }

a { color: var(--accent-2); text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent); }
a:hover { color: #7ee2fb; }

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

h1, h2, h3 { margin: 0; font-weight: 650; line-height: var(--lh-tight); }
p { margin: 0 0 var(--s3); }
code { font-family: var(--mono); font-size: .92em; }

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

.skip {
  position: absolute; left: var(--s4); top: -60px; z-index: 60;
  background: var(--accent); color: var(--accent-ink); font-weight: 700;
  padding: var(--s2) var(--s3); border-radius: var(--radius-sm);
  transition: top .12s ease;
}
.skip:focus { top: var(--s3); color: var(--accent-ink); }

/* ── header ─────────────────────────────────────────────────────────── */

.top {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); flex-wrap: wrap;
  padding: var(--s3) var(--s5);
  background: linear-gradient(180deg, #1a1f2bee, #12151dee);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--line);
}
.top::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: linear-gradient(90deg, transparent,
    color-mix(in srgb, var(--accent) 55%, transparent), transparent);
}

.brand { display: flex; align-items: center; gap: var(--s3); text-decoration: none; color: inherit; }
.brand-text { display: flex; flex-direction: column; }
.brand strong { font-size: var(--fs-h3); letter-spacing: .2px; }
.brand .dot { color: var(--accent); }
.brand .sub {
  font-size: 9px; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--dim); margin-top: 2px; font-weight: 600;
}

/* CSS-drawn pixel mark, 5×5 grid, no asset */
.mark {
  width: 32px; height: 32px; border-radius: 8px; position: relative; flex: none;
  background: linear-gradient(160deg, #1d2331, #12151d);
  border: 1px solid var(--line-2);
  box-shadow: inset 0 0 14px -6px var(--accent);
}
.mark::before {
  content: ""; position: absolute; left: 9px; top: 9px;
  width: 3px; height: 3px; background: var(--accent);
  box-shadow:
     4px 0   0 0 var(--accent),  8px 0   0 0 var(--r4),
     0   4px 0 0 var(--accent),  8px 4px 0 0 var(--accent),
     0   8px 0 0 var(--r3),      4px 8px 0 0 var(--accent),
     8px 8px 0 0 var(--accent);
}

.nav { display: flex; gap: var(--s1); flex-wrap: wrap; }
.nav a {
  font-size: var(--fs-tiny); font-weight: 600; letter-spacing: .9px; text-transform: uppercase;
  color: var(--dim); text-decoration: none;
  padding: var(--s2) var(--s3); border-radius: var(--radius-sm);
}
.nav a:hover { color: var(--text); background: var(--panel-2); }

/* ── shared bits ────────────────────────────────────────────────────── */

main { max-width: var(--wide); margin: 0 auto; padding: 0 var(--s5) var(--s8); }

.btn {
  display: inline-block; font: inherit; font-size: 14px; font-weight: 600;
  color: var(--text); background: var(--panel-2);
  border: 1px solid var(--line-2); text-decoration: none;
  padding: 9px 16px; border-radius: var(--radius-sm); cursor: pointer;
}
.btn:hover { background: #232937; border-color: #414a60; color: var(--text); }
.btn.primary {
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  border-color: color-mix(in srgb, var(--accent) 70%, #000);
  color: var(--accent-ink); font-weight: 700;
  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset, 0 6px 18px -10px var(--accent);
}
.btn.primary:hover { background: linear-gradient(180deg, #6cdcf5, var(--accent-2)); color: var(--accent-ink); }

.cta-row { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; margin: var(--s4) 0; }

.tiny { font-size: var(--fs-tiny); color: var(--dim); margin-bottom: var(--s3); }
.tiny code { color: #b6c3d6; }
.dim { color: var(--dim); }

/* ── hero ───────────────────────────────────────────────────────────────
   Full-width, shorter. It previously capped at 720px inside a 1080px
   container, which read as an unfinished two-column layout. */

.hero { padding: var(--s8) 0 var(--s6); }
.hero-copy { max-width: 54ch; }
.hero h1 {
  font-size: clamp(32px, 5.4vw, var(--fs-h1)); letter-spacing: -.5px;
  margin-bottom: var(--s4);
  background: linear-gradient(180deg, #ffffff, #b9c3d8);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero h1 .accent {
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.lede { font-size: var(--fs-lead); color: #c3cad9; max-width: 62ch; }

/* Stat strip — mono figures, baked from the API's own meta.json */
.facts {
  list-style: none; display: flex; flex-wrap: wrap; gap: var(--s5);
  margin: var(--s6) 0 0; padding: var(--s4) 0 0; border-top: 1px solid var(--line);
  font-size: var(--fs-tiny); color: var(--dim);
}
.facts b {
  display: block; font-family: var(--mono); font-size: var(--fs-body); color: var(--text);
  font-weight: 600; letter-spacing: -.2px;
}

/* ── section blocks ─────────────────────────────────────────────────────
   Eyebrow (the cyan-bar micro-label, the platform's signature) sits ABOVE
   the heading rather than being the heading. Section headings now outrank
   card titles, which was inverted before. */

.block { padding-top: var(--s7); scroll-margin-top: 84px; }
.block-head { border-bottom: 1px solid var(--line); padding-bottom: var(--s4); margin-bottom: var(--s5); }

.eyebrow {
  display: flex; align-items: center; gap: var(--s2);
  font-size: var(--fs-micro); letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--dim); font-weight: 700; margin: 0 0 var(--s2);
}
.eyebrow::before {
  content: ""; flex: none; width: 3px; height: 12px; border-radius: 2px;
  background: var(--accent); box-shadow: 0 0 10px -1px var(--accent);
}

.block h2 { font-size: var(--fs-h2); letter-spacing: -.3px; color: var(--text); }
.block-note { margin: var(--s3) 0 0; font-size: 14px; color: var(--dim); max-width: 68ch; }
.block h3 { font-size: var(--fs-card); color: var(--text); margin: var(--s5) 0 var(--s2); }
.block > p, .two-col p, .card p { max-width: 68ch; }

.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s6); align-items: start; }
/* Grid items default to min-width:auto, so a <pre> of unbreakable curl lines
   widens the track and takes the whole page with it. This is what keeps the
   code blocks scrolling inside themselves instead. */
.two-col > * { min-width: 0; }
.two-col h3:first-child { margin-top: 0; }

/* ── tool cards ─────────────────────────────────────────────────────── */

.toolgrid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--s4);
}

.tool {
  --rar: var(--line-2);
  display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(180deg, #181c25 0%, #14171f 46%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.045), 0 10px 26px -22px #000;
}
.tool[data-r="2"] { --rar: var(--r2); }
.tool[data-r="4"] { --rar: var(--r4); }
.tool[data-r] { border-color: color-mix(in srgb, var(--rar) 40%, var(--line)); }

.shot {
  display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
  border-bottom: 1px solid var(--line); background: #0f1219;
  image-rendering: pixelated;
}

/* A listing with no screenshot gets a slim rarity rule instead of a tall
   empty checkerboard. Three cards each with 170px of blank read as an
   abandoned page. */
.tool-noshot { border-top: 2px solid var(--rar); }

.tool-body { padding: var(--s4); display: flex; flex-direction: column; flex: 1; }
.tool-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2); flex-wrap: wrap; }
.tool h3 { font-size: var(--fs-card); color: var(--rar); letter-spacing: 0; text-transform: none; margin: 0; }
.tool .by { font-size: var(--fs-micro); letter-spacing: .6px; text-transform: uppercase; color: var(--dim); margin: 5px 0 var(--s3); font-weight: 600; }
.tool .desc { font-size: 14px; color: #c3cad9; margin-bottom: var(--s3); }

.pill {
  font-size: 9.5px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; white-space: nowrap;
}
.pill-official { color: var(--r4); border: 1px solid color-mix(in srgb, var(--r4) 40%, transparent); background: color-mix(in srgb, var(--r4) 10%, transparent); }
.pill-example  { color: var(--dim); border: 1px solid var(--line-2); background: #10141c; }

.tags { list-style: none; display: flex; flex-wrap: wrap; gap: 5px; margin: 0 0 var(--s3); padding: 0; }
.tags li {
  font-family: var(--mono); font-size: 10.5px; color: var(--dim);
  border: 1px solid var(--line); background: #10141c;
  padding: 2px 7px; border-radius: 4px;
}

.tool .status {
  font-size: var(--fs-tiny); color: var(--dim); margin: 0 0 var(--s3);
  padding: var(--s2) var(--s3); border-radius: var(--radius-sm);
  border: 1px solid var(--line); border-left: 2px solid var(--rar); background: #10141c;
}

.visit {
  margin-top: auto; font-size: 13px; font-weight: 600; text-decoration: none;
  color: var(--accent-2); display: inline-flex; align-items: center; gap: 4px;
}
.visit .host { font-family: var(--mono); }
.visit-none { color: var(--dim); font-weight: 500; font-style: italic; }
.tool-example { --rar: var(--r0); opacity: .86; }

/* The invitation card that replaced the two fake "example" listings. Three
   cards where two are placeholders reads worse than one card plus an ask. */
.tool-open {
  border-style: dashed; border-color: var(--line-2); background: none;
  box-shadow: none;
}
.tool-open .open-mark {
  font-family: var(--mono); font-size: 26px; line-height: 1; color: var(--accent);
  opacity: .5; margin: 0 0 var(--s3);
}
.tool-open h3 { color: var(--text); font-size: var(--fs-card); margin: 0 0 var(--s2); }
.tool-open .desc { color: var(--dim); }

/* ── next steps list (replaces the duplicated route/limit tables) ────── */

.next-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s3); }
.next-steps li {
  padding: var(--s4); border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(180deg, #181c25 0%, #14171f 46%);
}
.next-steps h3 { margin: 0 0 4px; font-size: var(--fs-card); }
.next-steps h3 a { text-decoration: none; }
.next-steps p { margin: 0; font-size: 13.5px; color: var(--dim); }

/* ── code, lists ────────────────────────────────────────────────────── */

.code {
  margin: 0 0 var(--s3); padding: var(--s3) var(--s4);
  background: #0d1017; border: 1px solid var(--line); border-radius: var(--radius-sm);
  overflow-x: auto; font-family: var(--mono); font-size: var(--fs-code); line-height: 1.65;
  color: #cdd8e8;
}
.code code { font-size: inherit; }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--s4); }
.card {
  padding: var(--s4); border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(180deg, #181c25 0%, #14171f 46%);
}
.card h3 { margin-top: 0; }
.card p { font-size: 13.5px; color: #c3cad9; margin: 0; }

.checklist { list-style: none; margin: 0 0 var(--s4); padding: 0; }
.checklist li {
  position: relative; padding: 4px 0 4px var(--s5); font-size: 14px; color: #c3cad9;
}
.checklist li::before {
  content: ""; position: absolute; left: 4px; top: 12px;
  width: 6px; height: 6px; background: var(--accent); border-radius: 1px;
}

.warn {
  font-size: 13.5px; color: #c3cad9; max-width: 68ch;
  padding: var(--s3) var(--s4); border-radius: var(--radius-sm);
  border: 1px solid var(--line); border-left: 3px solid var(--warn); background: #10141c;
}
.warn b { color: var(--warn); }

/* ── footer ─────────────────────────────────────────────────────────── */

.foot { border-top: 1px solid var(--line); background: #0d1016; padding: var(--s6) 0; }
/* same box as <main>, so the footer text lines up with the page content */
.foot-inner { max-width: var(--wide); margin: 0 auto; padding: 0 var(--s5); }
.foot p { font-size: 13.5px; color: var(--dim); }
.foot b { color: var(--text); }
.foot-links { display: flex; gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s3); font-size: 13px; }

/* ── responsive ─────────────────────────────────────────────────────── */

@media (max-width: 820px) {
  main { padding: 0 var(--s4) var(--s7); }
  .foot-inner { padding: 0 var(--s4); }
  .top { padding: var(--s3) var(--s4); }
  .two-col { grid-template-columns: 1fr; gap: var(--s5); }
  .hero { padding: var(--s6) 0 var(--s5); }
  .facts { gap: var(--s4) var(--s5); }
}

@media (max-width: 560px) {
  body { font-size: 14.5px; }
  .top { flex-direction: column; align-items: flex-start; gap: var(--s2); }
  .nav { margin-left: -8px; }
  .toolgrid { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
