/* ===========================================================================
   The Demonlist -- stylesheet
   Dark, high-contrast, built around a rank-first reading order.
   =========================================================================== */

:root {
  --bg:            #0a0b12;
  --bg-elevated:   #12141f;
  --bg-raised:     #191c2b;
  --line:          #262a3d;
  --line-soft:     #1d2030;

  --text:          #eef0f8;
  --text-muted:    #939ab5;
  --text-faint:    #646b87;

  --accent:        #ff5c5c;
  --accent-bright: #ff849f;
  --cyan:          #35d6f5;
  --gold:          #ffc94a;
  --silver:        #cfd6e6;
  --bronze:        #e08a4c;
  --danger:        #ff5f6d;
  --green:         #3ddc97;

  --radius:     14px;
  --radius-sm:  9px;

  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  background-image:
    radial-gradient(900px 500px at 12% -8%, rgba(124, 92, 255, 0.20), transparent 65%),
    radial-gradient(760px 460px at 92% 4%, rgba(53, 214, 245, 0.12), transparent 62%);
  background-attachment: fixed;
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

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

a { color: var(--accent-bright); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { line-height: 1.2; margin: 0 0 0.5em; letter-spacing: -0.02em; }
h1 { font-size: clamp(2rem, 5vw, 3.1rem); font-weight: 800; }
h2 { font-size: clamp(1.4rem, 3vw, 1.9rem); font-weight: 700; }
h3 { font-size: 1.1rem; font-weight: 650; }
p  { margin: 0 0 1rem; }

code, pre { font-family: var(--mono); font-size: 0.9em; }
pre {
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.85rem 1rem;
  overflow-x: auto;
}
code { background: rgba(124, 92, 255, 0.14); padding: 0.12em 0.4em; border-radius: 5px; }
pre code { background: none; padding: 0; }

.wrap { width: min(1140px, 100% - 2.5rem); margin-inline: auto; }
.muted { color: var(--text-muted); }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: #fff; padding: 0.7rem 1.1rem; border-radius: 0 0 8px 0;
}
.skip-link:focus { left: 0; }

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

/* --- header / navbar ------------------------------------------------------ */

/* The bar itself is just the visual; stickiness lives on the #site-header
   wrapper below. A sticky element can only travel inside its own containing
   block, and this one's parent is exactly its own height -- so sticking it here
   would leave it nowhere to go. */
.site-header {
  background: rgba(10, 11, 18, 0.82);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line-soft);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 68px;
}

.brand { display: flex; align-items: center; gap: 0.7rem; color: var(--text); }
.brand:hover { text-decoration: none; }

.brand .brand-logo {
  width: 64px; height: 64px;
  border-radius: 9px;
}

.brand-mark {
  width: 34px; height: 34px;
  border-radius: 9px;
  background: linear-gradient(135deg, var(--accent) 0%, var(--cyan) 100%);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 8px 20px -8px var(--accent);
  transform: rotate(45deg) scale(0.86);
  flex: none;
}

.brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.brand-text strong { font-size: 1.06rem; font-weight: 800; letter-spacing: -0.02em; }
.brand-text small {
  font-size: 0.66rem; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: 0.16em; font-weight: 600;
}
.brand-text img {
  width: 356px;
}

/* Links and account menu share one row; margin-left:auto pushes the whole
   group right, and .nav-auth being last puts the account menu furthest right. */
.primary-nav {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
}
.primary-nav ul { display: flex; gap: 0.25rem; list-style: none; margin: 0; padding: 0; }
.primary-nav a {
  white-space: nowrap;
  display: block;
  padding: 0.5rem 0.95rem;
  border-radius: 5px;
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.94rem;
  transition: color 0.15s, background 0.15s;
}
.primary-nav a:hover { color: var(--text); background: var(--bg-raised); text-decoration: none; }
.primary-nav a.active {
  color: var(--text);
  background: linear-gradient(135deg, rgba(124, 92, 255, 0.28), rgba(53, 214, 245, 0.16));
  box-shadow: inset 0 0 0 1px rgba(124, 92, 255, 0.45);
}

/* --- overflow menu ---------------------------------------------------------
   One button at every width. It holds the secondary pages, and once the window
   is too narrow for the bar, the pinned links fold into it as well. */

.nav-more { position: relative; }

.nav-more-trigger {
  position: relative;
  display: grid;
  place-items: center;
  width: 40px;
  height: 36px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
}
.nav-more-trigger:hover { border-color: var(--accent); }

.nav-more-bars,
.nav-more-bars::before,
.nav-more-bars::after {
  position: absolute;
  left: 50%;
  width: 17px;
  height: 2px;
  background: var(--text);
  border-radius: 2px;
  transform: translateX(-50%);
  transition: transform 0.2s, opacity 0.2s;
}
.nav-more-bars { top: 50%; margin-top: -1px; }
.nav-more-bars::before { content: ""; top: -6px; }
.nav-more-bars::after  { content: ""; top: 6px; }

.nav-more-trigger[aria-expanded="true"] .nav-more-bars { background: transparent; }
.nav-more-trigger[aria-expanded="true"] .nav-more-bars::before {
  transform: translateX(-50%) translateY(6px) rotate(45deg);
}
.nav-more-trigger[aria-expanded="true"] .nav-more-bars::after {
  transform: translateX(-50%) translateY(-6px) rotate(-45deg);
}

/* Anything waiting in the mod queue has to show on the closed button, or it
   would be invisible now that the mod panel lives behind this menu. */
.nav-more-badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 17px;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 0.66rem;
  font-weight: 700;
  line-height: 17px;
  text-align: center;
}

.nav-more-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.5rem);
  min-width: 210px;
  padding: 0.4rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.9);
  z-index: 60;
}

/* display:block is explicit because `.primary-nav ul` sets flex at the same
   specificity; without it the menu items lay out in a row. */
.nav-more-panel ul { display: block; list-style: none; margin: 0; padding: 0; }
.nav-more-panel a {
  display: block;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  color: var(--text-muted);
  font-size: 0.92rem;
  font-weight: 600;
}
.nav-more-panel a:hover { background: var(--bg-raised); color: var(--text); text-decoration: none; }
.nav-more-panel a.active { color: var(--text); background: var(--bg-raised); }

/* The pinned links are rendered twice; exactly one copy is ever shown. */
/* Scoped to outrank `.primary-nav ul`, which sets display:flex at the same
   specificity -- otherwise the panel shows a second copy of Home and The List
   on desktop. */
.nav-more-panel .nav-more-pinned { display: none; }
.nav-more-pinned + .nav-more-links { border-top: 0; }

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

main { flex: 1 0 auto; padding-bottom: 4.5rem; }

.section { margin-top: 3.5rem; }
.section-head { margin-bottom: 1.5rem; }
.section-head p { margin: 0; max-width: 62ch; }

.eyebrow {
  display: inline-block;
  font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.18em;
  color: var(--cyan);
  margin-bottom: 0.75rem;
}

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

.hero { padding: 4.5rem 0 1rem; }
.hero h1 { margin-bottom: 1rem; }
.hero h1 .grad {
  background: linear-gradient(100deg, var(--accent-bright), var(--cyan));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero-lede { font-size: 1.14rem; color: var(--text-muted); max-width: 60ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.75rem; justify-content: center;}

.hero-logo { width: 100%; }

.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.72rem 1.4rem;
  border-radius: 5px;
  font-weight: 650; font-size: 0.95rem;
  border: 3px solid transparent;
  cursor: pointer;
  transition: transform 0.15s, box-shadow 0.15s, background 0.15s;
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }
.btn-primary {
  background: var(--accent);
  color: #fff;
}
.btn-primary:hover { border-color: var(--accent-bright);}
.btn-ghost { 
  background: var(--bg-raised); 
  border-color: var(--line); 
  color: var(--text); 
}
.btn-ghost:hover { border-color: var(--accent); }

/* --- stat tiles ----------------------------------------------------------- */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
  margin-top: 3rem;
}
.stat {
  background: linear-gradient(160deg, var(--bg-elevated), rgba(18, 20, 31, 0.55));
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1.25rem 1.35rem;
}
.stat-value {
  font-family: var(--mono);
  font-size: 2rem; font-weight: 700; line-height: 1;
  color: var(--text);
}
.stat-label {
  margin-top: 0.5rem;
  font-size: 0.78rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.11em;
  color: var(--text-faint);
}

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

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.1rem;
}
.card {
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1.4rem 1.5rem;
}
.card h3 { margin-bottom: 0.4rem; }
.card p:last-child { margin-bottom: 0; }
.card .card-num {
  font-family: var(--mono);
  font-size: 0.8rem; font-weight: 700;
  color: var(--accent-bright);
  display: block; margin-bottom: 0.6rem;
}

