/* The landing page — theidleshard.com for anyone not logged in (routes/landing.js).
 *
 * ITS OWN STYLESHEET, deliberately, and never a section bolted onto game.css. That file is
 * 22,000 lines of a live game's UI where one unbalanced brace silently kills every rule
 * after it, and none of it — panels, gumps, the backpack grid — has anything to say about a
 * marketing page. The only thing the two share is the PALETTE, restated below rather than
 * imported, so a player who signs up here and lands in the game recognises the place.
 *
 * The tokens are copied from game.css's :root on purpose. A shared file would drag the whole
 * theme system (seven purchasable palettes, all keyed off a body class) onto a page that has
 * no player and therefore no theme, and re-theming a shop window is not a feature.
 */

:root {
  --shade: #0b0d12;
  --shade-2: #10131a;
  --panel: rgba(15, 17, 22, 0.85);
  --panel-deep: #12151c;
  --well: #080a0e;
  --accent: #ffb578;
  --accent-strong: #f08a42;
  --accent-deep: #d97a35;
  --accent-bright: #ffc98f;
  --ink: #e6e9ee;
  --ink-dim: #c3c8d0;
  --muted: #8d949f;
  --on-accent: #16110b;
  --edge: rgba(255, 158, 88, 0.22);
  --edge-soft: rgba(255, 158, 88, 0.10);
  --accent-rgb: 255, 181, 120;

  --serif: Georgia, 'Times New Roman', serif;
  --sans: system-ui, 'Segoe UI', Roboto, sans-serif;

  --wrap: 1180px;
  --radius: 14px;
  --radius-lg: 22px;

  /* One easing for everything that moves. A page with four different curves reads as four
     different pages. */
  --ease: cubic-bezier(0.22, 0.68, 0.24, 1);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* The sticky masthead would otherwise cover the top of every anchored section. */
  scroll-padding-top: 92px;
}

body {
  margin: 0;
  background: var(--shade);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-bright); }

h1, h2, h3 { font-family: var(--serif); font-weight: 400; line-height: 1.15; margin: 0; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }

/* Pixel art is 44px sprite sheets drawn at 2-4x here — smoothing turns them to mush. */
.pixel { image-rendering: pixelated; image-rendering: crisp-edges; }

/* ---------------------------------------------------------------- masthead ------------- */

.masthead {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 14px 28px;
  /* Transparent over the hero, glass once the page scrolls under it — the class is toggled
     by landing.js rather than done with scroll-timeline, which Safari still lacks. */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 0.35s var(--ease), border-color 0.35s var(--ease), backdrop-filter 0.35s var(--ease);
}
.masthead.is-stuck {
  background: rgba(8, 10, 14, 0.82);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  border-bottom-color: var(--edge-soft);
}
.masthead-brand { display: flex; align-items: center; gap: 11px; margin-right: auto; }
.masthead-brand img { width: 38px; height: 38px; }
.masthead-brand span {
  font-family: var(--serif);
  font-size: 19px;
  letter-spacing: 0.06em;
  color: var(--ink);
}
.masthead-nav { display: flex; align-items: center; gap: 26px; }
.masthead-nav a {
  color: var(--ink-dim);
  font-size: 14.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  position: relative;
  padding: 4px 0;
}
.masthead-nav a::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease);
}
.masthead-nav a:hover { color: var(--accent); }
.masthead-nav a:hover::after { transform: scaleX(1); }

/* ---------------------------------------------------------------- buttons -------------- */

/* Deliberately quiet. The first cut was a big saturated ember slab with a 36px glow under
   it, which read as an advert rather than as a door — "too big and in your face" was the
   note, and it was right. What sells this game is the art behind the button, so the button
   gets out of its way: a thin bright edge, a flat warm fill, no glow, and the same size in
   the masthead as in the hero. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 20px;
  border-radius: 8px;
  font-family: var(--sans);
  font-size: 14.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease), color 0.25s var(--ease);
}
.btn-primary {
  background: rgba(240, 138, 66, 0.14);
  border-color: rgba(var(--accent-rgb), 0.55);
  color: var(--accent);
}
.btn-primary:hover {
  background: rgba(240, 138, 66, 0.24);
  border-color: var(--accent);
  color: var(--accent-bright);
}
.btn-ghost {
  background: transparent;
  border-color: var(--edge);
  color: var(--ink-dim);
}
.btn-ghost:hover {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(var(--accent-rgb), 0.4);
  color: var(--ink);
}
/* Kept as a hook so the markup does not have to change, but no longer a size jump — the
   hero's call to action is the same object as the masthead's, which is the point. */
