/* ===========================================================================
   MU Chaos — player portal.

   Built around the artwork the game itself ships, so the site and the client
   look like one product:
     /game/main/api/icon/loginbg_nw.jpg   hero (character right, dark left)
     /game/main/api/icon/icon1|2|3.png    class portraits
     /game/main/ver/0/res/item/<icon>.png item art (7,047 files)
     /client/images/{icon,event,shop}/    small UI glyphs

   Every class name the JS renders is styled here — renaming one silently breaks
   a view, so the list is treated as an interface.
   =========================================================================== */

:root {
  /* Surfaces — cool, near-black, so the gold reads as light rather than paint */
  --bg-deep:      #05070e;
  --bg:           #080b14;
  --panel:        #0e1320;
  --panel-2:      #141b2c;
  --panel-hi:     #1b2438;
  --line:         #222c44;
  --line-soft:    #18202f;

  /* Ornament */
  --gold:         #c9a227;
  --gold-lt:      #f2dda6;
  --gold-dk:      #7d6318;

  /* Accents */
  --crimson:      #b52e3c;
  --azure:        #4a7ad4;
  --azure-lt:     #7fa8f0;

  /* Text — every pair checked at 4.5:1 or better on --panel */
  --text:         #ece8dd;
  --text-dim:     #a7aec4;
  --text-faint:   #737b91;

  /* Status */
  --ok:           #3fa96a;
  --warn:         #d99b21;
  --danger:       #d9414f;

  --radius:       12px;
  --radius-sm:    8px;
  --shadow:       0 18px 50px rgba(0,0,0,.55);
  --shadow-sm:    0 6px 18px rgba(0,0,0,.35);

  --font-display: "Cinzel", Georgia, serif;
  --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  --font-mono:    ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --header-h:     64px;
  --wrap:         1180px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg-deep);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: var(--azure-lt); text-decoration: none; }
a:hover { color: #a9c6f7; }
img { max-width: 100%; }
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 700; line-height: 1.15; margin: 0; }

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

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }
.muted, .faint { color: var(--text-faint); }
.faint { font-size: .85rem; }

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  /* Semi-transparent over the hero, solid once scrolled past it. */
  background: rgba(8, 11, 20, .82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line-soft);
}
.site-header .bar { display: flex; align-items: center; gap: 18px; width: 100%; min-width: 0; }
/* The wordmark keeps its space; everything to the right of it gives way first. Without
   this the nav -- which is as wide as whatever balance the player happens to hold -- won
   the row and slid underneath the brand. */
.site-header .brand { flex: 0 0 auto; }
.site-header .nav { min-width: 0; }

.brand { display: flex; align-items: center; gap: 10px; color: var(--gold-lt); font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; letter-spacing: .02em; white-space: nowrap; }
.brand:hover { color: var(--gold-lt); }
.brand img { width: 34px; height: 34px; object-fit: contain; filter: drop-shadow(0 2px 6px rgba(0,0,0,.6)); }
.brand .mark {
  width: 30px; height: 30px; flex: none; border-radius: 8px;
  background: linear-gradient(140deg, var(--gold), var(--gold-dk));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35);
}


/* Hidden until the phone breakpoint at the foot of this file turns it on. */
.nav-toggle {
  display: none;
  margin-left: auto;
  background: none; border: 1px solid var(--line);
  color: var(--text); font-size: 1.1rem;
  width: 40px; height: 38px; border-radius: var(--radius-sm); cursor: pointer;
}

.nav { display: flex; align-items: center; gap: 14px; margin-left: auto; }
.nav-primary { display: flex; align-items: center; gap: 2px; }