/* --- filter bar ----------------------------------------------------------- */

.filters {
  display: flex; flex-wrap: wrap; gap: 0.9rem; align-items: center;
  margin: 2rem 0 1.5rem;
  padding: 0.9rem 1rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}

.search-field { position: relative; flex: 1 1 260px; }
.search-field input {
  width: 100%;
  padding: 0.62rem 0.95rem 0.62rem 2.3rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text);
  font: inherit; font-size: 0.94rem;
}
.search-field input::placeholder { color: var(--text-faint); }
.search-field input:focus { border-color: var(--accent); outline: none; }
.search-field::before {
  content: "";
  position: absolute; left: 0.9rem; top: 50%;
  width: 13px; height: 13px; margin-top: -8px;
  border: 2px solid var(--text-faint); border-radius: 50%;
  pointer-events: none;
}

.tier-tabs { display: flex; gap: 0.35rem; flex-wrap: wrap; }
.tier-tabs button {
  padding: 0.45rem 0.9rem;
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.86rem; font-weight: 600;
  color: var(--text-muted);
  background: none;
  border: 1px solid var(--line);
  cursor: pointer;
  transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.tier-tabs button:hover { color: var(--text); border-color: var(--accent); }
.tier-tabs button.active { background: var(--accent); border-color: var(--accent); color: #fff; }

.result-count { font-size: 0.86rem; color: var(--text-faint); margin-left: auto; }

/* --- the list ------------------------------------------------------------- */

.level-list { display: flex; flex-direction: column; gap: 0.7rem; }

.level-row {
  display: grid;
  height: 196px;
  grid-template-columns: 62px 256px 1fr auto;
  align-items: center;
  gap: 1.1rem;
  padding: 0.85rem 1.15rem 0.85rem 0.85rem;
  background: var(--bg-elevated);
  border: 3px solid var(--line-soft);
  border-radius: var(--radius);
  transition: border-color 0.15s, transform 0.15s, background 0.15s;
}
.level-row:hover {
  border-color: rgba(124, 92, 255, 0.55);
  background: var(--bg-raised);
  transform: translateX(3px);
}

.level-rank {
  font-family: var(--mono);
  font-size: 1.55rem; font-weight: 700;
  text-align: center;
  color: var(--text-faint);
  letter-spacing: -0.03em;
}
.level-row[data-rank="1"] .level-rank { color: var(--gold); }
.level-row[data-rank="2"] .level-rank { color: var(--silver); }
.level-row[data-rank="3"] .level-rank { color: var(--bronze); }
.level-row[data-rank="1"] { border-color: rgba(255, 201, 74, 0.40); }
.level-row[data-rank="2"] { border-color: rgba(207, 214, 230, 0.28); }
.level-row[data-rank="3"] { border-color: rgba(224, 138, 76, 0.32); }

.level-thumb {
  width: 256px; aspect-ratio: 16 / 9;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: linear-gradient(135deg, #1b1f33, #2a2050);
  border: 1px solid var(--line);
  display: grid; place-items: center;
  flex: none;
}
.level-thumb img { width: 100%; height: 100%; object-fit: cover; }
.level-thumb .thumb-fallback {
  font-family: var(--mono); font-size: 1.3rem; font-weight: 700;
  color: rgba(255, 255, 255, 0.22);
}

.level-main { min-width: 0; }
.level-name {
  font-size: 1.12rem; font-weight: 700; letter-spacing: -0.01em;
  color: var(--text);
  display: inline-block;
}
.level-name:hover { color: var(--accent-bright); text-decoration: none; }

/* The whole card is one click target. Rather than wrapping the row in an
   anchor -- which would swallow the creator and verifier links inside it --
   the title's link grows a transparent layer over the card. It stays a single
   link in the accessibility tree, and the credit links below simply sit on a
   higher layer so they keep their own clicks. */
.level-name::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.level-by a { position: relative; z-index: 2; }

/* A level with artwork in media/logos shows it instead of its name. The height
   is capped rather than the width so wordmarks of different proportions all
   line up on the same baseline down the list. */
.level-logo {
  display: block;
  max-height: 52px;
  max-width: min(100%, 320px);
  width: auto;
  object-fit: contain;
  object-position: left center;
}
.level-name-logo { display: block; }

.level-by { font-size: 0.88rem; color: var(--text-muted); margin: 0.15rem 0 0; }
.level-by strong { color: var(--text); font-weight: 600; }

.level-tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }
.tag {
  font-size: 0.71rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.07em;
  padding: 0.2rem 0.5rem;
  border-radius: 5px;
  background: var(--bg-raised);
  color: var(--text-faint);
  border: 1px solid var(--line);
}
.tag-victors { color: var(--green); border-color: rgba(61, 220, 151, 0.30); }
.tag-points  { color: var(--accent-bright); border-color: rgba(124, 92, 255, 0.30); }

.level-side { text-align: right; display: flex; flex-direction: column; gap: 0.15rem; }
.level-points {
  font-family: var(--mono); font-size: 1.05rem; font-weight: 700; color: var(--text);
}
.level-side-label {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--text-faint); font-weight: 600;
}

.empty-state {
  text-align: center;
  padding: 4rem 1.5rem;
  background: var(--bg-elevated);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  color: var(--text-muted);
}

/* --- level detail --------------------------------------------------------- */

.breadcrumb { font-size: 0.86rem; color: var(--text-faint); margin: 2rem 0 1rem; }

.detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
}

.video-frame {
  aspect-ratio: 16 / 9;
  width: 100%;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  background: #000;
}
.video-frame iframe { width: 100%; height: 100%; border: 0; }
.video-missing {
  aspect-ratio: 16 / 9;
  display: grid; place-items: center;
  background: var(--bg-elevated);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  color: var(--text-faint);
}

.detail-title { display: flex; align-items: baseline; gap: 0.8rem; flex-wrap: wrap; }
/* The heading holds an image instead of text when the level has a logo, so it
   needs its own alignment -- a baseline does not exist inside a picture. */
.detail-title:has(.detail-heading-logo) { align-items: center; }
.detail-heading-logo .level-logo { max-height: 84px; max-width: min(100%, 460px); }
.detail-rank {
  font-family: var(--mono); font-weight: 700;
  font-size: 1rem; color: var(--accent-bright);
  padding: 0.2rem 0.6rem;
  border: 1px solid rgba(124, 92, 255, 0.40);
  border-radius: 7px;
}

.meta-list {
  margin: 0; padding: 0; list-style: none;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--bg-elevated);
  overflow: hidden;
}
.meta-list li {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: 0.72rem 1.1rem;
  border-bottom: 1px solid var(--line-soft);
  font-size: 0.92rem;
}
.meta-list li:last-child { border-bottom: 0; }
.meta-key { color: var(--text-faint); font-weight: 600; }
.meta-val { font-weight: 600; text-align: right; }
.meta-val.mono { font-family: var(--mono); }

.neighbours { display: flex; justify-content: space-between; gap: 1rem; margin-top: 2.5rem; }
.neighbours a { font-size: 0.92rem; }

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

.table-wrap { overflow-x: auto; border: 1px solid var(--line-soft); border-radius: var(--radius); }

table.data {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg-elevated);
  font-size: 0.93rem;
  min-width: 520px;
}
table.data th {
  text-align: left;
  font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.11em;
  color: var(--text-faint);
  padding: 0.75rem 1.1rem;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
table.data td {
  padding: 0.72rem 1.1rem;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
table.data tbody tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--bg-raised); }
table.data .num { font-family: var(--mono); font-weight: 600; }
table.data .rank-cell { color: var(--text-faint); font-family: var(--mono); font-weight: 700; width: 3.5rem; }
table.data tr[data-rank="1"] .rank-cell { color: var(--gold); }
table.data tr[data-rank="2"] .rank-cell { color: var(--silver); }
table.data tr[data-rank="3"] .rank-cell { color: var(--bronze); }

.pct { font-family: var(--mono); font-weight: 700; }
.pct-full { color: var(--green); }
.pct-part { color: var(--gold); }

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

.site-footer {
  border-top: 1px solid var(--line-soft);
  background: rgba(10, 11, 18, 0.6);
  padding: 2.5rem 0;
  font-size: 0.9rem;
}
.footer-inner p { margin: 0 0 0.4rem; }
.site-footer a { color: var(--text-muted); }
.site-footer a:hover { color: var(--accent-bright); }

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