.btn-lg { padding: 11px 24px; font-size: 15px; }

/* ---------------------------------------------------------------- hero ----------------- */

.hero {
  position: relative;
  /* 88 rather than 100: with the content top-anchored a full viewport of hero left a
     quarter-screen of empty art above the eyebrow before anything happened ("remove some
     of the deadspace"). The art still bleeds behind the next section's fade, so the
     composition loses nothing. */
  min-height: 88svh;
  display: flex;
  align-items: center;
  overflow: hidden;
  isolation: isolate;
}
.hero-art {
  position: absolute;
  inset: -8% 0 -8% 0;
  background-image: var(--hero-src);
  background-size: cover;
  background-position: center 38%;
  /* Nudged by landing.js on scroll. will-change keeps it on its own layer so the parallax
     never repaints the text over it. */
  will-change: transform;
  z-index: -2;
}
/* Two washes rather than one: a vertical fade so the headline always has ground to sit on,
   and an ember bloom from the lower left so the art reads as lit rather than tinted. */
.hero::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(120% 80% at 20% 100%, rgba(240, 138, 66, 0.16), transparent 60%),
    linear-gradient(180deg, rgba(8, 10, 14, 0.86) 0%, rgba(8, 10, 14, 0.55) 38%, rgba(8, 10, 14, 0.92) 88%, var(--shade) 100%);
}
/* Crest to the LEFT of the headline rather than stacked above it — the stack was what
   made the first screen so tall. The copy keeps its measure; the crest fills the margin
   the composition already had. */
.hero-inner {
  position: relative;
  display: grid;
  grid-template-columns: 150px minmax(0, 640px);
  column-gap: 36px;
  align-items: start;
  padding: 108px 0 72px;
  max-width: 960px;
}
.hero-crest {
  width: 150px;
  /* Optically level with the headline's cap height: the eyebrow row sits above the h1 in
     the copy column, so the crest drops past it. */
  margin-top: 34px;
  filter: drop-shadow(0 12px 32px rgba(0, 0, 0, 0.65));
}
.hero-copy { min-width: 0; }
.hero-stats { grid-column: 2; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 12.5px;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 20px;
}
.eyebrow::before {
  content: '';
  width: 26px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent));
}

.hero h1 {
  font-size: clamp(2.6rem, 6.2vw, 4.6rem);
  letter-spacing: -0.015em;
  margin-bottom: 22px;
}
.hero h1 em {
  font-style: normal;
  color: var(--accent);
  /* The one place on the page that gets the game's own blackletter, so the brand's voice
     shows up in the first line a stranger reads. */
  font-family: 'TIS Blackletter', var(--serif);
}
.hero-sub {
  font-size: clamp(1.05rem, 2vw, 1.3rem);
  color: var(--ink-dim);
  max-width: 620px;
  margin-bottom: 34px;
}
.hero-cta { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 46px; }

.hero-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 34px 44px;
  padding-top: 30px;
  border-top: 1px solid var(--edge-soft);
}
.hero-stat-num {
  font-family: var(--serif);
  font-size: 2.1rem;
  color: var(--accent);
  line-height: 1;
}
.hero-stat-label {
  font-size: 12.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 7px;
}

