@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700&family=Poppins:wght@400;500;600&display=swap');

/*
 * Retebra -- retrowave, kept deliberately quiet.
 *
 * The identity (violet night, neon, the horizon grid) stays; what changed is how often it
 * speaks. Neon is now reserved for four things only: the logo, the section you are in, the
 * element you have focused, and the one number a page is actually about. Everything else --
 * panels, tables, forms -- is built from hairlines and barely-there surfaces, so the glow
 * reads as emphasis again instead of as the default state of every pixel.
 */

:root {
  /* Ground: two stops of the same violet night, darkest at the horizon */
  --night: #150b26;
  --void: #07030e;

  /* Surfaces are a lift off the ground, never a box drawn around content */
  --surface: rgba(255, 255, 255, 0.035);
  --surface-hover: rgba(255, 255, 255, 0.055);
  --line: rgba(176, 142, 228, 0.14);
  --line-strong: rgba(176, 142, 228, 0.26);

  /* Two accents, with one job each: cyan acts, magenta brands */
  --cyan: #4fe3ff;
  --magenta: #ff3db0;

  --text: #ece4fb;
  --muted: #a99bc9;

  --glow-cyan: 0 0 12px rgba(79, 227, 255, 0.45);
  --glow-magenta: 0 0 14px rgba(255, 61, 176, 0.45);

  /* One spacing scale, used everywhere */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;

  --radius: 14px;
  --quick-nav-height: 60px;
}

* { box-sizing: border-box; }

/*
 * CRT scanlines over everything. Kept at a few percent: enough to give the page the texture
 * of a screen from the era, far too faint to fight the text for attention.
 */
html::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  /* plain alpha rather than a blend mode: multiply here composites against the whole page and
     flattened the banner (its gradient text and isolated stacking context) to black */
  background: repeating-linear-gradient(180deg, rgba(0, 0, 0, 0.22) 0 1px, transparent 1px 3px);
  opacity: 0.4;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--void);
  color: var(--text);
  font-family: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/*
 * The sky the landscape stands in. The ground itself -- the grid and the ranges walking out of
 * it -- is no longer CSS: it is one canvas (scene.js) so that both share a single perspective
 * and a ridge can actually meet the floor where its grid line does.
 */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -4;
  pointer-events: none;
  background:
    radial-gradient(90% 46% at 50% 100%, rgba(255, 61, 176, 0.26) 0%, transparent 70%),
    radial-gradient(60% 18% at 50% 100%, rgba(255, 138, 210, 0.18) 0%, transparent 75%),
    linear-gradient(180deg, var(--night) 0%, #0d0619 58%, var(--void) 100%);
}

/* Behind the landscape and deliberately unmasked -- the sky is the one thing that should reach
   the top of the page */
.sky {
  position: fixed;
  inset: 0;
  z-index: -3;
  display: block;
  pointer-events: none;
}

.scene {
  position: fixed;
  inset: 0;
  z-index: -2;
  display: block;
  pointer-events: none;
  opacity: 0.85;
  /*
   * The range comes out of a haze instead of appearing whole. The fade has to bite well below
   * the content: the peaks are tall by design now, and without this they climb straight
   * through the panels. Losing their summits to the haze is the point -- it reads as distance,
   * and it keeps the text unobstructed.
   */
  /* The range now keeps to the horizon instead of towering over the page, so the haze can sit
     much higher and let the far peaks be seen whole */
  mask-image: linear-gradient(to top, black 44%, rgba(0, 0, 0, 0.6) 66%, transparent 86%);
  -webkit-mask-image: linear-gradient(to top, black 44%, rgba(0, 0, 0, 0.6) 66%, transparent 86%);
}

a {
  color: var(--cyan);
  text-decoration: none;
  transition: color 0.15s ease;
}

a:hover { color: #a5f0ff; }

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

/* ---------------------------------------------------------------- banner */

.banner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 232px;
  overflow: hidden;
  border-bottom: 1px solid var(--line-strong);
  background:
    linear-gradient(180deg, rgba(10, 4, 20, 0.85) 0%, rgba(24, 10, 44, 0.2) 55%, rgba(255, 61, 176, 0.14) 100%);
  isolation: isolate;
}