@media (max-width: 900px) {
  .detail-grid { grid-template-columns: 1fr; }
}


/* Too narrow for the pinned links to sit on the bar: fold them into the menu.
   Both copies exist in the markup, so this is a straight swap with no
   JavaScript watching the viewport. */
@media (max-width: 760px) {
  /* .primary-nav ul sets display:flex at the same specificity, so this has to
     be scoped to outrank it rather than relying on source order. */
  .primary-nav .nav-pinned { display: none; }
  .nav-more-panel .nav-more-pinned {
    display: block;
    padding-bottom: 0.35rem;
    margin-bottom: 0.35rem;
    border-bottom: 1px solid var(--line-soft);
  }
}

/* Tighter still: the account button drops to just the avatar. */
@media (max-width: 460px) {
  .account-name, .account-caret { display: none; }
  .account-trigger { padding: 0.25rem; }
}

@media (max-width: 760px) {

  .level-row {
    grid-template-columns: 46px 1fr;
    grid-template-areas:
      "rank main"
      "side side";
    row-gap: 0.75rem;
  }
  .level-rank  { grid-area: rank; font-size: 1.25rem; }
  .level-main  { grid-area: main; }
  .level-thumb { display: none; }
  .level-logo  { max-height: 40px; }
  .detail-heading-logo .level-logo { max-height: 60px; }
  .level-side {
    grid-area: side;
    flex-direction: row; align-items: baseline; justify-content: flex-start;
    gap: 0.5rem; text-align: left;
  }

  .result-count { margin-left: 0; width: 100%; }
  .hero { padding-top: 3rem; }
  .neighbours { flex-direction: column; }
}

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

/* `hidden` has to beat the grid display used by list rows. */
.level-row[hidden], tr[hidden] { display: none !important; }

/* --- chrome injected by layout.js ------------------------------------------ */

/* Reserve the navbar's height so the page does not jump when it renders. */
/* Sticky lives here, not on .site-header: this wrapper is a flex child of
   body, so its containing block is the whole page and the bar has room to
   travel. min-height reserves the space before layout.js fills it in. */
#site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  min-height: 68px;
}

/* --- panels: errors, setup help, noscript ---------------------------------- */

.panel {
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1.6rem 1.75rem;
  margin: 2rem 0;
}
.panel h2 { margin-top: 0; font-size: 1.3rem; }
.panel h3 { margin-top: 1.6rem; }
.panel ol { line-height: 2; margin-bottom: 0; padding-left: 1.2rem; }
.panel p:last-child { margin-bottom: 0; }

.panel-error {
  border-color: rgba(255, 95, 109, 0.4);
  background: linear-gradient(160deg, rgba(255, 95, 109, 0.07), var(--bg-elevated));
}
.error-detail {
  color: var(--danger);
  border-color: rgba(255, 95, 109, 0.35);
  white-space: pre-wrap;
}

/* --- loading placeholders --------------------------------------------------- */

.skeleton { pointer-events: none; }
.skeleton .bar {
  display: block;
  height: 0.75rem;
  margin: 0.4rem 0;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--bg-raised) 0%, #262b45 50%, var(--bg-raised) 100%);
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
}
.skeleton .bar-sm { width: 40%; }
.skeleton .bar-md { width: 58%; }
.skeleton .bar-lg { width: 80%; }

.level-row.skeleton { border-color: var(--line-soft); }
.level-row.skeleton:hover {
  transform: none;
  background: var(--bg-elevated);
  border-color: var(--line-soft);
}
.level-row.skeleton .level-thumb { background: var(--bg-raised); border-color: var(--line-soft); }

@keyframes shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.stat-value-sm { font-size: 1.35rem; }

/* ===========================================================================
   Accounts, submissions and moderation
   =========================================================================== */

/* --- buttons: sizes and intents -------------------------------------------- */

.btn-sm { padding: 0.45rem 0.9rem; font-size: 0.86rem; }

.btn-discord {
  background: #5865f2;
  color: #fff;
  box-shadow: 0 12px 28px -14px #5865f2;
}
.btn-discord:hover { background: #4752c4; }

/* The Discord logo, drawn in CSS so the page pulls in no third-party asset. */
.discord-mark {
  width: 18px; height: 14px;
  flex: none;
  background: currentColor;
  -webkit-mask: center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 127 96'%3E%3Cpath d='M107 8A105 105 0 0 0 81 0l-3 7a97 97 0 0 0-29 0l-4-7a105 105 0 0 0-26 8C3 33-2 57 1 81a106 106 0 0 0 32 16l7-11c-6-2-11-5-16-8l4-3a75 75 0 0 0 64 0l4 3c-5 3-10 6-16 8l7 11a106 106 0 0 0 32-16c4-28-6-52-12-73zM42 66c-6 0-11-6-11-13s5-13 11-13 12 6 11 13c0 7-5 13-11 13zm42 0c-6 0-11-6-11-13s5-13 11-13 11 6 11 13-5 13-11 13z'/%3E%3C/svg%3E");
  mask: center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 127 96'%3E%3Cpath d='M107 8A105 105 0 0 0 81 0l-3 7a97 97 0 0 0-29 0l-4-7a105 105 0 0 0-26 8C3 33-2 57 1 81a106 106 0 0 0 32 16l7-11c-6-2-11-5-16-8l4-3a75 75 0 0 0 64 0l4 3c-5 3-10 6-16 8l7 11a106 106 0 0 0 32-16c4-28-6-52-12-73zM42 66c-6 0-11-6-11-13s5-13 11-13 12 6 11 13c0 7-5 13-11 13zm42 0c-6 0-11-6-11-13s5-13 11-13 11 6 11 13-5 13-11 13z'/%3E%3C/svg%3E");
}

.btn-danger { background: rgba(255, 95, 109, 0.14); color: #ff8b95; border-color: rgba(255, 95, 109, 0.45); }
.btn-danger:hover { background: rgba(255, 95, 109, 0.22); border-color: var(--danger); }

.btn-ok { background: rgba(61, 220, 151, 0.14); color: var(--green); border-color: rgba(61, 220, 151, 0.45); }
.btn-ok:hover { background: rgba(61, 220, 151, 0.22); border-color: var(--green); }

/* --- avatars ---------------------------------------------------------------- */

.avatar {
  border-radius: 50%;
  object-fit: cover;
  flex: none;
  background: var(--bg-raised);
  border: 1px solid var(--line);
}
.avatar-initials {
  display: inline-grid;
  place-items: center;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  background: linear-gradient(135deg, #23273c, #2f2450);
}

/* --- account menu in the navbar --------------------------------------------- */

.nav-auth { display: flex; align-items: center; margin-left: 0.75rem; }
.nav-note { font-size: 0.82rem; }

.nav-badge {
  display: inline-block;
  min-width: 18px;
  padding: 0 0.35rem;
  margin-left: 0.35rem;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 0.7rem; font-weight: 700;
  text-align: center;
  vertical-align: 1px;
}

.account-menu { position: relative; }

.account-trigger {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.3rem 0.55rem 0.3rem 0.3rem;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text);
  font: inherit; font-size: 0.9rem; font-weight: 600;
  cursor: pointer;
}
.account-trigger:hover { border-color: var(--accent); }
.account-name { max-width: 10rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-caret {
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--text-faint);
}

.account-dropdown {
  position: absolute;
  right: 0; top: calc(100% + 0.5rem);
  min-width: 190px;
  padding: 0.4rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.9);
  z-index: 60;
}
.account-dropdown a {
  display: block;
  padding: 0.5rem 0.7rem;
  border-radius: 8px;
  color: var(--text-muted);
  font-size: 0.9rem; font-weight: 600;
}
.account-dropdown a:hover { background: var(--bg-raised); color: var(--text); text-decoration: none; }
.account-dropdown hr { border: 0; border-top: 1px solid var(--line-soft); margin: 0.35rem 0; }

/* --- status pills ----------------------------------------------------------- */

.pill {
  display: inline-block;
  padding: 0.18rem 0.55rem;
  border-radius: 999px;
  font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  border: 1px solid transparent;
  vertical-align: 2px;
}
.pill-accepted { color: var(--green); background: rgba(61, 220, 151, 0.12); border-color: rgba(61, 220, 151, 0.35); }
.pill-pending  { color: var(--gold); background: rgba(255, 201, 74, 0.12); border-color: rgba(255, 201, 74, 0.35); }
.pill-rejected { color: #ff8b95; background: rgba(255, 95, 109, 0.12); border-color: rgba(255, 95, 109, 0.35); }
.pill-role     { color: var(--accent-bright); background: rgba(124, 92, 255, 0.14); border-color: rgba(124, 92, 255, 0.4); }

/* --- tabs -------------------------------------------------------------------- */

.tab-bar {
  display: flex; flex-wrap: wrap; gap: 0.3rem;
  margin: 1.5rem 0;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--line-soft);
}
.tab-bar button {
  padding: 0.5rem 1rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  color: var(--text-muted);
  font: inherit; font-size: 0.92rem; font-weight: 600;
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}
.tab-bar button:hover { color: var(--text); background: var(--bg-raised); }
.tab-bar button.active {
  color: var(--text);
  background: linear-gradient(135deg, rgba(124, 92, 255, 0.28), rgba(53, 214, 245, 0.16));
  border-color: rgba(124, 92, 255, 0.45);
}
.tab-count {
  display: inline-block;
  min-width: 20px; padding: 0 0.35rem;
  margin-left: 0.3rem;
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text-faint);
  font-family: var(--mono); font-size: 0.72rem; font-weight: 700;
  text-align: center;
}
.tab-bar button.active .tab-count { background: rgba(0, 0, 0, 0.3); color: var(--text); }

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

