/* Valdrys — site design system.
 *
 * The palette is lifted verbatim from ICON_STYLE.md ("Tarnished Aether") so the
 * site and the game are demonstrably one product. Its rule: ~90% desaturated
 * iron/ash/bone, ONE saturated accent, and that accent is either Radiant or
 * Blighted — almost never both in the same element.
 *
 * Fonts are the game's own, both SIL Open Font License (see assets/fonts/*-OFL.txt
 * and the credits page): Cinzel Decorative for the wordmark and display titles,
 * Marcellus SC for section headers. Body copy stays on a system stack — it is
 * read, not admired, and self-hosting a third face costs more than it earns.
 */

@font-face {
  font-family: "Cinzel Decorative";
  src: url("../fonts/CinzelDecorative-Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Marcellus SC";
  src: url("../fonts/MarcellusSC-Regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}

:root {
  /* Foundation */
  --void: #0d0b0c;
  --charcoal: #1a1618;
  --iron: #2b2a2e;
  --ash: #4a4a50;
  --bone: #d8cbb0;
  --steel: #a7b6be;

  /* Radiant pole — the Host's light */
  --bronze: #c8975a;
  --aether: #e8c57a;
  --celestial: #bfe9ff;
  --frost: #2fa8c8;

  /* Blighted pole — the decay */
  --ember: #e8501e;
  --blood: #b23a2a;
  --corruption: #8e5fc0;
  --blight: #5e8c5a;

  --ink: #cfc6b6;
  --ink-dim: #8a8177;
  --line: rgba(200, 151, 90, 0.22);

  --measure: 68ch;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --shell: 1200px;
}

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

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font: 400 clamp(1rem, 0.96rem + 0.2vw, 1.075rem)/1.7 ui-serif, Georgia, "Times New Roman", serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The blighted vignette: objects emerge from darkness (pillar 4 of the brief). */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(200, 151, 90, 0.07), transparent 60%),
    radial-gradient(100% 60% at 50% 100%, rgba(13, 11, 12, 0.9), transparent 70%);
}

main, header, footer { position: relative; z-index: 1; }

a { color: var(--aether); text-decoration-color: var(--line); text-underline-offset: 3px; }
a:hover { color: var(--bone); }
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--celestial);
  outline-offset: 3px;
  border-radius: 2px;
}

img { max-width: 100%; height: auto; display: block; }

.shell { width: min(100% - (var(--gutter) * 2), var(--shell)); margin-inline: auto; }

/* ---------- Type ---------- */

.display {
  font-family: "Cinzel Decorative", ui-serif, Georgia, serif;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.05;
  color: var(--bone);
  /* Never small: Cinzel's serifs crowd badly below ~20px (ui_theme.gd). */
  font-size: clamp(2.5rem, 1.6rem + 4.4vw, 5.5rem);
  margin: 0;
}

h2 {
  font-family: "Marcellus SC", ui-serif, Georgia, serif;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--aether);
  font-size: clamp(1.35rem, 1.1rem + 1vw, 1.9rem);
  margin: 0 0 0.35em;
}

h3 {
  font-family: "Marcellus SC", ui-serif, Georgia, serif;
  font-weight: 400;
  letter-spacing: 0.08em;
  color: var(--bone);
  font-size: 1.15rem;
  margin: 0 0 0.4em;
}

.eyebrow {
  font-family: "Marcellus SC", ui-serif, serif;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  font-size: 0.72rem;
  color: var(--bronze);
  margin: 0 0 1rem;
}

.lede { font-size: 1.15em; color: var(--bone); max-width: var(--measure); }
p { max-width: var(--measure); }
.dim { color: var(--ink-dim); }

/* A hairline that fades at both ends — the site's one recurring ornament. */
.rule {
  height: 1px;
  border: 0;
  margin: 0;
  background: linear-gradient(90deg, transparent, var(--line) 18%, var(--line) 82%, transparent);
}

/* ---------- Nav ---------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(13, 11, 12, 0.82);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.nav__inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 62px;
}
.nav__mark {
  font-family: "Cinzel Decorative", serif;
  font-size: 1.1rem;
  letter-spacing: 0.22em;
  color: var(--bone);
  text-decoration: none;
  margin-right: auto;
  white-space: nowrap;
  display: flex;
  align-items: center;
}
.nav__mark:hover { color: var(--aether); }
.nav__mark img { height: 38px; width: auto; display: block; }

/* The hero lockup. Capped by height AND viewport width so the logo never
   overwhelms a phone or outgrows a large monitor. */