/* The banner's horizon line */
.banner::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--magenta) 30%, #ffc2e6 50%, var(--magenta) 70%, transparent);
  opacity: 0.85;
  box-shadow: 0 0 22px rgba(255, 61, 176, 0.75);
}

.banner-title {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 280px;
  max-width: calc(100% - 32px);
  height: calc(100% - 16px);
}

.banner-logo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* ---------------------------------------------------------- quick access */

.quick-nav {
  position: sticky;
  top: 0;
  z-index: 1000;
  height: var(--quick-nav-height);
  border-bottom: 1px solid var(--line-strong);
  background: #0d0619;
}

.quick-nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  height: 100%;
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--s-4);
}

.quick-nav-sections { display: flex; gap: var(--s-2); min-width: 0; }
.quick-nav-group { position: relative; }

.quick-nav-group > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  min-height: 44px;
  padding: 8px var(--s-3);
  list-style: none;
  cursor: pointer;
  font-family: 'Orbitron', sans-serif;
  font-size: 12px;
  letter-spacing: 0;
  white-space: nowrap;
  color: var(--text);
  border-bottom: 2px solid transparent;
}

.quick-nav-group > summary::-webkit-details-marker { display: none; }
.quick-nav-group > summary::after {
  content: '';
  width: 6px;
  height: 6px;
  flex: 0 0 6px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
}

.quick-nav-group[open] > summary::after { transform: rotate(225deg) translate(-2px, -2px); }
.quick-nav-group.active > summary { border-bottom-color: var(--magenta); }
.quick-nav-group[open] > summary, .quick-nav-group > summary:hover { color: var(--cyan); background: var(--surface-hover); }

.quick-nav-menu {
  position: absolute;
  top: 100%;
  left: 0;
  width: 220px;
  padding: var(--s-2);
  border: 1px solid var(--line-strong);
  border-radius: 0 0 6px 6px;
  background: #10091c;
  box-shadow: 0 8px 18px #0007;
  max-height: calc(100dvh - var(--quick-nav-height) - 16px);
  overflow-y: auto;
}

.quick-nav-menu a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 8px var(--s-3);
  color: var(--text);
  overflow-wrap: anywhere;
}

.quick-nav-menu a:hover, .quick-nav-menu a[aria-current='page'] { color: var(--cyan); background: var(--surface-hover); }
.quick-nav .quick-account { flex-shrink: 0; justify-content: center; min-height: 44px; border-radius: 6px; letter-spacing: 0; }

/* ---------------------------------------------------------------- layout */

.layout {
  display: flex;
  align-items: flex-start;
  min-height: 100vh;
}

.sidebar {
  width: 232px;
  flex: 0 0 232px;
  padding: var(--s-6) var(--s-4);
  position: sticky;
  top: var(--quick-nav-height);
  height: calc(100vh - var(--quick-nav-height));
  overflow-y: auto;
  scrollbar-width: none;
  border-right: 1px solid var(--line);
  /* The landscape runs along the bottom of the viewport, straight behind the lower nav items.
     This keeps the ground from being read as part of the words in front of it. */
  background: linear-gradient(180deg, transparent 0%, rgba(7, 3, 14, 0.55) 55%, rgba(7, 3, 14, 0.8) 100%);
}

.sidebar::-webkit-scrollbar { display: none; }

.content {
  flex: 1;
  /* width + min-width together stop a wide child (a table) from stretching this column past
     the viewport: the auto margins that centre it would otherwise defeat the flex stretch and
     let it shrink-wrap its widest content instead */
  width: 100%;
  min-width: 0;
  max-width: 940px;
  margin: 0 auto;
  padding: var(--s-7) var(--s-6) 96px;
}

/* The Play Now promo image: a third column beside the content, same sticky treatment as the
   sidebar on the other side. */
.promo-rail {
  flex: 0 0 260px;
  width: 260px;
  padding: var(--s-7) var(--s-6) 0 0;
  position: sticky;
  top: var(--quick-nav-height);
  align-self: flex-start;
}

.promo-rail img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  transition: border-color 0.2s ease, filter 0.2s ease;
}

.promo-rail a:hover img {
  border-color: var(--cyan);
  filter: brightness(1.08);
}

