/* ShogiGO Web — brand: black + refined gold, Barlow Condensed display. */
:root {
  --gold: #d4a017;
  --gold-light: #e8c25a;
  --gold-deep: #8a6d3b;
  --cream: #f5eeda;
  --bg: #0b0b0d;
  --bg-2: #14141a;
  --bg-3: #1b1b22;
  --muted: #b8b0a0;
  --danger: #c0392b;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--cream);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  min-height: 100vh;
}

.topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 18px;
  background: var(--bg-2);
  border-bottom: 2px solid var(--gold-deep);
}

.crest { width: 44px; height: 44px; }

.brand-name {
  margin: 0;
  font-family: "Barlow Condensed", sans-serif;
  font-weight: 700;
  font-size: 26px;
  letter-spacing: 3px;
  color: var(--gold);
  line-height: 1;
}

.brand-tag {
  font-size: 12px;
  color: var(--muted);
  font-style: italic;
}

.topbar-right { margin-left: auto; display: flex; align-items: center; flex-wrap: wrap; row-gap: 4px; justify-content: flex-end; }

.toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--muted);
}

/* Click-to-cycle topbar controls (test, Buddy 2026-10-20): replaces the
   three dropdowns; shows the current value, one click rotates to next. */
.cycle-btn {
  background: var(--bg-3);
  color: var(--gold);
  border: 1px solid var(--gold-deep);
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
  padding: 4px 10px;
  cursor: pointer;
  white-space: nowrap;
}
.cycle-btn:active { transform: translateY(1px); }

.switch { position: relative; display: inline-block; width: 40px; height: 22px; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider {
  position: absolute; inset: 0; cursor: pointer;
  background: var(--bg-3); border: 1px solid var(--gold-deep); border-radius: 22px;
}
.slider:before {
  content: ""; position: absolute; width: 16px; height: 16px; left: 2px; top: 2px;
  background: var(--gold); border-radius: 50%; transition: transform .2s;
}
.switch input:checked + .slider:before { transform: translateX(18px); }

.layout {
  display: flex;
  gap: 20px;
  justify-content: center;
  align-items: flex-start;
  padding: 18px;
  max-width: 1180px;
  margin: 0 auto;
}

.board-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: stretch;
  min-width: 0;
}

/* Board-first column (owner report 2026-10-24, Academy UI too big):
   in the row layout the board column is a flex item with no width basis,
   so its width resolved from its children's max-content — and the lesson
   bubble's unwrapped narration text was the widest max-content in the
   column. The bubble's text length therefore set the column width (506→604
   at 1280px, 686→884 at 1920px), the bubble stretched to it, and the board
   jumped sideways at every narration step. Anchoring the column's basis to
   min-content makes the board canvas — the widest min-content child — set
   the column width instead: the bubble wraps to the board's width, the
   column equals the board, and the board's position is stable across
   stages. Scoped to the row layout only; the stacked (<=900px) layout's
   width:100% rule below is untouched. */
@media (min-width: 901px) {
  .board-col { flex-basis: min-content; }
}

.player-card {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--bg-2);
  border: 1px solid #2c2c34;
  border-radius: 10px;
  padding: 8px 12px;
}
.player-card .avatar {
  width: 50px; height: 50px; border-radius: 50%;
  background: #2b2b33; color: var(--gold);
  display: flex; align-items: center; justify-content: center;
  font-family: "Barlow Condensed", sans-serif; font-weight: 700; font-size: 20px;
  border: 1px solid var(--gold-deep);
  flex: none;
}
.player-card .avatar.you { font-size: 13px; }
/* P4 (2.0 progression): level line stacked directly under the self avatar. */
.player-card .avatar-col {
  display: flex; flex-direction: column; align-items: center; flex: none;
}
.player-card .player-level {
  font-size: 11px; font-weight: 700; color: var(--gold);
  margin-top: 2px; line-height: 1; white-space: nowrap;
}
.player-card .player-level.hidden { display: none; }
/* v1 badge showcase: up to 4 equal-size badges between name and clock. */
.player-card .badge-showcase {
  display: flex; gap: 6px; align-items: center;
  flex: none; margin-left: auto;
}
.player-card .badge-showcase.hidden { display: none; }
.showcase-badge {
  /* Dark medallion plate: badge art sits on a dark disc, readable on any banner. */
  width: 50px; height: 50px; border-radius: 50%;
  border: 2px solid #141418;
  background: #101014 no-repeat center / 78%;
  box-shadow: 0 3px 8px rgba(0,0,0,.6), inset 0 0 0 1px #2a2a32;
  position: relative; flex: none;
}
/* Badge-type art fills its whole canvas, so at the shared 78% it rendered
   as a 39px disc next to the ~48px-tall checkmate tiles (Buddy
   2026-10-20). Size badge art up so both read at the same scale in the
   player box; tiles keep the shared size (their portrait photos already
   fill the disc vertically). */
.showcase-badge:not(.showcase-tile) { background-size: 96%; }
/* Counter pill straddling the bottom edge: dark pill, gold number. */
.showcase-badge .badge-counter {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  margin-top: -7px;
  background: #101014; border: 1px solid #3a3a42;
  color: var(--gold);
  font-family: "Barlow Condensed", sans-serif; font-weight: 700; font-size: 10px;
  border-radius: 8px; padding: 0 5px; line-height: 1.5;
  pointer-events: none; white-space: nowrap;
}
}
/* Locked badges: real approved artwork, dimmed — never "?" silhouettes. */
.badge-icon.silhouette img { filter: brightness(0.42); }
.player-name { font-family: "Barlow Condensed", sans-serif; font-weight: 600; font-size: 19px; letter-spacing: 1px; }
.player-sub { font-size: 12px; color: var(--muted); }
/* Name + rating plate — Buddy 2026-10-20 ("gold rim, black back"): the
   same solid-box treatment the clock uses, so the player name and rating
   stay readable over bright, busy banner art. Light banners flip the
   plate light to match their dark text. */