.hero-scroll {
  position: absolute;
  left: 50%; bottom: 26px;
  transform: translateX(-50%);
  color: var(--muted);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  display: flex; flex-direction: column; align-items: center; gap: 9px;
}
.hero-scroll span { display: block; width: 1px; height: 34px; background: linear-gradient(180deg, var(--accent), transparent); animation: scroll-hint 2.4s var(--ease) infinite; }
@keyframes scroll-hint { 0%, 100% { opacity: 0.25; transform: scaleY(0.5); transform-origin: top; } 50% { opacity: 1; transform: scaleY(1); } }

/* ---------------------------------------------------------------- sections ------------- */

.section { padding: 108px 0; position: relative; }
.section-tight { padding: 78px 0; }
.section-head { max-width: 720px; margin-bottom: 56px; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section h2 {
  font-size: clamp(2rem, 4.2vw, 2.9rem);
  letter-spacing: -0.01em;
  margin-bottom: 18px;
}
.section-lede { font-size: 1.12rem; color: var(--ink-dim); }

/* A hairline that fades out at both ends — used between sections instead of a hard rule. */
.rule {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--edge), transparent);
  border: 0;
  margin: 0;
}

/* ---------------------------------------------------------------- pillars -------------- */

.pillars { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 22px; }
.pillar {
  position: relative;
  padding: 34px 30px 32px;
  border-radius: var(--radius-lg);
  background: linear-gradient(165deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
  border: 1px solid var(--edge-soft);
  overflow: hidden;
  transition: transform 0.35s var(--ease), border-color 0.35s var(--ease);
}
.pillar::before {
  /* An ember that warms the top edge on hover — the whole card lifts toward the light. */
  content: '';
  position: absolute;
  inset: -60% 20% auto 20%;
  height: 120%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(240, 138, 66, 0.16), transparent 70%);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
  pointer-events: none;
}
.pillar:hover { transform: translateY(-5px); border-color: rgba(var(--accent-rgb), 0.28); }
.pillar:hover::before { opacity: 1; }
.pillar-icon {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border-radius: 12px;
  background: rgba(240, 138, 66, 0.12);
  border: 1px solid var(--edge);
  margin-bottom: 20px;
  color: var(--accent);
}
.pillar-icon svg { width: 24px; height: 24px; }
.pillar h3 { font-size: 1.42rem; margin-bottom: 12px; }
.pillar p { margin: 0; color: var(--ink-dim); font-size: 15.5px; }

/* ---------------------------------------------------------------- progression ---------- */

.arc { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.arc-step {
  position: relative;
  padding: 28px 24px 26px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.028);
  border: 1px solid var(--edge-soft);
  transition: transform 0.35s var(--ease), background 0.35s var(--ease), border-color 0.35s var(--ease);
}
.arc-step:hover { transform: translateY(-4px); background: rgba(255, 255, 255, 0.055); border-color: rgba(var(--accent-rgb), 0.3); }
.arc-num {
  font-family: var(--serif);
  font-size: 13px;
  letter-spacing: 0.18em;
  color: var(--accent-deep);
  margin-bottom: 14px;
}
.arc-step h3 { font-size: 1.24rem; margin-bottom: 10px; }
.arc-step p { margin: 0; font-size: 14.8px; color: var(--muted); }
.arc-sprites { display: flex; gap: 6px; margin-bottom: 16px; height: 44px; align-items: flex-end; }
.arc-sprites img { width: 40px; height: 40px; filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.55)); }

/* ---------------------------------------------------------------- skills --------------- */

.skill-tabs { display: flex; flex-wrap: wrap; gap: 9px; margin-bottom: 30px; }
.skill-tab {
  padding: 10px 20px;
  border-radius: 999px;
  border: 1px solid var(--edge-soft);
  background: rgba(255, 255, 255, 0.03);
  color: var(--ink-dim);
  font-family: var(--sans);
  font-size: 14px;
  letter-spacing: 0.03em;
  cursor: pointer;
  transition: all 0.25s var(--ease);
}
.skill-tab:hover { color: var(--ink); border-color: var(--edge); }
.skill-tab[aria-selected='true'] {
  background: rgba(240, 138, 66, 0.14);
  border-color: rgba(var(--accent-rgb), 0.5);
  color: var(--accent);
  font-weight: 600;
}
/* THE ONE THAT HAD TO COME FIRST: `display: flex` here beats the user-agent's own
   `[hidden] { display: none }`, because an author rule always outranks the UA sheet. So the
   four categories the tab strip believes it is hiding were all on screen at once, stacked,
   in ragged rows of stretched boxes. Restating the hidden case explicitly is the whole fix,
   and it has to sit AFTER the display rule to win on order. */
