/* =====================================================================
   The Greatest MC Servers — BRAND TOKENS + SHARED PRIMITIVES
   =====================================================================

   THIS FILE IS THE SINGLE SOURCE OF TRUTH for every color, surface,
   border, radius, shadow, space step, type size, and motion timing on
   thegreatestmcservers.com (apex site + player wiki + previews).

   RULES
   -----
   1. No other stylesheet in this project may contain a raw color value
      (hex, rgb(), hsl()). Use var(--token). If a token is missing, add
      it HERE first with a comment naming where it is used.
   2. Per-surface tweaks belong in that surface's stylesheet, but they
      must be composed from these tokens.
   3. This is NOT the AI Plays Games brand file
      (tip-platform/public/static/brand.css). Different brand, different
      palette. Do not merge them.

   LOAD ORDER (enforced): brand.css BEFORE style.css / wiki.css.

   CONTENTS
   --------
   1. Palette (raw)          5. Space + radius + border
   2. Semantic surfaces      6. Shadow + motion
   3. Minecraft chat colors  7. Layout + z-index
   4. Typography             8. Shared primitives
   ===================================================================== */

:root {
  /* -- 1. Palette (raw) ------------------------------------------------
     Raw values live here only. Semantic tokens below point at them, so a
     re-skin is a handful of edits in this block. */
  --p-void: #05080f;          /* deepest night — top of sky gradient */
  --p-night: #070b12;         /* page background */
  --p-deep: #0a1220;          /* mid sky band, panel base */
  --p-slate: #101c2e;         /* raised surface */
  --p-white: #ffffff;
  --p-ink: #f2f4f8;           /* body text */
  --p-muted: #9aa8bc;         /* secondary text */
  --p-sky: #5ec8ff;           /* brand accent — links, focus, CTA */
  --p-sky-deep: #2aa6e8;      /* accent hover / gradient partner */
  --p-sky-ink: #061018;       /* text on top of a solid accent fill */
  --p-glass: 10, 18, 32;      /* rgb triple for translucent panels */
  --p-ink-rgb: 242, 244, 248; /* rgb triple for hairlines on dark */
  --p-sky-rgb: 94, 200, 255;  /* rgb triple for accent washes */
  --p-green-rgb: 85, 255, 85; /* rgb triple for live/ok pulses */
  --p-gold-rgb: 255, 170, 0;  /* rgb triple for warn washes */
  --p-red-rgb: 255, 85, 85;   /* rgb triple for danger washes */
  --p-aqua-rgb: 85, 255, 255; /* rgb triple for the Map nav button wash */
  --p-emerald-rgb: 80, 200, 120; /* nation GDP / bank meter */
  --p-fertility-rgb: 255, 140, 180; /* fertility meter */
  --p-silver-rgb: 206, 216, 230; /* nation stat rank — 2nd place medal */
  --p-bronze-rgb: 205, 133, 63;  /* nation stat rank — 3rd place medal */

  /* Minecraft chat palette — used for tags, states, in-game references. */
  --p-mc-blue: #5555ff;
  --p-mc-red: #ff5555;
  --p-mc-gold: #ffaa00;
  --p-mc-green: #55ff55;
  --p-mc-aqua: #55ffff;
  --p-mc-purple: #aa00aa;

  /* -- 2. Semantic surfaces -------------------------------------------- */
  --bg: var(--p-night);
  --sky-top: var(--p-void);
  --sky-mid: var(--p-deep);
  --sky-glow: rgba(40, 90, 140, 0.35);         /* sky.css radial bloom */

  --surface: rgba(var(--p-glass), 0.72);        /* cards, panels */
  --surface-solid: var(--p-deep);               /* header, drawer */
  --surface-raised: var(--p-slate);             /* hover on cards */
  --surface-sunken: rgba(0, 0, 0, 0.35);        /* inputs, code blocks */
  --surface-hover: rgba(var(--p-sky-rgb), 0.08);
  --surface-active: rgba(var(--p-sky-rgb), 0.16);

  /* Server-directory surfaces — solid, quiet, list-like. */
  --directory-card: rgba(var(--p-glass), 0.94);
  --directory-address: rgba(0, 0, 0, 0.22);
  --directory-art: var(--p-deep);

  --line: rgba(var(--p-ink-rgb), 0.14);         /* default hairline */
  --line-strong: rgba(var(--p-ink-rgb), 0.28);  /* emphasis / hover */
  --line-accent: rgba(var(--p-sky-rgb), 0.45);
  --bevel: rgba(var(--p-ink-rgb), 0.06);        /* top inner highlight */

  --ink: var(--p-ink);
  --ink-bright: var(--p-white);
  --ink-soft: rgba(var(--p-ink-rgb), 0.92);     /* long-form body copy */
  --muted: var(--p-muted);

  --accent: var(--p-sky);
  --accent-deep: var(--p-sky-deep);
  --accent-ink: var(--p-sky-ink);
  --accent-wash: rgba(var(--p-sky-rgb), 0.10);
  --accent-line: rgba(var(--p-sky-rgb), 0.35);

  --ok: var(--p-mc-green);
  --warn: var(--p-mc-gold);
  --danger: var(--p-mc-red);

  /* Status washes / hairlines / readable tints (membership join flow). */
  --ok-line: rgba(var(--p-green-rgb), 0.45);
  --ok-wash: rgba(var(--p-green-rgb), 0.12);
  --ok-ink: #b8ffb8;
  --warn-line: rgba(var(--p-gold-rgb), 0.45);
  --warn-ink: #ffd48a;
  --danger-line: rgba(var(--p-red-rgb), 0.5);
  --danger-ink: #ffb0b0;
  --surface-sunken-soft: rgba(0, 0, 0, 0.28);
  --badge-secret: #c9a227;      /* "preview" badge on the secret join page */

  /* -- 3. Minecraft chat colors (semantic aliases) ---------------------- */
  --tag-earth: var(--p-mc-blue);
  --tag-pvp: var(--p-mc-red);
  --tag-nations: var(--p-mc-gold);
  --tag-fair: var(--p-mc-green);
  --tag-trade: var(--p-mc-aqua);

  /* -- 4. Typography ---------------------------------------------------- */
  --font-display: "Press Start 2P", ui-monospace, monospace;
  --font-ui: "IBM Plex Sans", system-ui, -apple-system, sans-serif;
  --font-mono: ui-monospace, "Cascadia Code", Consolas, monospace;

  /* Display sizes are small on purpose — Press Start 2P runs large. */
  --fs-hero: clamp(1rem, 3.2vw, 1.55rem);
  --fs-display: clamp(0.85rem, 2.4vw, 1.05rem);
  --fs-title: clamp(0.72rem, 2vw, 0.88rem);
  --fs-label: 0.58rem;
  /* Network brand = only Press Start voice on the homepage.
     Server titles use UI type so the wordmark stays the brand. */
  --fs-network: clamp(1.35rem, 3.6vw, 1.85rem);
  --fs-server-title: clamp(1.2rem, 2.2vw, 1.4rem); /* 18–20px UI */
  --fs-join: clamp(0.95rem, 1.8vw, 1.0625rem);

  /* Reading sizes. Floor is 16px (--fs-xs) for anything a visitor must read;
     body sits above it because this is a docs site people scan on phones. */
  --fs-lead: 1.15rem;
  --fs-body: 1.0625rem;   /* 17px */
  --fs-sm: 1rem;          /* 16px — tables, nav, buttons */
  --fs-xs: 0.875rem;      /* 14px — hints, captions (never body) */
  --fs-micro: 0.75rem;    /* 12px — caps labels only, never a sentence */

  --lh-tight: 1.35;
  --lh-body: 1.55;
  --lh-display: 1.5;
  --tracking-caps: 0.12em;

  /* -- 5. Space + radius + border --------------------------------------- */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.25rem;
  --sp-6: 1.5rem;
  --sp-8: 2rem;
  --sp-10: 2.5rem;
  --sp-12: 3rem;
  --sp-16: 4rem;

  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --section-y: clamp(2rem, 5vw, 3.5rem);

  /* Blocky brand: panels are square, only chips/code get a radius. */
  --radius-block: 0;
  --radius-sm: 0.25rem;
  --radius: 0.4rem;
  --radius-pill: 999px;

  --border: 1px solid var(--line);
  --border-strong: 1px solid var(--line-strong);
  --border-accent: 1px solid var(--line-accent);

  /* -- 6. Shadow + motion ------------------------------------------------ */
  --shadow-1: 0 1px 0 var(--bevel) inset, 0 8px 24px rgba(0, 0, 0, 0.28);
  --shadow-2: 0 1px 0 var(--bevel) inset, 0 18px 44px rgba(0, 0, 0, 0.42);
  --glow-accent: 0 0 0 3px rgba(var(--p-sky-rgb), 0.16);
  /* Double halo (tight core + soft bloom) — hero art gets real atmosphere. */
  --glow-globe:
    drop-shadow(0 0 0.6rem rgba(var(--p-sky-rgb), 0.45))
    drop-shadow(0 0 3.25rem rgba(var(--p-sky-rgb), 0.3));
  --ring-live: rgba(var(--p-green-rgb), 0.5);   /* "live now" pulse dot */
  --ring-live-out: rgba(var(--p-green-rgb), 0); /* pulse end state */
  --scrim: rgba(0, 0, 0, 0.55);                 /* mobile drawer backdrop */
  --blur-panel: blur(8px);

  /* Square art with a baked-in night background (the globe render) reads as
     a box on the sky gradient. This mask trims it back to the sphere; the
     globe fills 92.3% of the source frame, so the fade sits just past its
     limb. */
  --mask-orb: radial-gradient(circle at 50% 50%, #000 0 45.5%, transparent 47.5%);

  --dur-fast: 0.15s;
  --dur: 0.22s;
  --dur-slow: 0.55s;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);

  /* -- 7. Layout + z-index ----------------------------------------------- */
  --w-page: 72rem;      /* wiki shell */
  --w-directory: 42rem; /* tight brand column — list reads as one unit */
  --server-icon: 2.75rem;  /* list glyph — subordinate to network wordmark */
  --server-icon-sm: 2.25rem;
  --w-content: 46rem;   /* apex site column */
  --w-nations: 78rem;   /* nations leaderboard + dossier */
  --w-prose: 44rem;     /* wiki reading measure */
  --w-nav: 17rem;       /* wiki sidebar */
  --header-h: 3.5rem;

  /* Minimum hit area for anything tappable (WCAG 2.5.5 AAA / Apple 44pt).
     Every button, nav link, and chip must reach this. */
  --tap: 2.75rem;       /* 44px */
  --status-dot: 0.625rem;
  --status-glow: 0 0 0 0.25rem var(--ok-wash);

  --z-sky: 0;
  --z-content: 1;
  --z-header: 10;
  --z-drawer: 20;
  --z-idea: 40; /* sticky Ideas? FAB — above wiki chrome */

  /* -- 8. Icon sizing ---------------------------------------------------- */
  --icon: 1.25rem;
  --icon-sm: 1rem;
  --icon-lg: 1.5rem;

  /* -- 9. Scrollbars (Firefox + WebKit) ----------------------------------
     Used on wiki nav, TOC, table wraps, and the page itself. Keep thin and
     brand-colored — default OS bars break the dark shell. */
  --scroll-size: 10px;
  --scroll-track: rgba(var(--p-ink-rgb), 0.04);
  --scroll-thumb: rgba(var(--p-sky-rgb), 0.35);
  --scroll-thumb-hover: rgba(var(--p-sky-rgb), 0.65);
}