/* ------------------------------------------------------------------ brand */

.sidebar-logo {
  display: block;
  text-align: center;
  margin-bottom: var(--s-7);
  color: inherit;
}

.sidebar-logo img {
  display: block;
  width: 160px;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
}

/* -------------------------------------------------------------- side nav */

.side-nav {
  display: flex;
  flex-direction: column;
  /* the sections space themselves -- see .side-section */
  gap: 0;
}

.side-section {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: var(--s-5);
}

/*
 * The section headers are the map of the site, so they are set as headers and not as the faint
 * grey captions they used to be: an Orbitron cap, its own lit edge, and a surface behind it.
 * The section you are inside takes the magenta -- a different colour from the cyan that marks
 * the individual page -- so "which part of the site am I in" and "which page am I on" are
 * answered separately instead of competing for the same highlight.
 */
.side-section-title {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-family: 'Orbitron', sans-serif;
  font-weight: 700;
  font-size: 0.74rem;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--text);
  margin: 0 0 var(--s-2);
  padding: var(--s-2) var(--s-3);
  border-left: 3px solid var(--line-strong);
  border-radius: 0 8px 8px 0;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.06), transparent 82%);
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

.side-section-mark {
  font-size: 0.62em;
  line-height: 1;
  color: var(--muted);
  transition: color 0.2s ease;
}

.side-section.active .side-section-title {
  color: #fff;
  border-left-color: var(--magenta);
  background: linear-gradient(90deg, rgba(255, 61, 176, 0.2), rgba(255, 61, 176, 0.04) 60%, transparent 90%);
  text-shadow: var(--glow-magenta);
}

.side-section.active .side-section-mark {
  color: var(--magenta);
  animation: nav-breathe 2.6s ease-in-out infinite;
}

.side-link {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  font-family: 'Poppins', sans-serif;
  font-size: 0.875rem;
  color: var(--muted);
  padding: var(--s-2) var(--s-3);
  border: none;
  border-radius: 0 6px 6px 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  transition:
    color 0.18s ease,
    background 0.18s ease,
    transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}

/* The neon edge grows out of the middle rather than just switching on */
.side-link::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--cyan);
  box-shadow: var(--glow-cyan);
  transform: scaleY(0);
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}

/* A light passes across the item on the way in */
.side-link::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(79, 227, 255, 0.16), transparent);
  transform: translateX(-100%);
  pointer-events: none;
}

/* Every link now sits under a section header, so the indent that used to be opt-in is the rule */
.side-section .side-link {
  padding-left: var(--s-5);
  font-size: 0.82rem;
}

.side-link:hover,
.side-link:focus-visible {
  color: var(--text);
  background: var(--surface);
  transform: translateX(5px);
}

.side-link:hover::before,
.side-link:focus-visible::before { transform: scaleY(1); }

.side-link:hover::after,
.side-link:focus-visible::after {
  animation: nav-sweep 0.65s ease-out;
}

@keyframes nav-sweep {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}

/* Where you are: a lit edge that keeps breathing, so the eye can find it while scrolling */
.side-link.active {
  color: #fff;
  background: linear-gradient(90deg, rgba(79, 227, 255, 0.12), transparent 72%);
  text-shadow: var(--glow-cyan);
}

.side-link.active::before {
  transform: scaleY(1);
  animation: nav-breathe 2.6s ease-in-out infinite;
}

@keyframes nav-breathe {
  0%, 100% { opacity: 1; box-shadow: var(--glow-cyan); }
  50% { opacity: 0.55; box-shadow: 0 0 4px rgba(79, 227, 255, 0.3); }
}

/* --------------------------------------------------------------- panels */

/*
 * Every window on the site is this one thing: a solid dark card, lifted off the landscape by
 * its own shadow, with a titled header ruled off from its contents. Standard on purpose --
 * against a moving background, a container that only whispers stops reading as a container at
 * all, and a page of differently-shaped whispers reads as clutter.
 */
.panel {
  position: relative;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.012) 40%),
    rgba(13, 6, 25, 0.95);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: var(--s-5) var(--s-6) var(--s-6);
  margin-bottom: var(--s-5);
  overflow: hidden;
  box-shadow:
    0 18px 45px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(0, 0, 0, 0.35);
}