.nav a {
  position: relative;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-size: .9rem; font-weight: 500; white-space: nowrap;
  transition: color .15s, background .15s;
}
.nav a:hover { color: var(--text); background: rgba(255,255,255,.05); }
.nav-primary > a.active { color: var(--gold-lt); }
.nav-primary > a.active::after {
  content: ''; position: absolute; left: 12px; right: 12px; bottom: 2px;
  height: 2px; border-radius: 2px; background: var(--gold);
}
.nav a.btn { color: #1a1405; }
.nav a.btn:hover { color: #1a1405; }

/* ---- dropdown menus ---- */

.nav-menu { position: relative; }
.nav-menu-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px;
  background: none; border: 0; border-radius: var(--radius-sm);
  color: var(--text-dim); font: inherit; font-size: .9rem; font-weight: 500;
  cursor: pointer; white-space: nowrap;
  transition: color .15s, background .15s;
}
.nav-menu-btn:hover { color: var(--text); background: rgba(255,255,255,.05); }
.nav-menu-btn.active { color: var(--gold-lt); }
.caret {
  width: 0; height: 0; flex: none;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: .7; transition: transform .15s;
}
.nav-menu.open .caret { transform: rotate(180deg); }

.nav-drop {
  position: absolute; top: calc(100% + 8px); right: 0;
  min-width: 190px; padding: 6px;
  display: none; flex-direction: column;
  background: var(--panel-hi);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  z-index: 120;
}
.nav-menu.open .nav-drop { display: flex; }
.nav-drop a { padding: 9px 12px; font-size: .88rem; }
.nav-drop a.active { color: var(--gold-lt); background: rgba(201,162,39,.10); }
.nav-drop a.danger { color: #f0a3ab; }
.nav-drop a.danger:hover { background: rgba(217,65,79,.12); color: #f0a3ab; }

/* ---- wallet chip ---- */

.nav-wallet {
  display: flex; align-items: center; gap: 12px;
  padding: 6px 12px !important;
  border-radius: 999px;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
  font-size: .84rem; color: var(--text);
}
.nav-wallet:hover { border-color: var(--gold-dk); background: rgba(201,162,39,.10); color: var(--text); }
.nav-wallet span { display: inline-flex; align-items: center; gap: 5px; }
.nav-wallet img { width: 16px; height: 16px; object-fit: contain; }

/* ---- signed out ---- */

.nav-cta { display: flex; align-items: center; gap: 8px; }
.nav-signin { color: var(--text-dim); }

/* ---- phone: the same DOM, as a drawer ---- */

@media (max-width: 900px) {
  .nav { gap: 8px; }
  .nav-wallet { order: -1; }
}

@media (max-width: 760px) {
  .nav-toggle { display: block; }
  .nav {
    display: none;
    position: absolute; top: var(--header-h); left: 0; right: 0;
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: 10px;
    background: rgba(8,11,20,.98);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow);
  }
  .nav.open { display: flex; }
  .nav-primary { flex-direction: column; align-items: stretch; gap: 0; }
  .nav a { padding: 12px 14px; }
  .nav-primary > a.active::after { display: none; }
  .nav-primary > a.active { background: rgba(201,162,39,.10); }

  /* The panels stop floating and become titled sections, so a phone shows every
     destination at once instead of hiding them behind taps. */
  .nav-menu { position: static; }
  .nav-menu-btn {
    width: 100%; justify-content: flex-start;
    padding: 14px 14px 6px;
    font-size: .7rem; letter-spacing: .14em; text-transform: uppercase;
    color: var(--text-faint); pointer-events: none;
  }
  .nav-menu-btn .caret { display: none; }
  .nav-drop {
    display: flex; position: static; min-width: 0; padding: 0;
    background: none; border: 0; box-shadow: none;
  }
  .nav-drop a { padding: 12px 14px; font-size: .9rem; }

  .nav-wallet {
    order: 0; justify-content: space-around;
    margin: 4px 0 10px; padding: 10px 12px !important;
    border-radius: var(--radius-sm);
  }
  .nav-cta { flex-direction: column; align-items: stretch; gap: 6px; margin-top: 8px; }
  .nav-cta .btn { width: 100%; }
}


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

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: .92rem; font-weight: 600; letter-spacing: .02em;
  cursor: pointer;
  transition: transform .12s, box-shadow .15s, background .15s, border-color .15s;
  text-align: center;
}
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .5; cursor: default; transform: none; }

.btn-primary, .btn-gold {
  background: linear-gradient(160deg, #e2be3f, var(--gold) 45%, var(--gold-dk));
  color: #1a1405;
  border-color: var(--gold-dk);
  box-shadow: 0 6px 18px rgba(201,162,39,.22), inset 0 1px 0 rgba(255,255,255,.4);
}
.btn-primary:hover, .btn-gold:hover { color: #1a1405; box-shadow: 0 8px 24px rgba(201,162,39,.34), inset 0 1px 0 rgba(255,255,255,.5); }

.btn-ghost {
  background: rgba(255,255,255,.04);
  border-color: var(--line);
  color: var(--text);
}
.btn-ghost:hover { background: rgba(255,255,255,.09); border-color: #33405e; color: var(--text); }

.btn-sm { padding: 7px 14px; font-size: .84rem; }
.btn-block { display: flex; width: 100%; }

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

.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: min(76vh, 620px);
  margin-top: calc(var(--header-h) * -1);
  padding: calc(var(--header-h) + 40px) 0 60px;
  overflow: hidden;
}
.hero-bg {
  position: absolute; inset: 0;
  background-size: cover;
  background-position: 72% center;   /* keeps the character in frame as it narrows */
  z-index: 0;
}
/* Two scrims: one darkens the left so the headline always has contrast, one fades
   the bottom into the page so the hero does not end on a hard edge. */
.hero::before {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(100deg, var(--bg-deep) 4%, rgba(5,7,14,.90) 32%, rgba(5,7,14,.35) 60%, rgba(5,7,14,.12) 100%);
}
.hero::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 180px; z-index: 1;
  background: linear-gradient(to bottom, rgba(5,7,14,0), var(--bg-deep));
}
.hero .wrap { position: relative; z-index: 2; }
.hero-inner { max-width: 620px; }

.eyebrow {
  font-family: var(--font-display);
  font-size: .78rem; font-weight: 600; letter-spacing: .22em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 14px;
}
.hero h1 { font-size: clamp(2.4rem, 6vw, 4rem); letter-spacing: .01em; }
.hero h1 em {
  display: block;
  margin-top: 8px;
  font-family: var(--font-body);
  font-style: normal;
  font-size: clamp(.95rem, 2vw, 1.15rem);
  font-weight: 500;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--gold-lt);
}
.hero p { margin: 18px 0 0; max-width: 52ch; color: var(--text-dim); font-size: 1.03rem; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* ---------------------------------------------------------- stat strip */

.stat-strip {
  position: relative;
  z-index: 3;
  margin-top: -34px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.stat-strip .stat { background: var(--panel); padding: 18px 16px; text-align: center; }
.stat-strip .v { font-family: var(--font-display); font-size: 1.5rem; font-weight: 700; color: var(--gold-lt); line-height: 1.2; }
.stat-strip .k { font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint); margin-top: 4px; }

/* -------------------------------------------------------------- classes */

.section-head { text-align: center; margin: 0 auto 34px; max-width: 640px; }
.section-head h2 { font-size: clamp(1.6rem, 3.4vw, 2.2rem); }
.section-head p { color: var(--text-dim); margin: 10px 0 0; }

.class-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.class-card {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--panel);
  transition: transform .18s, border-color .18s, box-shadow .18s;
}
.class-card:hover { transform: translateY(-4px); border-color: var(--gold-dk); box-shadow: var(--shadow); }
.class-card img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.class-card figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 40px 18px 16px;
  background: linear-gradient(to top, rgba(5,7,14,.96) 30%, rgba(5,7,14,0));
}
.class-card b { display: block; font-family: var(--font-display); font-size: 1.15rem; color: var(--gold-lt); }
.class-card span { display: block; font-size: .82rem; color: var(--text-dim); margin-top: 2px; }