.field { display: block; margin-bottom: 1.15rem; }
.field-label {
  display: block;
  margin-bottom: 0.4rem;
  font-size: 0.82rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-faint);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.65rem 0.85rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit; font-size: 0.95rem;
}
.field textarea { resize: vertical; min-height: 5rem; }
.field input:focus,
.field select:focus,
.field textarea:focus { border-color: var(--accent); outline: none; }
.field input::placeholder, .field textarea::placeholder { color: var(--text-faint); }
.field-hint { display: block; margin-top: 0.4rem; font-size: 0.83rem; color: var(--text-faint); }
.field-tight { margin-bottom: 0.6rem; }

.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0 1rem; }

.field-error {
  margin: 0.4rem 0 0;
  padding: 0.5rem 0.7rem;
  border-radius: var(--radius-sm);
  background: rgba(255, 95, 109, 0.1);
  border: 1px solid rgba(255, 95, 109, 0.35);
  color: #ff8b95;
  font-size: 0.87rem;
}
form > .field-error:first-child { margin-bottom: 1rem; }
.has-error { border-color: var(--danger) !important; }

/* Native date and number controls are unreadable on a dark ground otherwise. */
.field input[type="date"]::-webkit-calendar-picker-indicator,
.field input[type="number"]::-webkit-inner-spin-button { filter: invert(0.7); }

.panel-danger { border-color: rgba(255, 95, 109, 0.35); }
.confirm-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1rem; }
.confirm-delete { margin-top: 1rem; }

/* --- profile ------------------------------------------------------------------ */

.profile-head {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 1.5rem;
  align-items: start;
  margin-top: 3rem;
  padding: 1.75rem;
  background: linear-gradient(160deg, var(--bg-elevated), rgba(18, 20, 31, 0.5));
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.profile-identity h1 { font-size: clamp(1.6rem, 3.5vw, 2.2rem); margin-bottom: 0.35rem; }
.profile-country { margin: 0 0 0.6rem; font-size: 0.9rem; }
.profile-bio { margin: 0 0 0.6rem; max-width: 60ch; }
.profile-links { margin: 0; font-size: 0.9rem; }
.profile-score { text-align: right; }
.profile-score .stat-value { color: var(--accent-bright); }
.profile-stats { margin-top: 1rem; }

.review-row td {
  background: rgba(124, 92, 255, 0.05);
  font-size: 0.88rem;
  color: var(--text-muted);
}
.review-label {
  font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-faint);
  margin-right: 0.4rem;
}
.review-note { margin: 0.6rem 0 0; font-size: 0.9rem; color: var(--text-muted); }

.submission-list { display: flex; flex-direction: column; gap: 0.8rem; }
.submission-card {
  padding: 1.1rem 1.3rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.submission-head { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }
.submission-head h3 { margin: 0; }
.submission-card p { margin: 0.3rem 0 0; font-size: 0.9rem; }

.settings-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
}
.settings-grid .panel { margin-top: 0; }
.settings-grid > div > .panel + .panel { margin-top: 1.5rem; }

.discord-identity { display: flex; align-items: center; gap: 0.9rem; margin-bottom: 1rem; }
.discord-identity p { margin: 0.2rem 0 0; font-size: 0.88rem; }

/* --- moderation queue ---------------------------------------------------------- */

.queue-list { display: flex; flex-direction: column; gap: 0.9rem; }

.queue-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(240px, 300px);
  gap: 1.5rem;
  padding: 1.2rem 1.35rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.queue-main h3 { margin: 0 0 0.3rem; display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.queue-main p { margin: 0.3rem 0 0; font-size: 0.9rem; }
.queue-head { display: flex; gap: 1rem; align-items: flex-start; }
.queue-thumb { width: 128px; border-radius: var(--radius-sm); border: 1px solid var(--line); flex: none; }

.queue-note {
  padding: 0.6rem 0.8rem;
  margin-top: 0.7rem !important;
  background: var(--bg-raised);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
}
.queue-warning {
  margin-top: 0.7rem !important;
  color: var(--gold);
  font-weight: 600;
}

.queue-actions { display: flex; flex-direction: column; gap: 0.6rem; justify-content: center; }
.queue-actions input[type="text"] {
  width: 100%;
  padding: 0.55rem 0.75rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit; font-size: 0.88rem;
}
.queue-actions input:focus { border-color: var(--accent); outline: none; }
.queue-buttons { display: flex; gap: 0.5rem; }
.queue-buttons .btn { flex: 1; justify-content: center; }

.row-actions { display: flex; gap: 0.4rem; align-items: center; white-space: nowrap; }
.row-actions select {
  padding: 0.35rem 0.5rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 7px;
  color: var(--text);
  font: inherit; font-size: 0.82rem;
}

.user-cell { display: flex; align-items: center; gap: 0.7rem; }
.user-handle { margin: 0; font-size: 0.8rem; }

/* --- toasts -------------------------------------------------------------------- */

.toast-host {
  position: fixed;
  right: 1.25rem; bottom: 1.25rem;
  z-index: 200;
  display: flex; flex-direction: column; gap: 0.6rem;
  max-width: min(360px, calc(100vw - 2.5rem));
}

.toast {
  padding: 0.8rem 1.1rem;
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  box-shadow: 0 18px 40px -20px rgba(0, 0, 0, 0.9);
  font-size: 0.92rem; font-weight: 500;
  animation: toast-in 0.22s ease-out;
}
.toast-ok { border-color: rgba(61, 220, 151, 0.45); }
.toast-error { border-color: rgba(255, 95, 109, 0.5); color: #ff8b95; }
.toast.leaving { opacity: 0; transform: translateY(6px); transition: opacity 0.3s, transform 0.3s; }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* --- modals --------------------------------------------------------------------- */

.modal {
  width: min(680px, calc(100vw - 2.5rem));
  max-height: 85vh;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-elevated);
  color: var(--text);
  overflow: auto;
}
.modal::backdrop { background: rgba(5, 6, 12, 0.72); backdrop-filter: blur(3px); }
.modal-body { padding: 1.75rem; position: relative; }
.modal-body h2 { margin-top: 0; padding-right: 2rem; }

.modal-close {
  position: absolute;
  top: 0.9rem; right: 1rem;
  width: 30px; height: 30px;
  background: none;
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--text-muted);
  font-size: 1.2rem; line-height: 1;
  cursor: pointer;
}
.modal-close:hover { color: var(--text); border-color: var(--accent); }

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

@media (max-width: 900px) {
  .settings-grid { grid-template-columns: 1fr; }
  .queue-card { grid-template-columns: 1fr; }
  .profile-head { grid-template-columns: auto 1fr; }
  .profile-score { grid-column: 1 / -1; text-align: left; }
}

@media (max-width: 760px) {
  .nav-auth { margin-left: 0; margin-top: 0.6rem; }
  .account-dropdown { right: auto; left: 0; }
  .queue-head { flex-direction: column; }
  .queue-thumb { width: 100%; }
  .row-actions { flex-wrap: wrap; }
  .toast-host { left: 1.25rem; right: 1.25rem; max-width: none; }
}

/* --- account picker ---------------------------------------------------------- */

.user-picker { position: relative; }

.picker-chips {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  min-height: 2rem;
  margin-bottom: 0.5rem;
  align-items: center;
}
.picker-empty { font-size: 0.88rem; }