/* A lit seam along the top edge -- the panel catching the same light the sun gives off */
.panel::before {
  content: "";
  position: absolute;
  top: 0;
  left: 8%;
  right: 8%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 61, 176, 0.65) 25%, rgba(79, 227, 255, 0.7) 60%, transparent);
}

.panel > :last-child { margin-bottom: 0; }

/* The window's title bar: same rule under every heading, on every page */
.panel > h1,
.panel > h2,
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  margin: 0 calc(var(--s-6) * -1) var(--s-5);
  padding: 0 var(--s-6) var(--s-4);
  border-bottom: 1px solid var(--line-strong);
}

.panel > h1,
.panel > h2,
.panel-head > h1,
.panel-head > h2 {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  color: #fff;
  letter-spacing: 0.02em;
}

.panel-head > h1,
.panel-head > h2 {
  margin: 0;
  padding: 0;
  border: none;
  flex: 1;
}

.panel > h1,
.panel-head > h1 { font-size: 1.45rem; }

.panel > h2,
.panel-head > h2 {
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

.muted { color: var(--muted); }

/* ----------------------------------------------------------------- stats */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: var(--s-5);
  text-align: center;
}

/* The number a page is about: the second place neon is deliberate */
.stat-grid .stat-value {
  font-family: 'Orbitron', sans-serif;
  font-weight: 700;
  font-size: 2rem;
  line-height: 1.15;
  color: #fff;
  font-variant-numeric: tabular-nums;
  text-shadow: var(--glow-magenta);
}

/*
 * A stat whose value is a word, not a number ("Elite Knight", "Premium"). The big glowing
 * treatment above is built for digits: set a phrase in it and it shouts, wraps badly, and
 * drags the eye away from whatever number is sitting next to it.
 */
.stat-grid .stat-value.stat-text {
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--text);
  text-shadow: none;
  /* keeps a word-value optically centred against the digits beside it */
  padding: var(--s-2) 0;
}

.stat-grid .stat-label {
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: var(--s-2);
}

/* ---------------------------------------------------------------- tables */

/*
 * A leaderboard has more columns than a phone has room for. Scrolling the table sideways on
 * its own keeps the panel (and the page) from being dragged out of the viewport with it.
 */
.table-scroll {
  overflow-x: auto;
  margin: 0 calc(var(--s-3) * -1);
  padding: 0 var(--s-3);
}

table.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

table.data-table th {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: left;
  padding: 0 var(--s-3) var(--s-3);
  border-bottom: 1px solid var(--line-strong);
}

table.data-table td {
  padding: var(--s-3);
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}

table.data-table tbody tr:last-child td { border-bottom: none; }

table.data-table tbody tr {
  transition: background 0.12s ease;
}

table.data-table tbody tr:hover td { background: var(--surface-hover); }

/*
 * The podium is the only colour a leaderboard needs. It is marked in the markup rather than by
 * position, because with paging "the first three rows" and "the top three players" stopped
 * being the same thing -- a CSS nth-child rule would decorate #26, #27 and #28 on page two.
 */
.rank-cell {
  color: var(--muted);
  white-space: nowrap;
}

.rank-cell.podium {
  color: var(--magenta);
  font-weight: 600;
}

/*
 * A key/value sheet rather than a grid of records: the character page lists one fact per row,
 * label on the left. Same table furniture as every other table so the two never look like
 * different components.
 */
table.data-table.info-table th[scope="row"] {
  width: 38%;
  padding: var(--s-3);
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  color: var(--muted);
  vertical-align: top;
}

table.data-table.info-table tbody tr:last-child th { border-bottom: none; }

table.death-table th[scope='row'] {
  width: 140px;
  padding: var(--s-3);
  font-family: inherit;
  font-size: inherit;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  vertical-align: top;
  border-bottom-color: rgba(255, 255, 255, 0.04);
}

table.death-table td { overflow-wrap: anywhere; vertical-align: top; }
table.death-table tbody tr:last-child th { border-bottom: none; }
.character-deaths .panel-head { flex-wrap: wrap; }
.character-deaths { scroll-margin-top: calc(var(--quick-nav-height) + 12px); }

