/* wgf-account.css - /account/ (account_app.py): the Warband character-select
   stage (bottom of this file), Key Bindings editor, saved items, Discord panel,
   wallpaper teaser. Also linked by /tracked/ and /wallpapers/, so everything
   stage-specific is scoped .wgf-wb-* / .wgf-warband / body.wgf-warband-page.
   Sits on the chrome kit (wgf-chrome.css); only page-specific layout lives here. */

.wgf-account {
  max-width: 860px;
  margin: 0 auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.wgf-account-h1 {
  margin: 0;
  text-align: center;
}

.wgf-account-hint {
  opacity: 0.85;
  font-size: 0.92em;
  margin: 0 0 10px;
}

.wgf-account-status {
  min-height: 1.2em;
  margin: 8px 0 0;
  font-size: 0.9em;
  color: #ffd100;
}

.wgf-account-btnrow {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.wgf-account-id {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}

.wgf-account-avatar {
  border-radius: 50%;
  border: 2px solid #8b7355;
}

.wgf-account-email {
  opacity: 0.8;
  font-size: 0.9em;
}

/* -- Sign-in providers -- */

.wgf-account-note {
  opacity: 0.75;
  font-size: 0.88em;
  margin-top: 6px;
}

.wgf-account-providers {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

/* Battle.net button. Blizzard blue, in the client's beveled idiom - deliberately NOT
   a fabricated Blizzard logo (AI art is banned and inventing their mark is a brand
   violation). Swap in the official Battle.net asset kit when it is downloaded. */
.wgf-btn-bnet {
  display: inline-block;
  padding: 11px 22px;
  font-weight: 700;
  font-size: 1.02em;
  letter-spacing: 0.02em;
  color: #eaf6ff;
  text-decoration: none;
  border: 1px solid #0a5c9e;
  border-radius: 3px;
  background: linear-gradient(180deg, #1b9df5 0%, #0a72c4 52%, #075a9e 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.32),
              0 1px 3px rgba(0, 0, 0, 0.55);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.45);
}

.wgf-btn-bnet:hover,
.wgf-btn-bnet:focus-visible {
  background: linear-gradient(180deg, #35b0ff 0%, #1180d6 52%, #0a68b0 100%);
  color: #fff;
}

.wgf-btn-bnet:active {
  background: linear-gradient(180deg, #075a9e 0%, #0a72c4 100%);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5);
}

/* -- Key Bindings rows (the client's options-panel look) -- */

.wgf-kb-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid rgba(139, 115, 85, 0.45);
  border-radius: 3px;
  margin-bottom: 6px;
  background: rgba(0, 0, 0, 0.25);
}

#wgf-kb-editor.is-editing .wgf-kb-row:not(.is-fixed) {
  cursor: pointer;
}

#wgf-kb-editor.is-editing .wgf-kb-row:not(.is-fixed):hover {
  border-color: #ffd100;
  background: rgba(255, 209, 0, 0.08);
}

.wgf-kb-row.is-capturing {
  border-color: #ffd100;
  box-shadow: 0 0 8px rgba(255, 209, 0, 0.4);
}

.wgf-kb-row.is-changed .wgf-kb-row__key {
  color: #1eff00;
  border-color: #1eff00;
}

.wgf-kb-row.is-fixed {
  opacity: 0.6;
}

.wgf-kb-row__label {
  flex: 1;
}

.wgf-kb-row__key {
  min-width: 88px;
  text-align: center;
  padding: 3px 10px;
  border: 1px solid #8b7355;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.5);
  font-family: inherit;
  color: #ffd100;
}

.wgf-kb-row__key.is-unbound {
  color: #9d9d9d;
}

.wgf-kb-row__lock {
  font-size: 0.8em;
  opacity: 0.7;
}

.wgf-kb-row__unbind {
  display: none;
  border: 1px solid #8b7355;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.5);
  color: #ff4040;
  width: 24px;
  height: 24px;
  line-height: 1;
  cursor: pointer;
}

#wgf-kb-editor.is-editing .wgf-kb-row:not(.is-fixed) .wgf-kb-row__unbind {
  display: inline-block;
}

/* -- Saved items -- */

.wgf-saved-list {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
}

.wgf-saved-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid rgba(139, 115, 85, 0.3);
}

.wgf-saved-item .wgf-kb-row__unbind {
  display: inline-block;
  margin-left: auto;
}