.skill-grid { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px; }
.skill-grid[hidden] { display: none; }

/* ...and the boxes themselves are gone. A chip with a border, a fill and a hover lift is a
   button, and thirty-eight of them read as a control panel nobody can press. These are a
   LIST — the only job is to show how much there is of it — so they are set as quiet type on
   a hairline rule, with the accent kept for the hover. */
.skill-chip {
  padding: 6px 14px 6px 0;
  margin-right: 6px;
  border-right: 1px solid var(--edge-soft);
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-dim);
  white-space: nowrap;
  transition: color 0.2s var(--ease);
  /* Staggered in by landing.js setting --i per chip. */
  animation: chip-in 0.4s var(--ease) both;
  animation-delay: calc(var(--i, 0) * 22ms);
}
.skill-chip:last-child { border-right: 0; }
.skill-chip:hover { color: var(--accent); }
@keyframes chip-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.skill-note {
  margin-top: 34px;
  padding: 22px 26px;
  border-left: 2px solid var(--accent-deep);
  background: rgba(240, 138, 66, 0.06);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--ink-dim);
  font-size: 15.5px;
}

/* ---------------------------------------------------------------- split feature -------- */

.split { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; }
.split.flip .split-art { order: 2; }
.split-copy h2 { margin-bottom: 18px; }
.split-copy p { color: var(--ink-dim); }
.split-art { position: relative; }
.art-frame {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--edge);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.55);
  background: var(--well);
}
.art-frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.art-frame::after {
  /* Keeps the bottom of every screenshot-style frame sitting in shadow, so the frames all
     read as one set however differently lit the art inside them is. */
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 55%, rgba(8, 10, 14, 0.55));
  pointer-events: none;
}
.art-caption {
  position: absolute;
  left: 18px; bottom: 14px;
  z-index: 2;
  font-size: 12.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.9);
}

.feature-list { list-style: none; padding: 0; margin: 26px 0 0; display: grid; gap: 14px; }
.feature-list li { display: flex; gap: 13px; align-items: flex-start; font-size: 15.5px; color: var(--ink-dim); }
.feature-list li::before {
  content: '';
  flex: none;
  width: 7px; height: 7px;
  margin-top: 9px;
  border-radius: 2px;
  background: var(--accent-strong);
  transform: rotate(45deg);
  box-shadow: 0 0 12px rgba(240, 138, 66, 0.6);
}

/* ---------------------------------------------------------------- journal demo --------- */

/* A living recreation of the in-game Journal, built from the same palette as the real one.
   It types itself out on scroll (landing.js) because a still image of a combat log is the
   least persuasive way to show a game that is constantly, quietly doing things. */
.journal {
  border-radius: var(--radius);
  border: 1px solid var(--edge);
  background: linear-gradient(180deg, rgba(18, 21, 28, 0.96), rgba(8, 10, 14, 0.96));
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}
.journal-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--edge-soft);
  background: rgba(255, 255, 255, 0.025);
}
.journal-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent-deep); box-shadow: 0 0 10px rgba(240, 138, 66, 0.7); }
.journal-title { font-size: 12.5px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted); }
.journal-feed {
  padding: 16px 18px 20px;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.85;
  min-height: 268px;
}
.journal-line { display: flex; gap: 11px; opacity: 0; transform: translateY(6px); }
.journal-line.is-in { opacity: 1; transform: none; transition: opacity 0.4s var(--ease), transform 0.4s var(--ease); }
.journal-time { color: #5c626c; flex: none; font-variant-numeric: tabular-nums; }
.j-combat { color: var(--ink-dim); }
.j-success { color: #7fd1a8; }
.j-fail { color: #e0736a; }
.j-skill { color: var(--accent); }
.j-loot { color: #b79be0; }

/* ---------------------------------------------------------------- world map ------------ */

.map-frame {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--edge);
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.6);
}
.map-frame img { width: 100%; }
.map-frame::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(75% 65% at 50% 45%, transparent 40%, rgba(8, 10, 14, 0.7));
  pointer-events: none;
}

.gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; }
.gallery figure { margin: 0; position: relative; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--edge-soft); aspect-ratio: 16 / 10; }
.gallery img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.7s var(--ease); }
.gallery figure:hover img { transform: scale(1.07); }
.gallery figcaption {
  position: absolute; inset: auto 0 0 0;
  padding: 26px 16px 13px;
  background: linear-gradient(180deg, transparent, rgba(8, 10, 14, 0.92));
  font-size: 13.5px;
  letter-spacing: 0.06em;
  color: var(--ink);
}