.status-premium,
/* the stat tile sets its own colour at a higher specificity than a bare class can beat */
.stat-grid .stat-value.status-premium {
  color: #ffd45e;
  text-shadow: 0 0 10px rgba(255, 212, 94, 0.4);
}

/*
 * One button for every action that lives inside a window (logging out, creating a character).
 * Separate from .form-submit, which is the full-width one a form ends on.
 */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cyan);
  background: rgba(79, 227, 255, 0.07);
  border: 1px solid rgba(79, 227, 255, 0.45);
  border-radius: 999px;
  padding: 7px var(--s-4);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.16s ease, color 0.16s ease, box-shadow 0.16s ease;
}

.btn:hover {
  background: var(--cyan);
  color: var(--void);
  box-shadow: var(--glow-cyan);
}

/* The way out is not the thing you want the eye pulled towards */
.btn-quiet {
  color: var(--muted);
  background: transparent;
  border-color: var(--line-strong);
}

.btn-quiet:hover {
  background: rgba(255, 61, 176, 0.14);
  border-color: rgba(255, 61, 176, 0.5);
  color: #fff;
  box-shadow: none;
}

.rank-badge {
  display: inline-block;
  padding: 2px var(--s-2);
  border-radius: 999px;
  font-family: 'Orbitron', sans-serif;
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 1px solid var(--line-strong);
  color: var(--muted);
}

/* ----------------------------------------------------------------- forms */

/*
 * A form panel is the same window as every other one -- same width, same place on the page.
 * It used to shrink to 400px, which is what made stepping from Houses to Characters feel like
 * the site had changed shape under you. Only the form inside it is narrow now.
 */
.form-panel > form,
.form-panel > p,
.form-panel > .form-error {
  max-width: 400px;
  margin-left: auto;
  margin-right: auto;
}

.form-field { margin-bottom: var(--s-4); }

.form-field label {
  display: block;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--s-2);
}

.form-field input,
.form-field select,
.filter-form select,
.search-form input {
  width: 100%;
  background: rgba(0, 0, 0, 0.32);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px var(--s-3);
  color: var(--text);
  font-family: 'Poppins', sans-serif;
  font-size: 0.9rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form-field input::placeholder,
.search-form input::placeholder { color: var(--muted); opacity: 0.6; }

/*
 * Dropdowns.
 *
 * A bare <select> is drawn by the operating system: grey box, white text, a blue highlight that
 * belongs to Windows and not to this page. Stripping the native appearance and drawing the
 * chevron ourselves puts the closed control back under our own palette. The open list is the
 * browser's own popup and cannot be laid out from here, but colouring the options does carry
 * into it, so at least it stops being grey-on-blue.
 */
.select-wrap {
  position: relative;
  display: block;
}

.select-wrap select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: var(--s-6);
  cursor: pointer;
}

.select-wrap::after {
  content: "";
  position: absolute;
  right: var(--s-4);
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -5px;
  border-right: 2px solid var(--cyan);
  border-bottom: 2px solid var(--cyan);
  transform: rotate(45deg);
  pointer-events: none;
  transition: border-color 0.15s ease;
}

.select-wrap:hover::after { border-color: #a5f0ff; }

.select-wrap select:hover {
  border-color: var(--line-strong);
  background-color: rgba(79, 227, 255, 0.06);
}

/* Carried into the browser's own popup list -- the one part of a native dropdown that can
   still be given the page's colours */
.select-wrap select option {
  background-color: #150b26;
  color: var(--text);
}

.select-wrap select option:checked {
  background-color: #2a1140;
  color: #fff;
}

/* Focus is exactly where a glow earns its keep: it tells you where you are typing */
.form-field input:focus,
.form-field select:focus,
.filter-form select:focus,
.search-form input:focus {
  outline: none;
  border-color: var(--cyan);
  box-shadow: var(--glow-cyan);
}

.form-submit,
.search-form button {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: transparent;
  border: 1px solid var(--cyan);
  color: var(--cyan);
  border-radius: 8px;
  padding: 11px var(--s-5);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

.form-submit { width: 100%; }

.form-submit:hover,
.search-form button:hover {
  background: var(--cyan);
  color: var(--void);
  box-shadow: var(--glow-cyan);
}

.form-error {
  background: rgba(255, 61, 176, 0.1);
  border: 1px solid rgba(255, 61, 176, 0.45);
  border-radius: 8px;
  color: var(--text);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-4);
  font-size: 0.875rem;
}

/* Same box as .form-error, in the site's cyan instead of magenta: a change went through */
.admin-notice {
  background: rgba(79, 227, 255, 0.08);
  border: 1px solid rgba(79, 227, 255, 0.4);
  border-radius: 8px;
  color: var(--text);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-4);
  font-size: 0.875rem;
}