/* =====================================================================
   8. Shared primitives — used by both the apex site and the wiki.
   ===================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  color-scheme: dark; /* dark native scrollbars where custom ones don't apply */
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) var(--scroll-track);
}

html,
body {
  min-height: 100%;
  margin: 0;
}

/* WebKit / Chromium branded scrollbars site-wide. */
*::-webkit-scrollbar {
  width: var(--scroll-size);
  height: var(--scroll-size);
}

*::-webkit-scrollbar-track {
  background: var(--scroll-track);
}

*::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border: 2px solid transparent;
  background-clip: padding-box;
  border-radius: var(--radius-pill);
}

*::-webkit-scrollbar-thumb:hover {
  background: var(--scroll-thumb-hover);
  border: 2px solid transparent;
  background-clip: padding-box;
}

*::-webkit-scrollbar-corner {
  background: transparent;
}

body {
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: rgba(var(--p-sky-rgb), 0.3);
  color: var(--ink-bright);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* Night sky backdrop — every page sits on it. */
.sky {
  position: fixed;
  inset: 0;
  z-index: var(--z-sky);
  background:
    radial-gradient(ellipse 80% 60% at 80% 0%, var(--sky-glow), transparent 55%),
    linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 50%, var(--bg) 100%);
}

/* ---- Icons (sprite at /assets/icons.svg) ----------------------------- */
.icon {
  width: var(--icon);
  height: var(--icon);
  flex: 0 0 auto;
  color: inherit;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon--sm { width: var(--icon-sm); height: var(--icon-sm); }
.icon--lg { width: var(--icon-lg); height: var(--icon-lg); }

/* ---- Brand lockup ----------------------------------------------------- */
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-display);
  font-weight: 400;
  line-height: var(--lh-display);
  color: var(--ink-bright);
  text-decoration: none;
}