.picker-chip {
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.25rem 0.3rem 0.25rem 0.25rem;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.88rem; font-weight: 600;
}
.picker-chip button {
  width: 18px; height: 18px;
  display: grid; place-items: center;
  background: none;
  border: 0;
  border-radius: 50%;
  color: var(--text-faint);
  font-size: 1rem; line-height: 1;
  cursor: pointer;
}
.picker-chip button:hover { background: rgba(255, 95, 109, 0.18); color: #ff8b95; }

.picker-search { position: relative; }

.picker-results {
  position: absolute;
  left: 0; right: 0; top: calc(100% + 0.3rem);
  z-index: 70;
  max-height: 260px;
  overflow-y: auto;
  padding: 0.3rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.9);
}

.picker-option {
  display: flex; align-items: center; gap: 0.6rem;
  width: 100%;
  padding: 0.45rem 0.6rem;
  background: none;
  border: 0;
  border-radius: 7px;
  color: var(--text);
  font: inherit; font-size: 0.92rem; font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.picker-option:hover:not(:disabled) { background: var(--bg-raised); }
.picker-option:disabled { opacity: 0.55; cursor: default; }
.picker-tick { margin-left: auto; font-size: 0.78rem; font-weight: 500; }
.picker-none { margin: 0; padding: 0.6rem; font-size: 0.88rem; }

/* Inside a modal the results list must not be clipped by the scroll area. */
.modal .picker-results { max-height: 200px; }

.level-by a, .queue-main a.credit { color: inherit; }
.level-by a:hover { color: var(--accent-bright); }

/* ===========================================================================
   News, changelog and time machine
   =========================================================================== */

.post-card {
  padding: 1.5rem 1.65rem;
  margin-bottom: 1rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.post-card--pinned { border-color: rgba(124, 92, 255, 0.45); }
.post-card h3 { margin: 0.4rem 0 0.5rem; font-size: 1.25rem; }
.post-card h3 a { color: var(--text); }
.post-card h3 a:hover { color: var(--accent-bright); text-decoration: none; }

.post-full { margin-top: 2rem; max-width: 72ch; }
.post-full h1 { margin-bottom: 0.6rem; }

.post-byline {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 1rem;
  font-size: 0.88rem;
  color: var(--text-faint);
}
.post-byline a { color: var(--text-muted); }

.post-body p { margin: 0 0 0.9rem; }
.post-body p:last-child { margin-bottom: 0; }

.post-link { margin: 1rem 0 0; font-size: 0.88rem; }
.post-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; margin: 2rem 0 1rem; }

/* --- changelog --------------------------------------------------------------- */

.change-list { list-style: none; margin: 0; padding: 0; }

.change {
  display: flex;
  gap: 0.9rem;
  padding: 0.85rem 1.1rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: var(--bg-elevated);
  margin-bottom: 0.5rem;
}

.change-tag {
  flex: none;
  align-self: flex-start;
  min-width: 74px;
  text-align: center;
  padding: 0.2rem 0.5rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  border: 1px solid transparent;
}
.change-tag--added   { color: var(--green); background: rgba(61, 220, 151, 0.12); border-color: rgba(61, 220, 151, 0.35); }
.change-tag--moved   { color: var(--cyan); background: rgba(53, 214, 245, 0.12); border-color: rgba(53, 214, 245, 0.35); }
.change-tag--removed { color: #ff8b95; background: rgba(255, 95, 109, 0.12); border-color: rgba(255, 95, 109, 0.35); }

.change-main { min-width: 0; }
.change-line { margin: 0; font-size: 0.95rem; }
.change-reason { margin: 0.35rem 0 0; font-size: 0.88rem; color: var(--text-muted); }
.change-meta { margin: 0.3rem 0 0; font-size: 0.8rem; color: var(--text-faint); }
.change-gone { color: var(--text-muted); text-decoration: line-through; }

/* --- time machine ------------------------------------------------------------ */

.time-machine-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  flex-wrap: wrap;
}
.time-machine-cta h2 { margin: 0 0 0.35rem; font-size: 1.2rem; }
.time-machine-cta p { margin: 0; max-width: 52ch; }

.time-machine-caption { margin: 1.5rem 0 0.75rem; font-size: 0.92rem; }

.panel-warning {
  border-color: rgba(255, 201, 74, 0.4);
  background: linear-gradient(160deg, rgba(255, 201, 74, 0.07), var(--bg-elevated));
}

tr.row-gone td { opacity: 0.62; }

/* --- checkbox field ----------------------------------------------------------- */

.checkbox-field {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.checkbox-field input { width: auto; }
.checkbox-field span {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text-muted);
}

@media (max-width: 620px) {
  .change { flex-direction: column; gap: 0.5rem; }
  .change-tag { min-width: 0; align-self: flex-start; }
}

/* --- brand at narrow widths ---------------------------------------------------
   The wordmark is 356px at full size, which on a phone pushes the whole nav off
   the side of the screen. Let it shrink, and give the flex items permission to
   do so -- a flex item will not shrink below its content by default. */

/* No min-width:0 here. It lets the flex row squeeze .brand-text to zero,
   and a max-width:100% image inside a zero-width box disappears entirely.
   The per-breakpoint pixel widths below do the shrinking instead. */
.brand { flex: none; }

@media (max-width: 900px) {
  .brand .brand-logo { width: 46px; height: 46px; }
  .brand-text img { max-width: 240px; }
}

@media (max-width: 620px) {
  .brand .brand-logo { width: 38px; height: 38px; }
  .brand-text img { max-width: 170px; }
  .header-inner { gap: 0.6rem; }
}

@media (max-width: 420px) {
  /* Below this the wordmark and the controls cannot both fit, and the controls
     are the part people need. The icon still links home. */
  .brand-text { display: none; }
}

/* ===========================================================================
   Level thumbnails
   =========================================================================== */

/* The card own artwork, sitting behind its contents.
   .level-art is a real element rather than a pseudo-element because the image
   has to be set inline -- see the comment in format.js. */
.level-row { position: relative; isolation: isolate; }

.level-art {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-size: cover;
  background-position: center;
  opacity: 0.42;
  transition: opacity 0.15s;
}

/* Darkens towards the right so the points column keeps its contrast. */
.level-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    rgba(18, 20, 31, 0.30) 0%,
    rgba(18, 20, 31, 0.72) 55%,
    rgba(18, 20, 31, 0.90) 100%
  );
}

.level-row:hover .level-art { opacity: 0.6; }

.level-row.skeleton .level-art { display: none; }

/* --- scrolling thumbnail band (every page except the homepage) ---------------

   Two rows drifting opposite ways behind the content. The tiles are masked so
   they fade into one another at every edge -- the brief asked for no hard
   border between thumbnails, and a mask is what gives that, since a plain
   background-image would butt up square against its neighbour.               */

.thumb-bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2vh;
  background: var(--bg);
}

.thumb-row { overflow: hidden; height: 34vh; }

.thumb-row-inner {
  display: flex;
  height: 100%;
  width: max-content;
}

/* Translating by half the doubled strip lands on an identical frame. */
.thumb-row--a .thumb-row-inner { animation: thumb-drift-left 90s linear infinite; }
.thumb-row--b .thumb-row-inner { animation: thumb-drift-right 110s linear infinite; }