.admin-form h2 { margin-top: 0; }

.form-footer-note {
  text-align: center;
  margin-top: var(--s-4);
  font-size: 0.875rem;
}

.search-form {
  display: flex;
  gap: var(--s-2);
}

.search-form input { flex: 1; }
.search-form button { flex: 0 0 auto; }

.filter-form {
  display: flex;
  gap: var(--s-4);
  flex-wrap: wrap;
  margin-bottom: var(--s-5);
}

.filter-form .form-field {
  margin-bottom: 0;
  min-width: 180px;
  /* capped, so a page with a single filter gets a dropdown and not a control stretched across
     the whole window */
  max-width: 280px;
  flex: 1;
}

.town-group { margin-bottom: var(--s-6); }
.town-group h2 { margin-bottom: var(--s-3); }

/* ------------------------------------------------------- panel furniture */

/*
 * The quiet half of a window's title bar: a count, a category, a state. It sits opposite the
 * heading and is never the thing you read first.
 */
.panel-note {
  font-family: 'Orbitron', sans-serif;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.panel-note-warn { color: #ffd45e; }

.panel-actions {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

/*
 * Every list window is the same window: the same width as all the others (the content column
 * settles that) and a floor under its height, so stepping from a city with four houses to one
 * with forty does not make the page jump around. With a fixed page size the full ones already
 * match each other; this is what keeps the short ones in line too.
 */
.panel-list {
  display: flex;
  flex-direction: column;
  min-height: 560px;
}

.panel-list-body { flex: 1; }

/* ------------------------------------------------------------ pagination */

/*
 * Drawn above and below the list both. The one at the bottom is the point: having read to the
 * end of a page, the next page should be right there, not back at the top.
 */
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-bottom: var(--s-4);
}

.pager-bottom {
  margin-top: var(--s-5);
  margin-bottom: var(--s-2);
}

.pager-numbers {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  flex-wrap: wrap;
  justify-content: center;
}

.pager-number,
.pager-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  justify-content: center;
  min-width: 34px;
  height: 34px;
  padding: 0 var(--s-3);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: 'Orbitron', sans-serif;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  background: rgba(0, 0, 0, 0.25);
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.pager-number:hover,
.pager-arrow:hover {
  color: var(--text);
  border-color: var(--line-strong);
  background: var(--surface-hover);
}

.pager-number.active {
  color: var(--void);
  background: var(--cyan);
  border-color: var(--cyan);
  box-shadow: var(--glow-cyan);
}

.pager-arrow-label {
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* An end of the list is not an error -- the arrow stays in place and stops responding */
.pager-arrow.disabled {
  opacity: 0.32;
  pointer-events: none;
}

.pager-gap {
  color: var(--muted);
  padding: 0 var(--s-1);
}

.pager-count {
  text-align: center;
  font-size: 0.75rem;
  margin: 0;
}

/* ------------------------------------------------------------------ news */

.news-list {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
}

.news-item {
  padding-left: var(--s-4);
  border-left: 2px solid var(--line-strong);
}

.news-item:hover { border-left-color: var(--magenta); }

.news-meta {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-2);
}

.news-date {
  font-family: 'Orbitron', sans-serif;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.news-tag {
  font-family: 'Orbitron', sans-serif;
  font-size: 0.58rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 2px var(--s-2);
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  color: var(--muted);
}

/* The tag says what kind of post it is, so the four kinds have to be told apart at a glance */
.news-tag-update { color: var(--cyan); border-color: rgba(79, 227, 255, 0.45); }
.news-tag-fix { color: #8affc4; border-color: rgba(138, 255, 196, 0.4); }
.news-tag-event { color: var(--magenta); border-color: rgba(255, 61, 176, 0.45); }
.news-tag-notice { color: #ffd45e; border-color: rgba(255, 212, 94, 0.4); }

.news-title {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: 1.05rem;
  color: #fff;
  margin: 0 0 var(--s-2);
}

.news-item p { margin: 0 0 var(--s-3); }
.news-item > :last-child { margin-bottom: 0; }

.news-link {
  font-size: 0.85rem;
}

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

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--s-4);
}

.guide-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.25);
  color: var(--text);
  transition: border-color 0.18s ease, background 0.18s ease, transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}

.guide-card:hover {
  border-color: rgba(79, 227, 255, 0.5);
  background: rgba(79, 227, 255, 0.06);
  color: var(--text);
  transform: translateY(-3px);
}

.guide-card-tagline {
  font-family: 'Orbitron', sans-serif;
  font-size: 0.58rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--magenta);
}