.wordmark__mark {
  width: 28px;
  height: 28px;
  image-rendering: pixelated;
  border: var(--border);
}

.wordmark__text {
  font-size: 0.6rem;
  letter-spacing: 0.02em;
}

/* Network wordmark on the wiki (and any surface that needs the full name).
   Two lines so Press Start stays readable without becoming a long single run. */
.wordmark--network .wordmark__text {
  display: block;
  font-size: clamp(0.42rem, 1.1vw, 0.52rem);
  line-height: 1.45;
}

/* ---- Site header (shared by apex + wiki) ------------------------------ */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  height: var(--header-h);
  padding: 0 var(--gutter);
  border-bottom: 0;
  background: transparent;
  backdrop-filter: none;
}

.site-header__left {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-width: 0;
}

.site-header__nav {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}

.site-header__link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius);
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.site-header__link:hover,
.site-header__link.is-active {
  color: var(--accent);
  background: var(--surface-hover);
}

.site-header__link .icon {
  color: var(--muted);
  transition: color var(--dur-fast) var(--ease);
}

.site-header__link:hover .icon,
.site-header__link.is-active .icon {
  color: var(--accent);
}

/* Narrow screens: shrink the wordmark, never the nav labels. Icon-only nav
   tests badly for new and low-literacy visitors (NN/g icon usability), so the
   words "Servers" and "Map" stay on screen at every width. */