@keyframes thumb-drift-left {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@keyframes thumb-drift-right {
  from { transform: translateX(-50%); }
  to   { transform: translateX(0); }
}

.thumb-tile {
  flex: none;
  display: block;
  width: 30vw;
  min-width: 260px;
  height: 100%;
  background-size: cover;
  background-position: center;
  /* Soft on all four edges, so neighbours blend rather than meet. */
  -webkit-mask-image: radial-gradient(ellipse 62% 62% at 50% 50%, #000 40%, transparent 100%);
  mask-image: radial-gradient(ellipse 62% 62% at 50% 50%, #000 40%, transparent 100%);
}

/* Keeps the artwork well behind the text. */
.thumb-veil {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(10, 11, 18, 0.92) 0%, rgba(10, 11, 18, 0.70) 50%, rgba(10, 11, 18, 0.92) 100%);
}

/* The page's own background would otherwise paint straight over the band. */
body:not(.page-home) { background-color: transparent; }

.page-header{
  justify-self: center;
  transform: skewY(5deg);
}
/* ===========================================================================
   Tags, packs and the roulette
   =========================================================================== */

/* --- tags -------------------------------------------------------------------- */

.tag-custom {
  color: var(--tag-colour, var(--accent-bright));
  border-color: color-mix(in srgb, var(--tag-colour, var(--accent)) 45%, transparent);
  background: color-mix(in srgb, var(--tag-colour, var(--accent)) 14%, transparent);
}

.tag-enjoyment { color: var(--gold); border-color: rgba(255, 201, 74, 0.35); }

.tag-filter {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  margin: 0 0 1.25rem;
}
.tag-filter-label {
  font-size: 0.76rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-faint);
}
.tag-filter-list { display: flex; flex-wrap: wrap; gap: 0.35rem; }

.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.84rem;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.tag-chip:hover { color: var(--text); border-color: var(--tag-colour, var(--accent)); }
.tag-chip.active {
  color: var(--tag-colour, var(--accent-bright));
  border-color: color-mix(in srgb, var(--tag-colour, var(--accent)) 60%, transparent);
  background: color-mix(in srgb, var(--tag-colour, var(--accent)) 18%, transparent);
}
.tag-count { font-family: var(--mono); font-size: 0.74rem; opacity: 0.7; }


/* --- roulette ------------------------------------------------------------------ */

.roulette-current {
  display: flex;
  gap: 1.4rem;
  align-items: flex-start;
  padding: 1.5rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  margin-bottom: 1rem;
}
.roulette-thumb {
  width: 200px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  flex: none;
}
.roulette-current-main h2 { margin: 0.2rem 0 0.35rem; }
.roulette-current-main p { margin: 0; }

.roulette-target {
  margin-top: 0.9rem !important;
  padding: 0.6rem 0.9rem;
  background: var(--bg-raised);
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--accent);
  font-size: 0.98rem;
}
.roulette-target strong { color: var(--accent-bright); font-family: var(--mono); }

.roulette-form { margin-top: 0; }

.roulette-reveal { margin-top: 1rem; }
.roulette-reveal summary { cursor: pointer; font-weight: 600; }
.roulette-remaining { margin: 1rem 0 0; padding-left: 1.4rem; font-size: 0.92rem; }
.roulette-remaining li { margin-bottom: 0.25rem; }

.panel-ok {
  border-color: rgba(61, 220, 151, 0.4);
  background: linear-gradient(160deg, rgba(61, 220, 151, 0.07), var(--bg-elevated));
}

@media (max-width: 700px) {
  .roulette-current { flex-direction: column; }
  .roulette-thumb { width: 100%; }
}


/* --- rating bar ----------------------------------------------------------------
   The gradient sits on the whole track and the unfilled part is painted over.
   That keeps the colour tied to the score itself -- 50 lands on yellow, 90 on
   green -- rather than stretching a red-to-green ramp into whatever width the
   fill happens to be, which would make every score end green. */

.rating { display: flex; align-items: center; gap: 0.7rem; }

.rating-track {
  position: relative;
  flex: 1;
  height: 10px;
  min-width: 120px;
  border-radius: 999px;
  border: 1px solid var(--line);
  overflow: hidden;
  background: linear-gradient(90deg, #ff4d4d 0%, #ff9f45 25%, #ffc94a 50%, #9fd84a 75%, #3ddc97 100%);
}

.rating-track::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: var(--score, 0%);
  background: var(--bg-raised);
}

.rating-value {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 0.92rem;
  white-space: nowrap;
}

/* The rating bar needs room to breathe, unlike the one-word meta values. */
.meta-row-wide { align-items: center; }
.meta-row-wide .meta-val { flex: 1; max-width: 260px; }

/* --- filter menu ----------------------------------------------------------------
   One button beside the search box holds every way of narrowing the list, so the
   bar does not grow a new control each time a filter is added. */

.filter-menu { position: relative; }

.filter-trigger { position: relative; }

/* The [hidden] attribute is display:none at the same specificity, so it loses
   to the rule below on source order unless it is stated explicitly. */
.filter-badge[hidden] { display: none; }

.filter-badge {
  display: inline-block;
  min-width: 18px;
  padding: 0 0.3rem;
  margin-left: 0.45rem;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

.filter-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.5rem);
  z-index: 70;
  width: min(360px, calc(100vw - 3rem));
  max-height: 70vh;
  overflow-y: auto;
  padding: 1rem 1.1rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 24px 48px -24px rgba(0, 0, 0, 0.9);
}

.filter-group { border: 0; padding: 0; margin: 0 0 1.1rem; }
.filter-group legend {
  padding: 0;
  margin-bottom: 0.5rem;
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-faint);
}

.filter-check {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.3rem 0;
  font-size: 0.9rem;
  color: var(--text-muted);
  cursor: pointer;
}
.filter-check input { width: auto; }
.filter-check:hover { color: var(--text); }

.filter-range { display: flex; align-items: center; gap: 0.75rem; }
.filter-range input[type="range"] { flex: 1; }
.filter-range output {
  font-family: var(--mono);
  font-size: 0.85rem;
  font-weight: 700;
  min-width: 3rem;
  text-align: right;
}

.filter-actions { border-top: 1px solid var(--line-soft); padding-top: 0.9rem; }

/* --- packs ------------------------------------------------------------------- */

.pack-hero {
  position: relative;
  margin: 1.5rem 0 0;
  padding: 2.5rem 2rem 1.5rem;
  border-radius: var(--radius);
  overflow: hidden;
  border-bottom: 3px solid var(--pack-colour, var(--accent));
  isolation: isolate;
}

/* The pack's own levels form the banner, so each pack looks like itself. */
.pack-hero-art {
  position: absolute;
  inset: 0;
  z-index: -1;
  display: flex;
}
.pack-hero-art .pack-tile {
  flex: 1;
  background-size: cover;
  background-position: center;
  opacity: 0.55;
}
.pack-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(10, 11, 18, 0.95) 0%, rgba(10, 11, 18, 0.55) 60%, rgba(10, 11, 18, 0.35) 100%);
}

.pack-hero h1 { margin: 0.2rem 0 0.4rem; font-size: clamp(1.8rem, 4vw, 2.6rem); }
.pack-hero-meta { margin: 0; display: flex; align-items: baseline; gap: 0.9rem; font-size: 0.95rem; }
.pack-hero-meta strong { font-family: var(--mono); font-size: 1.5rem; color: var(--pack-colour, var(--accent-bright)); }
.pack-hero-desc { margin: 0.6rem 0 0; max-width: 60ch; }

.pack-layout {
  display: grid;
  grid-template-columns: minmax(0, 250px) minmax(0, 1fr);
  gap: 1.5rem;
  margin-top: 1.5rem;
}

.pack-side-label {
  margin: 0 0 0.6rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-faint);
}

.pack-side-item {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0.7rem 0.9rem;
  margin-bottom: 0.5rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
}
.pack-side-item:hover { border-color: var(--pack-colour, var(--accent)); }
.pack-side-item.active {
  border-color: var(--pack-colour, var(--accent));
  box-shadow: inset 0 0 0 1px var(--pack-colour, var(--accent));
}

.pack-side-art { position: absolute; inset: 0; z-index: -1; display: flex; }
.pack-side-art .pack-tile { flex: 1; background-size: cover; background-position: center; opacity: 0.3; }
.pack-side-item::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(12, 13, 22, 0.92), rgba(12, 13, 22, 0.72));
}

.pack-side-text { display: flex; flex-direction: column; line-height: 1.25; }
.pack-side-text small { color: var(--text-faint); font-size: 0.78rem; }

.pack-toolbar { display: flex; justify-content: flex-end; margin-bottom: 0.9rem; }
.pack-level-list { display: flex; flex-direction: column; gap: 0.6rem; }

.pack-level {
  position: relative;
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) 20px;
  align-items: center;
  gap: 0.9rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  overflow: hidden;
  isolation: isolate;
  color: var(--text);
  transition: border-color 0.15s, transform 0.15s;
}
.pack-level:hover { border-color: var(--accent); transform: translateX(3px); text-decoration: none; }

/* The level's own artwork behind its row, dimmed enough to read over. */
.pack-level::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image: var(--level-art);
  background-size: cover;
  background-position: center;
  opacity: 0.45;
}
.pack-level::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(10, 11, 18, 0.92) 0%, rgba(10, 11, 18, 0.75) 55%, rgba(10, 11, 18, 0.9) 100%);
}

.pack-level-rank { font-family: var(--mono); font-weight: 700; color: var(--text-faint); }
.pack-level-name { display: block; font-size: 1.02rem; }

