/* ==========================================================================
   Turtles Wow — theme
   Dark charcoal grounds, a warm gold-to-amber accent ramp, deep navy for the
   secondary strip. Condensed all-caps display type, clean sans body.
   Every colour below comes from the token block; nothing is hard-coded further
   down except pure black/white shadows.
   ========================================================================== */

:root {
  /* grounds */
  --ink-900: #1a1a1a;   /* base ground */
  --ink-850: #232323;   /* card on base ground */
  --ink-800: #2d2d2d;   /* alternating ground */
  --ink-750: #363636;   /* card on alternating ground */
  --navy-700: #1e3a5f;  /* secondary UI band */
  --navy-800: #16293f;  /* navy shade */

  /* accent ramp */
  --gold-400: #d4a574;  /* 7.8:1 on --ink-900, 6.2:1 on --ink-800 */
  --amber-400: #e8b76f; /* 9.5:1 on --ink-900 */
  --gold-600: #b98a58;  /* pressed / borders */

  /* text */
  --text: #e0e0e0;
  --text-dim: #a8a8a8;
  --text-on-gold: #1a1a1a;

  /* lines */
  --rule: #4a4a4a;
  --rule-soft: #3a3a3a;

  /* status */
  --status-online: #8fbf6a;
  --status-testing: #e8b76f;
  --status-offline: #8a8a8a;

  /* type */
  --font-display: "Oswald", "Arial Narrow", "Helvetica Neue", sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;

  /* metrics */
  --header-h: 72px;
  --container: 1160px;
  --gutter: 24px;
  --radius: 10px;
  --radius-sm: 8px;

  --shadow-card: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-lift: 0 8px 22px rgba(0, 0, 0, .45);
  --ease: cubic-bezier(.2, .7, .3, 1);
}

/* ------------------------------------------------------------------ base -- */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
  margin: 0;
  background: var(--ink-900);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; }

h1, h2, h3 {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: .005em;
  line-height: 1.05;
  margin: 0;
}

p { margin: 0; }

ul, ol, dl, dd { margin: 0; padding: 0; }
ul, ol { list-style: none; }

a { color: var(--gold-400); text-decoration: none; }
a:hover { color: var(--amber-400); }

code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: .9em;
  color: var(--gold-400);
}

:focus-visible {
  outline: 2px solid var(--amber-400);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip-link {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 200;
  padding: 12px 20px;
  background: var(--amber-400);
  color: var(--text-on-gold);
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: .08em;
  border-radius: var(--radius-sm);
}
.skip-link:focus { top: 12px; color: var(--text-on-gold); }

/* Text that only the screen reader gets. Used to give each class disclosure a
   unique accessible name without repeating the class name on screen. */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ------------------------------------------------------------- buttons -- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px 40px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .09em;
  line-height: 1;
  cursor: pointer;
  transition: background-color .18s var(--ease), border-color .18s var(--ease),
              color .18s var(--ease), transform .12s var(--ease),
              box-shadow .18s var(--ease);
}

.btn--gold {
  background-image: linear-gradient(180deg, var(--amber-400) 0%, var(--gold-400) 100%);
  color: var(--text-on-gold);
  box-shadow: var(--shadow-card);
}
.btn--gold:hover {
  background-image: linear-gradient(180deg, #f0c884 0%, #dfb180 100%);
  color: var(--text-on-gold);
  transform: translateY(-1px);
  box-shadow: var(--shadow-lift);
}
.btn--gold:active {
  background-image: linear-gradient(180deg, var(--gold-600) 0%, var(--gold-400) 100%);
  transform: translateY(0);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .3);
}

.btn--ghost {
  background-color: transparent;
  border-color: var(--rule);
  color: var(--text);
}
.btn--ghost:hover {
  border-color: var(--gold-400);
  color: var(--gold-400);
  transform: translateY(-1px);
}
.btn--ghost:active { transform: translateY(0); border-color: var(--gold-600); }

.btn--lg { padding: 19px 48px; font-size: 17px; }
.btn--sm { padding: 11px 22px; font-size: 13px; letter-spacing: .07em; }

/* -------------------------------------------------------------- header -- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background-color: rgba(26, 26, 26, .93);
  border-bottom: 1px solid var(--rule-soft);
  backdrop-filter: blur(10px);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: 24px;
  min-height: var(--header-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  color: var(--text);
  flex: 0 0 auto;
}
.brand:hover { color: var(--text); }

/* Mascot mark. It is a raster PNG/WebP, so size by height and let width follow
   the art's own aspect -- the source is 1292x1199 after transparent-edge trim. */
.brand__mark {
  height: 34px;
  width: auto;
  flex: 0 0 auto;
  display: block;
  transition: transform .18s var(--ease);
}

.brand:hover .brand__mark { transform: translateY(-1px) scale(1.04); }

.brand__word {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 21px;
  text-transform: uppercase;
  letter-spacing: .04em;
  white-space: nowrap;
}

.site-nav {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: 24px;
}

.site-nav__list {
  display: flex;
  flex: 1 1 auto;
  justify-content: center;
  gap: 6px;
}

.site-nav__list a {
  display: block;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .1em;
  transition: color .16s var(--ease), background-color .16s var(--ease);
}
.site-nav__list a:hover { color: var(--gold-400); background-color: var(--ink-800); }

.site-nav__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