@media (max-width: 680px) {
  .wordmark__text {
    font-size: 0.45rem;
  }

  .wordmark--network .wordmark__text {
    font-size: 0.38rem;
  }

  .site-header__link {
    padding: var(--sp-2);
    font-size: var(--fs-xs);
  }
}

/* Wiki (and any surface with brand + scope chip + nav): two stacked rows so
   the Press Start wordmark is readable and the right side is not a jam.
   Row 1 = brand alone (full width, centered). Row 2 = scope + primary nav
   as one tight centered flex cluster (not split into half-columns). */
@media (max-width: 680px) {
  body.wiki {
    --header-h: 6.25rem;
  }

  body.wiki .site-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2) var(--sp-3);
    height: var(--header-h);
    padding-block: var(--sp-3);
  }

  body.wiki .site-header__left {
    display: contents;
  }

  body.wiki .wordmark {
    flex: 0 0 100%;
    display: flex;
    justify-content: center;
  }

  body.wiki .wordmark--network .wordmark__text {
    font-size: 0.5rem;
    line-height: 1.4;
    text-align: center;
  }

  body.wiki .site-header__scope {
    font-size: var(--fs-xs);
  }

  body.wiki .site-header__nav {
    width: auto;
    justify-content: center;
    gap: var(--sp-1);
  }
}

.site-header__scope {
  flex: 0 0 auto;
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--line-accent);
  border-radius: var(--radius-pill);
  background: var(--surface-active);
  color: var(--accent);
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 700;
  white-space: nowrap;
}

@media (max-width: 420px) {
  .wordmark__text {
    font-size: 0.42rem;
  }

  .wordmark--network .wordmark__text {
    font-size: 0.38rem;
  }

  body.wiki .wordmark--network .wordmark__text {
    font-size: 0.46rem;
  }

  /* Keep "Earth Wiki" visible: kids need the context chip more than a
     long Press Start line at this width. */
  .site-header__scope {
    font-size: 0.7rem;
    padding: 0.2rem 0.55rem;
  }
}

/* ---- Panels ----------------------------------------------------------- */
.panel {
  padding: var(--sp-5);
  border: var(--border);
  border-radius: var(--radius-block);
  background: var(--surface);
  box-shadow: var(--shadow-1);
  backdrop-filter: var(--blur-panel);
}

/* ---- Eyebrow / caps label --------------------------------------------- */
.eyebrow {
  margin: 0;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--muted);
}