.hero__logo {
  width: auto;
  max-width: min(760px, 88vw);
  max-height: 42vh;
  margin: 0 auto 0.5rem;
  filter: drop-shadow(0 18px 46px rgba(0, 0, 0, 0.75));
}

/* Visually hidden, still read aloud and still indexed. The wordmark is now an
   image, so the page would otherwise have no <h1> text at all. */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}
.nav__links { display: flex; gap: 1.4rem; flex-wrap: wrap; align-items: center; }
.nav__links a {
  font-family: "Marcellus SC", serif;
  font-size: 0.82rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-decoration: none;
}
.nav__links a:hover { color: var(--aether); }

/* The menu button only exists once JS can operate it. */
.nav__burger { display: none; }

@media (max-width: 760px) {
  .nav__inner { flex-wrap: wrap; padding-bottom: 0.5rem; }
  .nav__mark { margin-right: auto; }

  /* Default — NO JavaScript — is every link visible, stacked. A taller header
     is a small cost; a phone with no navigation at all is not. The links were
     previously display:none here with nothing replacing them, which left mobile
     visitors able to reach other pages only via the footer. */
  .nav__links {
    order: 3;
    width: 100%;
    justify-content: center;
    gap: 0.9rem 1.25rem;
    padding: 0.35rem 0 0.5rem;
  }

  /* With JS, collapse behind a button. */
  .js-nav .nav__links {
    display: none;
    flex-direction: column;
    align-items: stretch;
    text-align: center;
    gap: 0;
    border-top: 1px solid var(--line);
    margin-top: 0.4rem;
  }
  .js-nav .nav__links.is-open { display: flex; }
  .js-nav .nav__links a {
    padding: 0.95rem 0.5rem;
    font-size: 0.95rem;
    border-bottom: 1px solid rgba(200, 151, 90, 0.1);
  }
  .js-nav .nav__links a:last-child { border-bottom: 0; }

  .js-nav .nav__burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px; height: 44px;   /* a real touch target, not a 20px glyph */
    background: none;
    border: 1px solid var(--line);
    color: var(--bone);
    cursor: pointer;
    padding: 0;
  }
  .nav__burger:hover { border-color: var(--bronze); color: var(--aether); }
  .nav__burger svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 1.6; }
  .nav__burger .bar-x { display: none; }
  .nav__burger[aria-expanded="true"] .bar-menu { display: none; }
  .nav__burger[aria-expanded="true"] .bar-x { display: block; }
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-block;
  font-family: "Marcellus SC", serif;
  font-size: 0.85rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.85em 2em;
  border: 1px solid var(--bronze);
  color: var(--aether);
  background: linear-gradient(180deg, rgba(200, 151, 90, 0.14), rgba(200, 151, 90, 0.04));
  transition: background 160ms ease, color 160ms ease, border-color 160ms ease;
}
.btn:hover {
  background: linear-gradient(180deg, rgba(232, 197, 122, 0.26), rgba(200, 151, 90, 0.1));
  color: var(--void);
  color: #f3e7cd;
  border-color: var(--aether);
}
.btn--ghost { border-color: var(--ash); color: var(--ink); background: none; }
.btn--ghost:hover { border-color: var(--bone); color: var(--bone); background: rgba(216, 203, 176, 0.06); }
.btn-row { display: flex; gap: 0.9rem; flex-wrap: wrap; margin-top: 2rem; }

/* ---------- Hero ---------- */

/* Full-bleed. The key art is set ONCE, via --hero-art on .hero, so swapping in
 * a better screenshot is a one-line change in the HTML and nothing else moves.
 * Until there is commissioned art, an in-engine capture does the job — the
 * scrim below is what makes an ordinary screenshot read as a hero. */
.hero {
  min-height: clamp(560px, 86vh, 900px);
  display: grid;
  place-items: center;
  text-align: center;
  padding: clamp(3rem, 8vh, 6rem) var(--gutter);
  position: relative;
  isolation: isolate;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, #15100f 0%, var(--void) 100%);
}

/* The art is a real <img>, not a background.
 *
 * It was a background-image driven by a --hero-art custom property, which
 * silently resolved against the WRONG base: a relative url() inside a custom
 * property resolves against the stylesheet that USES it, not the HTML that
 * declared it, so it looked for assets/css/assets/img/... and the hero rendered
 * as a black rectangle. An <img> has no such ambiguity, and it also lets the
 * browser preload it at high priority, which a CSS background cannot.
 *
 * Desaturated toward the palette but NOT dimmed into nothing — the scrim below
 * does the darkening. */