.nav-toggle {
  display: none;
  align-items: center;
  gap: 9px;
  margin-left: auto;
  padding: 9px 14px;
  background-color: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .1em;
  cursor: pointer;
}
.nav-toggle:hover { border-color: var(--gold-400); color: var(--gold-400); }

.nav-toggle__bars { display: block; width: 16px; }
.nav-toggle__bars i {
  display: block;
  height: 2px;
  background-color: currentColor;
  border-radius: 1px;
}
.nav-toggle__bars i + i { margin-top: 3px; }

/* ---------------------------------------------------------------- hero -- */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(64px, 12vw, 132px) clamp(72px, 12vw, 140px);
  border-bottom: 1px solid var(--rule-soft);
}

/* Hero backdrop: the painted tavern.
   Three stacked layers, top to bottom in paint order:
     1. a centre vignette -- the source art is brightest exactly where the
        headline and mascot sit, so this buys back the contrast
     2. a bottom-weighted scrim so the CTA row and the status pill stay legible
     3. the painting itself, WebP with a JPEG fallback, sized per viewport
   The 24x14 LQIP sits underneath as background-color's replacement so there is
   never a flat black frame while the real image streams in. */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: -2;
  background-color: #171525;
  background-image:
    radial-gradient(78% 62% at 50% 44%, rgba(10, 9, 18, .74) 0%, rgba(10, 9, 18, .42) 46%, rgba(10, 9, 18, 0) 78%),
    linear-gradient(to bottom, rgba(14, 12, 24, .58) 0%, rgba(14, 12, 24, .22) 34%, rgba(14, 12, 24, .52) 72%, rgba(20, 20, 20, .93) 100%),
    image-set(url("assets/hero-scene-1920.webp") type("image/webp"),
              url("assets/hero-scene-1920.jpg") type("image/jpeg"));
  background-size: cover, cover, cover;
  background-position: center center;
  background-repeat: no-repeat;
}

@media (max-width: 1300px) {
  .hero__bg {
    background-image:
      radial-gradient(78% 62% at 50% 44%, rgba(10, 9, 18, .74) 0%, rgba(10, 9, 18, .42) 46%, rgba(10, 9, 18, 0) 78%),
      linear-gradient(to bottom, rgba(14, 12, 24, .58) 0%, rgba(14, 12, 24, .22) 34%, rgba(14, 12, 24, .52) 72%, rgba(20, 20, 20, .93) 100%),
      image-set(url("assets/hero-scene-1280.webp") type("image/webp"),
                url("assets/hero-scene-1280.jpg") type("image/jpeg"));
  }
}

@media (min-width: 1921px) {
  .hero__bg {
    background-image:
      radial-gradient(78% 62% at 50% 44%, rgba(10, 9, 18, .74) 0%, rgba(10, 9, 18, .42) 46%, rgba(10, 9, 18, 0) 78%),
      linear-gradient(to bottom, rgba(14, 12, 24, .58) 0%, rgba(14, 12, 24, .22) 34%, rgba(14, 12, 24, .52) 72%, rgba(20, 20, 20, .93) 100%),
      image-set(url("assets/hero-scene-2560.webp") type("image/webp"),
                url("assets/hero-scene-2560.jpg") type("image/jpeg"));
  }
}

/* Ambient motion -------------------------------------------------------- */

/* Very slow drift on the backdrop. Scaled up first so the pan never exposes
   an edge. 70s round trip -- meant to be felt, not watched. */
.hero__bg {
  will-change: transform;
  animation: hero-drift 70s ease-in-out infinite alternate;
}

@keyframes hero-drift {
  from { transform: scale(1.06) translate3d(-1.1%, 0.6%, 0); }
  to   { transform: scale(1.11) translate3d(1.1%, -0.9%, 0); }
}

/* Firelight. Two warm pools sitting roughly over the lanterns on each side of
   the painting, breathing at different rates and slightly out of phase so it
   never reads as a single global pulse. This is what sells "lit by flame". */
.hero__flicker {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  mix-blend-mode: screen;
  background:
    radial-gradient(20% 26% at 13% 26%, rgba(255, 176, 78, .30) 0%, rgba(255, 176, 78, 0) 70%),
    radial-gradient(16% 22% at 76% 28%, rgba(255, 168, 74, .26) 0%, rgba(255, 168, 74, 0) 70%),
    radial-gradient(12% 18% at 51% 14%, rgba(255, 198, 120, .22) 0%, rgba(255, 198, 120, 0) 72%);
  animation: flicker-a 5.5s ease-in-out infinite;
}

.hero__flicker::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(14% 20% at 92% 47%, rgba(255, 186, 96, .26) 0%, rgba(255, 186, 96, 0) 72%),
    radial-gradient(11% 15% at 31% 52%, rgba(255, 178, 88, .20) 0%, rgba(255, 178, 88, 0) 74%);
  animation: flicker-b 3.7s ease-in-out infinite;
}

@keyframes flicker-a {
  0%, 100% { opacity: .82; }
  22%      { opacity: 1; }
  41%      { opacity: .74; }
  63%      { opacity: .95; }
  81%      { opacity: .8; }
}