.wgf-saved-region {
  font-size: 0.75em;
  opacity: 0.7;
  border: 1px solid rgba(139, 115, 85, 0.5);
  border-radius: 3px;
  padding: 1px 5px;
}

.wgf-account-discord {
  margin-top: 14px;
}

.wgf-discord-code {
  font-size: 1.4em;
  letter-spacing: 2px;
  color: #ffd100;
  text-align: center;
  padding: 8px;
  border: 1px dashed #8b7355;
  border-radius: 3px;
  user-select: all;
}

/* -- Wallpapers -- */

.wgf-wallgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}

.wgf-wallcard {
  margin: 0;
  border: 1px solid rgba(139, 115, 85, 0.45);
  border-radius: 4px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.35);
}

.wgf-wallcard img {
  display: block;
  width: 100%;
  height: 130px;
  object-fit: cover;
}

.wgf-wallcard figcaption {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  flex-wrap: wrap;
}

.wgf-wallcard__name {
  flex: 1;
  font-size: 0.9em;
}

.wgf-wallcard__badge {
  font-size: 0.72em;
  color: #ffd100;
  border: 1px solid #8b7355;
  border-radius: 3px;
  padding: 1px 5px;
}

.wgf-wallcard__dl {
  font-size: 0.85em;
}

.wgf-account-attr {
  margin: 12px 0 0;
  font-size: 0.78em;
  opacity: 0.65;
  text-align: center;
}

@media (max-width: 700px) {
  .wgf-wallgrid {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  }

  .wgf-wallcard img {
    height: 100px;
  }
}

/* -- Wallpapers teaser (2026-08-02) ---------------------------------------------
   The gallery moved to /wallpapers/. At 160 screens the grid was 84% of this page's
   bytes; a settings panel keeps one card that says how many there are. */