.pack-level-stats {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin-top: 0.35rem;
  font-size: 0.85rem;
}
.pack-level-points { font-family: var(--mono); color: var(--gold); white-space: nowrap; }
.pack-level-go { color: var(--text-faint); font-size: 1.3rem; text-align: right; }

.pack-finishers { border-top: 1px solid var(--line-soft); padding-top: 0.9rem; margin-top: 1.2rem; font-size: 0.9rem; }

@media (max-width: 820px) {
  .pack-layout { grid-template-columns: 1fr; }
  .pack-toolbar { justify-content: flex-start; }
  .pack-level { grid-template-columns: 44px minmax(0, 1fr); }
  .pack-level-go { display: none; }
}

/* The level checklist in the mod panel's pack editor. */
.pack-picker {
  max-height: 260px;
  overflow-y: auto;
  padding: 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg);
}
.pack-choice {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.3rem 0.4rem;
  border-radius: 6px;
  font-size: 0.9rem;
  cursor: pointer;
}
.pack-choice:hover { background: var(--bg-raised); }
.pack-choice input { width: auto; }

/* A value the form shows but does not ask for. */
.field-static {
  margin: 0;
  padding: 0.65rem 0.85rem;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--mono);
  font-weight: 700;
}

/* A level the reader has cleared. The border is the whole signal -- no bars,
   no percentages, and never anyone else's progress. */
.pack-level.is-done {
  border-color: var(--green);
  box-shadow: inset 0 0 0 1px rgba(61, 220, 151, 0.35);
}
.pack-level.is-done:hover { border-color: var(--green); }

.pack-level-done {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--green);
}

.pack-progress-note { margin: 0; font-size: 0.9rem; display: flex; align-items: center; gap: 0.6rem; }
.pack-progress-note strong { font-family: var(--mono); color: var(--text); }



/* ===========================================================================
   Players, flags and profiles
   =========================================================================== */

/* A player's own colour. Every rule below reads it through this fallback, so an
   account that has never picked one is drawn in the site accent and nothing has
   to branch on whether a colour exists. */
:root { --profile-colour: var(--accent); }

/* --- flags ------------------------------------------------------------------

   Images rather than the flag emoji: Windows ships no flag glyphs and would
   render every one of these as two bare letters. See flagHtml() in format.js. */
.flag {
  display: inline-block;
  border-radius: 3px;
  border: 1px solid var(--line);
  background: var(--bg-raised);
  vertical-align: middle;
  flex: none;
}

.pill-verified { color: var(--cyan); background: rgba(53, 214, 245, 0.12); border-color: rgba(53, 214, 245, 0.38); }
.pill-progress { color: var(--gold); background: rgba(255, 201, 74, 0.12); border-color: rgba(255, 201, 74, 0.35); }

/* --- the leaderboard --------------------------------------------------------

   A card per player rather than a table row: the face, the flag and the name
   are one identity, and the points and the hardest clear are what people come
   to compare. The completion and progress counts that used to sit here live on
   the profile now. */

.player-list { display: flex; flex-direction: column; gap: 0.55rem; }

.player-row {
  display: grid;
  grid-template-columns: 3.6rem auto auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.95rem;
  padding: 0.75rem 1.15rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-left: 3px solid var(--profile-colour);
  border-radius: var(--radius);
  transition: border-color 0.15s, transform 0.15s, background 0.15s;
}
.player-row:hover { background: var(--bg-raised); transform: translateX(3px); }

.player-rank {
  font-family: var(--mono);
  font-size: 1.25rem; font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--text-faint);
}
.player-row[data-rank="1"] .player-rank { color: var(--gold); }
.player-row[data-rank="2"] .player-rank { color: var(--silver); }
.player-row[data-rank="3"] .player-rank { color: var(--bronze); }

.player-flag { display: flex; align-items: center; min-width: 24px; }
.player-avatar .avatar { border-color: var(--profile-colour); }

.player-main { min-width: 0; }
.player-name {
  font-size: 1.05rem; font-weight: 700;
  color: var(--text);
  display: inline-block;
}
a.player-name:hover { color: var(--profile-colour); text-decoration: none; }

.player-hardest { margin-top: 0.15rem; font-size: 0.86rem; }
.hardest {
  display: inline-flex; align-items: center; gap: 0.45rem;
  color: var(--text-muted);
  min-width: 0;
}
.hardest:hover { color: var(--text); text-decoration: none; }
.hardest-rank { font-family: var(--mono); font-weight: 700; color: var(--text-faint); }
.hardest-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.player-side { text-align: right; }
.player-points {
  display: block;
  font-family: var(--mono); font-size: 1.05rem; font-weight: 700;
  color: var(--profile-colour);
}
.player-side-label {
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--text-faint); font-weight: 600;
}

/* --- profile header and stats ------------------------------------------------ */

.profile-head { border-left: 3px solid var(--profile-colour); }
.profile-avatar .avatar { border: 2px solid var(--profile-colour); }
.profile-score .stat-value { color: var(--profile-colour); }
.profile-country { display: flex; align-items: center; gap: 0.45rem; }

/* The hardest clear is a link, so it sits below the tile row rather than inside
   a grid of plain numbers. */
.stat-hardest {
  display: block;
  margin-top: 1rem;
  padding: 1.1rem 1.35rem;
  background: linear-gradient(160deg, var(--bg-elevated), rgba(18, 20, 31, 0.55));
  border: 1px solid var(--line-soft);
  border-left: 3px solid var(--profile-colour);
  border-radius: var(--radius);
  color: inherit;
}
.stat-hardest:hover { border-color: var(--profile-colour); text-decoration: none; }
.stat-hardest-name {
  font-size: 1.25rem; font-weight: 700;
  margin-top: 0.3rem;
  color: var(--text);
}
.stat-hardest-meta { font-family: var(--mono); font-size: 0.85rem; color: var(--text-faint); }

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

   The public profile's main view. Each card carries the level's own artwork,
   dimmed behind the text the same way the list rows are. */

.completion-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0.8rem;
}

.completion-card {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.9rem;
  padding: 1rem 1.15rem;
  min-height: 92px;
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  color: inherit;
  overflow: hidden;
  transition: border-color 0.15s, transform 0.15s;
}
.completion-card:hover {
  border-color: var(--profile-colour);
  transform: translateY(-2px);
  text-decoration: none;
}

.completion-art {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-size: cover;
  background-position: center;
  opacity: 0.34;
  transition: opacity 0.15s;
}
/* Keeps the points column readable over whatever the artwork happens to be. */
.completion-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    rgba(18, 20, 31, 0.55) 0%,
    rgba(18, 20, 31, 0.82) 60%,
    rgba(18, 20, 31, 0.93) 100%
  );
}
.completion-card:hover .completion-art { opacity: 0.5; }

.completion-rank {
  font-family: var(--mono); font-size: 1.15rem; font-weight: 700;
  color: var(--text-faint);
}
.completion-body { min-width: 0; }
.completion-name {
  display: block;
  font-weight: 700; font-size: 1.02rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.completion-tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.3rem; }
.completion-tags:empty { display: none; }

.completion-points { text-align: right; }
.completion-points-value {
  display: block;
  font-family: var(--mono); font-weight: 700;
  color: var(--profile-colour);
}
.completion-points-label {
  font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.11em;
  color: var(--text-faint); font-weight: 600;
}

/* --- settings: country and colour --------------------------------------------- */

.country-field { display: flex; align-items: center; gap: 0.7rem; }
.country-field select { flex: 1; }
/* Reserves the flag's width, so choosing a country does not shift the select. */
.country-flag {
  display: flex; align-items: center; justify-content: center;
  width: 24px; min-height: 18px;
  flex: none;
}