.hero__art {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
  filter: saturate(0.78) contrast(1.04);
  opacity: 0.82;
}

/* The scrim. Three stacked gradients: darken the edges, sink the bottom into
 * the page so there is no seam, and bloom a little aether-light behind the
 * title (pillar 4: objects emerge from darkness). */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(60% 46% at 50% 40%, rgba(232, 197, 122, 0.14), transparent 74%),
    linear-gradient(180deg, rgba(13, 11, 12, 0.50) 0%, rgba(13, 11, 12, 0.22) 40%, rgba(13, 11, 12, 0.86) 88%, var(--void) 100%),
    radial-gradient(120% 90% at 50% 46%, transparent 34%, rgba(13, 11, 12, 0.72) 100%);
}

.hero__inner { max-width: 62ch; }
.hero__tag {
  font-family: "Marcellus SC", serif;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  font-size: clamp(0.72rem, 0.66rem + 0.3vw, 0.9rem);
  color: var(--bronze);
  margin: 1.6rem 0 0;
}
.hero__lede { margin: 1.5rem auto 0; max-width: 54ch; color: var(--ink); }
.hero .btn-row { justify-content: center; }

/* The cracked-halo ornament: a broken ring, the brief's central image. */
.halo { width: min(320px, 62vw); height: auto; margin: 0 auto 0.5rem; display: block; opacity: 0.9; }

/* ---------- Sections ---------- */

section { padding: clamp(3.5rem, 9vh, 6.5rem) 0; }
.section-head { margin-bottom: 2.5rem; }

.grid { display: grid; gap: 1.25rem; }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

.card {
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(26, 22, 24, 0.9), rgba(13, 11, 12, 0.9));
  padding: 1.6rem 1.5rem;
  position: relative;
}
.card h3 { color: var(--bone); }
.card p { margin: 0; font-size: 0.96rem; color: var(--ink-dim); max-width: none; }

/* One emissive accent per card, set inline per class/pillar. */
.card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  background: var(--accent, var(--bronze));
  opacity: 0.75;
}

.card--muted { opacity: 0.62; }
.tag {
  display: inline-block;
  font-family: "Marcellus SC", serif;
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--void);
  background: var(--bronze);
  padding: 0.25em 0.7em;
  margin-left: 0.6rem;
  vertical-align: middle;
}

/* ---------- Regions ---------- */

.regions { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.1rem; }
.regions li {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid rgba(200, 151, 90, 0.12);
  flex-wrap: wrap;
}
.regions .name { font-family: "Marcellus SC", serif; color: var(--bone); letter-spacing: 0.06em; min-width: 15ch; }
.regions .meta { margin-left: auto; font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.regions .meta[data-pvp] { color: var(--blood); }

/* ---------- Media / gallery ---------- */

.shots { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

/* The first shot spans two columns when there is room — a gallery of equal
 * tiles reads as a contact sheet; one dominant image reads as art direction. */
.shots > :first-child { grid-column: span 2; }
@media (max-width: 700px) { .shots > :first-child { grid-column: auto; } }

.shot {
  border: 1px solid var(--line);
  background: var(--charcoal);
  overflow: hidden;
  margin: 0;
  position: relative;
}
.shot img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  transition: transform 400ms ease, filter 400ms ease;
}
.shot button {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.shot:hover img { transform: scale(1.03); filter: brightness(1.08); }
.shot figcaption {
  font-family: "Marcellus SC", serif;
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--line);
  text-align: left;
}

/* ---------- Lightbox ---------- */

.lightbox {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: min(96vw, 1600px);
  max-height: 94vh;
  overflow: visible;
}
.lightbox::backdrop { background: rgba(6, 5, 6, 0.93); backdrop-filter: blur(4px); }
.lightbox img {
  max-width: 100%;
  max-height: 88vh;
  width: auto;
  border: 1px solid var(--line);
  box-shadow: 0 0 90px rgba(0, 0, 0, 0.8);
}
.lightbox figcaption {
  font-family: "Marcellus SC", serif;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bone);
  padding-top: 0.9rem;
  text-align: center;
}
.lightbox__close {
  position: absolute;
  top: -2.6rem;
  right: 0;
  background: none;
  border: 1px solid var(--ash);
  color: var(--bone);
  font-size: 1.1rem;
  line-height: 1;
  padding: 0.4em 0.7em;
  cursor: pointer;
}
.lightbox__close:hover { border-color: var(--aether); color: var(--aether); }

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