/* ------------------------------------------------------------- features */

.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; }
.feature {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 20px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
}
.feature img { width: 38px; height: 38px; object-fit: contain; flex: none; }
.feature b { display: block; font-size: .98rem; }
.feature p { margin: 4px 0 0; font-size: .86rem; color: var(--text-dim); }

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

.panel {
  background: linear-gradient(170deg, var(--panel-2), var(--panel) 55%);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 20px;
  overflow: hidden;
}
.panel-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 15px 20px;
  border-bottom: 1px solid var(--line-soft);
  background: rgba(255,255,255,.015);
}
.panel-head h3 { font-size: 1.02rem; color: var(--gold-lt); }
.panel-head .faint { margin-left: auto; }
.panel-body { padding: 20px; }

.row { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; }
.col { min-width: 0; }

/* page heading */
.eyebrow + h2 { font-size: clamp(1.7rem, 4vw, 2.4rem); }
.rule { height: 2px; width: 72px; margin: 14px 0 26px; background: linear-gradient(90deg, var(--gold), transparent); border-radius: 2px; }
.rule i { display: none; }

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

.field { margin-bottom: 16px; }
.field > label, label.field > span { display: block; font-size: .8rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 6px; }
.form-note { font-size: .8rem; color: var(--text-faint); margin: -8px 0 16px; }

.input,
input[type=text], input[type=password], input[type=number], input[type=date], input[type=time], input[type=tel], select, textarea {
  width: 100%;
  padding: 11px 13px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: inherit;
  font-size: .93rem;
  transition: border-color .15s, box-shadow .15s;
}
.input:focus, input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--gold-dk);
  box-shadow: 0 0 0 3px rgba(201,162,39,.14);
}
textarea { min-height: 110px; resize: vertical; }
select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--text-faint) 50%), linear-gradient(135deg, var(--text-faint) 50%, transparent 50%); background-position: right 16px center, right 11px center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 34px; }

/* auth */
/* The form here is a bare .panel. .panel deliberately carries no padding of its own
   because ordinary panels take theirs from .panel-head / .panel-body — which this form
   does not use, so without an explicit rule the heading, the fields and the button all
   sit flush against the card border. */
.auth-shell { max-width: 430px; margin: 48px auto 72px; }
.auth-shell form.panel { margin-bottom: 0; }

/* One standard for every form and content panel in the portal.
   .panel itself carries no padding on purpose — .panel-head and .panel-body are what
   supply it — so all loose content lives in a .panel-body and inherits the same
   gutter, the same field rhythm, and the same distance from the bottom edge. */
.panel-body > h3 { margin-bottom: 8px; }
.panel-body > p { margin: 0 0 16px; }
.panel-body > p:last-child,
.panel-body > .field:last-child,
.panel-body > .form-note:last-child { margin-bottom: 0; }
.panel-body > .btn:last-child { margin-bottom: 0; }
.panel-body > .field + .btn-block,
.panel-body > .form-note + .btn-block { margin-top: 6px; }
.auth-tabs { display: flex; gap: 6px; margin-bottom: 22px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 5px; }
.auth-tabs button {
  flex: 1; padding: 9px; border: 0; border-radius: 6px;
  background: none; color: var(--text-dim); font: inherit; font-size: .88rem; font-weight: 600; cursor: pointer;
}
.auth-tabs button.active { background: var(--panel-hi); color: var(--gold-lt); }

/* -------------------------------------------------------------- servers */

.server-list { display: flex; flex-direction: column; }

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


/* ---------------------------------------------------------- misc atoms */

.tag { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: .72rem; font-weight: 600; border: 1px solid; }
.tag.ok   { color: #8fe0b0; border-color: #2c6b46; background: rgba(63,169,106,.12); }
.tag.warn { color: #f0cf8a; border-color: #6b551d; background: rgba(217,155,33,.12); }
.tag.dim  { color: var(--text-faint); border-color: var(--line); }

.wallet { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; padding: 20px; }
.wallet .w { display: flex; align-items: center; gap: 12px; padding: 14px; border-radius: var(--radius-sm); background: var(--panel-hi); border: 1px solid var(--line-soft); }
.wallet .w img { width: 32px; height: 32px; object-fit: contain; }
.wallet .v { font-family: var(--font-display); font-size: 1.2rem; font-weight: 700; color: var(--gold-lt); }
.wallet .k { font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint); }

.ms-row { display: flex; align-items: center; gap: 14px; padding: 14px 20px; border-bottom: 1px solid var(--line-soft); }
.ms-row:last-child { border-bottom: 0; }
.ms-need { flex: 1; min-width: 0; }
.ms-need b { display: block; }
.ms-act { display: flex; align-items: center; gap: 10px; flex: none; }


.table-scroll { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; font-size: .9rem; }
.tbl th { text-align: left; padding: 10px 12px; font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint); border-bottom: 1px solid var(--line); white-space: nowrap; }
.tbl td { padding: 11px 12px; border-bottom: 1px solid var(--line-soft); }
.tbl tr:last-child td { border-bottom: 0; }
.tbl code { font-family: var(--font-mono); font-size: .84rem; color: var(--gold-lt); }