.wgf-wallteaser {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px;
  text-decoration: none;
  border: 1px solid var(--wgf-border-neutral, #3a3632);
  background: rgba(0, 0, 0, 0.28);
}

.wgf-wallteaser:hover,
.wgf-wallteaser:focus-visible {
  border-color: var(--wgf-gold-dark, #8a6a1e);
  background: rgba(244, 196, 92, 0.07);
}

.wgf-wallteaser img {
  width: 160px;
  height: 80px;
  object-fit: cover;
  border: 1px solid rgba(0, 0, 0, 0.6);
  flex: 0 0 auto;
}

.wgf-wallteaser__body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

.wgf-wallteaser__n {
  font-family: var(--font-game, serif);
  font-size: 15px;
  color: var(--wgf-gold-bright, #ffd869);
}

.wgf-wallteaser__sub { font-size: 12.5px; color: var(--wgf-muted, #a99e92); }

@media (max-width: 480px) {
  .wgf-wallteaser img { width: 110px; height: 62px; }
}

/* -- Tracked Items (2026-08-02) --------------------------------------------------
   The list on /tracked/. Storage is saved_app; the star in the AH browser and the
   drop button here call the same API, so the two cannot disagree. */

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

.wgf-trk-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-bottom: 1px solid rgba(139, 115, 85, 0.3);
}

.wgf-trk-row.is-going { opacity: 0.45; }
.wgf-trk-row.is-error { box-shadow: inset 2px 0 0 #ff4040; }

.wgf-trk-name {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--wgf-gold-bright, #ffd869);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wgf-trk-name:hover { text-decoration: underline; }

.wgf-trk-region {
  flex: 0 0 auto;
  font-size: 0.75em;
  opacity: 0.7;
  border: 1px solid rgba(139, 115, 85, 0.5);
  border-radius: 3px;
  padding: 1px 5px;
}

.wgf-trk-when { flex: 0 0 auto; font-size: 0.78em; opacity: 0.6; }

.wgf-trk-drop {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  line-height: 1;
  border: 1px solid #8b7355;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.5);
  color: #ff4040;
  cursor: pointer;
}

.wgf-trk-drop:hover { background: rgba(255, 64, 64, 0.14); }

/* == The Warband character-select SCREEN (owner screenshot 2026-08-05) ==========
   /account/ is not a page with a hero on top: it IS the character-select screen,
   the same ruling the Dressing Room got the same day. This block is the account
   port of the architecture the owner approved in assets/wgf-dressing-room.css:

     .wgf-warband        the stage: full bleed, DEFINITE height (viewport - topbar)
     .wgf-wb-scene       the full-bleed art layer + its legibility scrim
     .wgf-wb-top         the account cluster band (BattleTag / Refresh / Sign Out)
     .wgf-wb-stage       the character cell: 3D canvas, or the render on a floor
     .wgf-wb-rail        the character list, a real grid COLUMN
     .wgf-wb-bottom      Back (left) | name + Enter World (centre) | options (right)
     .wgf-wb-panel       the Game Options slide-in (Key Bindings / Tracked / Wallpapers)

   THREE MEASURED DEFECTS this rewrite kills (headless Chrome, computed rects, the
   old file at 1280x720 through 5120x1440):

   1. THE ART NEVER PAINTED. `.wgf-warband > * { position: relative }` and
      `.wgf-wb-scene { position: absolute }` are BOTH specificity 0,1,0 and the
      blanket rule came later, so it won: the scene stopped being an overlay,
      became an auto-placed grid item in an implicit row under the whole section
      and measured 0px tall at every viewport (scene y=1425 h=0 at 1280x720).
      Fixed structurally: no blanket `> *` rule, every region owns a named area,
      the scene is the only absolutely positioned layer and is never a grid item.
   2. THE STAGE HAD NO DEFINITE HEIGHT. `min-height: clamp(560px, 100svh - 58px,
      1100px)` on a grid whose middle row is `minmax(0, 1fr)` lets that row
      resolve against CONTENT, so the raw Blizzard render (940x1410 intrinsic)
      blew the section to 1392-1709px inside a 569-1289px viewport and the foot
      landed a full screen below the fold. `height: calc(100svh - 58px)` is what
      makes 1fr mean "the leftover screen", exactly as the Dressing Room fix did.
   3. THE MODEL WAS NEVER SCALED AND THE SHADOW FLOATED. `max-height: 94%` on the
      render resolved against that indefinite height, i.e. against nothing, so
      the image drew at natural size; `.wgf-wb-spot` was a fixed 420x70 ellipse
      pinned to the STAGE's bottom 4%, measured 130px above the image's feet.
      Now the character is sized from the stage height (--wb-fill) and the floor
      pool + contact shadow ride inside .wgf-wb-figure, under the feet.

   Everything stays scoped .wgf-wb-* / .wgf-warband / body.wgf-warband-page, so
   /tracked/ and /wallpapers/ (which also link this stylesheet) are untouched. */

/* -- un-box the shell ---------------------------------------------------------
   Same idiom body.wgf-cc-page and body.wgf-ah-page already use: the page opts
   into a surface swap and the main column loses its 1220px cage. */
body.wgf-warband-page .wgf-shell-main {
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 0;
}

body.wgf-warband-page .wgf-site-footer {
  position: relative;
  z-index: 2;
}

.wgf-warband {
  /* The four numbers this screen is built from. The rail holds a 34px crest, a
     name and two sub-lines, so it stops shrinking at 248px; --wb-fill is the
     Dressing Room's CHAR_FILL (0.66) expressed in CSS, so the render path and
     the 3D path put the character at the same size on the same stage. */
  --wb-rail-w: clamp(248px, 22vw, 340px);
  --wb-top-h: 52px;
  --wb-fill: 66%;
  --wb-floor: 9%;

  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--wb-rail-w);
  grid-template-rows: var(--wb-top-h) minmax(0, 1fr) auto;
  grid-template-areas:
    "wb-top    wb-rail"
    "wb-stage  wb-rail"
    "wb-foot   wb-rail";
  /* DEFINITE height. The topbar is sticky and about 58px; leave it above the
     screen and take everything else. This one declaration is what makes the 1fr
     stage row, the rail's own scroll, and every percentage below resolve. */
  height: calc(100vh - 58px);
  height: calc(100svh - 58px);
  min-height: 560px;
  overflow: hidden;
  isolation: isolate;
  background: #07060a;
  color: var(--wgf-text, #e8e0d2);
}

/* -- the scene: real loading-screen art (server-verified on disk) ---------------
   The art box is inset PAST the stage on every side so `cover` scales beyond the
   extracted screen's letterbox bars, the same overscan trick the Dressing Room
   uses, and so an ultrawide stage crops from a bigger picture instead of a
   pixel-doubled one. When no asset resolves the gradients ARE the scene. */

.wgf-wb-scene {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.wgf-wb-art {
  position: absolute;
  inset: -14%;
  display: block;
  background-image: var(--wb-bg, radial-gradient(ellipse at 50% 35%, #1d2333 0%, #0a0d16 68%, #05060b 100%));
  background-position: center 42%;
  background-size: cover;
  background-repeat: no-repeat;
  filter: saturate(0.94) brightness(0.74);
}

@media (min-resolution: 1.5dppx) and (min-width: 1500px) {
  .wgf-wb-art {
    background-image: var(--wb-bg-2x, var(--wb-bg, radial-gradient(ellipse at 50% 35%, #1d2333 0%, #0a0d16 68%, #05060b 100%)));
  }
}

/* The legibility floor: open in the middle where the character stands, dark at
   the edges where the rail, the plates and the account cluster sit. */
.wgf-wb-scene::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(72% 64% at 42% 46%, rgba(6, 5, 8, 0) 0%, rgba(6, 5, 8, 0.5) 76%, rgba(4, 4, 7, 0.86) 100%),
    linear-gradient(180deg, rgba(8, 6, 10, 0.74) 0%, rgba(8, 6, 10, 0.1) 24%, rgba(6, 5, 8, 0.18) 58%, rgba(4, 4, 7, 0.92) 100%);
}

/* The post-OAuth notice floats over the stage so a failed sign-in is seen
   without scrolling. Markup is the shared .wgf-window kit, untouched. */
.wgf-warband #auth-notice {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 7;
  width: min(520px, 92%);
  box-shadow: 0 16px 50px rgba(0, 0, 0, 0.65);
}

/* -- top band: the account cluster --------------------------------------------- */

.wgf-wb-top {
  grid-area: wb-top;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-width: 0;
  padding: 8px 16px 0;
}

.wgf-wb-acct {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 12px;
  font-size: 13px;
  background: rgba(8, 9, 12, 0.72);
  border: 1px solid rgba(126, 104, 60, 0.5);
  border-radius: 4px;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.5);
}

.wgf-wb-avatar {
  border-radius: 50%;
  border: 1px solid #8b7355;
}

.wgf-wb-acct__who {
  font-family: var(--font-game, serif);
  color: var(--wgf-gold-bright, #ffd869);
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wgf-wb-acct__form {
  display: inline;
  margin: 0;
}

.wgf-wb-link {
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  font-size: 12.5px;
  color: var(--wgf-gold-bright, #ffd869);
  text-decoration: none;
  cursor: pointer;
  border-left: 1px solid rgba(126, 104, 60, 0.45);
  padding-left: 12px;
}

.wgf-wb-link:hover,
.wgf-wb-link:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* -- the character cell --------------------------------------------------------
   A grid with place-items:center for the flow children (sign-in panel, hints,
   silhouette) and an absolute overlay for the two character paths, so neither
   path can ever feed its own size back into the stage row. */

.wgf-wb-stage {
  grid-area: wb-stage;
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  min-width: 0;
  min-height: 0;
  padding: 0 12px;
  overflow: hidden;
}

/* The 3D path: the canvas host fills the cell and wgf-warband-3d.js frames the
   character inside it (ported fitToStage: body at 66% of the visible height,
   feet on a floor disc). Absolute so a 100%-height canvas cannot grow the row. */
.wgf-wb-model {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.wgf-wb-model canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100% !important;
  height: 100% !important;
}

/* The render-image path: a figure standing ON the floor line. Height comes from
   the stage (never from the image's intrinsic 940x1410), the image is anchored to
   the bottom of that box, and the pool + contact shadow live inside the figure so
   they are always under THESE feet at every viewport. */
.wgf-wb-figure {
  position: absolute;
  left: 50%;
  bottom: var(--wb-floor);
  transform: translateX(-50%);
  height: var(--wb-fill);
  max-width: min(70%, 900px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  pointer-events: none;
}

.wgf-wb-render {
  display: block;
  height: 100%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  object-position: 50% 100%;
  filter: drop-shadow(0 18px 26px rgba(0, 0, 0, 0.72));
}

/* The Dressing Room's grounding, in CSS: a wide warm pool of light on the floor
   (its floorDisc) with a tight dark contact ellipse right under the feet (its
   shadowDisc). Sized off the FIGURE, so it tracks the character, not the screen. */
.wgf-wb-spot {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translate(-50%, 45%);
  width: 190%;
  height: clamp(38px, 15%, 130px);
  border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(202, 176, 120, 0.17) 0%, rgba(202, 176, 120, 0.05) 45%, rgba(0, 0, 0, 0) 72%);
  pointer-events: none;
}

.wgf-wb-spot::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 40%;
  height: 46%;
  border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0.28) 52%, rgba(0, 0, 0, 0) 78%);
}

.wgf-wb-stagehint {
  margin: 0;
}

.wgf-wb-silhouette {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
}

.wgf-wb-silhouette__face {
  width: clamp(96px, 14vh, 168px);
  height: clamp(96px, 14vh, 168px);
  border-radius: 50%;
  border: 2px solid var(--wgf-gold-dark, #8a6a1e);
  object-fit: cover;
  box-shadow: 0 0 28px rgba(0, 0, 0, 0.8), 0 18px 40px rgba(0, 0, 0, 0.6);
  filter: saturate(0.85) brightness(0.92);
}

.wgf-wb-silhouette__face--blank {
  display: block;
  background: radial-gradient(circle at 50% 38%, #2a2e3c 0%, #0c0e15 75%);
}

.wgf-wb-hint {
  margin: 0;
  font-size: 12.5px;
  color: var(--wgf-muted, #a99e92);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}

/* Signed-out / message panel, centre screen. Capped to the cell so a long message
   scrolls inside the panel instead of stretching a row that must not stretch. */
.wgf-wb-signin {
  max-width: 520px;
  max-height: 100%;
  overflow-y: auto;
  text-align: center;
  padding: 26px 28px;
  background: rgba(8, 9, 13, 0.8);
  border: 1px solid rgba(126, 104, 60, 0.55);
  border-radius: 6px;
  box-shadow: 0 16px 50px rgba(0, 0, 0, 0.6);
}

.wgf-wb-signin p {
  margin: 0 0 14px;
  font-size: 14.5px;
  line-height: 1.55;
}

.wgf-wb-signin__title {
  margin: 0 0 12px;
  font-family: var(--font-game, serif);
  font-size: 22px;
  color: var(--wgf-gold-bright, #ffd869);
}

.wgf-wb-signin__btns {
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
  margin-bottom: 14px;
}

.wgf-wb-signin__note {
  font-size: 12px;
  color: var(--wgf-muted, #a99e92);
  margin-bottom: 0;
}

/* -- the character rail: a real grid COLUMN ------------------------------------
   `auto minmax(0, 1fr) auto` inside a column whose height is definite is what
   gives the list its own scroll instead of letting 20 characters set the height
   of the whole screen. */

.wgf-wb-rail {
  grid-area: wb-rail;
  z-index: 3;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  min-width: 0;
  min-height: 0;
  margin: 12px 12px 12px 0;
  background: linear-gradient(180deg, rgba(14, 15, 20, 0.93), rgba(9, 10, 14, 0.93));
  border: 1px solid rgba(126, 104, 60, 0.55);
  border-radius: 6px;
  box-shadow: 0 12px 44px rgba(0, 0, 0, 0.6), inset 0 0 0 1px rgba(0, 0, 0, 0.55);
  overflow: hidden;
}

.wgf-wb-railtop {
  display: flex;
  gap: 8px;
  padding: 10px;
  border-bottom: 1px solid rgba(126, 104, 60, 0.35);
}

.wgf-wb-search {
  flex: 1;
  min-width: 0;
  padding: 7px 10px;
  font: inherit;
  font-size: 13px;
  color: var(--wgf-text, #e8e0d2);
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid rgba(126, 104, 60, 0.45);
  border-radius: 4px;
}

.wgf-wb-search::placeholder {
  color: var(--wgf-muted, #a99e92);
}

.wgf-wb-search:focus-visible {
  outline: none;
  border-color: var(--wgf-gold, #f4c45c);
  box-shadow: 0 0 6px rgba(var(--wgf-gold-rgb, 244, 196, 92), 0.4);
}

.wgf-wb-add {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-game, serif);
  font-size: 21px;
  line-height: 1;
  text-decoration: none;
  color: var(--wgf-gold-bright, #ffd869);
  background: radial-gradient(circle at 50% 30%, rgba(122, 88, 26, 0.7), rgba(46, 34, 12, 0.85));
  border: 1px solid var(--wgf-gold-dark, #8a6a1e);
  border-radius: 4px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

.wgf-wb-add:hover,
.wgf-wb-add:focus-visible {
  border-color: var(--wgf-gold, #f4c45c);
  box-shadow: 0 0 8px rgba(var(--wgf-gold-rgb, 244, 196, 92), 0.45);
}

.wgf-wb-list {
  min-height: 0;
  overflow-y: auto;
  padding: 8px;
  scrollbar-width: thin;
  scrollbar-color: #4a3f2a rgba(0, 0, 0, 0.45);
}

.wgf-wb-list::-webkit-scrollbar {
  width: 10px;
}

.wgf-wb-list::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.45);
}

.wgf-wb-list::-webkit-scrollbar-thumb {
  background: #4a3f2a;
  border-radius: 5px;
  border: 2px solid rgba(0, 0, 0, 0.5);
}

.wgf-wb-railmsg {
  padding: 8px 6px;
}

/* Region groups: honest headers (US / EU / whatever the roster holds). */
.wgf-wb-group {
  margin-bottom: 8px;
}

.wgf-wb-group__head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 10px;
  font-family: var(--font-game, serif);
  font-size: 12.5px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--wgf-gold-bright, #ffd869);
  background: linear-gradient(180deg, rgba(42, 35, 22, 0.92), rgba(24, 20, 13, 0.92));
  border: 1px solid rgba(126, 104, 60, 0.42);
  border-radius: 4px;
  cursor: pointer;
}

.wgf-wb-group__arrow {
  font-size: 11px;
  transition: transform 0.15s;
}

.wgf-wb-group.is-collapsed .wgf-wb-group__arrow {
  transform: rotate(-90deg);
}

.wgf-wb-group.is-collapsed .wgf-wb-group__cards {
  display: none;
}

.wgf-wb-group__n {
  margin-left: auto;
  font-size: 11px;
  color: var(--wgf-muted, #a99e92);
}

/* One character card: class-colored name, Level N Class, muted realm, crest. */
.wgf-wb-card {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 6px 0 0;
  padding: 8px 10px;
  text-align: left;
  font: inherit;
  color: inherit;
  background: linear-gradient(180deg, rgba(20, 21, 26, 0.88), rgba(12, 13, 17, 0.88));
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 4px;
  cursor: pointer;
  transition: border-color 0.12s, box-shadow 0.12s;
}

.wgf-wb-card:hover,
.wgf-wb-card:focus-visible {
  border-color: rgba(var(--wgf-gold-rgb, 244, 196, 92), 0.5);
}

.wgf-wb-card.is-selected {
  background: linear-gradient(180deg, rgba(124, 90, 28, 0.6), rgba(66, 47, 15, 0.66));
  border-color: var(--wgf-gold, #f4c45c);
  box-shadow:
    0 0 12px rgba(var(--wgf-gold-rgb, 244, 196, 92), 0.45),
    inset 0 0 0 1px rgba(var(--wgf-gold-rgb, 244, 196, 92), 0.35);
}

.wgf-wb-card__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.wgf-wb-card__name {
  font-family: var(--font-game, serif);
  font-size: 17px;
  line-height: 1.15;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

.wgf-wb-card__line {
  font-size: 12.5px;
  opacity: 0.92;
}

.wgf-wb-card__realm {
  font-size: 11.5px;
  color: var(--wgf-muted, #a99e92);
}

.wgf-wb-card__crest {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.7));
}

/* The per-character Dressing Room link. Exactly one exists at a time (the JS moves
   it), it sits under the gold selected card as its sibling, and it reads as a quiet
   gold caption so the rail stays a character list, not a menu of buttons. */
.wgf-wb-cardlink {
  display: block;
  margin: 0 0 2px;
  padding: 4px 10px 5px;
  font-size: 11.5px;
  letter-spacing: 0.05em;
  text-align: right;
  text-decoration: none;
  color: var(--wgf-gold, #f4c45c);
  background: linear-gradient(180deg, rgba(66, 47, 15, 0.5), rgba(24, 20, 13, 0.35));
  border: 1px solid rgba(var(--wgf-gold-rgb, 244, 196, 92), 0.3);
  border-top: 0;
  border-radius: 0 0 4px 4px;
}

.wgf-wb-cardlink:hover,
.wgf-wb-cardlink:focus-visible {
  color: var(--wgf-gold-bright, #ffd869);
  border-color: var(--wgf-gold, #f4c45c);
  text-decoration: underline;
}

/* Rail foot: the Link-a-character slot, honestly labeled. */
.wgf-wb-railfoot {
  display: flex;
  gap: 8px;
  padding: 10px;
  border-top: 1px solid rgba(126, 104, 60, 0.35);
}

.wgf-wb-linkchar {
  flex: 1;
  text-align: center;
}

/* -- the foot: Back | name + Enter World | caption + Game Options --------------- */

.wgf-wb-bottom {
  grid-area: wb-foot;
  z-index: 3;
  display: grid;
  grid-template-columns: minmax(120px, 1fr) auto minmax(120px, 1fr);
  align-items: end;
  gap: 14px;
  padding: 8px 18px 18px;
}

.wgf-wb-back {
  justify-self: start;
}

.wgf-wb-enterbox {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
}

.wgf-wb-bottomright {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  justify-self: end;
}

.wgf-wb-name {
  min-height: 1.1em;
  font-family: var(--font-game-display, var(--font-game, serif));
  font-size: clamp(24px, 2.4vw, 38px);
  line-height: 1.05;
  color: var(--wgf-gold-bright, #ffd869);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.9), 0 0 24px rgba(0, 0, 0, 0.6);
}

/* Dressing Room: the SECOND act of the flow, stacked under Enter World. Same red
   plate kit, one size down - Enter World keeps --lg (44px), this one rides the base
   button (34px) at a narrower min-width, so the primary action still wins the eye. */
.wgf-wb-dressing {
  min-width: 168px;
  opacity: 0.93;
}

.wgf-wb-dressing:hover,
.wgf-wb-dressing:focus-visible {
  opacity: 1;
}

.wgf-wb-status {
  min-height: 1.1em;
  margin: 0;
  font-size: 12.5px;
  color: #ffd100;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}

.wgf-wb-caption {
  font-family: var(--font-game, serif);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--wgf-gold, #f4c45c);
  opacity: 0.92;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}

/* -- Game Options: ONE plate on the stage, one slide-in drawer -----------------
   The three windows that used to sit BELOW the screen (Key Bindings, Tracked
   Items, the wallpaper teaser) are the same markup, moved inside this panel. The
   interaction is the Dressing Room's Customize panel, verbatim: a red plate on
   the foot, a right-side slide-in, Escape closes. */

.wgf-wb-optbtn.wgf-btn-red {
  min-width: 176px;
}

.wgf-wb-panel {
  position: absolute;
  z-index: 6;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(440px, 94vw);
  display: flex;
  flex-direction: column;
  border-left: 1px solid #6a5b3a;
  background: linear-gradient(180deg, rgba(13, 11, 9, 0.97), rgba(8, 7, 6, 0.98));
  box-shadow: -14px 0 40px rgba(0, 0, 0, 0.6);
  transform: translateX(0);
  transition: transform 180ms ease;
}

.wgf-wb-panel[hidden] {
  display: flex;
  transform: translateX(101%);
  visibility: hidden;
}

.wgf-wb-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid #3a332a;
}

.wgf-wb-panel__title {
  margin: 0;
  color: var(--wgf-gold-bright, #ffd869);
  font-family: var(--font-game, serif);
  font-size: 0.95rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.wgf-wb-panel__close {
  border: 1px solid #4a4133;
  border-radius: 4px;
  background: rgba(10, 9, 7, 0.8);
  color: #c9b47e;
  font: inherit;
  line-height: 1;
  padding: 5px 9px;
  cursor: pointer;
}

.wgf-wb-panel__close:hover,
.wgf-wb-panel__close:focus-visible {
  color: #ffe08a;
  border-color: #6a6153;
}

.wgf-wb-tabs {
  display: flex;
  gap: 6px;
  padding: 8px 10px;
  border-bottom: 1px solid #3a332a;
}

.wgf-wb-tab {
  flex: 1 1 auto;
  padding: 6px 8px;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: #c9b47e;
  background: linear-gradient(180deg, rgba(30, 25, 16, 0.9), rgba(16, 14, 10, 0.9));
  border: 1px solid rgba(126, 104, 60, 0.45);
  border-radius: 4px;
  cursor: pointer;
}

.wgf-wb-tab:hover,
.wgf-wb-tab:focus-visible {
  border-color: var(--wgf-gold, #f4c45c);
  color: var(--wgf-gold-bright, #ffd869);
}

.wgf-wb-tab.is-on {
  color: var(--wgf-gold-bright, #ffd869);
  border-color: var(--wgf-gold, #f4c45c);
  box-shadow: inset 0 0 0 1px rgba(var(--wgf-gold-rgb, 244, 196, 92), 0.3);
}

.wgf-wb-panel__body {
  flex: 1 1 auto;
  padding: 12px;
  overflow-y: auto;
  scrollbar-width: thin;
}

/* The three windows keep their kit markup and their IDs; inside the drawer they
   drop the page-window furniture and read as gold-trimmed sections. */
.wgf-wb-panel .wgf-window {
  margin: 0 0 14px;
  max-width: none;
  border-color: rgba(126, 104, 60, 0.55);
  background: rgba(12, 11, 9, 0.72);
}

.wgf-wb-panel .wgf-window:last-child {
  margin-bottom: 0;
}

.wgf-wb-panel .wgf-window__title {
  font-size: 0.86rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.wgf-wb-panel .wgf-window__body {
  padding: 10px;
}

.wgf-wb-panel .wgf-kb-row {
  padding: 6px 8px;
  font-size: 13px;
}

.wgf-wb-panel .wgf-kb-row__key {
  min-width: 72px;
  font-size: 12px;
}

.wgf-wb-panel .wgf-wallteaser img {
  width: 120px;
  height: 62px;
}

/* -- width tiers ---------------------------------------------------------------
   Only the layout variables move: every region owns a grid cell, so a narrower or
   a much wider screen re-proportions the SAME layout instead of sliding anything
   on top of anything else. */

@media (max-width: 1279px) {
  .wgf-warband {
    --wb-rail-w: clamp(232px, 26vw, 300px);
  }

  .wgf-wb-bottom {
    padding: 6px 12px 14px;
  }

  .wgf-wb-optbtn.wgf-btn-red,
  .wgf-wb-dressing {
    min-width: 140px;
  }
}

/* The owner's screenshot case: a very wide or zoomed-out viewport. The rail grows
   with the screen (at 5120px a 340px rail reads as a crushed corner strip), and the
   character keeps a hard pixel ceiling so it never becomes a billboard. */
@media (min-width: 2200px) {
  .wgf-warband {
    --wb-rail-w: clamp(340px, 15vw, 480px);
    --wb-top-h: 60px;
  }

  .wgf-wb-figure {
    max-width: min(46%, 1100px);
  }

  .wgf-wb-bottom {
    grid-template-columns: minmax(200px, 1fr) auto minmax(200px, 1fr);
  }
}

/* -- height tiers --------------------------------------------------------------
   A short screen (a laptop, or the owner's 1440px-tall ultrawide) has to spend its
   pixels on the character, not on chrome. */

@media (max-height: 900px) {
  .wgf-warband {
    --wb-top-h: 46px;
    --wb-fill: 68%;
    --wb-floor: 7%;
  }
}

@media (max-height: 720px) {
  .wgf-warband {
    --wb-top-h: 42px;
    --wb-fill: 70%;
    --wb-floor: 5%;
  }

  .wgf-wb-bottom {
    padding: 4px 14px 10px;
  }
}

/* -- phone: the rail docks under the character, the screen may grow -------------
   Still cells, still no overlap: the grid becomes a single column of four rows and
   the definite height becomes a minimum, exactly as the Dressing Room does. */

@media (max-width: 900px) {
  .wgf-warband {
    --wb-top-h: auto;
    height: auto;
    min-height: calc(100vh - 52px);
    min-height: calc(100svh - 52px);
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(220px, 1fr) auto auto;
    grid-template-areas:
      "wb-top"
      "wb-stage"
      "wb-foot"
      "wb-rail";
  }

  .wgf-wb-top {
    padding: 8px 10px 0;
  }

  .wgf-wb-rail {
    margin: 0;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
    border-radius: 8px 8px 0 0;
    max-height: 44svh;
  }

  .wgf-wb-bottom {
    grid-template-columns: auto 1fr;
    grid-template-areas:
      "enter enter"
      "back  right";
    align-items: center;
    row-gap: 12px;
  }

  .wgf-wb-enterbox {
    grid-area: enter;
  }

  .wgf-wb-back {
    grid-area: back;
  }

  .wgf-wb-bottomright {
    grid-area: right;
  }

  .wgf-wb-caption {
    font-size: 10.5px;
  }

  .wgf-wb-acct {
    flex-wrap: wrap;
    justify-content: flex-end;
  }

  .wgf-wb-acct__who {
    max-width: 130px;
  }

  .wgf-wb-panel {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .wgf-wb-panel,
  .wgf-wb-card,
  .wgf-wb-group__arrow {
    transition: none;
  }
}