/* Opt-in: elements only hide themselves once JS confirms it can reveal them,
 * so with JS disabled or broken the page is simply visible rather than blank.
 * That failure mode matters more than the animation does. */
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 700ms cubic-bezier(.2,.7,.3,1), transform 700ms cubic-bezier(.2,.7,.3,1);
  will-change: opacity, transform;
}
.js-reveal .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js-reveal .reveal { opacity: 1; transform: none; transition: none; }
  .shot img { transition: none; }
  .shot:hover img { transform: none; }
}

/* ---------- News ---------- */

.news { list-style: none; padding: 0; margin: 0; display: grid; gap: 1rem; }
.news li { border: 1px solid var(--line); padding: 1.3rem 1.5rem; background: rgba(26, 22, 24, 0.55); }
.news h3 { margin-bottom: 0.25em; }
.news .when {
  font-family: "Marcellus SC", serif;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--bronze);
  display: block;
  margin-bottom: 0.5rem;
}
.news p { margin: 0; color: var(--ink-dim); font-size: 0.96rem; max-width: none; }

/* ---------- Callout ---------- */

.callout {
  border: 1px solid var(--line);
  border-left: 2px solid var(--bronze);
  background: rgba(26, 22, 24, 0.7);
  padding: 1.4rem 1.6rem;
  margin: 2rem 0;
}
.callout p:last-child { margin-bottom: 0; }

/* ---------- Legal / long-form pages ---------- */

.prose { max-width: var(--measure); }
.prose h2 { margin-top: 2.4em; }
.prose h2:first-of-type { margin-top: 0; }
.prose ul { padding-left: 1.2em; }
.prose li { margin-bottom: 0.5em; }
.prose code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.9em;
  background: var(--charcoal);
  border: 1px solid var(--line);
  padding: 0.1em 0.4em;
}
.page-head { padding: clamp(2.5rem, 7vh, 4.5rem) 0 0; }
.updated { font-size: 0.82rem; color: var(--ink-dim); letter-spacing: 0.06em; }

/* ---------- Footer ---------- */

.footer {
  border-top: 1px solid var(--line);
  padding: 0 0 3.5rem;
  margin-top: 2rem;
  background: linear-gradient(180deg, transparent, rgba(26, 22, 24, 0.6));
}

/* Top band: mark left, back-to-top centred, social right — the shape most game
   sites settle on, because it puts the one control people actually want (get me
   back up this very long page) in the middle where it cannot be missed. */
.footer__band {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1.5rem;
  padding: 2.5rem 0;
  border-bottom: 1px solid rgba(200, 151, 90, 0.12);
}
.footer__band img { height: 46px; width: auto; opacity: 0.85; }
.footer__band a:hover img { opacity: 1; }
.footer__social { display: flex; gap: 1rem; justify-content: flex-end; align-items: center; }
.footer__social a {
  display: inline-flex;
  width: 40px; height: 40px;
  align-items: center; justify-content: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--ink-dim);
  transition: color 160ms ease, border-color 160ms ease, background 160ms ease;
}
.footer__social a:hover { color: var(--aether); border-color: var(--bronze); background: rgba(200, 151, 90, 0.08); }
.footer__social svg { width: 19px; height: 19px; fill: currentColor; }

/* The back-to-top medallion: a ring of hairlines around the label. */
.totop {
  position: relative;
  display: grid;
  place-items: center;
  width: 132px; height: 132px;
  text-decoration: none;
  font-family: "Marcellus SC", serif;
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-align: center;
  line-height: 1.3;
}
.totop:hover { color: var(--aether); }
.totop svg {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  stroke: var(--line);
  fill: none;
  transition: stroke 240ms ease, transform 500ms cubic-bezier(.2,.7,.3,1);
}
.totop:hover svg { stroke: var(--bronze); transform: rotate(60deg); }
.totop span { position: relative; z-index: 1; }

@media (max-width: 720px) {
  .footer__band { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 2rem; }
  .footer__social { justify-content: center; }
}
@media (prefers-reduced-motion: reduce) { .totop:hover svg { transform: none; } }