/* ---- Buttons ----------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: var(--sp-3) var(--sp-5);
  border: var(--border);
  border-radius: var(--radius-block);
  font: inherit;
  font-weight: 600;
  font-size: var(--fs-sm);
  text-decoration: none;
  cursor: pointer;
  transition:
    background var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}

.btn:active {
  transform: translateY(1px);
}

.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.btn--primary:hover:not(:disabled) {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
}

.btn--secondary {
  background: transparent;
  color: var(--ink);
}

.btn--secondary:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--surface-hover);
}

.btn--ghost {
  padding: var(--sp-2) var(--sp-3);
  border-color: transparent;
  background: transparent;
  color: var(--muted);
}

.btn--ghost:hover:not(:disabled) {
  color: var(--accent);
  background: var(--surface-hover);
}

/* ---- Tags --------------------------------------------------------------
   The Minecraft chat palette shows up on the ICON only. Four differently
   coloured labels in a row reads noisy; one accent per glyph reads branded. */
.tag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--ink-soft);
}

.tag .icon {
  color: var(--tag-color, var(--muted));
}

.tag--earth { --tag-color: var(--tag-earth); }
.tag--pvp { --tag-color: var(--tag-pvp); }
.tag--nations { --tag-color: var(--tag-nations); }
.tag--fair { --tag-color: var(--tag-fair); }
.tag--trade { --tag-color: var(--tag-trade); }

/* ---- Facts strip -------------------------------------------------------
   The screening questions a Minecraft player asks before typing an address:
   edition, whitelist, PvP, money, store. Label + value, no marketing. */
.facts {
  margin: var(--sp-5) 0 0;
  padding: 0;
  list-style: none;
  border: var(--border);
}

.fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-2) var(--sp-4);
  border-top: var(--border);
}

.fact:first-child {
  border-top: 0;
}

/* `display: flex` outranks the hidden attribute, so rows that wait on live
   data (player count) need this or they flash a placeholder. */
.fact[hidden] {
  display: none;
}

.fact__k {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--muted);
}

.fact__v {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--ink-bright);
}

/* ---- Copy-to-clipboard control ---------------------------------------- */
.copy-ip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  max-width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  font: inherit;
}

.copy-ip__text {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  line-height: var(--lh-tight);
  color: var(--ink);
  /* Prefer soft <wbr> breaks (earth. | thegreatestmcservers.com).
     `anywhere` orphaned the trailing "m" on phones — break-word does not. */
  overflow-wrap: break-word;
  word-break: normal;
}

.copy-ip__icon {
  position: relative;
  flex: 0 0 auto;
  width: var(--icon);
  height: var(--icon);
  color: var(--muted);
}

/* Hard display swap (no opacity cross-fade) — the pop keyframe below still
   gives the check a bounce-in, but visibility itself is never ambiguous. */