@keyframes flicker-b {
  0%, 100% { opacity: .7; }
  30%      { opacity: 1; }
  55%      { opacity: .66; }
  78%      { opacity: .9; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__flicker,
  .hero__flicker::after { animation: none; }
}

/* A soft shaft of light sweeping the scene. Sits above the backdrop but under
   every layer that carries text. */
.hero::before {
  content: "";
  position: absolute;
  inset: -20% -35%;
  z-index: -2;
  pointer-events: none;
  background: linear-gradient(74deg,
              transparent 34%,
              rgba(232, 183, 111, .085) 46%,
              rgba(232, 183, 111, .16) 50%,
              rgba(232, 183, 111, .085) 54%,
              transparent 66%);
  animation: hero-shaft 26s ease-in-out infinite alternate;
}

@keyframes hero-shaft {
  from { transform: translate3d(-16%, 0, 0); opacity: .55; }
  to   { transform: translate3d(16%, 0, 0);  opacity: 1; }
}

/* Looping video backdrop, injected by hero-motion.js only after it is playing.
   Sits under everything; the gradient stays behind it as the fallback. */
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -3;
  opacity: 0;
  transition: opacity .9s var(--ease);
  pointer-events: none;
}

.hero--video .hero__video { opacity: 1; }

/* With video running, dim the gradient's own art and calm the overlays so the
   footage reads clearly and the text keeps its contrast. */
.hero--video .hero__bg {
  background-image:
    linear-gradient(to bottom, rgba(20, 20, 20, .58) 0%, rgba(20, 20, 20, .28) 45%, rgba(20, 20, 20, .86) 100%);
  animation: none;
}

.hero--video .hero__grain { opacity: .035; }
.hero--video::before { opacity: .45; }

/* Drifting motes canvas, injected by hero-motion.js */
.hero__motes {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* When a painted scene is supplied, the grain and shaft back off so the art
   is not muddied. */
.hero--scene .hero__grain { opacity: .035; }
.hero--scene::before { opacity: .6; }

@media (prefers-reduced-motion: reduce) {
  .hero__bg,
  .hero::before { animation: none; }
  .hero__motes { display: none; }
}

.hero--still .hero__motes { display: none; }

.hero__grain {
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Kept low over real painted art -- grain that reads well on a flat gradient
     just muddies a painting. */
  opacity: .028;
  pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
}

.hero__inner { text-align: center; }

.lockup { margin-bottom: clamp(28px, 5vw, 44px); }

/* Hero mascot: the page's visual anchor, so it gets real size.
   A warm ground-glow sits behind it so the cartoon art reads against the
   near-black hero without a hard cut-out edge. */
.lockup__mascot {
  width: clamp(132px, 14vw, 200px);
  height: auto;
  margin: 0 auto;
  display: block;
  filter: drop-shadow(0 18px 34px rgba(0, 0, 0, .55));
  animation: mascot-settle .7s var(--ease) both;
}

.lockup { position: relative; }

.lockup::before {
  content: "";
  position: absolute;
  left: 50%;
  top: clamp(86px, 9.2vw, 132px);
  width: clamp(170px, 18vw, 260px);
  height: clamp(44px, 5vw, 68px);
  transform: translateX(-50%);
  background: radial-gradient(ellipse at center,
              rgba(212, 165, 116, .26) 0%,
              rgba(212, 165, 116, .08) 45%,
              transparent 72%);
  pointer-events: none;
  z-index: -1;
}

@keyframes mascot-settle {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .lockup__mascot { animation: none; }
}

.lockup__word {
  margin-top: 12px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(28px, 5.5vw, 44px);
  text-transform: uppercase;
  letter-spacing: .14em;
  line-height: 1.1;
}

.lockup__sub {
  margin-top: 6px;
  color: var(--text-dim);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .26em;
}

.hero__thesis {
  font-size: clamp(2.35rem, 8.4vw, 5.4rem);
  font-weight: 700;
  line-height: .96;
  letter-spacing: .012em;
  color: #fff;
  text-shadow: 0 2px 24px rgba(0, 0, 0, .55);
}

.hero__lede {
  max-width: 44rem;
  margin: clamp(20px, 3vw, 30px) auto 0;
  font-size: 16.5px;
  color: var(--text);
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px;
  margin-top: clamp(28px, 4vw, 40px);
}

.hero__note {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: clamp(26px, 4vw, 38px);
  padding: 9px 18px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background-color: rgba(26, 26, 26, .6);
  color: var(--text-dim);
  font-size: 13.5px;
}

/* ------------------------------------------------------------ sections -- */

.section {
  padding-block: clamp(68px, 9vw, 116px);
  border-bottom: 1px solid var(--rule-soft);
}
.section--alt { background-color: var(--ink-800); }

/* sections carry tabindex="-1" so JS can move focus after an anchor jump;
   they are never Tab-reachable, so the ring is suppressed for that case only */
.section:focus:not(:focus-visible) { outline: none; }

.block { text-align: center; }

.eyebrow {
  font-family: var(--font-display);
  font-size: 12.5px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .3em;
  color: var(--gold-400);
  margin-bottom: 14px;
}

.section-title {
  font-size: clamp(1.9rem, 5.2vw, 3.1rem);
  font-weight: 700;
  letter-spacing: .01em;
}

.block__copy {
  max-width: 42rem;
  margin: 20px auto 0;
  color: var(--text);
}
.block__copy + .block__copy { margin-top: 14px; }

.block .btn { margin-top: clamp(26px, 4vw, 38px); }

.block__fineprint {
  margin-top: 16px;
  color: var(--text-dim);
  font-size: 13.5px;
}

/* -------------------------------------------------------- feature list -- */

.feature-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
  margin-top: clamp(34px, 5vw, 48px);
  text-align: left;
}