.footer__grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); padding-top: 2.5rem; }
.footer h4 {
  font-family: "Marcellus SC", serif;
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--bronze);
  margin: 0 0 0.9rem;
}
.footer ul { list-style: none; padding: 0; margin: 0; }
.footer li { margin-bottom: 0.45rem; }
.footer a { color: var(--ink-dim); text-decoration: none; font-size: 0.9rem; }
.footer a:hover { color: var(--aether); }
.footer__fine {
  margin-top: 2.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid rgba(200, 151, 90, 0.12);
  font-size: 0.8rem;
  color: var(--ink-dim);
  text-align: center;
}
.footer__fine p { max-width: none; margin: 0 auto 0.6rem; }

/* The centred legal row, small-caps and spaced like the rest of the chrome. */
.footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
  justify-content: center;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
}
.footer__legal a {
  font-family: "Marcellus SC", serif;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-decoration: none;
}
.footer__legal a:hover { color: var(--aether); }

/* Rating: stated honestly rather than faked with a borrowed ESRB badge. */
.rating {
  display: inline-block;
  border: 1px solid var(--line);
  padding: 0.35em 0.8em;
  font-family: "Marcellus SC", serif;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin-top: 0.5rem;
}

/* ---------- Ladder / standings ---------- */

.ladder { list-style: none; margin: 1.25rem 0 0; padding: 0; counter-reset: rank; }
.ladder li {
  display: grid;
  grid-template-columns: 2.2rem 1fr auto auto auto;
  align-items: baseline;
  gap: 0.5rem 1rem;
  padding: 0.7rem 0.25rem;
  border-bottom: 1px solid rgba(200, 151, 90, 0.12);
}
.ladder li:last-child { border-bottom: 0; }

/* The top three carry the rarity ladder's colours, so the site and the game
   agree on what "best" looks like. */
.ladder li:nth-child(1) .ladder__rank { color: var(--aether); }
.ladder li:nth-child(2) .ladder__rank { color: var(--steel); }
.ladder li:nth-child(3) .ladder__rank { color: var(--bronze); }

.ladder__rank {
  font-family: "Marcellus SC", serif;
  font-size: 0.9rem;
  color: var(--ink-dim);
  text-align: right;
}
.ladder__name {
  font-family: "Marcellus SC", serif;
  color: var(--bone);
  letter-spacing: 0.04em;
  overflow-wrap: anywhere;
}
.ladder__class, .ladder__detail {
  font-size: 0.76rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.ladder__value {
  font-family: "Marcellus SC", serif;
  color: var(--aether);
  font-size: 1rem;
  min-width: 3ch;
  text-align: right;
}
.board h2 { margin-bottom: 0.3em; }

/* Inside a skill card the class and detail columns are noise — the name and the
   number are the whole story. */
.card .ladder li { grid-template-columns: 1.8rem 1fr auto; padding: 0.5rem 0; }
.card .ladder .ladder__class, .card .ladder .ladder__detail { display: none; }

@media (max-width: 560px) {
  .ladder li { grid-template-columns: 2rem 1fr auto; }
  .ladder__class, .ladder__detail { display: none; }
}

/* ---------- News cards ---------- */

.newscards { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.newscard {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(26, 22, 24, 0.9), rgba(13, 11, 12, 0.9));
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  transition: border-color 200ms ease, transform 200ms ease;
}
.newscard:hover { border-color: var(--bronze); transform: translateY(-3px); }
.newscard__img { aspect-ratio: 16 / 9; overflow: hidden; background: var(--charcoal); }
.newscard__img img { width: 100%; height: 100%; object-fit: cover; transition: transform 400ms ease; }
.newscard:hover .newscard__img img { transform: scale(1.05); }
.newscard__body { padding: 1.2rem 1.3rem 1.4rem; display: flex; flex-direction: column; gap: 0.5rem; }
.newscard__tag {
  font-family: "Marcellus SC", serif;
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--void);
  background: var(--bronze);
  align-self: flex-start;
  padding: 0.25em 0.7em;
}
.newscard h3 { margin: 0.2em 0 0; color: var(--bone); font-size: 1.05rem; }
.newscard p { margin: 0; font-size: 0.92rem; color: var(--ink-dim); max-width: none; }
.newscard time {
  font-family: "Marcellus SC", serif;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bronze);
}
@media (prefers-reduced-motion: reduce) {
  .newscard, .newscard__img img { transition: none; }
  .newscard:hover { transform: none; }
  .newscard:hover .newscard__img img { transform: none; }
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: var(--gutter);
  top: 0.5rem;
  z-index: 100;
  background: var(--charcoal);
  color: var(--bone);
  padding: 0.6em 1em;
  border: 1px solid var(--bronze);
}