.colour-field { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
.swatches { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.swatch {
  width: 30px; height: 30px;
  padding: 0;
  border-radius: 50%;
  background: var(--swatch);
  border: 2px solid transparent;
  box-shadow: 0 0 0 1px var(--line);
  cursor: pointer;
  transition: transform 0.12s, border-color 0.12s;
}
.swatch:hover { transform: scale(1.12); }
.swatch.active { border-color: var(--text); }

.colour-custom { display: flex; align-items: center; gap: 0.6rem; }
.colour-custom input[type="color"] {
  width: 42px; height: 32px;
  padding: 2px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.colour-custom code { font-size: 0.85rem; color: var(--text-muted); }

@media (max-width: 760px) {
  .player-row {
    grid-template-columns: 2.6rem auto auto minmax(0, 1fr);
    grid-template-areas:
      "rank flag avatar main"
      "side side side side";
    row-gap: 0.6rem;
  }
  .player-rank   { grid-area: rank; font-size: 1.05rem; }
  .player-flag   { grid-area: flag; }
  .player-avatar { grid-area: avatar; }
  .player-main   { grid-area: main; }
  .player-side   { grid-area: side; text-align: left; }
  .player-points { display: inline; }
  .player-side-label { margin-left: 0.35rem; }

  .completion-grid { grid-template-columns: 1fr; }
}

/* The credits paragraph above carries the 2rem gap before the detail grid, so
   the chip row takes that gap over when it is present. */
.detail-tags { margin: -1.25rem 0 2rem; }

/* .field sets display:block, which is an author rule and so beats the browser's
   own [hidden] { display: none }. Without this the subdivision field would stay
   visible for countries that have no list. Same trap as .filter-badge above. */
.field[hidden] { display: none; }

/* Sits between the name and the hardest clear on the leaderboard. Quieter than
   the name so the row still reads name-first. */
.player-place {
  font-size: 0.78rem;
  color: var(--text-faint);
  margin-top: 0.1rem;
}

/* Skillset chips on a public profile. The count is the point of the chip, so it
   gets its own weight rather than being folded into the label. */
.skill-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.skill-chip {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.35rem 0.5rem 0.35rem 0.7rem;
  border-radius: 999px;
  font-size: 0.82rem; font-weight: 600;
  color: var(--tag-colour, var(--accent-bright));
  border: 1px solid color-mix(in srgb, var(--tag-colour, var(--accent)) 45%, transparent);
  background: color-mix(in srgb, var(--tag-colour, var(--accent)) 14%, transparent);
}
.skill-count {
  min-width: 1.55rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  font-family: var(--mono); font-size: 0.78rem;
  text-align: center;
  color: var(--text);
  background: color-mix(in srgb, var(--tag-colour, var(--accent)) 28%, transparent);
}

/* Homepage "latest" strip: announcement beside recent changes, stacking on
   narrow screens. Either column can be absent, so this is a grid of whatever
   is actually there rather than a fixed two-up. */
.home-latest-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
  align-items: start;
}

/* --- Stats viewer: leaderboard left, world map filling the right ---------- */

.players-page {
  display: grid;
  /* The map owns half the viewport and is pinned there; the list keeps a
     readable measure in what is left rather than stretching to meet it. */
  grid-template-columns: minmax(0, 1fr) 50vw;
  align-items: start;
}

.players-column {
  width: min(1140px, 100% - 2.5rem);
  margin-inline: auto;
  padding-bottom: 4rem;
}

.players-map {
  position: sticky;
  /* #site-header is sticky at 68px, so the map starts below it and takes the
     rest of the viewport. */
  top: 68px;
  height: calc(100vh - 68px);
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--line-soft);
  background: var(--bg-raised);
}

/* Below this the two panes are both too narrow to be worth having. The map
   goes first because it is the summary and the list is the detail. */
@media (max-width: 1100px) {
  .players-page { grid-template-columns: minmax(0, 1fr); }
  .players-map {
    position: static;
    height: 60vh;
    border-left: 0;
    border-bottom: 1px solid var(--line-soft);
    order: -1;
  }
  .players-column { padding-top: 1rem; }
}

.map-canvas {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  cursor: grab;
  touch-action: none;
}
.map-canvas.is-dragging { cursor: grabbing; }
.map-canvas svg { display: block; width: 100%; height: 100%; }

.map-land {
  /* Filled per-shape from the points total; this is the "not on the list at
     all" colour that shows through when nothing overrides it. */
  fill: var(--bg-elevated);
  stroke: var(--line);
  /* Hairlines whatever the zoom: the viewBox scales stroke widths with
     everything else, and vector-effect is what opts out of that. */
  stroke-width: 0.6;
  vector-effect: non-scaling-stroke;
}
.map-sub { stroke-width: 0.4; }

/* Only shapes with players react to the pointer, and only when their people
   cannot all be drawn -- see the JS. */
.map-land.is-hoverable { cursor: pointer; }
.map-land.is-hoverable:hover { stroke: var(--accent-bright); stroke-width: 1.4; }

.map-markers { position: absolute; inset: 0; pointer-events: none; }

.map-cluster {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex; align-items: center; gap: 2px;
  pointer-events: auto;
}

.map-face { display: block; line-height: 0; border-radius: 50%; }
.map-face img,
.map-face .avatar-initials {
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 2px solid var(--bg);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.45);
}
.map-face:hover img,
.map-face:focus-visible img { border-color: var(--accent-bright); }

/* Stand-in for a region too small to hold even one avatar. */
.map-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--accent-bright);
  border: 2px solid var(--bg);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}

.map-more {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 5px;
  border-radius: 999px;
  font-family: var(--mono); font-size: 0.7rem; font-weight: 700;
  color: var(--text);
  background: var(--accent);
  border: 2px solid var(--bg);
}

.map-bubble {
  position: absolute;
  z-index: 3;
  max-width: 17rem;
  padding: 0.6rem 0.7rem;
  border-radius: var(--radius);
  background: var(--bg);
  border: 1px solid var(--line);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  /* Deliberately interactive: the faces inside link to profiles, and for a
     region too small to draw them this bubble is the only way to reach them.
     Moving onto it stops the SVG hover firing, so it stays put. */
}
.map-bubble-title {
  margin: 0 0 0.45rem;
  font-size: 0.76rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-faint);
}
.map-bubble-faces { display: flex; flex-wrap: wrap; gap: 0.3rem; }

.map-controls {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0.9rem 0;
}
.map-zoom { display: flex; gap: 0.3rem; }
.map-toggle {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.78rem; color: var(--text-faint);
  cursor: pointer; user-select: none;
}
.map-note { margin: 0; padding: 0.35rem 0.9rem 0.7rem; font-size: 0.72rem; }

/* Version line under the homepage logo. Deliberately quiet -- it is a footnote
   about the site, not part of the pitch. */
.hero-version {
  /* .hero-logo spans the full width and .hero-actions centres itself, so the
     hero has no inherited centring for this to pick up. */
  text-align: center;
  margin: 0.4rem 0 0;
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--text-faint);
  letter-spacing: 0.04em;
}

/* --- Point breakdown ring + bars ----------------------------------------- */

.breakdown {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 1.5rem;
  align-items: center;
  padding: 1.1rem 1.3rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
@media (max-width: 620px) {
  .breakdown { grid-template-columns: minmax(0, 1fr); justify-items: center; }
}

.breakdown-ring { position: relative; width: 116px; height: 116px; flex: none; }
.breakdown-ring svg {
  width: 100%; height: 100%;
  /* Start slices at twelve o'clock rather than three. */
  transform: rotate(-90deg);
}
.ring-track,
.ring-slice {
  fill: none;
  stroke-width: 4.2;
}
.ring-track { stroke: var(--bg-raised); }

.breakdown-centre {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.1rem;
  pointer-events: none;
}
.breakdown-centre strong { font-size: 1.35rem; font-family: var(--mono); }
.breakdown-centre span {
  font-size: 0.62rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--text-faint);
}

.breakdown-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.breakdown-row {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.8rem;
}
@media (max-width: 620px) {
  .breakdown-row { grid-template-columns: 6rem minmax(0, 1fr) auto; gap: 0.5rem; }
}

.breakdown-key {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font-size: 0.84rem; font-weight: 600;
  color: var(--text-muted);
}
.breakdown-key::before {
  content: ''; width: 8px; height: 8px; flex: none;
  border-radius: 50%; background: var(--dot, var(--accent));
}

.breakdown-track {
  height: 7px;
  border-radius: 999px;
  background: var(--bg-raised);
  overflow: hidden;
}
.breakdown-fill { display: block; height: 100%; border-radius: 999px; }
.breakdown-points { font-family: var(--mono); font-size: 0.86rem; }

/* --- Packs a player has cleared ------------------------------------------- */

.pack-chips { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.pack-chip {
  display: flex; flex-direction: column; gap: 0.15rem;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius);
  color: inherit;
  border: 1px solid color-mix(in srgb, var(--pack-colour, var(--accent)) 45%, transparent);
  background: color-mix(in srgb, var(--pack-colour, var(--accent)) 12%, var(--bg-elevated));
  transition: border-color 0.15s, transform 0.15s;
}
.pack-chip:hover {
  border-color: var(--pack-colour, var(--accent));
  transform: translateY(-1px);
}
.pack-chip-name { font-weight: 700; font-size: 0.92rem; }
.pack-chip-meta {
  font-size: 0.74rem;
  color: var(--text-faint);
  font-family: var(--mono);
}