.player-meta {
  background: rgba(10, 10, 10, 0.78);
  border: 1px solid rgba(212, 160, 23, 0.75);
  border-radius: 8px;
  padding: 3px 10px 4px;
  min-width: 0;
}
.player-meta .player-sub { color: #d8d2bd; }
.player-card.banner-light .player-meta {
  background: rgba(245, 240, 225, 0.88);
  border-color: #8a6d3b;
}
.clock {
  margin-left: auto; font-variant-numeric: tabular-nums;
  font-size: 15px; font-weight: 700;
  /* Solid box so the timer stays readable over any banner art. */
  background: rgba(10, 10, 10, 0.82);
  color: #f5f0e1;
  border: 1px solid #d4a017;
  border-radius: 6px;
  padding: 2px 8px;
  text-shadow: none;
}

.hand-tray {
  display: flex;
  gap: 6px;
  align-items: center;
  /* Owner-authorized first-capture fix (2026-10-26): reserve the full
     one-piece shape even when empty, so the board does not shift when
     the first piece arrives. Border-box: 46px piece + 6px top + 18px
     bottom padding (room for the count badge) + 2px border = 72px.
     Empty and 1-piece trays are then the same height, both hands. */
  min-height: 72px;
  background: var(--bg-2);
  border: 1px solid #2c2c34;
  border-radius: 10px;
  padding: 6px 10px 18px;
  flex-wrap: wrap;
}
.hand-tray.active { border-color: var(--gold); }
.hand-empty { font-size: 12px; color: var(--muted); font-style: italic; }
.hand-piece {
  position: relative;
  width: 46px; height: 46px;
  border-radius: 8px;
  cursor: default;
  border: 2px solid transparent;
}
.hand-tray#handBottom .hand-piece { cursor: pointer; }
.hand-piece.sel { border-color: var(--gold); background: rgba(212,160,23,.12); }
.hand-piece img { width: 100%; height: 100%; pointer-events: none; }
/* White's piece SVGs point down (board orientation); flip upright in hand. */
.white-hand .hand-piece img { transform: rotate(180deg); }
/* Midnight hand SVGs carry the same horizontal stretch as the board tiles;
   narrow them back to the ShogiGO tile width (per-side factors, board.js). */
.hand-piece img.hand-midnight-img.black { transform: scaleX(0.9651); }
.hand-piece img.hand-midnight-img.white { transform: scaleX(0.9224); }
.white-hand .hand-piece img.hand-midnight-img.white { transform: rotate(180deg) scaleX(0.9224); }
.hand-piece img.hand-badge-img { object-fit: contain; }
.white-hand .hand-piece img.hand-badge-img { transform: none; }
.hand-piece img.hand-newtile-img { object-fit: contain; }
.white-hand .hand-piece img.hand-newtile-img { transform: none; }
.hand-piece .cnt {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  margin-top: 3px;
  color: var(--gold); font-size: 12px; font-weight: 700;
  white-space: nowrap;
}

.board-wrap { position: relative; }
#board { display: block; border-radius: 6px; box-shadow: 0 8px 40px rgba(0,0,0,.6); }

.promo-picker {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  background: var(--bg-2); border: 2px solid var(--gold);
  border-radius: 12px; padding: 18px 22px; text-align: center;
  box-shadow: 0 12px 48px rgba(0,0,0,.7); z-index: 5;
}
.promo-title { font-family: "Barlow Condensed", sans-serif; font-size: 22px; color: var(--gold); margin-bottom: 12px; letter-spacing: 1px; }
.promo-picker button {
  margin: 6px;
  padding: 14px 28px;
  font-size: 18px;
  min-width: 150px;
  min-height: 52px;
  border-radius: 10px;
  border: 1px solid var(--gold-deep);
  background: var(--bg-3);
  color: var(--cream);
  font-family: "Barlow Condensed", sans-serif;
  font-weight: 600;
  letter-spacing: 1px;
  cursor: pointer;
}
.promo-picker button:active { background: var(--gold); color: #141414; }
@media (max-width: 900px) {
  .promo-picker {
    padding: 22px 26px;
    width: calc(100vw - 60px);
    max-width: 340px;
  }
  .promo-picker button {
    display: block;
    width: 100%;
    margin: 8px 0;
    padding: 16px;
    font-size: 20px;
  }
}

.board-toast {
  position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%);
  background: rgba(20,20,26,.92); border: 1px solid var(--gold-deep);
  color: var(--cream); padding: 8px 18px; border-radius: 20px;
  font-size: 14px; z-index: 4; white-space: nowrap;
}

.side-col { width: 300px; flex: none; display: flex; flex-direction: column; gap: 12px; }

.side-col-a, .side-col-b {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

@media (min-width: 1280px) {
  .layout { max-width: 1560px; }
  .side-col {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 12px;
    width: 620px;
    flex: none;
  }
  .side-col-a, .side-col-b { flex: 1 1 0; }
}


.panel {
  background: var(--bg-2);
  border: 1px solid #2c2c34;
  border-radius: 10px;
  padding: 12px 14px;
}
.panel-title {
  font-family: "Barlow Condensed", sans-serif;
  font-weight: 600; font-size: 17px; letter-spacing: 2px;
  color: var(--gold); margin-bottom: 8px;
}
.acct-scope-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid #2c2c34;
}
.acct-scope-label { color: var(--gold); font-weight: 600; font-size: 13px; }
.panel select {
  width: 100%; padding: 8px; font-size: 15px;
  background: var(--bg-3); color: var(--cream);
  border: 1px solid var(--gold-deep); border-radius: 8px;
}
.bot-desc { margin-top: 8px; font-size: 13px; color: var(--muted); }

.btn-row { display: flex; gap: 8px; margin-bottom: 8px; }
.btn-row:last-child { margin-bottom: 0; }
.btn {
  flex: 1; padding: 10px 8px;
  background: var(--bg-3); color: var(--cream);
  border: 1px solid var(--gold-deep); border-radius: 8px;
  font-size: 14px; cursor: pointer;
  font-family: "Barlow Condensed", sans-serif; font-weight: 600; letter-spacing: 1px; font-size: 16px;
}
.btn:hover { border-color: var(--gold); }
/* Home Dojo entry mark (Art final, owner pick 1C): the 256px Torii Ring
 * shipping WebP on its centered square canvas, transparency preserved.
 * Displayed at the verified 32px legibility size. */
#dojoSlotBtn .home-dojo-mark { width: 32px; height: 32px; object-fit: contain; vertical-align: middle; margin-right: 6px; background: transparent; }
/* Unified home icon family (owner-approved 2026-10-24): thick gold ring /
 * dark center marks in a shared 32px slot, transparency kept. Dojo keeps
 * its own home-dojo-mark rule and file, unwired by this change. */
.home-family-mark { width: 32px; height: 32px; object-fit: contain; vertical-align: middle; margin-right: 6px; background: transparent; }
.btn.primary { background: var(--gold); color: #141414; border-color: var(--gold); }
.btn.primary:hover { background: var(--gold-light); }
.btn.danger { background: #7a1f1a; color: #ffd9d4; border-color: #b3352c; }
.btn.danger:hover { background: #93261f; border-color: #d6453a; }
.btn.danger:disabled { opacity: 0.55; }
.profile-danger-row { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.delete-picker { max-width: 420px; }
.delete-picker .profile-hint { margin-bottom: 8px; }
.btn.danger { border-color: var(--danger); color: #e88; }
.btn.big { font-size: 20px; padding: 12px 28px; flex: none; }

.moves-panel { min-height: 120px; max-height: 320px; display: flex; flex-direction: column; }
.moves {
  margin: 0; padding: 0 0 0 4px; list-style: none;
  overflow-y: auto; font-size: 14px; line-height: 1.7;
  display: flex; flex-wrap: wrap; gap: 2px 10px;
  font-variant-numeric: tabular-nums;
}
.moves li.black-move { color: var(--cream); }
.moves li.white-move { color: var(--muted); }

.help { font-size: 13px; color: var(--muted); line-height: 1.6; margin: 0; }
.dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin: 0 2px; }
.dot.quiet { background: rgba(76,175,80,.7); }
.dot.capture { background: rgba(211,47,47,.7); }

.gameover {
  position: fixed; inset: 0; z-index: 20;
  background: rgba(0,0,0,.72);
  display: flex; align-items: center; justify-content: center;
}
.gameover .crest { width: 72px; height: 72px; }
.gameover-card {
  background: var(--bg-2); border: 2px solid var(--gold);
  border-radius: 16px; padding: 32px 48px; text-align: center;
  /* Popup fit (2026-10-24): a flex-centered panel must never grow past
     the viewport on content min-width (e.g. .gameover-sub's 320px + the
     96px of horizontal padding = 416px > a phone viewport). */
  max-width: calc(100vw - 32px); min-width: 0;
}
.gameover-title {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 42px; font-weight: 700; color: var(--gold); letter-spacing: 2px;
  margin: 8px 0;
}
.gameover-sub { color: var(--muted); margin-bottom: 20px; max-width: 320px; }
#btnKifu { margin-top: 12px; }

.hidden { display: none !important; }

/* Popup scroll lock (mobile popup fix, 2026-10-24): while any popup is
   open the background page must not scroll; only the popup's own content
   scrolls internally. Toggled by shogiLockScroll/shogiUnlockScroll. */
body.shogi-scroll-locked { overflow: hidden; }

/* ---- account ---- */
#accountBody .btn { width: 100%; margin-top: 8px; }
#accountBody .btn-row .btn { margin-top: 8px; }
.acct-row { display: flex; align-items: center; gap: 12px; }
.acct-meta { min-width: 0; }
.acct-name {
  font-family: "Barlow Condensed", sans-serif;
  font-weight: 600; font-size: 20px; letter-spacing: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.acct-sub { font-size: 13px; color: var(--gold-light); }
.acct-record { margin-top: 8px; font-size: 13px; color: var(--muted); }
/* Phase 2: three independent ranked ladders. */
.acct-ladders { display: flex; gap: 8px; margin-top: 12px; }
.acct-ladder {
  flex: 1; text-align: center; padding: 8px 4px;
  background: rgba(255,255,255,0.04); border: 1px solid rgba(212,160,23,0.25);
  border-radius: 8px;
}
.acct-ladder.active { border-color: var(--gold); background: rgba(212,160,23,0.12); }
.acct-ladder-mode { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; }
.acct-ladder-rating { font-size: 18px; font-weight: 700; color: var(--gold-light); margin-top: 2px; }
/* STEP 6: Game History UI. */
.acct-history-section { margin-top: 0; }
#historyPanel .acct-history-section { padding: 0; }
.acct-history-title { color: var(--gold); font-size: 16px; margin: 0 0 8px 0; }
.acct-history-list { display: flex; flex-direction: column; gap: 8px; max-height: 400px; overflow-y: auto; }
.acct-history-item {
  display: flex; align-items: center; gap: 10px;
  padding: 10px; background: rgba(255,255,255,0.04);
  border: 1px solid rgba(212,160,23,0.2); border-radius: 8px;
}
.hist-result {
  font-size: 11px; font-weight: 700; padding: 4px 8px; border-radius: 4px;
  text-transform: uppercase; letter-spacing: 0.5px; flex: none;
}
.hist-win { background: rgba(76,175,80,0.2); color: #4caf50; }
.hist-loss { background: rgba(244,67,54,0.2); color: #f44336; }
.hist-draw { background: rgba(158,158,158,0.2); color: #9e9e9e; }
.hist-info { flex: 1; min-width: 0; }
.hist-opp { font-size: 14px; font-weight: 600; color: #e0e0e0; }
.hist-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }
.hist-delta { font-size: 16px; font-weight: 700; flex: none; }
.hist-delta.pos { color: #4caf50; }
.hist-delta.neg { color: #f44336; }
.avatar-badge {
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: "Barlow Condensed", sans-serif; font-weight: 700;
  border: 2px solid;
  flex: none;
}
.avatar-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin: 8px 0 4px;
  max-height: 264px;
  overflow-y: auto;
}
.avatar-grid .avatar-badge { cursor: pointer; width: 100% !important; aspect-ratio: 1; }
.avatar-grid .avatar-badge.picked {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
/* Real avatar art: prerendered PNGs. */
.avatar-img {
  border-radius: 50%;
  object-fit: cover;
  display: block;
  flex: none;
}
.avatar-badge.avatar-img { border: none; padding: 0; }
#opponentAvatar .avatar-img { width: 44px; height: 44px; }
.player-card .avatar.you .avatar-img { width: 100%; height: 100%; }
/* Online panel */
.online-opp {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 8px;
}
.online-opp .avatar-img { width: 44px; height: 44px; }
.online-status {
  font-size: 14px; color: var(--gold);
  margin: 6px 0 10px; min-height: 20px;
}
.challenge-item {
  border-top: 1px solid #2a2a2e; padding: 8px 0;
  display: flex; flex-direction: column; gap: 6px;
  font-size: 14px;
}
/* C1: challenge-send UI. */
.challenge-send { border-top: 1px solid #2a2a2e; padding: 8px 0; display: flex; flex-direction: column; gap: 6px; }
.challenge-send input[type="text"] {
  width: 100%; box-sizing: border-box;
  background: #111; color: #eee; border: 1px solid #333; border-radius: 6px;
  padding: 8px; font-size: 14px;
}
.challenge-send input[type="text"]:disabled { opacity: 0.5; }
#onlinePanel .btn-row { margin-top: 8px; }
#onlinePanel select { width: 100%; margin-bottom: 4px; }
.profile-card { max-width: 420px; width: calc(100vw - 48px); }
.field-label {
  display: block; text-align: left;
  font-size: 13px; color: var(--muted); margin: 10px 0 4px;
}
.field-input {
  width: 100%; padding: 10px 12px; font-size: 17px;
  background: var(--bg-3); color: var(--cream);
  border: 1px solid var(--gold-deep); border-radius: 8px;
}
.field-input:focus { outline: none; border-color: var(--gold); }
.field-hint { font-size: 12px; color: var(--muted); margin-top: 4px; text-align: left; }
.field-error { font-size: 13px; color: #e88; margin-top: 8px; min-height: 18px; }
.profile-card .btn-row { margin-top: 12px; }

@media (max-width: 900px) {
  .layout { flex-direction: column; align-items: center; padding: 10px; gap: 12px; }
  .board-col { width: 100%; max-width: 520px; min-width: 0; }
  .board-wrap { max-width: 100%; }
  #board { max-width: 100%; height: auto; }
  .side-col { width: 100%; max-width: 560px; }
  .brand-tag { display: none; }
  .topbar { padding: 8px 12px; }
  .brand-name { font-size: 22px; }
}

/* ShogiGO modal (replaces native confirm()). */
.shogi-modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(0, 0, 0, 0.72);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.shogi-modal {
  background: var(--bg-2); color: var(--cream);
  border: 1px solid var(--gold-deep); border-radius: 12px;
  padding: 24px; max-width: min(380px, calc(100vw - 40px)); width: 100%;
  min-width: 0;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}
.shogi-modal h3 {
  margin: 0 0 12px 0; font-size: 20px; color: var(--gold);
  font-family: var(--font-display);
}
.shogi-modal p { margin: 0 0 20px 0; font-size: 15px; color: var(--cream); line-height: 1.5; }
.shogi-modal .btn-row { display: flex; gap: 12px; justify-content: flex-end; margin: 0; }
.shogi-modal .btn-danger {
  background: #a33; color: #fff; border: 1px solid #c55;
  padding: 10px 20px; border-radius: 8px; font-size: 15px; cursor: pointer;
  font-family: var(--font-display);
}
.shogi-modal .btn-danger:hover { background: #b44; }
/* ---------- in-game chat ---------- */
.chat-panel { display: flex; flex-direction: column; max-height: 320px; }
.chat-messages {
  overflow-y: auto; display: flex; flex-direction: column; gap: 6px;
  padding: 4px 2px; min-height: 80px; max-height: 220px;
}
.chat-msg { font-size: 13px; line-height: 1.35; color: var(--cream); word-wrap: break-word; }
.chat-msg .chat-name { color: var(--gold); font-weight: 600; margin-right: 6px; }
.chat-msg.mine .chat-name { color: #8ab4ff; }
.chat-msg .chat-actions { margin-left: 6px; font-size: 11px; opacity: 0.6; }
.chat-msg .chat-actions button {
  background: none; border: none; color: var(--cream); cursor: pointer;
  font-size: 11px; padding: 0 4px; text-decoration: underline;
}
.chat-msg .chat-actions button:hover { opacity: 1; color: var(--gold); }
.chat-input-row { display: flex; gap: 6px; margin-top: 6px; }
.chat-input-row input {
  flex: 1; background: var(--bg-1); color: var(--cream);
  border: 1px solid var(--gold-deep); border-radius: 6px;
  padding: 8px 10px; font-size: 14px;
}
.chat-input-row input:focus { outline: none; border-color: var(--gold); }

/* ---------- tournaments (contract §15) ---------- */
.tournament-overlay {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  background: #0a0a0a; z-index: 10000; overflow-y: auto;
}
.tournament-screen { max-width: 800px; margin: 0 auto; padding: 16px; }
.tournament-header {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 16px; padding-bottom: 12px;
  border-bottom: 2px solid #D4A017;
}
.tournament-title {
  font-size: 24px; font-weight: 700; color: #D4A017;
  font-family: var(--font-display); letter-spacing: 1px;
}
.tournament-tabs { display: flex; gap: 8px; margin-bottom: 16px; }
.tournament-list { display: flex; flex-direction: column; gap: 12px; }
.tournament-card {
  background: var(--bg-2); border: 1px solid var(--gold-deep);
  border-radius: 12px; padding: 16px;
}
.tournament-card-title { font-size: 18px; font-weight: 700; color: var(--gold); }
.tournament-card-sub { font-size: 14px; color: var(--cream); opacity: 0.8; margin: 4px 0; }
.tournament-card-count { font-size: 16px; font-weight: 600; color: var(--cream); margin: 4px 0; }
.tournament-card-reward { font-size: 14px; color: var(--gold); margin: 4px 0 12px 0; }
.tournament-empty { text-align: center; color: var(--cream); opacity: 0.6; padding: 32px; }
.tournament-resume-banner {
  background: #1a2a1a; border: 1px solid #4a4; border-radius: 8px;
  padding: 12px; margin-bottom: 12px; color: var(--cream);
  display: flex; justify-content: space-between; align-items: center;
}
.tournament-info { font-size: 14px; color: var(--cream); opacity: 0.8; margin: 4px 0; }
.tournament-count { font-size: 28px; font-weight: 700; color: var(--gold); margin: 16px 0; text-align: center; }
.tournament-players { display: flex; flex-direction: column; gap: 8px; margin: 16px 0; }
.tournament-player-row {
  background: var(--bg-2); border-radius: 8px; padding: 10px 14px;
  display: flex; justify-content: space-between;
}
.tournament-player-name { color: var(--cream); font-weight: 600; }
.tournament-status { text-align: center; color: var(--gold); font-size: 16px; margin: 16px 0; }
.tournament-bracket { display: flex; flex-direction: column; gap: 24px; }
.tournament-round-title {
  font-size: 16px; font-weight: 700; color: var(--gold);
  letter-spacing: 2px; margin-bottom: 12px; text-align: center;
}
.tournament-match {
  background: var(--bg-2); border: 1px solid var(--gold-deep);
  border-radius: 10px; padding: 14px; margin-bottom: 12px;
}
.tournament-match.mine { border-color: var(--gold); border-width: 2px; }
.tournament-match-player { font-size: 16px; color: var(--cream); padding: 4px 0; }
.tournament-match-player.winner { color: var(--gold); font-weight: 700; }
.tournament-match-player.loser { opacity: 0.5; text-decoration: line-through; }
.tournament-match-vs { text-align: center; font-size: 12px; opacity: 0.5; margin: 4px 0; }
.tournament-match-status { font-size: 13px; color: var(--gold); margin-top: 8px; }
.tournament-match .btn { margin-top: 10px; width: 100%; }
.tournament-eliminated { font-size: 13px; color: #c66; margin-top: 8px; font-style: italic; }
.tournament-champion {
  text-align: center; font-size: 28px; color: var(--gold);
  font-weight: 700; margin: 24px 0; padding: 20px;
  border: 2px solid var(--gold); border-radius: 12px;
  background: rgba(212, 160, 23, 0.1);
}
.tournament-badge-earned {
  text-align: center; font-size: 18px; color: var(--gold); margin: 16px 0;
}
@media (min-width: 700px) {
  .tournament-bracket { flex-direction: row; justify-content: space-around; }
  .tournament-round { flex: 1; max-width: 320px; }
}

/* ---------- badges & collection ---------- */
.badges-overlay {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  background: #0a0a0a; z-index: 10000; overflow-y: auto;
}
.badges-screen { max-width: 900px; margin: 0 auto; padding: 16px; }
.badges-section { margin-bottom: 32px; }
.badges-section-title {
  font-size: 20px; font-weight: 700; color: #D4A017;
  letter-spacing: 2px; margin-bottom: 12px;
  border-bottom: 1px solid #D4A017; padding-bottom: 8px;
}
.badges-progress {
  font-size: 18px; color: var(--cream); text-align: center; margin: 12px 0;
}
.badges-complete {
  text-align: center; font-size: 20px; color: #D4A017; font-weight: 700;
  margin: 12px 0; padding: 12px; border: 2px solid #D4A017; border-radius: 8px;
}
.badges-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px; margin-top: 12px;
}
.badge-card {
  background: var(--bg-2); border: 1px solid var(--gold-deep);
  border-radius: 10px; padding: 12px; text-align: center;
}
.badge-card.owned { border-color: #D4A017; }
.badge-card.locked { opacity: 0.6; }
.badge-card.equipped { border-width: 2px; border-color: #4a4; }
.badge-icon {
  width: 64px; height: 64px; margin: 0 auto 8px auto;
  display: flex; align-items: center; justify-content: center;
}
.badge-icon img { width: 100%; height: 100%; object-fit: contain; }
.badge-icon.silhouette {
  background: #222; border-radius: 8px; font-size: 32px; color: #555;
}
.badge-icon.badge-placeholder {
  background: #1a1a1a; border-radius: 50%; font-size: 28px;
  border: 2px solid #555;
}
.badge-icon.tier-premium { border-color: #D4A017; }
.badge-name { font-weight: 600; color: var(--cream); font-size: 14px; margin: 4px 0; }
.badge-desc { font-size: 12px; color: var(--cream); opacity: 0.7; margin: 4px 0; }
.badge-status-owned { color: #4a4; font-size: 12px; font-weight: 700; margin: 4px 0; }
.badge-status-locked { color: #888; font-size: 12px; font-weight: 700; margin: 4px 0; }
.badge-status-equipped { color: #4a4; font-size: 12px; font-weight: 700; margin: 4px 0; }
.badge-unlock { font-size: 11px; color: var(--cream); opacity: 0.6; margin: 4px 0; line-height: 1.3; }
.badge-card .btn { margin-top: 8px; }
/* In-game equipped display */
.equipped-icon {
  width: 20px; height: 20px; display: inline-block; vertical-align: middle;
  margin-right: 4px;
}
.equipped-icon img { width: 100%; height: 100%; object-fit: contain; }
.equipped-icon.badge-placeholder {
  background: #1a1a1a; border-radius: 50%; font-size: 12px;
  border: 1px solid #D4A017; text-align: center; line-height: 18px;
  color: #D4A017;
}

/* SEO footer: descriptive site text below the game layout */
.site-footer {
  max-width: 900px;
  margin: 28px auto 40px;
  padding: 0 20px;
  color: #b9ac8b;
  font-size: 14px;
  line-height: 1.6;
  text-align: center;
}
.site-footer .footer-title {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 20px;
  letter-spacing: 2px;
  color: var(--gold);
  margin: 0 0 8px;
  font-weight: 600;
}
.site-footer p { margin: 0 0 10px; }
.site-footer .footer-links a { color: var(--gold); text-decoration: underline; }

/* §16 global online presence indicator */
.online-pill {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  color: var(--muted, #b9ac8b);
  margin-right: 12px;
  white-space: nowrap;
}
.online-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #4caf50;
  margin-right: 6px;
  box-shadow: 0 0 6px #4caf50;
}

/* Focus mode: hide side panel, enlarge board + hand pieces (desktop) */
.icon-btn {
  background: transparent;
  border: 1px solid #3a3a42;
  border-radius: 8px;
  color: var(--muted, #b9ac8b);
  font-size: 16px;
  width: 32px; height: 32px;
  cursor: pointer;
  margin-right: 12px;
  line-height: 1;
}
.icon-btn:hover { border-color: var(--gold); color: var(--gold); }
.icon-btn.active { border-color: var(--gold); color: var(--gold); background: rgba(212,160,23,.12); }
body.focus-mode aside.side-col { display: none; }
body.focus-mode .layout { max-width: 1500px; }
body.focus-mode .hand-piece { width: 62px; height: 62px; }
body.focus-mode .hand-tray { min-height: 88px; /* 62px piece + 6 + 18 + 2, same reserve rule */ }

/* Compact mode: tighter spacing for small windows/laptops. */
body.compact-mode .layout { gap: 10px; padding: 10px; }
body.compact-mode .panel { padding: 8px 10px; }
body.compact-mode .panel-title { margin-bottom: 6px; }
body.compact-mode .player-card { padding: 5px 8px; gap: 8px; }
body.compact-mode .player-card .avatar { width: 38px; height: 38px; font-size: 15px; }
body.compact-mode .player-card .badge-showcase { gap: 4px; }
body.compact-mode .showcase-badge { width: 38px; height: 38px; }
body.compact-mode .hand-piece { width: 38px; height: 38px; }
body.compact-mode .hand-tray { min-height: 48px; padding: 4px 6px; /* already reserved: 38 + 4 + 4 + 2 = 48, unchanged */ }
body.compact-mode .topbar { padding: 6px 10px; }
body.compact-mode .brand-name { font-size: 20px; }
body.compact-mode .side-col { gap: 8px; }
body.compact-mode .board-col { gap: 6px; }

/* Game review mode */
.review-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px;
  background: var(--bg-2);
  border: 1px solid var(--gold);
  border-radius: 10px;
}
.review-bar .icon-btn { margin-right: 0; }
.review-pos { color: var(--muted, #b9ac8b); font-size: 14px; min-width: 64px; text-align: center; }
.moves li.review-cur { background: rgba(212,160,23,.25); border-radius: 4px; }
.moves li { cursor: pointer; }

/* Master Jin commentary */
.jin-comment {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin-top: 8px;
  padding: 10px 14px;
  background: var(--bg-2);
  border: 1px solid #2c2c34;
  border-left: 3px solid var(--gold);
  border-radius: 10px;
  font-size: 14px;
  line-height: 1.45;
}
.jin-avatar { width: 36px; height: 36px; flex-shrink: 0; border-radius: 50%; }
.jin-name { color: var(--gold); font-weight: 700; margin-right: 8px; }
/* Fixed height: the box never changes size regardless of content — no layout shift ever */
.jin-comment { height: 88px; overflow-y: auto; }
.jin-comment > div { min-width: 0; }

/* Engine eval bar (review mode) */
.eval-bar {
  position: absolute;
  left: -36px; top: 0;
  width: 26px; height: 100%;
  background: #e8e8e8;
  border: 1px solid #3a3a42;
  border-radius: 5px;
  overflow: hidden;
}
.eval-black {
  position: absolute; bottom: 0; left: 0; right: 0;
  background: #141414;
  height: 50%;
  transition: height 0.25s;
}
.eval-score {
  position: absolute; bottom: 3px; left: 0; right: 0;
  text-align: center; font-size: 9px; font-weight: 700;
  color: #fff; mix-blend-mode: difference;
  pointer-events: none;
}
@media (max-width: 760px) { .eval-bar { display: none; } }
/* Move classifications */
.moves li .cls-badge {
  display: inline-block;
  margin-left: 6px;
  font-size: 11px;
  font-weight: 700;
}
.moves li.cls-best .cls-badge { color: #4caf50; }
.moves li.cls-good .cls-badge { color: #8bc34a; }
.moves li.cls-inacc { border-left: 3px solid #ffc107; }
.moves li.cls-inacc .cls-badge { color: #ffc107; }
.moves li.cls-mist { border-left: 3px solid #ff9800; }
.moves li.cls-mist .cls-badge { color: #ff9800; }
.moves li.cls-blund { border-left: 3px solid #f44336; }
.moves li.cls-blund .cls-badge { color: #f44336; }

/* Campaign: Path of 20 Masters (Phase 1) */
.campaign-btn {
  width: 100%; margin-top: 8px; padding: 10px;
  background: linear-gradient(135deg, #6b5b2e, #d4a017);
  color: #1a1a1a; border: none; border-radius: 8px;
  font-weight: 700; cursor: pointer; font-size: 14px;
}
/* Teaching hub button (owner order 2026-10-28; Stage 1 label + size,
 * Stage 2 symbol wired in the same build after the owner's
 * "Approve it, wire it in" for Art's home_teaching_vs_v1): the mark
 * uses the Gauntlet treatment exactly — shipping 256 PNG in the
 * 32px home-family-mark slot, no scaling or force-fitting.
 * Width, padding, and font already match Gauntlet through the shared
 * .campaign-btn class (measured identical at 1920/1280/390). Height
 * did not before the mark: Gauntlet renders 52px (10 padding + 32
 * icon + 10 padding) while text-only Teaching rendered 36px (10 +
 * 16 text line + 10). min-height 52px (border-box, so padding
 * included) closed exactly that gap, and with the 32px mark in place
 * the box is 32 content + 20 padding = 52 by construction; the rule
 * stays as the floor. min-height, not height, so a wrapped label at
 * a pathological narrow width grows instead of clipping. */
#btnTeaching { min-height: 52px; }
.campaign-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.9);
  z-index: 1000; overflow-y: auto; padding: 20px;
}
.campaign-overlay.hidden { display: none; }
.campaign-title { color: #d4a017; text-align: center; margin: 10px 0; }
.campaign-note { color: #aaa; text-align: center; font-size: 13px; }
.campaign-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 12px; max-width: 600px; margin: 0 auto;
}
.campaign-card {
  background: #2a2a2e; border-radius: 10px; padding: 10px;
  text-align: center; border: 2px solid transparent;
}
.campaign-card.defeated { border-color: #4caf50; }
.campaign-card.locked { opacity: 0.6; }
.campaign-avatar { width: 60px; height: 60px; border-radius: 50%; }
.campaign-name { color: #e8e0c8; font-weight: 700; margin-top: 4px; }
.campaign-title-sub { color: #888; font-size: 12px; }
.campaign-close {
  display: block; margin: 20px auto; padding: 10px 30px;
  background: #444; color: #fff; border: none; border-radius: 8px; cursor: pointer;
}
.campaign-victory {
  position: fixed; top: 30%; left: 50%; transform: translate(-50%, -50%);
  background: #2a2a2e; border: 2px solid #d4a017; border-radius: 12px;
  padding: 24px; z-index: 1001; text-align: center; color: #e8e0c8;
  max-width: calc(100vw - 32px);
}

/* Equipped badge in You card */
.you-badge {
  width: 24px; height: 24px; border-radius: 50%;
  border: 2px solid #d4a017; vertical-align: middle; margin-left: 6px;
  object-fit: cover;
}
.you-badge.hidden { display: none; }

.player-name-row { display: flex; align-items: center; }

/* Kanji hand tiles (shown when kanjiMode is on; mirrors board tile colors) */
.hand-kanji {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  font-family: serif; font-weight: 700; font-size: 28px;
  /* shogi pentagon tile, point UP for hand pieces */
  clip-path: polygon(7.69% 96%, 92.31% 96%, 92.31% 38.96%, 50% 4%, 7.69% 38.96%);
  pointer-events: none;
  /* Shift glyph down: pentagon's visual center sits below geometric center. */
  padding-top: 8px; box-sizing: border-box;
}
/* Midnight Kanji hand tiles: black tile, metal glyph + outline per side */
.hand-midnight-kanji {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  font-family: serif; font-weight: 700; font-size: 28px;
  background: #1c1a1e;
  clip-path: polygon(7.69% 96%, 92.31% 96%, 92.31% 38.96%, 50% 4%, 7.69% 38.96%);
  pointer-events: none;
  padding-top: 8px; box-sizing: border-box;
}
.hand-midnight-kanji.black {
  color: #d4a017;
  /* Board-matching gold border (#d4a017, board midnight-kanji edge) via
     inset SVG stroke; replaces the drop-shadow outline, which clip-path
     clips away on device. */
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><polygon points='10.23,93.53 89.77,93.53 89.77,39.91 50,7.05 10.23,39.91' fill='none' stroke='%23d4a017' stroke-width='4' stroke-linejoin='miter'/></svg>");
  background-size: 100% 100%; background-repeat: no-repeat;
}
.hand-midnight-kanji.white {
  color: #c6cad2;
  /* Board-matching silver border (#c6cad2) via inset SVG stroke (see above). */
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><polygon points='10.23,93.53 89.77,93.53 89.77,39.91 50,7.05 10.23,39.91' fill='none' stroke='%23c6cad2' stroke-width='4' stroke-linejoin='miter'/></svg>");
  background-size: 100% 100%; background-repeat: no-repeat;
}
.hand-kanji.black { background: #f5eeda; color: #1a1a1a;
  /* Board-matching bronze border (#8a6d3b, board kanji edge). SVG stroke,
     inset so the full stroke lies inside the clip-path pentagon: regular
     borders and same-element drop-shadows are clipped away on device. */
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><polygon points='10.23,93.53 89.77,93.53 89.77,39.91 50,7.05 10.23,39.91' fill='none' stroke='%238a6d3b' stroke-width='4' stroke-linejoin='miter'/></svg>");
  background-size: 100% 100%; background-repeat: no-repeat; }
.hand-kanji.white {
  background: #2b2b33; color: #f5eeda;
  /* Board-matching bronze border (#8a6d3b) via inset SVG stroke (see above).
     Replaces the drop-shadow outline, which clip-path clips away on device. */
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><polygon points='10.23,93.53 89.77,93.53 89.77,39.91 50,7.05 10.23,39.91' fill='none' stroke='%238a6d3b' stroke-width='4' stroke-linejoin='miter'/></svg>");
  background-size: 100% 100%; background-repeat: no-repeat;
}
.hand-traditional {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  font-family: serif; font-weight: 700; font-size: 28px;
  color: #1a1a1a;
  /* woodgrain tile, darker than board so it stands out */
  background: linear-gradient(90deg, #c99a4e 0%, #d9b06a 50%, #c99a4e 100%);
  /* Board-matching wood border (#7a5c2e, board traditional edge) via inset
     SVG stroke layered OVER the gradient. Replaces the 2px solid border,
     which clip-path clips away on device. */
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><polygon points='10.23,93.53 89.77,93.53 89.77,39.91 50,7.05 10.23,39.91' fill='none' stroke='%237a5c2e' stroke-width='4' stroke-linejoin='miter'/></svg>"), linear-gradient(90deg, #c99a4e 0%, #d9b06a 50%, #c99a4e 100%);
  background-size: 100% 100%, 100% 100%; background-repeat: no-repeat, no-repeat;
  /* shogi pentagon tile, point UP for hand pieces */
  clip-path: polygon(7.69% 96%, 92.31% 96%, 92.31% 38.96%, 50% 4%, 7.69% 38.96%);
  pointer-events: none;
  /* Shift glyph down to match board positioning. */
  padding-top: 8px; box-sizing: border-box;
}

/* ============ "Your profile" screen (WYSIWYG players-box) ============ */
.profile-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.72); z-index: 70;
  display: flex; align-items: center; justify-content: center; padding: 12px;
}
.profile-screen {
  background: #161616; border: 1px solid #d4a017; border-radius: 12px;
  max-width: min(540px, calc(100vw - 24px)); width: 94vw; max-height: 92vh; overflow-y: auto; padding: 16px;
  min-width: 0;
}
.profile-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.profile-title {
  font-family: "Barlow Condensed", sans-serif; font-weight: 700; font-size: 24px;
  letter-spacing: 2px; color: #d4a017;
}
.profile-hint { color: #999; font-size: 13px; margin-bottom: 10px; }
.profile-preview { margin-bottom: 6px; }
.profile-preview-card { width: 100%; }
.profile-section-title {
  font-family: "Barlow Condensed", sans-serif; font-weight: 700; font-size: 16px;
  letter-spacing: 1.5px; color: #d4a017; margin: 14px 0 8px;
}
/* Badge ghost slots (4, matching the live showcase). */
.profile-slots { display: flex; gap: 6px; margin-left: auto; flex: none; align-items: center; }
.ghost-slot {
  width: 40px; height: 40px; border-radius: 50%;
  border: 2px dashed #5a5a5a; color: #5a5a5a;
  display: flex; align-items: center; justify-content: center;
  font-size: 20px; cursor: pointer; flex: none;
  background-size: cover; background-position: center;
}
.ghost-slot.filled { border-style: solid; border-color: #d4a017; color: transparent; }
.ghost-slot.slot-selected { outline: 2px solid #ffd94d; outline-offset: 2px; box-shadow: 0 0 10px rgba(212,160,23,.75); }
/* Avatar picker grid — Buddy 2026-10-20: bigger faces, 4 per row, scroll. */
.avatar-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.avatar-pick {
  width: 100%; max-width: 88px; aspect-ratio: 1; height: auto; border-radius: 50%; cursor: pointer;
  border: 2px solid transparent; overflow: hidden; justify-self: center;
}
.avatar-pick.selected { border-color: #d4a017; }
.avatar-pick.locked { filter: brightness(0.42); cursor: not-allowed; }
/* Banner swatches. */
.banner-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; align-items: center; }
.banner-swatch {
  width: 120px; height: 36px; border-radius: 6px; cursor: pointer;
  border: 2px solid #3a3a3a;
  background-size: cover; background-repeat: no-repeat; background-position: center;
  background-color: #0a0a0a;
}
.banner-swatch.selected { border-color: #d4a017; }
/* Code-defined banner patterns. */
/* Per-slot badge picker. */
.badge-picker-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.78); z-index: 80;
  display: flex; align-items: center; justify-content: center; padding: 12px;
}
.badge-picker {
  background: #161616; border: 1px solid #d4a017; border-radius: 12px;
  max-width: min(440px, calc(100vw - 24px)); width: 92vw; max-height: 80vh; overflow-y: auto; padding: 16px;
  min-width: 0;
}
/* (The per-slot badge picker popup was removed 2026-10-20 — badges are
   picked in the Badges tab grid. .badge-picker styles remain for the
   delete-account dialog, which shares the overlay shell.) */
/* Username row. */
.profile-name-row { display: flex; flex-direction: column; gap: 4px; }
.profile-name-input {
  background: #0e0e0e; border: 1px solid #3a3a3a; border-radius: 6px;
  color: #f5f0e1; font-size: 16px; padding: 8px 10px; max-width: 280px;
}
.profile-name-input:focus { border-color: #d4a017; outline: none; }
.profile-error { color: #e06c6c; font-size: 13px; min-height: 18px; }

/* Light player-card banners (white/gold): dark text stays readable. */
.player-card.banner-light .player-name,
.player-card.banner-light .player-sub,

/* Rating display picker (Your profile). */
.rating-row { display: flex; gap: 8px; flex-wrap: wrap; }
.rating-opt {
  background: #0e0e0e; border: 1px solid #3a3a3a; border-radius: 6px;
  color: #f5f0e1; font-size: 14px; padding: 8px 14px; cursor: pointer;
}
.rating-opt.selected { border-color: #d4a017; color: #d4a017; font-weight: 700; }

/* Campaign reset button (Path of 20 Masters). */
.campaign-reset {
  margin-top: 10px; background: transparent; border: 1px solid #6a2a2a;
  color: #c08080; border-radius: 6px; padding: 8px 16px; font-size: 14px;
  cursor: pointer;
}
.campaign-reset:hover:not(:disabled) { border-color: #a04040; color: #e0a0a0; }
.campaign-reset:disabled { opacity: .6; cursor: default; }

/* Daily Puzzle (v1). */
.daily-btn {
  background: #1a1a1e; border: 1px solid #d4a017; color: #f5f0e1;
  border-radius: 6px; padding: 6px 10px; font-size: 14px; cursor: pointer;
}
.daily-btn:hover { background: #2a2a2e; }
.daily-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.96); z-index: 200;
  display: flex; align-items: center; justify-content: center; padding: 12px;
}
.daily-overlay.hidden { display: none; }
.daily-card {
  background: #141416; border: 1px solid #d4a017; border-radius: 12px;
  max-width: min(560px, calc(100vw - 24px)); width: 100%; max-height: 94vh; overflow-y: auto; padding: 16px;
  min-width: 0;
}
.daily-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
.daily-title { color: #d4a017; font-size: 20px; font-weight: bold; }
.daily-sub { color: #999; font-size: 13px; margin-top: 2px; }
.daily-close { background: none; border: none; color: #999; font-size: 20px; cursor: pointer; padding: 4px; }
.daily-close:hover { color: #f5f0e1; }
.daily-sora { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px; }
.daily-sora-avatar { width: 48px; height: 48px; border-radius: 50%; border: 2px solid #d4a017; flex-shrink: 0; }
/* The Puzzle Master portrait had NO size rule and rendered at its 512px
   natural width, crushing the bubble and overflowing the card on every
   viewport (measured card scrollWidth 623px at both 390px and 1280px). */
.daily-sora-img { width: 64px; height: 64px; object-fit: cover; border-radius: 50%; border: 2px solid #d4a017; flex: 0 0 auto; }
.daily-sora-bubble {
  background: #1e1e22; border: 1px solid #3a3a40; border-radius: 0 12px 12px 12px;
  padding: 10px 12px; color: #f5f0e1; font-size: 14px; line-height: 1.4; flex: 1;
  min-width: 0;
}
.daily-board-wrap { display: flex; flex-direction: column; align-items: center; gap: 6px; margin-bottom: 12px; }
.daily-board { width: 100%; max-width: 440px; aspect-ratio: 1; border-radius: 8px; cursor: pointer; }
.daily-hand { display: flex; gap: 4px; min-height: 34px; align-items: center; justify-content: center; flex-wrap: wrap; }
.daily-hand-piece {
  width: 32px; height: 32px; border-radius: 6px; background: #2a2a2e; border: 1px solid #4a4a52;
  display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 18px; color: #f5f0e1;
}
.daily-hand-piece.selected { border-color: #d4a017; background: #3a3220; }
.daily-hand-piece img { width: 28px; height: 28px; }
.daily-controls { display: flex; gap: 8px; justify-content: center; }
.daily-controls .hidden { display: none; }

/* Sora's Tactics (endless rated puzzles). */
.tactics-stats { display: flex; gap: 12px; justify-content: center; margin: 12px 0; }
.tactics-stat { display: flex; flex-direction: column; align-items: center; min-width: 70px; }
.tactics-stat-num { color: #d4a017; font-size: 24px; font-weight: bold; }
.tactics-stat-lbl { color: #999; font-size: 12px; }
.tactics-spinner {
  width: 36px; height: 36px; margin: 16px auto 4px;
  border: 4px solid #3a3a40; border-top-color: #d4a017; border-radius: 50%;
  animation: tactics-spin 0.9s linear infinite;
}
@keyframes tactics-spin { to { transform: rotate(360deg); } }
.tactics-close {
  position: absolute; top: 8px; right: 12px;
  background: none; border: none; color: #888; font-size: 20px; cursor: pointer;
}
.tactics-close:hover { color: #fff; }
.tactics-retry {
  background: #d4a017; color: #000; border: none; border-radius: 6px;
  padding: 10px 24px; font-size: 16px; cursor: pointer; margin-top: 12px;
}
.tactics-retry:hover { background: #e5b52a; }
.tactics-banner-row { display: flex; gap: 14px; color: #ccc; font-size: 13px; margin-top: 4px; }
.tactics-banner-row b { color: #d4a017; }

/* Accumulative checkmate tile counter. */
.tile-counter {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  margin-top: 2px;
  color: var(--gold); font-weight: bold; font-size: 12px;
  white-space: nowrap;
}
.badge-icon { position: relative; }
.daily-ver { font-size: 10px; color: #888; font-weight: normal; }

/* Unlocked checkmate tiles: Art bakes the gold frame into the trophy image. */
.badge-icon.unlocked-tile {
  width: 84px; height: 84px;
  border: none; border-radius: 10px;
  box-shadow: none;
  background: transparent;
  overflow: hidden;
}
.badge-icon.unlocked-tile img {
  width: 100%; height: 100%; object-fit: contain;
}

/* Showcase tiles (player box). */
.showcase-badge.showcase-tile {
  /* Checkmate tiles join the same medallion circle as every other badge. */
  background-repeat: no-repeat;
}
.showcase-badge.showcase-tile.kanji-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.showcase-badge.showcase-tile.kanji-tile .tile-kanji-overlay {
  font-size: 24px;
  font-weight: 700;
  color: #f5f0e1;
  text-shadow: 0 2px 4px rgba(0,0,0,0.9), 0 0 8px rgba(0,0,0,0.8);
  z-index: 1;
}

/* Kanji tile in the collection grid. */
.badge-icon.kanji-tile-display {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 48px;
  font-weight: 700;
  color: #f5f0e1;
  background: #1a1a1a;
  text-shadow: 0 2px 6px rgba(0,0,0,0.9);
}
.badge-icon.kanji-tile-display.silhouette {
  opacity: 0.4;
}

/* Profile tabs (Avatars | Badges). */
.profile-tabs {
  display: flex;
  gap: 8px;
  margin: 16px 0 12px 0;
}
.profile-tab {
  flex: 1;
  /* Flex items refuse to shrink below their longest word by default;
     the five uppercase labels (~95px min each) forced the whole panel
     past a phone viewport. min-width: 0 lets the tabs share the row. */
  min-width: 0;
  padding: 10px;
  background: #1a1a1a;
  border: 1px solid #444;
  border-radius: 8px;
  color: #aaa;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.profile-tab.active {
  background: #2a2a1a;
  border-color: #d4a017;
  color: #d4a017;
}
/* Badges tab \u2014 slot strip + full collection grid (Buddy 2026-10-20).
   One uniform medallion size everywhere so the grid stays clean when a
   player owns the whole set; the count pill sits on the art itself. */
.badge-slot-strip { display: flex; gap: 12px; align-items: flex-start; margin: 8px 0 4px; }
.badge-slot { display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; }
.badge-slot .slot-label { font-size: 10px; letter-spacing: 1px; color: #999; }
.badge-slot.selected .slot-label { color: #ffd94d; }
.badge-slot.selected .badge-medallion { border-color: #ffd94d; box-shadow: 0 0 10px rgba(212,160,23,.8); }
.badge-tab-hint { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; color: #aaa; font-size: 13px; margin: 4px 0 8px; }
.btn-small { padding: 3px 10px; font-size: 12px; }
.badge-medallion {
  position: relative; border-radius: 50%; background: #101014;
  border: 2px solid #3a3a3a; box-shadow: 0 2px 8px rgba(0,0,0,.6);
  display: flex; align-items: center; justify-content: center; flex: none;
}
.badge-medallion.slot-size { width: 54px; height: 54px; }
.badge-medallion.grid-size { width: 76px; height: 76px; }
.badge-medallion img { border-radius: 50%; }
.badge-medallion img.medallion-badge { width: 100%; height: 100%; object-fit: cover; }
.badge-medallion img.medallion-tile { width: 88%; height: 88%; object-fit: contain; }
/* Explicit pixel sizes as well: Edge mis-resolves the percentage-sized
   flex-child img and shrinks tiles to a thumbnail (Buddy 2026-10-20;
   Chrome/Firefox were fine). Fixed px is unambiguous in every engine. */
.badge-medallion.grid-size img.medallion-tile { width: 67px; height: 67px; }
.badge-medallion.slot-size img.medallion-tile { width: 47px; height: 47px; }
.badge-medallion .medallion-plus { color: #666; font-size: 24px; line-height: 1; }
.badge-medallion .count-pill {
  position: absolute; bottom: -6px; left: 50%; transform: translateX(-50%);
  background: #101014; color: #ffd94d; border: 1px solid #d4a017; border-radius: 999px;
  font-size: 12px; font-weight: 700; line-height: 18px; padding: 0 7px; white-space: nowrap;
}
.badge-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px 10px;
  max-height: 360px;
  overflow-y: auto;
  padding: 6px 2px;
}
.badge-grid-section {
  grid-column: 1 / -1;
  font-family: "Barlow Condensed", sans-serif; font-weight: 700;
  letter-spacing: 1.5px; color: #d4a017; margin-top: 4px;
}
.badge-cell { display: flex; flex-direction: column; align-items: center; gap: 5px; cursor: pointer; }
.badge-cell .badge-cell-name { font-size: 11px; color: #ccc; text-align: center; line-height: 1.15; }
.badge-cell .slot-chip { font-size: 10px; font-weight: 700; letter-spacing: 1px; color: #ffd94d; }
.badge-cell.in-slot .badge-medallion { border-color: #d4a017; box-shadow: 0 0 10px rgba(212,160,23,.55); }
.badge-cell.locked { cursor: default; }
.badge-cell.locked .badge-medallion { opacity: .38; filter: saturate(.35); }
.badge-cell.locked .badge-cell-name { color: #777; }
.profile-empty {
  grid-column: 1 / -1;
  text-align: center;
  color: #888;
  padding: 20px;
  font-size: 14px;
}

/* Coaching screen. */
.coaching-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.85); z-index: 200; display: flex; align-items: center; justify-content: center; padding: 16px; }
.coaching-card { background: #1a1a1a; border: 2px solid #d4a017; border-radius: 12px; max-width: min(640px, calc(100vw - 32px)); width: 100%; max-height: 90vh; overflow-y: auto; padding: 20px; min-width: 0; }
.coaching-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.coaching-title { font-size: 22px; font-weight: bold; color: #d4a017; }
.coaching-close { background: none; border: none; color: #888; font-size: 20px; cursor: pointer; }
.coaching-sub { color: #aaa; margin-bottom: 12px; }
.coaching-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.coach-card { background: #222; border: 2px solid #444; border-radius: 8px; padding: 16px; cursor: pointer; text-align: center; min-width: 0; }
.coach-card:hover { border-color: #d4a017; }
.coach-avatar { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; margin-bottom: 8px; border: 2px solid #d4a017; }
.coach-name { font-size: 20px; font-weight: bold; color: #fff; }
.coach-title { color: #d4a017; margin: 4px 0; }
.coach-tagline { color: #888; font-style: italic; font-size: 13px; margin: 8px 0; }
.coach-count { color: #666; font-size: 12px; }
.lesson-list { display: flex; flex-direction: column; gap: 8px; }
.lesson-item { display: flex; align-items: center; gap: 12px; background: #222; border: 1px solid #444; border-radius: 8px; padding: 12px; cursor: pointer; }
.lesson-item:hover { border-color: #d4a017; }
.lesson-item.done { border-color: #2a7a2a; }
.lesson-num { font-size: 18px; color: #d4a017; font-weight: bold; min-width: 32px; }
.lesson-info { flex: 1; }
.lesson-title { font-weight: bold; color: #fff; }
.lesson-goal { color: #888; font-size: 13px; }
.lesson-done { color: #4a4; font-size: 20px; }
.academy-summary { color: #ddd; font-size: 14px; margin: 4px 0 10px; }
.academy-recommend { color: #9a94a6; font-size: 12.5px; line-height: 1.45; margin: 2px 0 8px; }
.academy-override { border: 1px solid #d4a017; background: rgba(212, 160, 23, 0.10); color: #e8cf8a; border-radius: 8px; padding: 10px 12px; font-size: 13px; line-height: 1.45; margin-bottom: 14px; }
.academy-course { color: #d4a017; font-size: 18px; font-weight: bold; margin: 18px 0 2px; }
.academy-course-sub { color: #aaa; font-size: 13px; margin-bottom: 8px; }
.academy-module { color: #fff; font-size: 14px; font-weight: bold; margin: 12px 0 6px; }
.lesson-item.soon { cursor: default; opacity: 0.72; }
.lesson-item.soon:hover { border-color: #444; }
.pill-soon { border: 1px solid #d4a017; color: #d4a017; border-radius: 999px; padding: 3px 10px; font-size: 12px; white-space: nowrap; }
.lock-tag { color: #e8cf8a; font-size: 12px; white-space: nowrap; }
.lesson-intro { background: #222; border-left: 3px solid #d4a017; padding: 12px; margin: 12px 0; color: #ddd; font-style: italic; }
.lesson-goal-box { background: #2a2a1a; border: 1px solid #d4a017; border-radius: 8px; padding: 10px; margin: 12px 0; color: #fff; }
.lesson-board-wrap { display: flex; justify-content: center; margin: 16px 0; }
.lesson-board-wrap canvas { max-width: 100%; height: auto; }
.lesson-hint { color: #aaa; margin: 8px 0; min-height: 20px; }
.lesson-error { color: #f66; margin: 12px 0; }

/* Puzzle/Lesson mode banners (main board). */
.mode-banner { position: fixed; top: 60px; left: 50%; transform: translateX(-50%); background: #1a1a1a; border: 2px solid #d4a017; border-radius: 12px; padding: 16px 20px; max-width: 600px; width: calc(100% - 40px); z-index: 150; box-shadow: 0 4px 20px rgba(0,0,0,0.5); }
.mode-banner-title { font-size: 18px; font-weight: bold; color: #d4a017; margin-bottom: 8px; }
.mode-banner-goal { color: #fff; margin-bottom: 8px; }
.mode-banner-intro { color: #aaa; font-style: italic; font-size: 14px; margin-bottom: 12px; max-height: 100px; overflow-y: auto; }
.mode-banner-actions { display: flex; gap: 8px; }
.mode-banner-hint { color: #8af; margin-top: 8px; min-height: 20px; }

/* Collapsible mode banners (don't block the board). */
.mode-banner-header { display: flex; justify-content: space-between; align-items: center; cursor: pointer; padding: 4px 0; }
.mode-banner-toggle { color: #d4a017; font-size: 14px; }
.mode-banner.mode-banner-collapsed .mode-banner-body { display: none; }
.mode-banner.mode-banner-collapsed { padding: 8px 16px; }

/* Your Profile CTA — stands out, invites the click. */
.btn-profile-cta {
  background: linear-gradient(135deg, #d4a017, #f5c542) !important;
  color: #1a1a1a !important;
  font-weight: bold !important;
  border: 2px solid #f5c542 !important;
  box-shadow: 0 0 12px rgba(212, 160, 23, 0.5);
  animation: profile-cta-glow 2.5s ease-in-out infinite;
}
.btn-profile-cta:hover {
  box-shadow: 0 0 20px rgba(212, 160, 23, 0.8);
  transform: translateY(-1px);
}
@keyframes profile-cta-glow {
  0%, 100% { box-shadow: 0 0 8px rgba(212, 160, 23, 0.4); }
  50% { box-shadow: 0 0 16px rgba(212, 160, 23, 0.7); }
}

/* Sheen sweep on the profile CTA — subtle, once every 15s like the app. */
.btn-profile-cta {
  position: relative;
  overflow: hidden;
}
.btn-profile-cta::after {
  content: "";
  position: absolute;
  top: 0;
  left: -60%;
  width: 45%;
  height: 100%;
  background: linear-gradient(105deg, transparent, rgba(255,255,255,0.45), transparent);
  transform: skewX(-20deg);
  pointer-events: none;
  animation: profile-sheen 15s ease-in-out infinite;
}
@keyframes profile-sheen {
  0% { left: -60%; }
  8% { left: 130%; }
  100% { left: 130%; }
}

/* ============ Mobile browser compatibility (<=480px) ============ */
@media (max-width: 480px) {
  /* Profile screen: fit small screens, scroll inner content. */
  .profile-screen {
    width: 96vw; max-height: 94vh; padding: 12px;
    margin: 0;
  }
  .profile-title { font-size: 20px; }
  /* Avatar grid: 4 columns on phones (was 6). */
  .avatar-grid { grid-template-columns: repeat(4, 1fr); gap: 10px; }
  .avatar-pick { width: 56px; height: 56px; }
  /* Banner swatches: slightly larger touch targets. */
  .banner-swatch { width: 108px; height: 36px; }
  /* Badge picker: fit. */
  .badge-picker { width: 96vw; max-height: 94vh; }
  /* Mode banners (puzzle/lesson): don't overflow. */
  .mode-banner { max-width: 96vw; left: 50%; }
  .mode-banner-intro { max-height: 120px; }
  /* Coaching popup: fit. (2026-10-24: the old .coaching-box/.daily-box
     selectors matched nothing — the live classes are .coaching-card /
     .daily-card — so these rules were dead until now.) */
  .coaching-overlay .coaching-card { width: 96vw; max-height: 94vh; }
  /* Daily puzzle popup: fit. */
  .daily-overlay .daily-card { width: 96vw; max-height: 94vh; }
  /* Profile tabs: five uppercase labels must share one phone row. */
  .profile-tab { padding: 10px 4px; font-size: 12px; letter-spacing: 0; }
  /* Coaching grid: three columns cannot fit a phone card's min width. */
  .coaching-grid { grid-template-columns: repeat(2, 1fr); }
  /* Game-over / account-modal shell: margin + slimmer padding on phones. */
  .gameover { padding: 16px; }
  .gameover-card { padding: 20px 16px; }
}

/* Training Academy (Lesson Director prototype) — EVERYTHING lives in
   Tate's speech bubble under his instructor card (Buddy, 2026-10-20:
   "get rid of the pop up one — just have the multiple choice come from
   the chat box out of the avatar"). The bubble is an absolutely
   positioned overlay: it is out of flow and can NEVER affect the
   board's size (Buddy's firm requirement). Narration is clamped to
   3 lines; question options are never clamped — a question and all
   its answers are always fully visible and tappable. */
/* Lesson mode only: the header's control cluster (Layout / Pieces /
   Move Sound / account) is wider than a phone and otherwise forces the
   whole document into horizontal scrolling. Let it wrap while a lesson
   is active; normal play is unaffected. */
body.academy-active .topbar-right { flex-wrap: wrap; row-gap: 4px; justify-content: flex-end; }
body.academy-active { overflow-x: hidden; }
body.academy-active #opponentCard { position: relative; }
.academy-bubble { position: static; margin: 8px 2px 0; background: #f5efe0; border: 2px solid #d4a017; border-radius: 12px; box-shadow: 0 4px 16px rgba(0,0,0,0.35); padding: 10px 12px; pointer-events: none; }
/* CARD placement (owner direction 2026-10-24: bubble up onto Tate's
   player box): the lesson bubble sits as an overlay at the instructor
   card's top-left — #opponentCard is already position:relative in
   lesson mode, so top:0/left:0/width:100% pins it exactly to the card
   at exactly the card's (= board's) width on every viewport, and being
   out of flow it can never shift the board. Scoped to the card child
   only. Tradeoff: while expanded it covers the instructor card and,
   for tall bubbles, extends down over the hand tray / board top ranks;
   collapsed it sits on the card and clears the board on both viewports
   (see academy.js ensureBubble for the full accounting). The old
   .board-wrap > #academyBubble rule is superseded by the
   #opponentCard rule below; the .academy-panel skip in board.js
   _measureChrome stays moot for the bubble (absolute children never
   count as chrome) and is kept harmlessly. */
#opponentCard > #academyBubble.academy-bubble { position: absolute; top: 0; left: 0; width: 100%; margin: 0; z-index: 5; }
.academy-bubble-tail { display: none; }
.academy-bubble-btn { min-height: 44px; padding: 8px 14px; }
.academy-bubble button, .academy-bubble a { pointer-events: auto; }
.academy-bubble.hidden { display: none; }
.academy-bubble-tail { position: absolute; top: -7px; left: 30px; width: 14px; height: 14px; background: #f5efe0; border-left: 2px solid #d4a017; border-top: 2px solid #d4a017; transform: rotate(45deg); }
.academy-bubble-text { color: #1c1a15; font-size: 15px; line-height: 1.4; max-height: 46vh; overflow-y: auto; }
/* NEVER clamp lesson text (Buddy, 2026-10-20): a 3-line clamp cut Tate's
   lines off mid-sentence with "…" and the rest was unreadable. The bubble
   grows to fit the full line; extreme lines scroll inside the bubble. */
.academy-bubble-text:empty { display: none; }
.academy-bubble-objective { color: #7a5c00; font-weight: 600; font-size: 14px; line-height: 1.35; margin-top: 6px; }
.academy-bubble-objective:empty { display: none; }
.academy-bubble-options { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.academy-bubble-options:empty { display: none; }
.academy-bubble-option { background: #e7ddc4; color: #1c1a15; border: 2px solid #8a7a4d; border-radius: 10px; padding: 8px 10px; text-align: left; font-size: 15px; line-height: 1.35; white-space: normal; width: 100%; cursor: pointer; }
.academy-bubble-actions { display: flex; gap: 8px; margin-top: 8px; align-items: center; }
.academy-bubble-spacer { flex: 1 1 auto; }
.academy-bubble-btn { background: #1a1a20; color: #f5efe0; border: 1px solid #8a7a4d; border-radius: 8px; padding: 6px 12px; font-size: 14px; cursor: pointer; }
.academy-bubble-btn.gold { background: #d4a017; color: #1a1a20; font-weight: 700; }
.academy-bubble-btn.quiet { background: transparent; color: #6b6250; border-color: #c9bd9d; }
.academy-bubble-btn.hidden { display: none; }
/* Collapsed (practice free play): text, objective and options hide; the
   controls row — Exit lesson — stays. The whole board is visible. */
.academy-bubble.collapsed { padding: 6px 10px; pointer-events: auto; cursor: pointer; }
.academy-bubble-peekline { display: none; }
.academy-bubble.collapsed.boardask .academy-bubble-peekline { display: block; color: #7a5c00; font-weight: 600; font-size: 14px; line-height: 1.35; margin-bottom: 6px; }
.academy-bubble.collapsed .academy-bubble-text,
.academy-bubble.collapsed .academy-bubble-objective,
.academy-bubble.collapsed .academy-bubble-options { display: none; }
.academy-bubble.collapsed .academy-bubble-actions { margin-top: 0; }
.academy-bubble.collapsed .academy-bubble-tail { display: none; }


/* ===== 2026-10-23 calibration + progression cosmetics ===== */
.player-card .avatar { position: relative; }
.player-title { color: #d4a017; font-size: 12px; font-weight: 600; letter-spacing: 0.4px; line-height: 1.2; }
.avatar-border { position: absolute; inset: -4px; width: calc(100% + 8px); height: calc(100% + 8px); pointer-events: none; }
.player-card { position: relative; }
.banner-border-frame { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; border-radius: inherit; }
.profile-preview-card { position: relative; overflow: hidden; }
.cosmetic-grid { display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0; }
.cosmetic-cell { width: 118px; background: #101014; border: 1px solid #26262d; border-radius: 10px; padding: 8px; text-align: center; cursor: pointer; }
.cosmetic-cell img { width: 72px; height: 72px; object-fit: contain; }
.cosmetic-cell.locked { opacity: 0.55; cursor: default; }
.cosmetic-cell.selected { border-color: #d4a017; box-shadow: 0 0 0 1px #d4a017; }
.cosmetic-name { font-size: 12px; margin-top: 4px; line-height: 1.25; }
.cosmetic-state { font-size: 10px; letter-spacing: 0.6px; color: #9a9aa5; margin-top: 2px; }
.cosmetic-cell.selected .cosmetic-state { color: #d4a017; }
.banner-swatch.prog { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-height: 44px; }
.banner-swatch-label { font-size: 10px; color: #d8d8e0; }
.banner-swatch.locked { opacity: 0.55; }
@media (max-width: 640px) {
  .topbar { flex-wrap: nowrap; padding: 6px 8px; gap: 6px; }
  .topbar-right { flex-wrap: nowrap; row-gap: 0; gap: 4px; }
  .topbar .cycle-btn, .topbar button { padding: 4px 7px; font-size: 12px; white-space: nowrap; }
  .academy-bubble-btn { min-height: 44px; }
}

/* XP toast (ShogiXpToast): fixed overlay, never resizes or blocks the board. */
#xpToastWrap {
  position: fixed; top: 88px; left: 50%; transform: translateX(-50%);
  z-index: 9000; display: flex; flex-direction: column; align-items: center; gap: 8px;
  pointer-events: none; width: min(92vw, 420px);
}
.xp-toast {
  background: #101014; border: 1px solid #D4A017; border-radius: 12px;
  padding: 10px 18px; text-align: center;
  box-shadow: 0 0 18px rgba(212, 160, 23, 0.45);
  opacity: 0; transform: translateY(-8px);
  transition: opacity 0.3s, transform 0.3s;
}
.xp-toast.show { opacity: 1; transform: translateY(0); }
.xp-toast-amount { color: #FFD700; font-weight: 700; font-size: 18px; display: block; }
.xp-toast-label { color: #e8e8e8; font-size: 13px; display: block; margin-top: 2px; }
.xp-toast-levelup { border-width: 2px; padding: 14px 22px; }
.xp-toast-level { color: #FFD700; font-weight: 800; font-size: 20px; letter-spacing: 1px; display: block; }

/* Puzzle Rush HUD + summary (Step 4). Fixed/overlay elements, never in
   .board-col, so neither can shrink the board. */
.rush-hud {
  position: fixed; top: 112px; left: 50%; transform: translateX(-50%);
  /* Owner-approved Rush overlap fix (2026-10-26): z-index 151 puts the
     HUD above the puzzle banner (z-index 150) on every puzzle,
     regardless of DOM order — the banner is re-created per puzzle bind
     while the HUD is created once, so at equal z-index the banner
     painted above from the second puzzle onward. Stays below the
     z-index 200 session-end summary overlay. */
  z-index: 151; background: #1a1a1a; border: 1px solid #d4a017; border-radius: 10px;
  padding: 6px 14px; color: #ffd700; font-size: 14px; font-weight: 600;
  white-space: nowrap; pointer-events: none;
  box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
.rush-summary-wrap {
  position: fixed; inset: 0; z-index: 200; display: flex;
  align-items: center; justify-content: center; pointer-events: none;
}
.rush-summary-card {
  background: #101014; border: 2px solid #d4a017; border-radius: 14px;
  padding: 20px 24px; max-width: min(92vw, 420px); text-align: center;
  box-shadow: 0 8px 30px rgba(0,0,0,0.6); pointer-events: auto;
}
.rush-summary-title { color: #ffd700; font-weight: 800; font-size: 19px; margin-bottom: 10px; }
.rush-summary-line { color: #e8e8e8; font-size: 14px; margin-bottom: 8px; }
.rush-summary-stats { color: #e8e8e8; font-size: 15px; margin-bottom: 8px; }
.rush-summary-stats b { color: #ffd700; }
.rush-local { color: #aaa; font-size: 12px; }
.rush-summary-actions { display: flex; gap: 10px; justify-content: center; margin-top: 14px; }

/* Gauntlet banner (M4, 2026-10-27): handicap game status, clock, impasse panel. */
.gauntlet-banner { background: #101014; border: 1px solid #d4a017; border-radius: 8px; padding: 8px 10px; margin-bottom: 8px; }
.gauntlet-banner-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; justify-content: space-between; }
.gauntlet-banner-row span { color: #e8e8e8; font-size: 14px; }
.gauntlet-clock { color: #ffd700; }
.gauntlet-status { color: #aaa; font-size: 12px; margin-top: 2px; }
.gauntlet-impasse { color: #e8e8e8; font-size: 13px; margin-top: 6px; }
.gauntlet-impasse strong { color: #ffd700; }
/* Gauntlet click-cycle picker (PIVOT, 2026-10-27): dial label, removed tray,
   text board preview, preset row. */
.gauntlet-dial-label { color: #ffd700; font-weight: 700; margin: 8px 0 4px; }
.gauntlet-dial-tray { color: #e8e8e8; font-size: 14px; margin: 4px 0; }
.gauntlet-dial-note { color: #aaa; font-size: 12px; margin: 4px 0 8px; }
.gauntlet-presets { flex-wrap: wrap; }
/* Gauntlet picker popup (owner direction 2026-10-27, superseding the
   in-flow panel): the shared modal shell, but the picker content is
   tall (half-board + 14 buttons), so it gets its own max-height +
   scroll — small screens scroll the popup, never clip it. */
.gauntlet-picker-modal { max-height: calc(100dvh - 40px); overflow-y: auto; }
/* Level picker (owner order 2026-10-28): a much wider popup than the
   narrow shared modal, so the level boxes + half-board read as their
   own feature. Phone widths still clamp to the viewport. */
.gauntlet-picker-modal { max-width: min(720px, calc(100vw - 40px)); }
/* Tighten (owner order 2026-10-28): the whole picker fits one viewport
   with no scrollbar — tight padding, no reserved label heights, and a
   compact level grid. The old 4.5em/7.5em/3em reserves (built for the
   previous picker layout) would blow the budget on their own. */
.gauntlet-picker-modal { padding: 12px; }
.gauntlet-picker-modal h3 { margin: 0 0 4px 0; }
.gauntlet-picker-modal .gauntlet-dial-label { min-height: 2.4em; margin: 6px 0 4px; }
.gauntlet-picker-modal .gauntlet-dial-note { min-height: 0; margin: 2px 0 6px; }
.gauntlet-level-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px; margin: 0 0 8px 0;
}
.gauntlet-level-btn {
  width: 100%; height: auto; min-height: 0; padding: 8px 6px;
  box-sizing: border-box; display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "title star" "desc desc";
  text-align: left; gap: 2px;
}
.gauntlet-level-title { grid-area: title; font-weight: 700; font-size: 15px; }
.gauntlet-level-star { grid-area: star; color: #ffd700; font-size: 18px; line-height: 1; min-height: 18px; }
.gauntlet-level-desc { grid-area: desc; color: #ccc; font-size: 13px; line-height: 1.3; }
/* Practice tile: row 3, beside Level 7, spanning 2 columns. Its own
   − / + adjust the showing setup directly; no separate view. */
.gauntlet-practice-tile {
  grid-column: span 2; box-sizing: border-box;
  background: #1a1a1e; border: 1px solid #3a3a42; border-radius: 8px;
  padding: 8px; display: flex; flex-direction: column;
  justify-content: center; gap: 6px;
}
.gauntlet-practice-label { font-weight: 700; font-size: 15px; color: #ffd700; }
.gauntlet-practice-row { display: flex; gap: 8px; }
.gauntlet-practice-btn { flex: 1; height: 36px; font-size: 18px; padding: 0; }
/* Locked text area (owner fix 2026-10-27): reserve the longest
   content so dialing/presets never shift or resize the popup.
   Label: longest "Custom step — 10 pieces removed · Gauntlet
   moves first" (3 lines at narrow widths); tray: longest
   10-piece gives-list (5 lines); note: floor note (2 lines).
   min-height only reserves — longer content still grows
   instead of clipping, and the half-board/grid below never move
   between states at any width the popup supports. */
.gauntlet-picker-modal .gauntlet-dial-label { margin: 4px 0 2px; min-height: 4.5em; }
.gauntlet-picker-modal .gauntlet-dial-tray { margin: 2px 0 8px; min-height: 7.5em; }
.gauntlet-picker-modal .gauntlet-dial-note { min-height: 3em; }
/* Half-board wrap: centers the canvas; the canvas itself is cropped
   to half height by gauntlet.js (buffer stays square). */
.gauntlet-halfboard-wrap { text-align: center; margin: 8px 0; }
.gauntlet-halfboard-wrap canvas { max-width: 100%; }
/* ONE grid, every button the same size: dial controls, all presets,
   Start, Close. Same height, same font, full cell width — no mixed
   widths/heights, no oversized Start, no full-width Close outlier. */
.gauntlet-pick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 8px; margin: 0 0 8px 0;
}
.gauntlet-pick-btn {
  width: 100%; height: 44px; padding: 0 6px; font-size: 14px;
  box-sizing: border-box;
}

/* ---------- Teaching Mode (Phase 1: review-only core) ---------- */
.teach-modal .teach-note { font-size: 13px; opacity: 0.75; margin-top: 12px; }
/* Owner order (2026-10-28, test channel): the Set handicap label area is
   ONE SET SIZE — a fixed height tall enough for the longest label — so
   changing handicap never moves the buttons below it. Longest current
   label is the Custom 10-piece line (113 chars); at 13px/line-height 1.5
   (19.5px/line) that wraps to 4 lines on a 320px phone (232px content
   width), so 4 lines = 78px. If a longer label is ever added, raise
   this height — never let the area grow with the text. Dial label only;
   no other modal's notes are sized by this rule. */
.teach-modal .teach-dial-label { height: 78px; }
.teach-title-input { width: 100%; padding: 10px 12px; font-size: 15px;
  background: #1a1a1e; color: var(--cream); border: 1px solid #3a3a42;
  border-radius: 8px; box-sizing: border-box; margin-bottom: 12px; }
.teach-list { display: flex; flex-direction: column; gap: 10px; max-height: 50vh; overflow-y: auto; margin-bottom: 14px; }
.teach-list-item { display: flex; gap: 10px; align-items: center; padding: 10px 12px;
  background: #1a1a1e; border: 1px solid #3a3a42; border-radius: 8px; cursor: pointer; }
.teach-list-item:hover { border-color: var(--gold); }
.teach-list-main { flex: 1; min-width: 0; }
.teach-list-title { font-size: 15px; font-weight: 600; color: var(--cream); }
.teach-list-meta { font-size: 12px; opacity: 0.75; margin-top: 2px; }
.teach-list-mine { font-size: 12px; color: var(--gold); font-weight: 600; }
.teach-preview-board { width: min(100%, 420px); margin: 0 auto 12px auto; }
.teach-preview-board canvas { width: 100%; height: auto; display: block; }
.teach-room { position: fixed; inset: 0; z-index: 200; background: #0d0d0f;
  overflow-y: auto; display: flex; flex-direction: column; }
.teach-room-header { display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  padding: 10px 16px; border-bottom: 1px solid #2a2a30; }
.teach-phase { background: var(--gold); color: #141414; font-weight: 700;
  padding: 4px 12px; border-radius: 999px; font-size: 13px; }
.teach-room-title { font-size: 16px; font-weight: 600; color: var(--cream); flex: 1; min-width: 200px; }
.teach-room-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.teach-room .btn-danger { background: #a33; color: #fff; border: 1px solid #c55; }
.teach-room .btn-danger:hover { background: #b44; }
/* Phase 3 host moderation row: KICK + mute, prominent under the header. */
.teach-host-row { display: flex; flex-wrap: wrap; gap: 8px;
  padding: 0 16px 8px; border-bottom: 1px solid #2a2a30; }
.teach-host-row .btn-danger { font-weight: 700; }
/* Phase 3 saved-review list entries. */
.teach-saved-item { border: 1px solid #2a2a30; border-radius: 8px;
  padding: 10px 12px; margin-bottom: 10px; }
.teach-saved-title { font-weight: 600; color: var(--cream); }
.teach-saved-meta { font-size: 13px; opacity: 0.75; margin: 4px 0 8px; }
.teach-local-banner, .teach-away-banner, .teach-wait-banner {
  padding: 8px 16px; font-size: 14px; text-align: center; }
.teach-local-banner { background: #2a2410; color: var(--gold); }
.teach-away-banner { background: #3a1a1a; color: #ffb4b4; }
.teach-wait-banner { background: #1a2a1a; color: #b4ffb4; }
.teach-dot { color: #ff5a5a; margin-left: 10px; }
.teach-room-body { display: flex; flex-wrap: wrap; gap: 20px; padding: 12px; align-items: flex-start; }
.teach-board-col { display: flex; flex-direction: column; gap: 8px; }
.teach-board-wrap { position: relative; width: min(92vw, 520px); }
.teach-board-wrap canvas { display: block; width: 100%; height: auto; }
.teach-annot { position: absolute; left: 0; top: 0; touch-action: none; cursor: crosshair; }
/* Hand-row stability (owner 2026-10-28: the bottom controls shift
   when a hand goes empty <-> filled). A filled one-row tray is 54px
   tall (32px graphic + 20px button padding + 2px border); an empty
   tray was 18px, so the kifu bar + eval below jumped 36px per tray
   (72px for both) on every first capture / last piece played, and
   another 54px per tray when a hand wrapped to two rows. The tray
   now reserves one full chip row (54 + 2 rounding headroom), so
   empty and one-row states are IDENTICAL heights and the bottom
   controls never move between them. A hand growing past one row
   still grows the tray — the alternative (a permanent two-row
   reservation) would leave 108px of blank space under every empty
   hand and break the no-scroll fit at every viewport; that tradeoff
   is the owner's call if he wants it. */
.teach-hand { font-size: 13px; color: var(--cream); opacity: 0.85; min-height: 56px; }
.teach-kifu-bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* Kifu buttons 2px narrower per side (owner 2026-10-28 no-scroll
   fit): the bar wrapped to 3 lines because line 1 (4 nav buttons +
   the fixed 250px ply slot) ran just over the 520 column; the
   narrower buttons pull it to 2 lines on PC. The ply slot itself
   is untouched — it is the per-turn shift fix. */
.teach-kifu-bar .btn { padding: 10px 6px; }
.teach-ply { font-size: 14px; color: var(--gold); font-weight: 600; }
.teach-eval { font-size: 14px; color: var(--cream); background: #1a1a1e;
  border: 1px solid #3a3a42; border-radius: 8px; padding: 6px 12px; }
.teach-chat-col { flex: 1; min-width: 260px; max-width: 380px; display: flex; flex-direction: column; gap: 8px; }
.teach-chat-title { font-size: 15px; font-weight: 600; color: var(--gold); }
.teach-chat-messages { display: flex; flex-direction: column; gap: 6px;
  overflow-y: auto; max-height: 420px; background: #141417;
  border: 1px solid #2a2a30; border-radius: 8px; padding: 10px; }
.teach-chat-muted { font-size: 13px; color: #ffb4b4; }
.teach-chat-row { display: flex; gap: 8px; }
.teach-chat-input { flex: 1; padding: 10px 12px; font-size: 14px;
  background: #1a1a1e; color: var(--cream); border: 1px solid #3a3a42;
  border-radius: 8px; box-sizing: border-box; }
.teach-chat-input:disabled { opacity: 0.5; }
/* Wide-screen room cleanup (owner 2026-10-28): match the usual game
   look — centered board + side column, normal-sized moderation
   buttons. Scoped to min-width: 901px (the main game's row
   breakpoint); the phone layout below 901px is untouched, board
   sizing is untouched (520 cap = main game), and no
   .teach-preview-board rule is touched here (the overflow fix,
   owner 2026-10-28 Option B, lives at the .teach-preview-board rule
   + board.js _resize instead).
   Without this, the body group hugs the left (void on the right) and
   the two host-row buttons stretch to half the row each (.btn flex:1). */
@media (min-width: 901px) {
  /* Centering nudge 1 (owner 2026-10-28): gap 20 -> 8 pulls board and
     chat toward each other under centering (board ~6px right, chat
     center ~6px left, group still centered).
     Centering nudge 2 (owner 2026-10-28, tasked via Manager): chat
     panel 380 -> 264 (narrowed 116). Board center moves ~58px right
     (board offset is -(gap + chat)/2, so -116 chat = +58 board) and
     the group narrows 116, tighter to center. Honest geometry note:
     under centering the chat panel's CENTER cannot move (it depends
     only on board-column width + gap, both unchanged here) — the
     panel narrows around its center, so its right edge pulls ~58px
     left and its left edge moves ~58px right. A literal chat-center
     shift would need a smaller board or un-centering, neither
     authorized. Gap stays 8 (floor kept), no overlap, board 520
     unchanged.
     Per-turn shift fix (owner 2026-10-28, tasked via Manager): the
     kifu-bar status (.teach-ply, "Ply N · X to move") changed width
     every turn, and the board column sizes to the kifu bar's
     max-content, so the centered group re-centered every turn and
     board + chat shifted in opposite directions. The label now has
     a reserved 250px slot (centered text, nowrap, ellipsis cap), so
     its width contribution never changes — the room stops shifting
     as the game advances. 250 covers the owner's known labels with
     headroom ("Ply 999 · Shogitest1 to move" ~215); a longer name
     truncates with an ellipsis instead of moving the room. */
  .teach-room-body { justify-content: center; gap: 8px; }
  /* Board/chat closeness correction (owner 2026-10-28, "shifting the
     board and chat further away from eachother"): the nudge-2
     arithmetic measured the FLEX gap (column-to-chat = 8) but the
     owner's eye measured BOARD-to-chat — and the board column had
     no width of its own, so it sized to the kifu bar's UNWRAPPED
     max-content (8 buttons + the fixed 250px ply slot + gaps =
     ~1212px in the sandbox font, ~1068px in Barlow Condensed),
     leaving the 520 board left-aligned inside it. Rendered
     measurement (real stylesheet + real kifu bar DOM, headless
     Chrome): at 1920 the visible board-to-chat gap was 700px
     (sandbox font) with column-to-chat still 8, and at 1280 the
     1212px column pushed the chat onto the next row entirely.
     The fix caps the column at board width, so the ALREADY-WRAPPING
     kifu bar (flex-wrap: wrap in the base rule) wraps to two
     lines inside 520 instead of stretching the column: board and
     chat then sit exactly 8px apart as a 792px pair (520 + 8 +
     264) centered on the viewport. The 250px ply slot STAYS, so
     no per-turn shift returns (its width never changes, so the
     wrap points never move). Phone untouched: this rule lives
     only in the 901px block. */
  .teach-board-col { width: min(92vw, 520px); }
  .teach-host-row { border-bottom: none; }
  .teach-host-row .btn { flex: none; }
  .teach-chat-col { max-width: 264px; }
  .teach-ply { flex: none; width: 250px; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
.teach-hand-chip.selected { outline: 2px solid #d4a017; outline-offset: 1px; }
/* Teaching hand chips show the piece graphic (owner 2026-10-28),
   mirroring the main game's hand tray for the room's piece style.
   The chip BUTTON is unchanged (same tap target, handler, order);
   only its content changed from a letter code to graphic + count.
   Graphics are 32px so a full tray fits the 520 board width. Phone
   and PC both (not media-scoped). White SVGs point down in file, so
   the White tray flips them upright like the main game; badge and
   newtile art point up in file and are exempt, as there. Midnight
   SVGs carry the board's horizontal stretch, narrowed back here. */
.teach-hand-chip { display: inline-flex; align-items: center; gap: 4px; }
.teach-hand-chip img { width: 32px; height: 32px; pointer-events: none; }
.teach-hand-chip .hand-traditional, .teach-hand-chip .hand-kanji, .teach-hand-chip .hand-midnight-kanji { width: 32px; height: 32px; font-size: 20px; }
.teach-hand.white-hand .teach-hand-chip img { transform: rotate(180deg); }
.teach-hand.white-hand .teach-hand-chip img.hand-badge-img,
.teach-hand.white-hand .teach-hand-chip img.hand-newtile-img { transform: none; }
.teach-hand .teach-hand-chip img.hand-midnight-img.black { transform: scaleX(0.9651); }
.teach-hand .teach-hand-chip img.hand-midnight-img.white { transform: scaleX(0.9224); }
.teach-hand.white-hand .teach-hand-chip img.hand-midnight-img.white { transform: rotate(180deg) scaleX(0.9224); }
.teach-dial-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 8px; }
.teach-dial-grid .btn { flex: none; }

/* ShogiGO Web — My Progress hub + unified shell (WS-A preview).
 * Black/gold identity; medallion language matches the badge showcase
 * (plate #101014, gold #d4a017). No board-column styles are touched. */

.shell-nav { display: inline-flex; gap: 6px; align-items: center; margin-right: 10px; }
.shell-nav .btn { white-space: nowrap; }
.shell-nav .btn.active { border-color: #d4a017; color: #d4a017; }
.dojo-menu { position: absolute; z-index: 60; background: #101014; border: 1px solid #d4a017;
  border-radius: 8px; padding: 6px; display: flex; flex-direction: column; gap: 4px;
  box-shadow: 0 8px 24px rgba(0,0,0,.6); }
.dojo-menu .btn { text-align: left; }

.progress-overlay { position: fixed; inset: 0; z-index: 55; background: rgba(4,4,6,.82);
  overflow-y: auto; padding: 18px 10px 40px; }
.progress-screen { max-width: 860px; margin: 0 auto; background: #0c0c0f; color: #e8e0c8;
  border: 1px solid #2c2c33; border-radius: 14px; padding: 18px 18px 26px; }
.progress-header { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.progress-title { font-family: "Barlow Condensed", sans-serif; font-size: 26px; letter-spacing: 2px;
  color: #d4a017; flex: 1; }
.provisional-tag { font-size: 11px; letter-spacing: 1px; color: #0c0c0f; background: #d4a017;
  border-radius: 999px; padding: 3px 9px; font-weight: 700; white-space: nowrap; }

.progress-identity { display: flex; gap: 16px; align-items: center; background: #101014;
  border: 1px solid #26262d; border-radius: 12px; padding: 14px 16px; margin: 10px 0; }
.progress-avatarbox { position: relative; width: 92px; height: 92px; flex: 0 0 auto; text-align: center; }
.progress-avatarbox img.avatar { width: 92px; height: 92px; border-radius: 50%; object-fit: cover; display: block; }
.progress-avatarbox img.pborder { position: absolute; inset: 0; width: 92px; height: 92px; pointer-events: none; }
.progress-lv { margin-top: 5px; display: inline-block; background: #101014; border: 1px solid #d4a017;
  color: #d4a017; border-radius: 999px; font-weight: 700; font-size: 13px; padding: 2px 10px; }
.progress-idmeta { flex: 1; min-width: 200px; }
.progress-name { font-size: 20px; font-weight: 700; color: #f5f0e1; }
.progress-equipped-title { color: #c9a227; font-variant: small-caps; letter-spacing: 2px; font-size: 15px; min-height: 18px; }
.progress-bannerstrip { position: relative; height: 26px; border-radius: 6px; overflow: hidden; margin: 6px 0 8px; background: #000; }
.progress-bannerstrip img.banner { width: 100%; height: 100%; object-fit: cover; display: block; }
.progress-bannerstrip img.bborder { position: absolute; inset: 0; width: 100%; height: 100%; }
.xpbar { height: 14px; background: #1a1a20; border: 1px solid #33333c; border-radius: 999px; overflow: hidden; }
.xpbar-fill { height: 100%; background: linear-gradient(90deg, #8a6a10, #d4a017); border-radius: 999px; }
.xpbar-text { font-size: 13px; color: #cfc7a8; margin-top: 5px; }
.next-reward { font-size: 13.5px; color: #e8e0c8; margin-top: 3px; }
.next-reward b { color: #d4a017; }

.progress-tabs { display: flex; gap: 6px; margin: 12px 0 4px; }
.progress-tabs .btn.active { border-color: #d4a017; color: #d4a017; }

.schedule-note { font-size: 13px; color: #cfc7a8; background: #101014; border: 1px solid #26262d;
  border-radius: 10px; padding: 10px 12px; margin: 10px 0; }
.schedule-note b { color: #d4a017; }
.roadmap-row { display: flex; gap: 12px; padding: 10px 6px; border-bottom: 1px solid #1d1d23; align-items: flex-start; }
.roadmap-row.capstone { background: rgba(212,160,23,.05); border-radius: 8px; }
.roadmap-lv { flex: 0 0 64px; text-align: center; }
.roadmap-lv .lv-num { font-family: "Barlow Condensed", sans-serif; font-size: 21px; color: #d4a017; }
.roadmap-lv .lv-sub { font-size: 10.5px; color: #8f887a; letter-spacing: .5px; }
.roadmap-items { display: flex; flex-wrap: wrap; gap: 10px; flex: 1; }
.roadmap-empty { color: #5d594f; font-size: 12.5px; padding-top: 6px; }
.reward-tile { flex: 1 1 104px; max-width: 140px; min-width: 96px; background: #101014; border: 1px solid #26262d; border-radius: 10px;
  padding: 8px 8px 7px; text-align: center; position: relative; }
.reward-tile.equipped { border-color: #d4a017; box-shadow: 0 0 0 1px #d4a017 inset; }
.reward-tile .tile-art { height: 62px; display: flex; align-items: center; justify-content: center; position: relative; }
.reward-tile img.art-avatar { width: 58px; height: 58px; border-radius: 50%; object-fit: cover; }
.reward-tile img.art-pborder { position: absolute; width: 62px; height: 62px; }
.reward-tile img.art-banner { width: 102px; height: 20px; object-fit: cover; border-radius: 4px; }
.reward-tile .art-bannerwrap { position: relative; width: 102px; height: 26px; }
.reward-tile img.art-bborder { position: absolute; inset: 0; width: 102px; height: 26px; }
.reward-tile .art-swatch { width: 102px; height: 20px; border-radius: 4px; background: #000; border: 1px solid #26262d; }
.reward-tile .art-style { font-size: 30px; color: #d4a017; line-height: 1; }
.reward-tile .art-title { color: #c9a227; font-variant: small-caps; letter-spacing: 1.5px; font-size: 14.5px; }
.reward-tile .art-crest { width: 44px; height: 44px; opacity: .85; }
.reward-tile.locked .tile-art { filter: grayscale(.45) brightness(.5); }
.reward-tile .tile-name { font-size: 11.5px; color: #e8e0c8; margin-top: 5px; line-height: 1.25; min-height: 28px; }
.reward-tile .tile-cat { font-size: 10px; color: #8f887a; letter-spacing: 1px; text-transform: uppercase; }
.reward-tile .tile-state { font-size: 10.5px; margin-top: 3px; font-weight: 700; }
.tile-state.owned { color: #9db87c; } .tile-state.locked { color: #b08850; } .tile-state.equipped { color: #d4a017; }

.mission-card { background: #101014; border: 1px solid #26262d; border-radius: 10px; padding: 12px 14px; margin: 8px 0; }
.mission-card .mission-top { display: flex; justify-content: space-between; gap: 10px; }
.mission-card .mission-name { font-weight: 700; color: #f5f0e1; }
.mission-card .mission-xp { color: #d4a017; font-weight: 700; white-space: nowrap; }
.mission-card .mission-desc { font-size: 13px; color: #cfc7a8; margin-top: 2px; }
.mission-card .mission-state { font-size: 12.5px; margin-top: 6px; }
.mission-progress { height: 8px; background: #1a1a20; border-radius: 999px; overflow: hidden; margin-top: 6px; }
.mission-progress > div { height: 100%; background: #d4a017; }
.reset-line { font-size: 13px; color: #cfc7a8; margin: 10px 0; }
.reset-line b { color: #d4a017; }
.hub-note { font-size: 13px; color: #cfc7a8; line-height: 1.5; }

/* --- Academy & Dojo destination entrances (WS-A visual direction) --- */
.dest-hero { background: #101014; border: 1px solid #26262d; border-radius: 12px; padding: 16px; margin: 10px 0; }
/* Academy emblem hero header (Art final, owner pick 2A): full-width and
 * uncropped by construction — no fixed height, no cover crop, so the
 * engraved frame renders intact at any viewport width. */
.academy-hero-img { width: 100%; height: auto; display: block; object-fit: contain; }
.dest-hero-title { font-family: "Barlow Condensed", sans-serif; font-size: 24px; letter-spacing: 1.5px; color: #d4a017; margin-bottom: 4px; }
.dojo-hero { display: flex; gap: 16px; align-items: center; }
.pm-portrait { width: 92px; height: 92px; border-radius: 50%; object-fit: cover; border: 2px solid #d4a017; flex: 0 0 auto; }
.coach-row { display: flex; gap: 12px; flex-wrap: wrap; margin: 12px 0; }
.coach-card { flex: 1 1 200px; background: #101014; border: 1px solid #26262d; border-radius: 12px; padding: 14px; text-align: center; }
.coach-portrait { width: 96px; height: 96px; border-radius: 50%; object-fit: cover; border: 2px solid #d4a017; }
.coach-name { font-size: 17px; font-weight: 700; color: #f5f0e1; margin-top: 8px; }
.coach-role { color: #c9a227; font-variant: small-caps; letter-spacing: 2px; font-size: 13.5px; }
.coach-line { font-size: 13px; color: #cfc7a8; line-height: 1.45; min-height: 56px; }
.dest-rec { font-size: 13.5px; color: #e8e0c8; background: #141007; border: 1px dashed #8a6a10; border-radius: 10px; padding: 10px 12px; }
.track-section { margin: 16px 0; }
.track-head { display: flex; gap: 12px; align-items: center; margin-bottom: 6px; }
.track-icon { width: 44px; height: 44px; }
.track-name { font-family: "Barlow Condensed", sans-serif; font-size: 20px; letter-spacing: 1.5px; color: #d4a017; }
.track-blurb { font-size: 12.5px; color: #8f887a; }
.lesson-row { display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 7px 10px; border-bottom: 1px solid #1d1d23; }
.lesson-title { font-size: 14px; color: #e8e0c8; }
.lesson-soon { font-size: 10.5px; letter-spacing: 1px; color: #8f887a; }
.dojo-grid { display: flex; gap: 12px; flex-wrap: wrap; margin: 12px 0; }
.dojo-card { flex: 1 1 170px; background: #101014; border: 1px solid #26262d; border-radius: 12px; padding: 14px; text-align: center; }
.dojo-icon { width: 56px; height: 56px; }
.dojo-glyph { display: block; width: 56px; height: 56px; line-height: 56px; font-size: 48px; color: #ffd700; align-self: center; }
.dojo-name { font-size: 16px; font-weight: 700; color: #f5f0e1; margin-top: 6px; }
.dojo-desc { font-size: 12.5px; color: #cfc7a8; line-height: 1.45; min-height: 72px; }
/* Dojo entrance header mark (2026-10-24, owner order): the Torii Ring final
   beside the title, between title and pill. 32px display — the same verified
   size as the home Dojo mark; flex: 0 0 auto so it never shrinks on narrow
   rows. Academy shell call passes no mark, so its header is untouched. */
.dojo-header-mark { width: 32px; height: 32px; object-fit: contain; flex: 0 0 auto; }
/* Dojo card alignment (2026-10-24, HQ-approved CSS-only fix): cards in a row
   already stretch to equal height via the grid; making each card a column
   and pushing its action to the bottom with margin-top:auto aligns all four
   actions. The .btn override cancels the base .btn { flex: 1 } rule, which
   would otherwise grow the button vertically inside the column. No text,
   destination, icon, or behavior changes; no hardcoded offsets; stacked
   mobile cards are unaffected (no free space for the auto margin to absorb). */
.dojo-card { display: flex; flex-direction: column; }
.dojo-card .dojo-icon { align-self: center; }
.dojo-card > .btn, .dojo-card > .lesson-soon { flex: 0 0 auto; margin-top: auto; align-self: center; }
.mission-card .mission-icon { width: 30px; height: 30px; vertical-align: middle; margin-right: 8px; }


/* ===== 2026-10-23 sprint: schools, stars, missions, QA, calibration ===== */
.progress-header { flex-wrap: wrap; row-gap: 6px; }
.provisional-tag { white-space: normal; text-align: center; }
.school-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-top: 12px; }
.school-card { background: #101014; border: 1px solid #26262d; border-radius: 12px; padding: 14px 10px; text-align: center; cursor: pointer; color: inherit; font: inherit; }
.school-card:hover { border-color: #d4a017; }
.school-icon { width: 56px; height: 56px; object-fit: contain; }
.school-name { font-weight: 700; margin-top: 6px; }
.school-coach { color: #d4a017; font-size: 12px; margin-top: 2px; }
.school-blurb { font-size: 12px; color: #b9b9c2; line-height: 1.35; }
.school-count { font-size: 11px; color: #9a9aa5; margin-top: 6px; }
.school-head { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 10px; }
.school-title { font-size: 20px; font-weight: 700; }
.lesson-list { display: flex; flex-direction: column; gap: 6px; }
.lesson-star { font-size: 18px; width: 24px; text-align: center; flex: 0 0 auto; }
.lesson-star.earned { color: #d4a017; }
.lesson-star.completed { color: #d4a017; opacity: 0.45; }
.lesson-star.locked { color: #55555f; }
/* Per-school lesson lists: fixed control column (owner order 2026-10-24).
 * The base .btn rule grows (flex:1), which let Begin buttons balloon to
 * fill each row and wander with title length. In a lesson row the control
 * must NOT grow, shrink, or size to the title: one fixed slot on every
 * row, in every school, on both viewports. The COMING SOON label takes
 * the same slot so Soon rows align with Begin rows. Titles take the
 * remaining space and wrap; they are never truncated. */
.lesson-row .lesson-title { flex: 1 1 auto; min-width: 0; }
.lesson-row .begin-btn { width: 96px; height: 44px; flex: 0 0 auto; }
.lesson-row .lesson-soon { width: 96px; flex: 0 0 auto; text-align: center; white-space: nowrap; }
.missions-card { background: #101014; border: 1px solid #26262d; border-radius: 12px; padding: 12px; margin-top: 14px; }
.missions-title { font-weight: 700; letter-spacing: 1px; margin-bottom: 6px; }
.qa-tag { display: inline-block; margin-top: 8px; padding: 3px 8px; border: 1px solid #d4a017; border-radius: 999px; color: #d4a017; font-size: 11px; letter-spacing: 0.5px; }
.badges-embed .badges-screen { max-width: none; padding: 0; }
@media (max-width: 640px) {
  .school-grid { grid-template-columns: repeat(2, 1fr); }
  .pm-portrait { width: 64px; height: 64px; }
  .reward-tile { flex-basis: 44%; }
}