/* ---------------------------------------------------------------- bestiary ------------- */

.bestiary { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
.beast {
  width: 84px;
  padding: 12px 6px 10px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--edge-soft);
  text-align: center;
  transition: all 0.3s var(--ease);
}
.beast:hover { transform: translateY(-5px); border-color: rgba(var(--accent-rgb), 0.4); background: rgba(240, 138, 66, 0.09); }
.beast img { width: 48px; height: 48px; margin: 0 auto 8px; }
.beast span { font-size: 10.5px; letter-spacing: 0.05em; color: var(--muted); display: block; line-height: 1.3; }

/* ---------------------------------------------------------------- house ladder --------- */

/* Nine bordered, filled, hover-lifting boxes in a row is a row of buttons, whatever the
   markup says — and a visitor who tries to click one learns the page is lying to them. The
   ladder is a SEQUENCE, so it is set as one: names in a line, separated by a mark, warming
   from muted toward the accent as the houses get grander. Nothing to press, and the shape of
   the progression is now the thing you actually read. */
.ladder { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0; }
.rung {
  display: inline-flex;
  align-items: baseline;
  font-size: 15px;
  line-height: 1.9;
  /* From the muted body colour up to the full accent across the nine tiers, so a Castle
     visibly sits at the top of the run without needing a badge to say so. */
  color: color-mix(in srgb, var(--muted) calc(100% - var(--n) * 12%), var(--accent) calc(var(--n) * 12%));
}
.rung + .rung::before {
  content: '';
  width: 5px; height: 5px;
  margin: 0 14px;
  flex: none;
  border-radius: 1px;
  background: currentColor;
  opacity: 0.45;
  transform: rotate(45deg) translateY(-1px);
}
/* The last rung is the destination the whole section is about. */
.rung:last-child { color: var(--accent); font-family: var(--serif); font-size: 17px; }

/* ---------------------------------------------------------------- closing cta ---------- */

.closer { position: relative; overflow: hidden; text-align: center; padding: 130px 0; }
.closer-art {
  position: absolute; inset: 0;
  background-image: var(--closer-src);
  background-size: cover;
  background-position: center 60%;
  z-index: -2;
}
.closer::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(70% 60% at 50% 50%, rgba(240, 138, 66, 0.2), transparent 65%),
    linear-gradient(180deg, var(--shade) 0%, rgba(8, 10, 14, 0.82) 40%, var(--shade) 100%);
}
.closer h2 { font-size: clamp(2.2rem, 5vw, 3.4rem); margin-bottom: 20px; }
.closer p { color: var(--ink-dim); max-width: 560px; margin: 0 auto 34px; font-size: 1.1rem; }
.closer-cta { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }

.invite-note {
  margin-top: 30px;
  font-size: 14px;
  color: var(--muted);
}

/* ---------------------------------------------------------------- discord -------------- */