.skeleton { height: 76px; border-radius: var(--radius-sm); background: linear-gradient(90deg, var(--panel-2) 25%, var(--panel-hi) 37%, var(--panel-2) 63%); background-size: 400% 100%; animation: sk 1.3s ease infinite; margin: 20px; }
@keyframes sk { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.spinner { width: 15px; height: 15px; border: 2px solid rgba(255,255,255,.28); border-top-color: currentColor; border-radius: 50%; animation: sp .7s linear infinite; }
@keyframes sp { to { transform: rotate(360deg); } }

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

#toasts { position: fixed; right: 18px; bottom: 18px; z-index: 300; display: flex; flex-direction: column; gap: 10px; }
.toast {
  padding: 12px 16px; border-radius: var(--radius-sm);
  background: var(--panel-hi); border: 1px solid var(--line);
  box-shadow: var(--shadow); font-size: .89rem; max-width: 340px;
}
.toast.ok  { border-color: #2c6b46; }
.toast.err { border-color: #6b2029; }

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

.site-footer { margin-top: 70px; padding: 28px 0; border-top: 1px solid var(--line-soft); background: var(--bg); color: var(--text-faint); font-size: .86rem; }
.site-footer .bar { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.site-footer .social { margin-left: auto; display: flex; gap: 12px; }
.site-footer .social img { width: 22px; height: 22px; opacity: .55; transition: opacity .15s; }
.site-footer .social a:hover img { opacity: 1; }

/* ------------------------------------------------------------ item art */

/* One item in ~250 has no picture, so an empty tile must look deliberate: the
   frame and the quality ring carry it rather than a broken-image glyph. */
.item-tile {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; flex: none;
  border-radius: var(--radius-sm);
  background: linear-gradient(160deg, var(--panel-hi), var(--panel-2));
  border: 1px solid rgba(255,255,255,.10);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
  overflow: hidden;
}
.item-tile img { width: 100%; height: 100%; object-fit: contain; display: block; }
.item-tile .amt {
  position: absolute; right: 2px; bottom: 1px;
  font-style: normal; font-size: 10px; font-weight: 700; line-height: 1.3;
  padding: 0 3px; border-radius: 4px;
  color: #fff; background: rgba(4,6,12,.8);
}

/* Quality ring. The client bakes its own palette into its art, so this is a
   consistent ranking cue of our own, not a reproduction of the in-game colours. */
.item-tile.q0  { border-color: rgba(154,162,182,.55); }
.item-tile.q1  { border-color: rgba(79,169,106,.65); }
.item-tile.q2  { border-color: rgba(74,122,212,.65); }
.item-tile.q3  { border-color: rgba(139,92,214,.65); }
.item-tile.q4  { border-color: rgba(217,139,33,.70); }
.item-tile.q5  { border-color: rgba(217,65,79,.70); }
.item-tile.q6  { border-color: rgba(201,162,39,.75); }
.item-tile.q7  { border-color: rgba(53,184,196,.70); }
.item-tile.q8  { border-color: rgba(217,95,168,.70); }
.item-tile.q9  { border-color: rgba(240,217,160,.80); }
.item-tile.q10 { border-color: rgba(245,242,232,.85); }

.gifts { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }
.gift { display: flex; flex-direction: column; align-items: center; gap: 5px; width: 78px; text-align: center; background: none; border: 0; padding: 0; }
.gift-name {
  font-size: 11px; line-height: 1.25; color: var(--text-dim);
  /* Two lines then ellipsis — item names run long and must not shift the grid. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* input[type=number]{width:100%} is (0,1,1) and outranks a bare class, so the
   quantity box needs the element qualifier to keep its own width. */
input.qty { width: 92px; text-align: right; padding: 8px 10px; }

/* --------------------------------------------------------------- top up */

.gate-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin-bottom: 18px; }
.gate {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  text-align: left; padding: 14px 16px;
  border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); font: inherit; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.gate:hover { border-color: var(--gold-dk); }
.gate.sel { border-color: var(--gold); background: var(--panel-hi); }

.order-lead { margin: 0 0 16px; color: var(--text-dim); }
.order-code { display: flex; flex-direction: column; gap: 2px; padding: 14px 16px; margin-bottom: 18px; border-radius: var(--radius-sm); border: 1px dashed var(--gold-dk); background: rgba(201,162,39,.07); }
.order-code b { font-family: var(--font-mono); font-size: 1.45rem; letter-spacing: .06em; color: var(--gold-lt); }
.order-detail { display: grid; grid-template-columns: auto 1fr; gap: 8px 18px; margin: 0 0 18px; }
.order-detail dt { color: var(--text-faint); font-size: .84rem; }
.order-detail dd { margin: 0; font-size: .92rem; }
.order-qr { display: block; width: 210px; max-width: 100%; margin: 0 0 18px; border-radius: var(--radius-sm); background: #fff; padding: 8px; }

.notice { padding: 20px; border-radius: var(--radius); border: 1px solid rgba(217,155,33,.35); background: rgba(217,155,33,.07); }
.notice b { display: block; margin-bottom: 6px; color: var(--gold-lt); }
.notice p { margin: 0; color: var(--text-dim); font-size: .9rem; }

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

@media (max-width: 900px) {
  .class-grid { grid-template-columns: repeat(3, 1fr); gap: 12px; }
  .stat-strip { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 760px) {
  .hero { min-height: 0; padding-bottom: 44px; }
  .hero-bg { background-position: 66% center; }
  .hero::before { background: linear-gradient(180deg, rgba(5,7,14,.72) 0%, rgba(5,7,14,.86) 55%, var(--bg-deep) 100%); }
  .hero-inner { max-width: none; }

  .class-grid { grid-template-columns: 1fr; }
  .ms-row { flex-wrap: wrap; }
  .ms-act { width: 100%; justify-content: flex-end; }
  .gift { width: 70px; }
  .item-tile { width: 42px; height: 42px; }
  #toasts { left: 14px; right: 14px; bottom: 14px; }
  .toast { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  html { scroll-behavior: auto; }
}

/* ---------------------------------------------------------------- wheel */

.wheel-stage { display: flex; justify-content: center; padding: 8px 0 18px; }

.wheel-frame {
  position: relative;
  width: min(360px, 82vw);
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  padding: 10px;
  background: linear-gradient(160deg, var(--gold), var(--gold-dk) 55%, #241d08);
  box-shadow: var(--shadow), inset 0 0 0 1px rgba(255,255,255,.18);
}

.wheel-svg {
  display: block; width: 100%; height: 100%;
  /* Labels are decoration, not content to select; dragging over the wheel was
     highlighting them and drawing blue boxes across the face. */
  user-select: none; -webkit-user-select: none;
  border-radius: 50%;
  transform-origin: 50% 50%;
  will-change: transform;
  background: var(--panel);
}
/* Free spin while the server is deciding; the landing transition replaces it. */
@keyframes wheel-free { to { transform: rotate(360deg); } }
.wheel-svg.freewheel { animation: wheel-free .7s linear infinite; }

.wheel-label { font-family: var(--font-body); font-size: 14px; font-weight: 700; fill: var(--text); letter-spacing: .02em; }
.wheel-label.rare { fill: var(--gold-lt); }
.wheel-spoke { stroke: rgba(255,255,255,.14); stroke-width: 1.5; }

.wheel-pointer {
  position: absolute; top: -4px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; z-index: 3;
  border-left: 13px solid transparent; border-right: 13px solid transparent;
  border-top: 26px solid var(--gold-lt);
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.6));
}
.wheel-hub {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 54px; height: 54px; border-radius: 50%; z-index: 2;
  background: radial-gradient(circle at 35% 30%, #2b364f, #0e1320 70%);
  border: 2px solid var(--gold-dk);
  box-shadow: 0 4px 14px rgba(0,0,0,.6);
}

.wheel-controls { display: flex; align-items: center; justify-content: center; gap: 16px; flex-wrap: wrap; }
.wheel-meta { font-variant-numeric: tabular-nums; }

.wheel-result { min-height: 52px; margin-top: 14px; text-align: center; }
.wheel-result b { display: block; font-family: var(--font-display); font-size: 1.1rem; }
.wheel-result span { display: block; color: var(--text-dim); font-size: .92rem; margin-top: 2px; }
.wheel-result.won b { color: var(--gold-lt); }
.wheel-result.none b { color: var(--text-faint); }

.wheel-legend {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px; margin-top: 6px;
  border-top: 1px solid var(--line-soft); padding-top: 16px;
}
.wheel-legend-item { display: flex; align-items: center; gap: 9px; font-size: .84rem; color: var(--text-dim); min-width: 0; }
.wheel-legend-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wheel-legend-item.rare span { color: var(--gold-lt); }
.prize-none {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; flex: none;
  border-radius: var(--radius-sm); border: 1px dashed var(--line);
  color: var(--text-faint);
}

.wheel-log { display: flex; align-items: baseline; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line-soft); font-size: .86rem; }
.wheel-log:last-child { border-bottom: 0; }
.wheel-log b { flex: 1; min-width: 0; font-weight: 500; }
.wheel-log span { flex: none; font-size: .78rem; }

@media (prefers-reduced-motion: reduce) {
  .wheel-svg.freewheel { animation: none; }
  .wheel-svg { transition: none !important; }
}

/* ------------------------------------------------------------- play page */

.platforms { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px; }

.platform {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: linear-gradient(165deg, var(--panel-2), var(--panel) 60%);
  transition: border-color .18s, transform .18s, box-shadow .18s;
}
.platform:hover { border-color: var(--gold-dk); transform: translateY(-3px); box-shadow: var(--shadow); }

/* The game's own hero art, washed back far enough to stay a texture rather than
   compete with the text sitting on it. */
.platform-art {
  position: absolute; inset: 0; z-index: 0;
  background-size: cover; background-position: 70% center;
  opacity: .16;
  mask-image: linear-gradient(105deg, transparent 30%, #000 100%);
  -webkit-mask-image: linear-gradient(105deg, transparent 30%, #000 100%);
}

/* Same 20px gutter as every other panel body in the portal. */
.platform-body { position: relative; z-index: 2; padding: 20px; }
.platform-body h3 { margin-bottom: 8px; }
.platform-body p { margin: 0 0 14px; color: var(--text-dim); max-width: 42ch; }

.platform-glyph {
  width: 30px; height: 30px; display: block; margin-bottom: 12px;
  fill: none; stroke: var(--gold); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}

.platform-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
.platform-meta span {
  font-size: .72rem; letter-spacing: .04em;
  padding: 3px 9px; border-radius: 999px;
  color: var(--text-dim);
  border: 1px solid var(--line); background: rgba(255,255,255,.04);
}

/* A drawn handset — the Android robot is a trademark licensed only under CC BY, and
   a decorative icon is not worth attaching an attribution obligation to the site. */
.platform-figure {
  position: absolute; z-index: 1; right: -26px; bottom: -46px;
  transform: rotate(-11deg);
  pointer-events: none;
  opacity: .92;
}
.phone {
  position: relative;
  width: 132px; height: 232px;
  border-radius: 20px;
  padding: 8px;
  background: linear-gradient(155deg, #2b3550, #10151f);
  border: 1px solid rgba(255,255,255,.16);
  box-shadow: 0 16px 40px rgba(0,0,0,.55);
}
.phone-notch {
  position: absolute; top: 7px; left: 50%; transform: translateX(-50%);
  width: 42px; height: 5px; border-radius: 3px; background: rgba(0,0,0,.6);
}
.phone-screen {
  width: 100%; height: 100%;
  border-radius: 13px;
  background: radial-gradient(circle at 50% 38%, #1d2740, #070a12 72%);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.phone-screen img { width: 74%; height: auto; object-fit: contain; filter: drop-shadow(0 3px 10px rgba(0,0,0,.6)); }

.platform-note { margin-top: 18px; max-width: 78ch; }

@media (max-width: 900px) {
  /* The handset would sit under the text once the card narrows. */
  .platform-figure { display: none; }
}

/* -------------------------------------------------- realm + news cards */

/* Both home cards cap their height and scroll, so ten realms or twenty posts cannot
   push the rest of the page down. The cap is generous enough that the common case —
   a handful of entries — never shows a scrollbar at all. */
.scroll-list {
  max-height: 300px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.scroll-list::-webkit-scrollbar { width: 8px; }
.scroll-list::-webkit-scrollbar-track { background: transparent; }
.scroll-list::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
.scroll-list::-webkit-scrollbar-thumb:hover { background: var(--panel-hi); }

.server {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line-soft);
  transition: background .15s;
}
.server:last-child { border-bottom: 0; }
.server:hover { background: rgba(255,255,255,.025); }
.server .nm { font-weight: 600; }
.server .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--ok); box-shadow: 0 0 0 3px rgba(63,169,106,.18); }
.server .tag { margin-left: auto; }

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

.news-item {
  display: block;
  padding: 15px 20px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--text);
  transition: background .15s;
}
.news-item:last-child { border-bottom: 0; }
.news-item:hover { background: rgba(255,255,255,.04); color: var(--text); }
.news-item h4 { font-family: var(--font-display); font-size: 1rem; margin: 4px 0 0; color: var(--gold-lt); }
.news-item time { display: block; font-size: .74rem; color: var(--text-faint); margin-top: 6px; }
.news-tag {
  display: inline-block;
  font-size: .66rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gold);
}
.news-excerpt {
  margin: 6px 0 0; font-size: .86rem; color: var(--text-dim);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ---- article ---- */

.article-meta { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; padding-bottom: 14px; border-bottom: 1px solid var(--line-soft); }
.article-meta time { font-size: .8rem; color: var(--text-faint); }

.article { max-width: 72ch; }
.article h2, .article h3, .article h4, .article h5 { color: var(--gold-lt); margin: 26px 0 10px; }
.article h2 { font-size: 1.35rem; }
.article h3 { font-size: 1.15rem; }
.article h4, .article h5 { font-size: 1rem; }
.article > :first-child { margin-top: 0; }
.article p { margin: 0 0 14px; color: var(--text-dim); }
.article strong { color: var(--text); font-weight: 600; }
.article ul { margin: 0 0 14px; padding-left: 20px; color: var(--text-dim); }
.article li { margin-bottom: 6px; }
.article code { font-family: var(--font-mono); font-size: .86em; background: var(--panel-hi); border: 1px solid var(--line-soft); border-radius: 4px; padding: 1px 5px; color: var(--gold-lt); }
.article hr { border: 0; border-top: 1px solid var(--line); margin: 22px 0; }
.article a { color: var(--azure-lt); text-decoration: underline; text-underline-offset: 2px; }

/* ------------------------------------------------- art panels + glyphs */

/* The same treatment as the Play page's platform cards, shared by the home sections
   and every form: the game's own art washed behind, a stroked glyph in the head. */
.panel-art-host { position: relative; }
.panel-art {
  position: absolute; inset: 0; z-index: 0;
  background-size: cover;
  opacity: .13;
  /* Fades out toward the content so text always sits on near-flat ground. */
  mask-image: linear-gradient(115deg, transparent 34%, #000 100%);
  -webkit-mask-image: linear-gradient(115deg, transparent 34%, #000 100%);
  pointer-events: none;
}
.panel-art-host > .panel-head,
.panel-art-host > .panel-body,
.panel-art-host > .scroll-list,
.panel-art-host > .wallet { position: relative; z-index: 1; }

.head-glyph {
  width: 20px; height: 20px; flex: none;
  fill: none; stroke: var(--gold); stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: .95;
}

/* ------------------------------------------------------------ form polish */

label.f > span,
.field > label,
label.field > span {
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-faint);
}

/* A visible, deliberate focus state rather than the browser default — these are the
   only controls on the site a player types into. */
.input:focus, input:focus, select:focus, textarea:focus {
  border-color: var(--gold-dk);
  box-shadow: 0 0 0 3px rgba(201,162,39,.16);
  background: var(--panel);
}
.input::placeholder, input::placeholder, textarea::placeholder { color: var(--text-faint); opacity: .8; }

/* Inputs sit on the art, so they need their own ground to stay readable. */
.panel-art-host .input,
.panel-art-host input[type=text],
.panel-art-host input[type=password],
.panel-art-host input[type=email],
.panel-art-host input[type=number],
.panel-art-host input[type=tel],
.panel-art-host select,
.panel-art-host textarea { background: rgba(8, 11, 20, .72); }

.auth-tabs { background: rgba(8, 11, 20, .6); }

/* ------------------------------------------------------------- realm rows */

.server {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 20px;
  border-bottom: 1px solid var(--line-soft);
  transition: background .15s;
}
.server:last-child { border-bottom: 0; }
.server:hover { background: rgba(255,255,255,.035); }

/* The realm's short code, so a row is identifiable at a glance in a long list. */
.server-badge {
  flex: none;
  width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 10px;
  font-family: var(--font-display); font-size: .82rem; font-weight: 700;
  letter-spacing: .02em;
  color: var(--gold-lt);
  background: linear-gradient(150deg, var(--panel-hi), var(--panel-2));
  border: 1px solid var(--line);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
}

.server-info { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.server-info b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.server-meta { font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-faint); margin-top: 1px; }

.server-state { display: inline-flex; align-items: center; gap: 8px; flex: none; }
.server .dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--ok); box-shadow: 0 0 0 3px rgba(63,169,106,.18);
}
.server.maint .dot { background: var(--warn); box-shadow: 0 0 0 3px rgba(217,155,33,.18); }
.server.full  .dot { background: var(--text-faint); box-shadow: 0 0 0 3px rgba(115,123,145,.16); }

/* No wrap rule: the name already ellipsises, so badge, name and pill stay on one
   line at every width and rows stay compact. Wrapping at 520px made a two-realm card
   107px per row for no gain. */
@media (max-width: 420px) {
  .server { padding: 12px 14px; gap: 10px; }
  .server-badge { width: 34px; height: 34px; font-size: .74rem; }
}



/* ============================================================ player dashboard === */
/* The signed-in landing page, plus the rankings and public code list that came with
   it. Everything here reuses the portal's existing tokens — no new colours are
   introduced, so a later theme change moves this too. */

.dash { display: flex; flex-direction: column; gap: 18px; }
.dash-panel { padding: 0; }

/* ---- identity strip ---- */
.dash-hero {
  display: flex; flex-wrap: wrap; gap: 18px 24px;
  align-items: center; justify-content: space-between;
  padding: 22px 24px;
}
.dash-hero-l { min-width: 0; flex: 1 1 22rem; }
.dash-hero-l h3 { margin: 2px 0 6px; font-size: 1.5rem; line-height: 1.15; }
.dash-eyebrow {
  font-size: .68rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--gold); font-weight: 600;
}
.dash-hero-meta { color: var(--text-dim); font-size: .92rem; }
.dash-hero-meta .sep { opacity: .45; margin: 0 .45rem; }
.dash-note { margin-top: .5rem; font-size: .8rem; color: var(--text-dim); opacity: .85; }
.dash-hero-r { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---- balances ---- */
.dash-stats {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
}
.dash-stat {
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 14px 16px;
}
.dash-stat-v { font-size: 1.45rem; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.dash-stat-v.accent { color: var(--gold); }
.dash-stat-k { font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); margin-top: 4px; }
.dash-stat-n { font-size: .72rem; color: var(--text-dim); opacity: .7; }

/* ---- progress bars ---- */
.dash-bar {
  height: 8px; border-radius: 99px; overflow: hidden;
  background: rgba(255, 255, 255, .07); margin: 8px 0;
}
.dash-bar > i { display: block; height: 100%; background: var(--text-dim); border-radius: 99px; }
.dash-bar.gold > i { background: linear-gradient(90deg, var(--gold-dk), var(--gold)); }
.dash-bar.ready > i { background: linear-gradient(90deg, #2f8f57, #47c07c); }

/* ---- VIP ---- */
.dash-vip-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.dash-vip-badge {
  font-weight: 700; letter-spacing: .06em; padding: 4px 12px; border-radius: 6px;
  background: rgba(201, 162, 39, .13); color: var(--gold);
  border: 1px solid rgba(201, 162, 39, .3);
}
.dash-perks { display: grid; gap: 8px 18px; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); margin-top: 12px; }
.dash-perk { display: flex; justify-content: space-between; gap: 10px; font-size: .86rem; border-bottom: 1px dashed var(--line); padding-bottom: 5px; }
.dash-perk .k { color: var(--text-dim); }
.dash-perk .v { font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---- today ---- */
.dash-today { display: flex; gap: 16px; align-items: flex-start; }
.dash-today-n {
  flex: 0 0 auto; min-width: 3.2rem; height: 3.2rem; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums;
  background: rgba(255, 255, 255, .05); color: var(--text-dim);
  border: 1px solid var(--line);
}
.dash-today-n.on {
  background: rgba(201, 162, 39, .14); color: var(--gold);
  border-color: rgba(201, 162, 39, .34);
}
.dash-today h4 { margin: 0 0 4px; font-size: 1rem; }
.dash-today p { margin: 0; font-size: .88rem; }

/* ---- reward tracks ---- */
.dash-tracks { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); }
.dash-track {
  background: rgba(255, 255, 255, .025); border: 1px solid var(--line);
  border-radius: 10px; padding: 14px 16px;
}
.dash-track-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 10px; }
.dash-track-head h4 { margin: 0; font-size: .98rem; }
.dash-track-sub { font-size: .76rem; color: var(--text-dim); margin-top: 2px; }
.dash-track-line { font-size: .88rem; color: var(--text-dim); }
.dash-track-line b { color: var(--text); font-variant-numeric: tabular-nums; }
.dash-track-foot { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-top: 8px; }
.dash-track-foot .faint { font-size: .78rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-empty { font-size: .86rem; color: var(--text-dim); margin: 6px 0 0; }

.dash-pill {
  font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; font-weight: 700;
  padding: 3px 8px; border-radius: 99px; white-space: nowrap;
}
.dash-pill.ready { background: rgba(71, 192, 124, .15); color: #47c07c; border: 1px solid rgba(71, 192, 124, .3); }
.dash-pill.you { background: rgba(201, 162, 39, .15); color: var(--gold); margin-left: .5rem; }

/* ---- quick links ---- */
.dash-quick { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.dash-tile {
  display: flex; flex-direction: column; gap: 3px;
  padding: 13px 15px; border-radius: 10px; text-decoration: none;
  background: rgba(255, 255, 255, .025); border: 1px solid var(--line);
  transition: border-color .15s, transform .15s, background .15s;
}
.dash-tile:hover { border-color: rgba(201, 162, 39, .45); transform: translateY(-1px); background: rgba(255, 255, 255, .045); }
.dash-tile.hot { border-color: rgba(71, 192, 124, .38); }
.dash-tile-t { font-weight: 600; color: var(--text); }
.dash-tile-n { font-size: .78rem; color: var(--text-dim); }

/* ---- rankings ---- */
.dash-tabs { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.dash-tab {
  background: transparent; border: 1px solid var(--line); color: var(--text-dim);
  padding: 6px 14px; border-radius: 99px; cursor: pointer; font: inherit; font-size: .86rem;
}
.dash-tab.on { border-color: rgba(201, 162, 39, .5); color: var(--gold); background: rgba(201, 162, 39, .08); }

/* A leaderboard is long and numeric; it scrolls inside its own box rather than
   widening the page. */
.table-wrap { overflow-x: auto; }
.dash-table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.dash-table th, .dash-table td { text-align: left; padding: .5rem .7rem; border-bottom: 1px solid var(--line); }
.dash-table th { font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); font-weight: 600; }
.dash-table td.rk, .dash-table td.nu { font-variant-numeric: tabular-nums; }
.dash-table td.nu { text-align: right; }
.dash-table td.rk { width: 3rem; color: var(--text-dim); }
.dash-table tr.mine td { background: rgba(201, 162, 39, .07); }
.dash-table tbody tr:last-child td { border-bottom: 0; }

/* ---- codes ---- */
.dash-codes { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); margin-top: 12px; }
.dash-code {
  display: flex; flex-direction: column; gap: 3px; text-align: left; cursor: pointer;
  padding: 12px 14px; border-radius: 10px; font: inherit;
  background: rgba(255, 255, 255, .025); border: 1px dashed var(--line);
  color: var(--text);
}
.dash-code:hover { border-color: rgba(201, 162, 39, .5); border-style: solid; }
.dash-code-v { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 1.05rem; font-weight: 700; letter-spacing: .06em; color: var(--gold); }
.dash-code-n { font-size: .76rem; color: var(--text-dim); }

@media (max-width: 560px) {
  .dash-hero { padding: 18px; }
  .dash-hero-r { width: 100%; }
  .dash-hero-r .btn { flex: 1 1 auto; text-align: center; }
}
@media (prefers-reduced-motion: reduce) {
  .dash-tile { transition: none; }
  .dash-tile:hover { transform: none; }
}

/* Ranking reward bands, shown with the board because getServerRank returns both. */
.dash-rankgifts { display: grid; gap: 6px; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); margin-bottom: 14px; }
.dash-rankgift { display: flex; gap: 10px; align-items: baseline; font-size: .82rem; background: rgba(255,255,255,.025); border: 1px solid var(--line); border-radius: 8px; padding: 7px 11px; }
.dash-rankgift .b { color: var(--gold); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dash-rankgift .g { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Realm switcher — only rendered when the account has a character on more than one. */
.dash-switch { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 12px; font-size: .82rem; }
.dash-chip {
  display: inline-flex; gap: 7px; align-items: baseline; cursor: pointer; font: inherit;
  background: rgba(255,255,255,.03); border: 1px solid var(--line); color: var(--text);
  border-radius: 99px; padding: 5px 13px;
}
.dash-chip .n { color: var(--text-dim); font-size: .76rem; }
.dash-chip.on { border-color: rgba(201,162,39,.5); background: rgba(201,162,39,.09); cursor: default; }
.dash-chip:not(.on):hover { border-color: rgba(201,162,39,.4); }
.dash-need { font-size: .78rem; white-space: nowrap; }