.guide-card-title {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: 1rem;
  color: #fff;
  margin: 0;
}

.guide-card-summary {
  font-size: 0.85rem;
  color: var(--muted);
  margin: 0;
  flex: 1;
}

.guide-card-more {
  font-family: 'Orbitron', sans-serif;
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cyan);
}

.card-grid-compact .guide-card-summary { display: none; }

/* ---------------------------------------------------------------- guides */

.guide-lead {
  font-size: 1rem;
  color: var(--text);
  margin: 0 0 var(--s-6);
  max-width: 62ch;
}

.guide-block { margin-bottom: var(--s-6); }

.guide-block-title {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--cyan);
  margin: 0 0 var(--s-3);
}

.guide-block p { max-width: 62ch; margin: 0 0 var(--s-3); }

.guide-list {
  margin: 0;
  padding-left: var(--s-5);
  max-width: 62ch;
}

.guide-list li { margin-bottom: var(--s-2); }

.guide-note { font-size: 0.82rem; margin-top: 0; }

.guide-source {
  font-size: 0.75rem;
  margin: 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}

.guide-source code {
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
  color: var(--cyan);
}

/* --------------------------------------------------------- account cards */

.action-grid {
  display: grid;
  /* narrow enough that the three of them still sit on one row inside the content column */
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--s-3);
}

.action-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.25);
  color: var(--text);
  transition: border-color 0.18s ease, background 0.18s ease;
}

.action-card:hover {
  border-color: rgba(79, 227, 255, 0.5);
  background: rgba(79, 227, 255, 0.06);
  color: var(--text);
}

.action-card-title {
  font-family: 'Orbitron', sans-serif;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
}

.action-card-note {
  font-size: 0.8rem;
  color: var(--muted);
}

/* The one button on the page that is about spending money -- gold, not cyan */
.btn-coin {
  color: #ffd45e;
  background: rgba(255, 212, 94, 0.08);
  border-color: rgba(255, 212, 94, 0.45);
}

.btn-coin:hover {
  background: #ffd45e;
  color: var(--void);
  box-shadow: 0 0 14px rgba(255, 212, 94, 0.45);
}

/* ----------------------------------------------------------- guild logos */

/*
 * The crest frame is drawn whether or not there is an image in it: an empty frame with the
 * guild's initial says "a logo goes here" far better than blank space does, and it keeps the
 * row heights identical between guilds that have one and guilds that do not.
 */
.guild-crest {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.35);
}

.guild-crest img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.guild-crest-empty {
  font-family: 'Orbitron', sans-serif;
  font-weight: 700;
  color: var(--muted);
  opacity: 0.6;
}

.guild-crest-small { width: 34px; height: 34px; }
.guild-crest-small .guild-crest-empty { font-size: 0.85rem; }

.guild-crest-large { width: 104px; height: 104px; border-radius: 14px; }
.guild-crest-large .guild-crest-empty { font-size: 2.2rem; }

.col-logo { width: 34px; }

.guild-identity {
  display: flex;
  align-items: center;
  gap: var(--s-5);
}

.guild-identity-name {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: 1.1rem;
  color: #fff;
  margin: 0 0 var(--s-1);
}

.guild-identity-text p { margin: 0; font-size: 0.85rem; }