.feature {
  padding: 26px 24px;
  background-color: var(--ink-750);
  border: 1px solid var(--rule-soft);
  border-top: 2px solid var(--gold-400);
  border-radius: var(--radius);
}

.feature__title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--amber-400);
}

.feature__copy {
  margin-top: 10px;
  font-size: 15px;
  color: var(--text);
}

/* --------------------------------------------------------- class grid -- */
/* Cards are generated from data/classes.json by data/render_classes.py.
   The disclosure is a native <details>, so it is keyboard-operable, announces
   its own expanded state, and the whole section still reads with JS disabled. */

/* min() keeps the track from outgrowing a narrow viewport -- a bare
   minmax(400px, 1fr) would force a horizontal scrollbar at 360px. */
.class-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
  gap: 18px;
  margin-top: clamp(36px, 5vw, 52px);
}

.class-card {
  display: flex;
  flex-direction: column;
  padding: 26px 24px 24px;
  background-color: var(--ink-850);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius);
  text-align: left;
  overflow-wrap: break-word;
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.class-card:hover {
  border-color: var(--gold-600);
  background-color: #262626;
}
.class-card:hover .sigil { color: var(--amber-400); }
.class-card:focus-within { border-color: var(--gold-600); }

.class-card__head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.sigil {
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  color: var(--gold-400);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: color .2s var(--ease);
}

.class-card__id { min-width: 0; }

.class-card__name {
  font-size: 23px;
  font-weight: 600;
  letter-spacing: .05em;
  color: #fff;
}

/* the class talent tree's own name */
.class-card__tab {
  margin-top: 6px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .18em;
  line-height: 1.3;
  color: var(--gold-400);
}

.class-card__identity {
  margin-top: 16px;
  font-size: 15px;
  color: var(--text);
}

.class-card__alias {
  margin-top: 8px;
  font-size: 13.5px;
  color: var(--text-dim);
}

/* ---- meta chips ---- */

.class-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}

.meta-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 13px;
  background-color: rgba(0, 0, 0, .26);
  border: 1px solid var(--rule-soft);
  border-radius: 999px;
}

.meta-chip dt {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--text-dim);
}

.meta-chip dd { font-size: 13.5px; color: var(--text); }

/* ---- specs ---- */

.spec-list {
  margin-top: 20px;
  border-top: 1px solid var(--rule-soft);
}

.spec { padding: 13px 0; border-bottom: 1px solid var(--rule-soft); }

.spec__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 12px;
}

.spec__name {
  margin: 0;
  font-family: var(--font-display);
  font-size: 15.5px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .06em;
  line-height: 1.25;
  color: #fff;
}

/* Role badge. Damage is the roster default and stays quiet; the eight specs
   that tank, heal, support or run a pack are the interesting ones, so they
   take the gold treatment. */
.role {
  flex: 0 0 auto;
  padding: 3px 11px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .14em;
  line-height: 1.5;
  color: var(--text-dim);
  white-space: nowrap;
}

.role--nondamage {
  border-color: var(--gold-600);
  background-color: rgba(232, 183, 111, .08);
  color: var(--amber-400);
}

.spec__copy {
  margin-top: 6px;
  font-size: 14px;
  color: var(--text);
}

/* ---- disclosure ---- */

.class-more { margin-top: auto; }

.class-more__summary {
  display: flex;
  align-items: center;
  gap: 10px;
  /* padding is tuned so the hit area clears 44px on touch */
  padding: 18px 2px 7px;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--gold-400);
}
.class-more__summary::-webkit-details-marker { display: none; }
.class-more__summary::marker { content: ""; }
.class-more__summary:hover { color: var(--amber-400); }

.class-more__summary::after {
  content: "";
  flex: 0 0 auto;
  margin-left: auto;
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .2s var(--ease);
}
.class-more[open] .class-more__summary::after { transform: rotate(-135deg); }

.class-more__body { padding-top: 6px; }

.class-more__sub {
  margin-top: 14px;
  font-family: var(--font-display);
  font-size: 11.5px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .2em;
  color: var(--text-dim);
}

.ability {
  margin-top: 10px;
  padding: 13px 16px;
  background-color: rgba(0, 0, 0, .26);
  border-left: 2px solid var(--gold-600);
  border-radius: var(--radius-sm);
}

.ability__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
}

.ability__name {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--amber-400);
}

.ability__tag {
  padding: 2px 9px;
  border: 1px solid var(--gold-600);
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--amber-400);
}

.ability__copy { margin-top: 6px; font-size: 14px; color: var(--text); }

/* where the ability comes from: a spec kit, or the level it is learned at */
.ability__src {
  margin-top: 8px;
  font-size: 12.5px;
  letter-spacing: .02em;
  color: var(--text-dim);
}

.class-rules { margin-top: 6px; }

.rule {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--rule-soft);
}
.rule:last-child { border-bottom: 0; }

.rule dt {
  flex: 0 0 118px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .1em;
  line-height: 1.7;
  color: var(--text-dim);
}

.rule dd { flex: 1 1 190px; font-size: 14px; color: var(--text); }

/* -------------------------------------------------------------- steps -- */

.steps {
  max-width: 46rem;
  margin: clamp(32px, 5vw, 44px) auto 0;
  text-align: left;
}

.step {
  background-color: var(--ink-750);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius);
}
.step + .step { margin-top: 12px; }
.step[open] { border-color: var(--gold-600); }