.discord-card {
  display: flex;
  align-items: center;
  gap: 18px;
  max-width: 560px;
  margin: 0 auto;
  padding: 20px 24px;
  border-radius: var(--radius);
  background: rgba(88, 101, 242, 0.11);
  border: 1px solid rgba(88, 101, 242, 0.34);
  transition: all 0.3s var(--ease);
  text-align: left;
}
.discord-card:hover { background: rgba(88, 101, 242, 0.19); transform: translateY(-3px); }
.discord-card svg { width: 30px; height: 30px; fill: #8d9bff; flex: none; }
.discord-card strong { display: block; color: var(--ink); font-size: 15.5px; }
.discord-card span { font-size: 13.5px; color: var(--muted); }

/* ---------------------------------------------------------------- footer --------------- */

.site-foot { border-top: 1px solid var(--edge-soft); padding: 44px 0 54px; background: var(--well); }
.foot-row { display: flex; flex-wrap: wrap; gap: 22px; align-items: center; justify-content: space-between; }
.foot-brand { display: flex; align-items: center; gap: 11px; color: var(--muted); font-size: 14px; }
.foot-brand img { width: 30px; height: 30px; opacity: 0.8; }
.foot-links { display: flex; flex-wrap: wrap; gap: 22px; }
.foot-links a { color: var(--muted); font-size: 14px; }
.foot-links a:hover { color: var(--accent); }
.foot-note { margin-top: 26px; font-size: 12.5px; color: #5c626c; }

.patch-chip {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 7px 15px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--edge-soft);
  font-size: 13px;
  color: var(--ink-dim);
}
.patch-chip b { color: var(--accent); font-weight: 600; }
.patch-pulse {
  width: 7px; height: 7px; border-radius: 50%;
  background: #4f9d55;
  box-shadow: 0 0 0 0 rgba(79, 157, 85, 0.7);
  animation: pulse 2.6s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(79, 157, 85, 0.6); }
  70% { box-shadow: 0 0 0 9px rgba(79, 157, 85, 0); }
  100% { box-shadow: 0 0 0 0 rgba(79, 157, 85, 0); }
}

/* ---------------------------------------------------------------- reveal --------------- */

/* Everything below the fold starts slightly low and faded, and is released by an
   IntersectionObserver. Written so that if the script never runs, .reveal elements are
   still visible — a page whose content depends on JS is a page that shows a stranger
   nothing when something goes wrong. landing.js adds .reveal-armed to opt in. */
.reveal-armed .reveal { opacity: 0; transform: translateY(26px); }
.reveal-armed .reveal.is-visible {
  opacity: 1;
  transform: none;
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--d, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal-armed .reveal { opacity: 1 !important; transform: none !important; }
  .hero-scroll span, .patch-pulse { animation: none; }
  .skill-chip { animation: none; }
  * { transition-duration: 0.01ms !important; }
}

/* ---------------------------------------------------------------- responsive ----------- */

@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; gap: 34px; }
  .split.flip .split-art { order: 0; }
  .masthead-nav { display: none; }
  .section { padding: 74px 0; }
  .hero-inner { grid-template-columns: 1fr; padding: 108px 0 72px; }
  .hero-crest { width: 96px; margin-top: 0; margin-bottom: 18px; }
  .hero-stats { grid-column: 1; }
  .hero-stats { gap: 24px 32px; }
  .hero-stat-num { font-size: 1.7rem; }
}
@media (max-width: 560px) {
  body { font-size: 16px; }
  .wrap { padding: 0 18px; }
  .masthead { padding: 12px 18px; }
  .hero-cta .btn { width: 100%; }
  .beast { width: 72px; }
}

/* ---------------------------------------------------------------- screenshots ---------- */

/* A real capture of the game, as opposed to the painted backdrops elsewhere on the page.
   Framed a little more plainly than .art-frame: no gradient wash over the bottom, because a
   screenshot is evidence and dimming half of it defeats the point. */
.shot {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--edge);
  background: var(--well);
  box-shadow: 0 26px 60px rgba(0, 0, 0, 0.5);
}
.shot img { width: 100%; display: block; }
.shot-label {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 14px;
  border-top: 1px solid var(--edge-soft);
  background: rgba(255, 255, 255, 0.025);
  font-size: 12.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.shot-label::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent-deep);
  flex: none;
}