.guild-logo-form {
  margin-top: var(--s-5);
  padding-top: var(--s-5);
  border-top: 1px solid var(--line);
  max-width: 460px;
}

.form-hint { font-size: 0.78rem; margin: calc(var(--s-2) * -1) 0 var(--s-3); }

.review-list {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.review-item {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.25);
}

.review-item-text { flex: 1; min-width: 0; }

.review-item-text h3 {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: 0.95rem;
  margin: 0 0 var(--s-1);
}

.review-item-text p { margin: 0; font-size: 0.8rem; }

/* A submitted URL can be any length at all and must not push the buttons off the card */
.review-url {
  color: var(--muted);
  overflow-wrap: anywhere;
}

.review-actions {
  display: flex;
  gap: var(--s-2);
  flex: none;
}

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

@media (max-width: 860px) {
  :root { --quick-nav-height: 104px; }
  .quick-nav-inner { gap: var(--s-2); padding: 0 var(--s-3); }
  .quick-nav-sections { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--s-1); flex: 1; }
  .quick-nav-group { position: static; min-width: 0; }
  .quick-nav-group > summary { height: 44px; padding: 8px 6px; gap: 6px; font-size: 10px; line-height: 14px; white-space: normal; }
  .quick-nav-menu { left: var(--s-3); right: var(--s-3); width: auto; }
  .quick-nav .quick-account { padding: 8px 10px; font-size: 10px; }
  table.death-table th[scope='row'] { width: 104px; padding: 10px 6px; font-size: 12px; }
  table.death-table td { padding: 10px 6px; font-size: 12px; }

  /*
   * Stacked, the children must fill the width. The flex-start above is there to keep the
   * sidebar and the content top-aligned side by side; left on in column direction it makes
   * each child shrink to its own content instead, so a wide table drags the whole page
   * sideways past the viewport.
   */
  .layout {
    flex-direction: column;
    align-items: stretch;
  }

  /* The quick-nav's own Account button already covers the phone-width case; the promo image
     is a nice-to-have that would otherwise push everything else below the fold */
  .promo-rail {
    display: none;
  }

  .sidebar {
    width: 100%;
    flex: none;
    position: static;
    height: auto;
    padding: var(--s-5) var(--s-4);
    border-right: none;
    border-bottom: 1px solid var(--line);
  }

  /* On a phone the nav is a header, not a column: it has to cost as little height as it can,
     or the first screenful is all chrome and no content */
  .sidebar-logo {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: var(--s-3);
    margin-bottom: var(--s-4);
  }

  .sidebar-logo img { width: 124px; }

  .side-nav {
    flex-direction: column;
    gap: var(--s-3);
  }

  /* Each section keeps its header on its own line and lets its links wrap into a row under it,
     so the sections stay legible as sections instead of melting into one strip of chips */
  .side-section {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-1);
    margin-bottom: 0;
  }

  .side-section-title {
    width: 100%;
    margin-bottom: var(--s-1);
  }

  /* Laid out in a row, the lit edge belongs under the item, not beside it */
  .side-link {
    width: auto;
    border-radius: 6px;
  }

  .side-link::before {
    left: 0;
    right: 0;
    top: auto;
    bottom: 0;
    width: auto;
    height: 2px;
    transform: scaleX(0);
  }

  .side-link:hover,
  .side-link:focus-visible { transform: none; }

  .side-link:hover::before,
  .side-link:focus-visible::before,
  .side-link.active::before { transform: scaleX(1); }

  .side-section .side-link { padding-left: var(--s-3); }

  .side-link.active { background: rgba(79, 227, 255, 0.11); }

  .content { padding: var(--s-5) var(--s-4) 72px; }

  .panel { padding: var(--s-5); }

  .banner { height: 156px; }

  /* The floor under a list window is there to stop desktop pages jumping between sections; on
     a phone it only ever adds empty scrolling */
  .panel-list { min-height: 0; }

  .guild-identity {
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
  }

  .review-item {
    flex-direction: column;
    align-items: flex-start;
  }

  .review-actions { width: 100%; }

  /* The word beside each arrow is the first thing to go when the strip runs out of room */
  .pager-arrow-label { display: none; }

}

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