.step__summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 16px;
  padding: 18px 22px;
  cursor: pointer;
  list-style: none;
}
.step__summary::-webkit-details-marker { display: none; }
.step__summary::marker { content: ""; }

.step__title {
  flex: 1 1 auto;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--text);
}
.step[open] .step__title,
.step__summary:hover .step__title { color: var(--gold-400); }

/* expand affordance — a plain chevron, no icon font, no image */
.step__summary::after {
  content: "";
  flex: 0 0 auto;
  align-self: center;
  width: 8px;
  height: 8px;
  margin-left: 4px;
  border-right: 2px solid var(--gold-400);
  border-bottom: 2px solid var(--gold-400);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .2s var(--ease);
}
.step[open] .step__summary::after { transform: rotate(-135deg); }

.step__state {
  flex: 0 0 auto;
  padding: 4px 12px;
  border: 1px solid var(--gold-600);
  border-radius: 999px;
  color: var(--amber-400);
  font-size: 12px;
  letter-spacing: .04em;
  white-space: nowrap;
}

.step__body {
  margin-inline: 22px;
  padding-block: 18px 24px;
  border-top: 1px solid var(--rule-soft);
}
.step__body p { font-size: 15px; }
.step__body p + p { margin-top: 12px; }
.step__body .btn { margin-top: 18px; }

.step__pending {
  padding: 12px 16px;
  border-left: 3px solid var(--status-testing);
  background-color: rgba(232, 183, 111, .07);
  color: var(--text);
}

.step.is-highlight { border-color: var(--amber-400); }

/* ---------------------------------------------------------------- faq -- */

.faq {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 22px 32px;
  margin-top: clamp(32px, 5vw, 44px);
  text-align: left;
}

.faq__q {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--amber-400);
}

.faq__a {
  margin-top: 6px;
  font-size: 15px;
  color: var(--text);
}

/* ------------------------------------------------------- status strip -- */

.status-strip {
  background-color: var(--navy-700);
  background-image: linear-gradient(180deg, var(--navy-700) 0%, var(--navy-800) 100%);
  border-bottom: 1px solid var(--rule-soft);
  padding-block: 30px;
}

.status-strip__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 32px;
}

.status-strip__heading {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: .24em;
  color: var(--gold-400);
}

.realm-list {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  flex: 1 1 auto;
}

.realm {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 10px 20px;
  background-color: rgba(0, 0, 0, .28);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 999px;
}

.realm__name {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: #fff;
}

.realm__label { font-size: 13.5px; color: var(--text); }

.dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: var(--status-offline);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, .07);
  flex: 0 0 auto;
}
.dot--online { background-color: var(--status-online); }
.dot--testing { background-color: var(--status-testing); }
.dot--offline { background-color: var(--status-offline); }

.realm--online .realm__label { color: var(--status-online); }
.realm--testing .realm__label { color: var(--status-testing); }

.status-strip__note {
  flex: 1 1 100%;
  color: #c7d3e2;
  font-size: 13px;
}

/* ---------------------------------------------------------------- news -- */

.news-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: 20px;
  margin-top: clamp(34px, 5vw, 48px);
  text-align: left;
}

.news-card {
  padding: 28px 26px 30px;
  background-color: var(--ink-850);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius);
}

.news-card__tag {
  display: inline-block;
  padding: 4px 12px;
  border: 1px solid var(--gold-600);
  border-radius: 4px;
  font-family: var(--font-display);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: .18em;
  color: var(--amber-400);
}

.news-card__title {
  margin-top: 16px;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: .03em;
  color: #fff;
}

.news-card__copy {
  margin-top: 10px;
  font-size: 15px;
  color: var(--text);
}

/* -------------------------------------------------------------- footer -- */

.site-footer {
  background-color: var(--ink-900);
  padding-top: clamp(48px, 7vw, 76px);
}

.site-footer__inner {
  display: grid;
  grid-template-columns: minmax(260px, 1.3fr) 2fr;
  gap: 44px;
  padding-bottom: 44px;
}

.brand--footer .brand__mark { height: 30px; width: auto; }
.brand--footer .brand__word { font-size: 19px; }

.site-footer__blurb {
  margin-top: 16px;
  max-width: 32rem;
  color: var(--text-dim);
  font-size: 14px;
}

.social {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 20px;
  padding: 10px 18px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .1em;
  transition: border-color .18s var(--ease), color .18s var(--ease);
}
.social:hover { border-color: var(--gold-400); color: var(--gold-400); }
.social svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.site-footer__links {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 32px;
}

.link-group__title {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .2em;
  color: var(--gold-400);
  margin-bottom: 14px;
}

.link-group li + li { margin-top: 9px; }

.link-group a {
  color: var(--text);
  font-size: 14.5px;
}
.link-group a:hover { color: var(--gold-400); }

.site-footer__bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
  padding-block: 22px;
  border-top: 1px solid var(--rule-soft);
  color: var(--text-dim);
  font-size: 13.5px;
}