.copy-ip__clip,
.copy-ip__check,
.copy-ip__warn {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.copy-ip__clip { display: block; }
.copy-ip__check { display: none; color: var(--ok); }
.copy-ip__warn { display: none; color: var(--danger); }

.copy-ip:hover .copy-ip__icon { color: var(--accent); }
.copy-ip.is-copied .copy-ip__clip,
.copy-ip.is-copy-failed .copy-ip__clip { display: none; }

.copy-ip.is-copied .copy-ip__check {
  display: block;
  animation: copy-pop 0.35s var(--ease);
}

.copy-ip.is-copy-failed .copy-ip__warn {
  display: block;
  animation: copy-pop 0.35s var(--ease);
}

@keyframes copy-pop {
  0% { transform: scale(0.55); }
  55% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* ---- Join panel (homepage + Getting started wiki) -------------------- */
.join {
  margin-top: var(--sp-6);
  padding: var(--sp-5);
}

.join .copy-ip--hero {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: var(--tap);
  margin-top: var(--sp-2);
}

.join .copy-ip--hero .copy-ip__text {
  flex: 1 1 auto;
  min-width: 0;
  font-size: clamp(0.95rem, 2.6vw, 1.2rem);
  font-weight: 600;
  color: var(--accent);
}

.join .copy-ip--hero .copy-ip__icon {
  flex: 0 0 auto;
  width: var(--tap);
  height: var(--tap);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
}

.join .copy-ip--hero:hover .copy-ip__text {
  color: var(--ink-bright);
}

.join .copy-ip--hero:hover .copy-ip__icon {
  color: var(--ink-bright);
}

.join .copy-ip--hero.is-copied .copy-ip__icon {
  color: var(--ok);
}

@media (max-width: 560px) {
  .join .copy-ip--hero .copy-ip__text {
    font-size: 1rem;
    line-height: 1.4;
  }
}

.join__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
  padding-top: var(--sp-5);
  border-top: var(--border);
}

/* ---- Footer ------------------------------------------------------------ */
.site-footer {
  position: relative;
  z-index: var(--z-content);
  border-top: var(--border);
  padding: var(--sp-8) var(--gutter);
  color: var(--muted);
  font-size: var(--fs-xs);
}

.site-footer__inner {
  max-width: var(--w-page);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
}

.site-footer a {
  color: var(--muted);
  text-decoration: none;
}

.site-footer a:hover {
  color: var(--accent);
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
}

/* ---- Motion ------------------------------------------------------------ */
@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.rise {
  animation: rise var(--dur-slow) var(--ease) both;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Screen-reader only */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Skip link */
.skip-link {
  position: absolute;
  left: var(--sp-4);
  top: calc(var(--sp-2) * -6);
  z-index: var(--z-drawer);
  padding: var(--sp-2) var(--sp-4);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  text-decoration: none;
  transition: top var(--dur) var(--ease);
}

.skip-link:focus {
  top: var(--sp-2);
}

/* ---- Ideas? FAB (homepage + wiki) --------------------------------------
   Tiny fixed control, bottom-left. Slides a one-line input out to the right. */
.idea-box {
  position: fixed;
  left: var(--sp-2);
  bottom: var(--sp-2);
  z-index: var(--z-idea);
  display: flex;
  align-items: center;
  gap: 0;
  max-width: calc(100vw - var(--sp-4));
  pointer-events: none;
}

.idea-box__fab,
.idea-box__panel,
.idea-box__form,
.idea-box__send {
  pointer-events: auto;
}

.idea-box__fab {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  flex-shrink: 0;
  height: 1.35rem;
  padding: 0 0.35rem 0 0.28rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: rgba(var(--p-glass), 0.78);
  backdrop-filter: var(--blur-panel);
  color: var(--muted);
  font-family: var(--font-ui);
  font-size: 0.625rem; /* 10px — intentionally tiny */
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.01em;
  cursor: pointer;
  opacity: 0.72;
  transition:
    opacity var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    background var(--dur-fast) var(--ease);
}

.idea-box__fab:hover,
.idea-box.is-open .idea-box__fab {
  opacity: 1;
  color: var(--accent);
  border-color: var(--line-accent);
  background: var(--surface-solid);
}

.idea-box__icon {
  width: 0.7rem;
  height: 0.7rem;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

.idea-box__label {
  white-space: nowrap;
}

.idea-box__panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  margin-left: 0;
  opacity: 0;
  transform: translateX(-0.4rem);
  transition:
    opacity var(--dur-fast) var(--ease),
    transform var(--dur) var(--ease),
    margin-left var(--dur) var(--ease);
}

.idea-box__panel[hidden] {
  display: none !important;
}

.idea-box.is-shown .idea-box__panel {
  margin-left: var(--sp-1);
  opacity: 1;
  transform: translateX(0);
}

.idea-box__form {
  display: flex;
  align-items: center;
  gap: 0;
  height: 1.35rem;
  border: 1px solid var(--line-accent);
  border-radius: var(--radius-sm);
  background: var(--surface-solid);
  overflow: hidden;
}

.idea-box__input {
  width: 12.5rem;
  min-width: 0;
  height: 100%;
  padding: 0 0.4rem;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 0.6875rem; /* 11px */
  outline: none;
}

.idea-box__input::placeholder {
  color: var(--muted);
  opacity: 0.85;
}

.idea-box__send {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 100%;
  flex-shrink: 0;
  border: 0;
  border-left: 1px solid var(--line);
  background: var(--accent-wash);
  color: var(--accent);
  cursor: pointer;
}

.idea-box__send:hover:not(:disabled) {
  background: var(--surface-active);
}

.idea-box__send:disabled {
  opacity: 0.5;
  cursor: wait;
}

.idea-box__status {
  margin: 0.15rem 0 0;
  padding: 0 0.25rem;
  font-family: var(--font-ui);
  font-size: 0.625rem;
  color: var(--muted);
  white-space: nowrap;
}

.idea-box__status[data-kind="ok"] {
  color: var(--ok-ink);
}

.idea-box__status[data-kind="err"] {
  color: var(--danger-ink);
}

.idea-box__sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 420px) {
  .idea-box__input {
    width: min(10.5rem, calc(100vw - 6.5rem));
  }
}