.site-footer__domain {
  font-family: var(--font-display);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* ---------------------------------------------------------- responsive -- */

@media (max-width: 1000px) {
  .site-nav__list a { padding: 10px 10px; letter-spacing: .06em; }
  .btn { padding: 15px 30px; }
  .btn--lg { padding: 17px 34px; }
}

@media (max-width: 880px) {
  :root { --header-h: 64px; }

  .nav-toggle { display: inline-flex; }

  .site-nav {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 12px var(--gutter) 22px;
    background-color: var(--ink-900);
    border-bottom: 1px solid var(--rule-soft);
    box-shadow: var(--shadow-lift);
  }
  .site-header.is-open .site-nav { display: flex; }

  .site-nav__list {
    flex-direction: column;
    justify-content: flex-start;
    gap: 0;
  }
  .site-nav__list a {
    padding: 14px 4px;
    border-bottom: 1px solid var(--rule-soft);
    border-radius: 0;
    font-size: 15px;
    letter-spacing: .12em;
  }
  .site-nav__list a:hover { background-color: transparent; }

  .site-nav__actions {
    margin-top: 18px;
    flex-direction: column;
    align-items: stretch;
  }

  .site-footer__inner { grid-template-columns: 1fr; gap: 34px; }
}

@media (max-width: 560px) {
  :root { --gutter: 18px; }

  body { font-size: 15.5px; }

  .btn { width: 100%; padding: 15px 20px; }
  .hero__cta { flex-direction: column; align-items: stretch; }
  .hero__note { display: flex; text-align: left; border-radius: var(--radius); }

  .status-strip__inner { flex-direction: column; align-items: flex-start; }
  .realm { width: 100%; }

  .step__summary { padding: 16px 18px; }
  .step__body { margin-inline: 18px; padding-bottom: 20px; }

  .class-card { padding: 22px 18px 20px; }
  .class-card__head { gap: 13px; }
  .sigil { width: 38px; height: 38px; }
  .class-card__name { font-size: 21px; }
  .ability { padding: 12px 14px; }
  .rule dt { flex: 1 1 100%; }

  .site-footer__links { grid-template-columns: repeat(2, 1fr); gap: 26px; }
}

@media (max-width: 380px) {
  .brand__word { font-size: 18px; }
  .nav-toggle__label { display: none; }
  .site-footer__links { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------ reduced motion -- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  .btn:hover,
  .btn:active,
  .class-card:hover,
  .social:hover { transform: none; }
}

/* ==========================================================================
   ACCOUNT AREA + DOWNLOAD  —  added, nothing above this line was changed.

   Every rule below is expressed in the tokens declared at the top of this
   file. No new colour is invented that is not derived from that ramp, and no
   existing selector is redefined, so the pages that shipped before this block
   render exactly as they did.
   ========================================================================== */

:root {
  /* Form surfaces. One step darker than --ink-850 so an input reads as a well
     cut into the card rather than another card sitting on it. */
  --field-bg: #141414;
  --field-bg-alt: #1c1c1c;      /* on the --ink-800 alternating ground */

  /* Feedback. Measured against --ink-900:
       --danger  6.7:1   --status-online 8.2:1   --amber-400 9.5:1          */
  --danger: #e08b7a;
  --danger-line: #c96a5a;
}

/* ------------------------------------------------- logged in / logged out --
   The header ships the LOGGED-OUT markup. An inline script at the top of each
   page adds .is-authed to <html> before the header is parsed, which swaps the
   two groups with no flash and no layout jump.

   With JavaScript off, .is-authed is never added, so the visitor sees Register
   and Login — which is the correct thing to show someone whose session we
   cannot check. Both links work without script. */

.js-auth-in { display: none !important; }
html.is-authed .js-auth-in { display: inline-flex !important; }
html.is-authed .js-auth-out { display: none !important; }

/* The account chip in the header: shows who you are, links to the account page */
.nav-account {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 9px 16px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .08em;
  max-width: 15rem;
  transition: border-color .18s var(--ease), color .18s var(--ease);
}
.nav-account:hover { border-color: var(--gold-400); color: var(--gold-400); }
.nav-account__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-account__dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--status-online);
  box-shadow: 0 0 0 3px rgba(143, 191, 106, .16);
}

/* --------------------------------------------------------- compact hero --
   Subpages reuse the homepage's painted tavern backdrop at a shorter height,
   so /register and /login are obviously the same site rather than a bare form
   on a black page. .hero__bg, .hero__flicker and .hero__grain are the
   homepage's own elements, unmodified. */

.hero--compact { padding-block: clamp(44px, 7vw, 78px) clamp(40px, 6vw, 66px); }
.hero--compact .hero__inner { text-align: center; }
.hero--compact .hero__title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5.6vw, 3.2rem);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.02;
  color: #fff;
  text-shadow: 0 2px 20px rgba(0, 0, 0, .6);
}
.hero--compact .hero__sub {
  max-width: 40rem;
  margin: 16px auto 0;
  color: var(--text);
  font-size: 16px;
}

/* --------------------------------------------------------- stat band ------
   The four numbers that are the reason to be here. Sits directly under the
   hero on the homepage. */

.stat-band {
  background-color: var(--ink-850);
  border-bottom: 1px solid var(--rule-soft);
  padding-block: clamp(26px, 4vw, 38px);
}

.stat-band__inner {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px 12px;
  text-align: center;
}

.stat__num {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4.6vw, 2.9rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: .02em;
  color: var(--amber-400);
}

.stat__label {
  margin-top: 8px;
  font-family: var(--font-display);
  font-size: 11.5px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .18em;
  color: var(--text-dim);
}

@media (max-width: 640px) {
  .stat-band__inner { grid-template-columns: repeat(2, 1fr); gap: 22px 12px; }
}

/* ------------------------------------------------------------- notices ----
   One component for every "here is what happened" message: form errors, the
   success panel after registering, the "not switched on yet" state. */

.notice {
  border: 1px solid var(--rule-soft);
  border-left: 3px solid var(--rule);
  background-color: rgba(255, 255, 255, .03);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  color: var(--text);
  font-size: 15px;
  text-align: left;
}
.notice + .notice { margin-top: 12px; }
.notice__title {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--text);
  margin-bottom: 6px;
}
.notice p + p { margin-top: 9px; }
.notice code {
  display: inline-block;
  padding: .12em .4em;
  background-color: rgba(0, 0, 0, .45);
  border-radius: 4px;
  color: var(--amber-400);
  word-break: break-all;
}
.notice--good { border-left-color: var(--status-online); }
.notice--good .notice__title { color: var(--status-online); }
.notice--warn { border-left-color: var(--status-testing); }
.notice--warn .notice__title { color: var(--status-testing); }
.notice--bad  { border-left-color: var(--danger-line); }
.notice--bad  .notice__title { color: var(--danger); }
.notice--info { border-left-color: var(--gold-600); }
.notice--info .notice__title { color: var(--gold-400); }
.notice:empty { display: none; }

/* -------------------------------------------------------------- panels ----
   The card an auth form or an account section sits in. */

.panel {
  max-width: 36rem;
  margin: clamp(28px, 4vw, 40px) auto 0;
  padding: clamp(24px, 4vw, 34px);
  background-color: var(--ink-850);
  border: 1px solid var(--rule-soft);
  border-top: 2px solid var(--gold-400);
  border-radius: var(--radius);
  text-align: left;
}
.section--alt .panel { background-color: var(--ink-750); }
.panel--wide { max-width: 52rem; }
.panel + .panel { margin-top: 20px; }

.panel__title {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--amber-400);
}
.panel__lede { margin-top: 10px; color: var(--text-dim); font-size: 14.5px; }
.panel__foot {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--rule-soft);
  color: var(--text-dim);
  font-size: 14px;
}
.panel__foot a { font-weight: 500; }

/* --------------------------------------------------------------- forms ----
   Labels are real <label for>, hints are wired with aria-describedby, and the
   focus ring is a 3px halo rather than the browser default so it is visible
   against the dark ground at a glance. */

.form { margin-top: 22px; }
.form fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.form legend { padding: 0; }

.field { margin: 0 0 20px; }

.field__label {
  display: block;
  margin-bottom: 7px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--text);
}
.field__label .req { color: var(--gold-400); }

.field__input {
  display: block;
  width: 100%;
  /* 15px x 1.4 line-height + 2 x 13px padding + borders clears 48px, so every
     field is comfortably above the 44px touch target minimum. */
  padding: 13px 14px;
  font-family: var(--font-body);
  font-size: 16px;              /* 16px stops iOS Safari zooming on focus */
  line-height: 1.4;
  color: var(--text);
  background-color: var(--field-bg);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.section--alt .field__input { background-color: var(--field-bg-alt); }
.field__input::placeholder { color: var(--text-dim); opacity: 1; }
.field__input:hover { border-color: #5c5c5c; }
.field__input:focus {
  outline: 2px solid transparent;   /* keeps a ring in forced-colours mode */
  outline-offset: 0;
  border-color: var(--gold-400);
  box-shadow: 0 0 0 3px rgba(212, 165, 116, .26);
}
.field__input[aria-invalid="true"] { border-color: var(--danger-line); }
.field__input[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px rgba(201, 106, 90, .28);
}
.field__input:disabled { opacity: .55; cursor: not-allowed; }
.field__input[readonly] { color: var(--text-dim); }

/* password field + its show/hide button */
.field__wrap { position: relative; display: flex; }
.field__wrap .field__input { padding-right: 5.2rem; }
.field__peek {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  /* Sits inside a 50px-tall field. 40px of that is the button itself, so the
     target clears the comfortable-tap threshold without crowding the caret. */
  min-width: 4.4rem;
  min-height: 40px;
  padding: 9px 8px;
  background-color: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-family: var(--font-display);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .1em;
  cursor: pointer;
}
.field__peek:hover { color: var(--gold-400); }

.field__hint {
  display: block;
  margin-top: 7px;
  color: var(--text-dim);
  font-size: 13.5px;
  line-height: 1.5;
}
.field__hint strong { color: var(--text); font-weight: 600; }

/* Live per-field feedback. Empty by default so it takes no space. */
.field__msg {
  display: block;
  margin-top: 7px;
  font-size: 13.5px;
  line-height: 1.5;
}
.field__msg:empty { display: none; }
.field__msg--bad  { color: var(--danger); }
.field__msg--good { color: var(--status-online); }

/* character counter that appears as you approach the 16-character ceiling */
.field__count {
  float: right;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: .08em;
  color: var(--text-dim);
}
.field__count--near { color: var(--status-testing); }
.field__count--at   { color: var(--danger); }

.form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 26px;
}
.form__actions .btn { margin-top: 0; }
.btn[aria-disabled="true"],
.btn:disabled { opacity: .6; cursor: progress; transform: none; }

/* off-screen honeypot: no real visitor and no screen reader ever meets it */
.hp {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* the rules box that sits above the register form */
.rules {
  margin-top: 4px;
  padding: 16px 18px;
  background-color: rgba(0, 0, 0, .26);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-sm);
}
.rules__title {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--gold-400);
}
.rules ul { margin-top: 10px; }
.rules li {
  position: relative;
  padding-left: 20px;
  font-size: 14.5px;
  color: var(--text);
}
.rules li + li { margin-top: 8px; }
.rules li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: .55em;
  width: 7px;
  height: 7px;
  border-right: 2px solid var(--gold-400);
  border-bottom: 2px solid var(--gold-400);
  transform: rotate(-45deg);
}

/* ------------------------------------------------------- key/value list --
   The account facts. A <dl> so a screen reader reads "Account name: FOO"
   rather than two unrelated cells. */

.kv { margin-top: 18px; }
.kv__row {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 16px;
  padding: 12px 0;
  border-bottom: 1px solid var(--rule-soft);
}
.kv__row:last-child { border-bottom: 0; }
.kv dt {
  flex: 0 0 11.5rem;
  font-family: var(--font-display);
  font-size: 12.5px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .1em;
  line-height: 1.7;
  color: var(--text-dim);
}
.kv dd {
  flex: 1 1 12rem;
  font-size: 15px;
  color: var(--text);
  overflow-wrap: break-word;
}
.kv dd code { color: var(--amber-400); }

@media (max-width: 560px) {
  .kv dt { flex: 1 1 100%; }
}

/* ---------------------------------------------------------- characters ----
   Rendered only if the account API returns a character list. */

.char-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 12px;
  margin-top: 18px;
}

.char-card {
  padding: 16px 18px;
  background-color: rgba(0, 0, 0, .26);
  border: 1px solid var(--rule-soft);
  border-left: 2px solid var(--gold-600);
  border-radius: var(--radius-sm);
}
.char-card__name {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: #fff;
}
.char-card__meta { margin-top: 6px; font-size: 13.5px; color: var(--text-dim); }

/* -------------------------------------------------------- download page ---
   The one thing a visitor came here to do. */

.dl {
  max-width: 46rem;
  margin: clamp(28px, 4vw, 40px) auto 0;
  text-align: left;
}

.dl-card {
  padding: clamp(24px, 4vw, 32px);
  background-color: var(--ink-850);
  border: 1px solid var(--gold-600);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
}
.section--alt .dl-card { background-color: var(--ink-750); }

.dl-card__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 24px;
}
.dl-card__row .btn { margin-top: 0; flex: 0 0 auto; }

.dl-card__facts { flex: 1 1 14rem; min-width: 0; }
.dl-card__name {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: #fff;
}
.dl-card__meta {
  margin-top: 6px;
  color: var(--text-dim);
  font-size: 13.5px;
  overflow-wrap: break-word;
}
.dl-card__hash {
  margin-top: 12px;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--text-dim);
  overflow-wrap: break-word;
  word-break: break-all;
}

/* numbered install steps */
.steps-num { counter-reset: stepnum; margin-top: 26px; }
.steps-num > li {
  counter-increment: stepnum;
  position: relative;
  padding: 0 0 0 52px;
  min-height: 36px;
}
.steps-num > li + li { margin-top: 20px; }
.steps-num > li::before {
  content: counter(stepnum);
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--gold-600);
  border-radius: 50%;
  background-color: rgba(232, 183, 111, .08);
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--amber-400);
}
.steps-num__title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text);
  line-height: 34px;
}
.steps-num__copy { margin-top: 6px; font-size: 15px; color: var(--text); }
.steps-num__copy + .steps-num__copy { margin-top: 10px; }
.steps-num__copy code {
  padding: .12em .4em;
  background-color: rgba(0, 0, 0, .45);
  border-radius: 4px;
  word-break: break-all;
}

@media (max-width: 460px) {
  .steps-num > li { padding-left: 44px; }
  .steps-num > li::before { width: 30px; height: 30px; font-size: 14px; }
  .steps-num__title { line-height: 30px; font-size: 15px; }
}

/* ----------------------------------------------------- misc small parts ---*/

/* A quiet inline link row under a form: "Already have an account? Log in" */
.alt-links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin-top: 20px;
  font-size: 14.5px;
  color: var(--text-dim);
}

/* Loading placeholder used by the account page while it asks the API. */
.loading {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text-dim);
  font-size: 14.5px;
}
.loading::before {
  content: "";
  width: 14px;
  height: 14px;
  border: 2px solid var(--rule);
  border-top-color: var(--gold-400);
  border-radius: 50%;
  animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .loading::before { animation: none; border-top-color: var(--rule); }
}

/* 404 */
.oops { text-align: center; }
.oops__code {
  font-family: var(--font-display);
  font-size: clamp(4rem, 18vw, 9rem);
  font-weight: 700;
  line-height: 1;
  color: var(--gold-600);
  letter-spacing: .04em;
}

/* Wide/preformatted content must never make the page itself scroll sideways. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

@media (max-width: 560px) {
  .panel { padding: 22px 18px; }
  .form__actions { flex-direction: column; align-items: stretch; }
  .form__actions .btn { width: 100%; }
  .dl-card__row .btn { width: 100%; }
}

/* The burger is the single most-tapped control on a phone and shipped at 46x32.
   This is the only pre-existing rule this file's additions adjust, and it
   changes one number: enough vertical padding to clear a 44px target. Nothing
   moves on desktop, where the button is display:none. */
@media (max-width: 880px) {
  .nav-toggle { padding-block: 15px; }
}
