:root {
  --crimson-0:#240606;
  --crimson-1:#3d0b0b;
  --crimson-hi:#5a1414;
  --gold:#d9b24a;
  --gold-hi:#f0d178;
  --gold-soft:#caa14a;
  --gold-dim:#8c7331;
  /* Generic slot frame (see the shared rule by .tslot): the gold gradient every
     framed tile paints as its border-box layer, the 1px black outline shadow
     composable into any box-shadow list, and the dark lacquer BODY empty/idle
     tiles share (filled tiles paint their own state body over it). */
  --slot-frame:linear-gradient(150deg, rgba(243,231,196,.55) 0%, rgba(146,120,84,.5) 55%, rgba(243,231,196,.4) 100%);
  --slot-outline:0 0 0 1px #000;
  --slot-body:linear-gradient(180deg, #241709, #120c05);
  --parch:#f3e7c4;
  --jade-1:#3fae86;
  --jade-2:#2a7c5e;
  --jade-edge:#1d5742;
  --jade-soft:#aef0d6;
  --warn:#e8a98f;
  --warn-deep:#9e2418;
  --up:#5fd0a0;
  --down:#e2906f;
  --line:rgba(217,178,74,.20);
  --line-soft:rgba(217,178,74,.12);
  --panel:rgba(60,12,12,.72);
  --panel-2:rgba(40,8,8,.72);
  --card:rgba(70,16,15,.5);
  --card-2:rgba(40,9,9,.55);
  --topbar:#2a0808;
  --accent:var(--gold);
  --gap:22px;
  --pad:24px;
  --rail-w:116px;   /* half-width of the left sidebar (.railbar spans 2×); content pages clear 2× */
}
* { box-sizing:border-box; }
html,
body { margin:0; height:100%; }
body {
  min-height:100vh; font-family:'Noto Serif', Georgia, serif; color:var(--parch);
  background:radial-gradient(150% 100% at 50% -20%, var(--crimson-hi) 0%, var(--crimson-1) 46%, var(--crimson-0) 100%) fixed;
  -webkit-font-smoothing:antialiased;
}
body::before {
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background-image:
    repeating-linear-gradient(63deg, rgba(217,178,74,.05) 0 1px, transparent 1px 78px),
    repeating-linear-gradient(-63deg, rgba(217,178,74,.05) 0 1px, transparent 1px 78px);
  -webkit-mask-image:radial-gradient(80% 70% at 50% 35%, #000 0%, transparent 80%);
          mask-image:radial-gradient(80% 70% at 50% 35%, #000 0%, transparent 80%);
}
.app {
  position:relative; z-index:1; min-height:100vh; display:grid;
  grid-template-columns:1fr;
  grid-template-rows:auto auto auto auto 1fr;
  grid-template-areas:"brand" "nav" "order" "prison" "main";
}
.brandbar { grid-area:brand; }
.orderbar { grid-area:order; }
.prisobar { grid-area:prison; }
.main-area { grid-area:main;
  /* Shared page surface: the dark slate texture lives here so every page (and
     any gap a page leaves) sits on it instead of the bare crimson body. */
  background:#141009 url(/assets/ui/header-texture.png?v=8f41a3c587) center / cover no-repeat; }
body.lay-rail .app {
  height:100vh; overflow:hidden;
  grid-template-columns:1fr;
  grid-template-rows:auto auto auto 1fr;
  grid-template-areas:"brand" "order" "prison" "body";
}
body.lay-rail .hud { display:flex; }
body.lay-rail .brandbar .spacer { flex:0 0 14px; }
.shell-body { grid-area:body; position:relative; display:flex; flex-direction:row; min-height:0; overflow:hidden; }
.shell-body > .main-area { flex:1 1 auto; min-width:0; min-height:0; overflow:auto;
  /* Uniform breathing room above EVERY page (full-height pages resolve their
     100% against the content box, so they simply start 25px down — no scroll).
     The world map is the one true edge-to-edge page: exempted below. */
  padding-top:25px; }
.shell-body > .main-area:has(.world-map) { padding-top:0; }

/* ── Page-transition loader ─────────────────────────────────────────
   Sits over the content region (shell-body is position:relative; the
   brandbar lives in a sibling grid area). z-index 23 keeps it UNDER the
   floating HUD rails (.railbar/.rail-shell at 24): only the page content
   fades — the chrome never dips. Kept in the DOM always; navigate()
   toggles .show/.veil. Off = invisible & click-through, so it never
   interferes when idle. */
.page-loader {
  position:absolute; inset:0; z-index:23;
  display:grid; place-items:center;
  background:radial-gradient(circle at 50% 44%, rgba(20,14,8,.52), rgba(9,6,3,.80));
  backdrop-filter:blur(2px);
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .16s ease, visibility 0s linear .16s;
}
.page-loader.show {
  opacity:1; visibility:visible; pointer-events:auto;
  transition:opacity .16s ease;
}
.page-loader-spin {
  grid-area:1/1;
  width:64px; height:64px; border-radius:50%;
  border:3px solid rgba(217,178,74,.20);
  border-top-color:var(--gold, #d9b24a);
  box-shadow:0 0 18px rgba(217,178,74,.18);
  animation:roe-spin .8s linear infinite;
}
.page-loader-crest {
  grid-area:1/1;
  font-family:"Noto Serif SC", serif; font-size:26px; font-weight:700;
  color:var(--gold-hi, #f0d178); text-shadow:0 1px 6px rgba(0,0,0,.6);
  pointer-events:none;
}
@keyframes roe-spin { to { transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .page-loader-spin { animation-duration:1.6s; }
}

/* ── Page-swap fade-through-black ────────────────────────────────────
   navigate() raises .veil over the outgoing page (quick fade to dark),
   swaps the DOM beneath it, and drops it once the new page settles
   (softer fade-in). Unlike the translucent .show backdrop, the veil is
   fully opaque so nothing behind the swap — the red lacquer body, the
   emptied main area — ever shows through. The spinner/crest stay hidden
   unless .show joins in (slow swaps only). */
.page-loader.veil {
  opacity:1; visibility:visible; pointer-events:auto;
  background:radial-gradient(circle at 50% 44%, #140e08, #090603);
  transition:opacity .12s ease;
}
.page-loader-spin, .page-loader-crest { opacity:0; transition:opacity .16s ease; }
.page-loader.show .page-loader-spin, .page-loader.show .page-loader-crest { opacity:1; }
.brandbar {
  position:relative; z-index:30; display:flex; align-items:center; gap:16px;
  padding:13px 26px; min-height:72px;
  background:
    linear-gradient(180deg, rgba(20,15,9,.22), rgba(8,6,3,.42)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat,
    linear-gradient(180deg,#241a10 0%, #19130c 52%, #120d08 100%);
  /* 6px gold frame along the bottom edge (favo header-frame tileset) */
  border-style:solid; border-width:0 0 6px 0;
  border-image:url(/assets/ui/header-frame.png?v=8f41a3c587) 10 round;
  box-shadow:0 10px 26px rgba(0,0,0,.55);
}
.brand { display:flex; align-items:center; gap:14px; }
.crest {
  width:46px; height:46px; flex:none; border-radius:11px; display:grid; place-items:center;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:25px; color:#2a0808;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  border:1px solid var(--gold-hi); box-shadow:0 0 0 3px rgba(217,178,74,.18), inset 0 1px 0 rgba(255,255,255,.5);
}
.brandbar .brand { padding-left:112px; }
.brandbar .crest {
  position:absolute; left:16px; top:-6px; width:90px; height:112px; z-index:33;
  display:block; flex:none; border:0; border-radius:0; box-shadow:none;
  background:url(/assets/ui/brand-banner.png?v=8f41a3c587) top center/contain no-repeat;
  filter:drop-shadow(0 8px 12px rgba(0,0,0,.6)); pointer-events:none;
}
.brandbar .crest span {
  position:absolute; left:0; right:0; top:15px; text-align:center;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:30px;
  color:var(--gold-hi); text-shadow:0 2px 5px #000;
}
.brand .bt { line-height:1; }
.brand h1 { font-family:'Cinzel',serif; font-weight:700; font-size:23px; margin:0; letter-spacing:.05em;
  background:linear-gradient(180deg,#fbe6ad 0%,#e7c879 34%,#c79844 64%,#8a6322 100%);
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; color:transparent;
  filter:drop-shadow(0 1px 1px rgba(0,0,0,.65)); }
.brand .plan { font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.24em; color:rgba(241,230,198,.55); margin-top:5px; text-transform:uppercase; }
.brandbar .spacer { flex:1; }
.hud { display:none; align-items:center; gap:9px; }
.player { display:flex; align-items:center; gap:13px; }
.merit-pill {
  display:inline-flex; align-items:center; gap:7px; height:34px; padding:0 14px; border-radius:8px;
  background:linear-gradient(180deg,#7a1f17,#4c110c); border:1px solid rgba(199,152,68,.5);
  box-shadow:inset 0 1px 0 rgba(255,180,120,.18), 0 2px 6px rgba(0,0,0,.45);
}
.merit-pill svg { width:16px; height:16px; color:var(--gold-hi); }
.merit-pill .lab { font-family:'JetBrains Mono',monospace; font-size:9.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--gold-hi); }
.merit-pill .mv { font-family:'JetBrains Mono',monospace; font-weight:700; font-size:14px; color:#fff; font-variant-numeric:tabular-nums; }
.player .pname { font-family:'Cinzel',serif; font-weight:600; font-size:14.5px; color:var(--parch); letter-spacing:.06em; }
.player .avatar {
  width:42px; height:42px; border-radius:50%; flex:none; overflow:hidden; display:grid; place-items:center;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:18px; color:var(--gold-hi);
  border:2px solid var(--gold); box-shadow:0 0 0 1px #000, 0 2px 6px rgba(0,0,0,.5);
  background:radial-gradient(120% 90% at 50% 30%, #7d2a1c, #4a0f0b);
}
.player .avatar img { width:100%; height:140%; object-fit:cover; object-position:50% 8%; }
.icon-btn {
  width:36px; height:36px; border-radius:8px; display:grid; place-items:center; cursor:pointer;
  color:rgba(241,230,198,.7); transition:all .15s ease;
  background:linear-gradient(180deg,#3a3d44 0%, #23262b 46%, #15171b 100%);
  border:1px solid #0a0b0d;
  box-shadow:inset 0 1px 0 rgba(180,186,196,.45), inset 0 -3px 5px rgba(0,0,0,.55), 0 2px 5px rgba(0,0,0,.5);
}
.icon-btn svg { width:17px; height:17px; }
.icon-btn:hover { color:var(--gold-hi);
  background:linear-gradient(180deg,#474a52 0%, #2c2f35 46%, #1a1c20 100%);
  box-shadow:inset 0 1px 0 rgba(200,206,216,.55), inset 0 -3px 5px rgba(0,0,0,.5), 0 0 12px rgba(247,221,142,.32), 0 2px 5px rgba(0,0,0,.5); }
.nav {
  position:relative; display:inline-flex; align-items:center; gap:9px; cursor:pointer;
  font-family:'Cinzel',serif; font-weight:600; font-size:14px; letter-spacing:.02em;
  color:rgba(243,231,196,.6); padding:15px 15px; border:0; background:none; transition:color .15s ease;
}
.nav svg { width:16px; height:16px; opacity:.8; flex:none; }
.nav:hover { color:var(--parch); }
.nav.active { color:var(--accent); }
.nav.active::after {
  content:""; position:absolute; left:12px; right:12px; bottom:-1px; height:2.5px; border-radius:2px;
  background:linear-gradient(90deg, var(--gold-soft), var(--gold-hi)); box-shadow:0 0 12px rgba(240,209,120,.5);
}
.counters { display:flex; align-items:center; gap:8px; }
.ctr {
  display:inline-flex; align-items:center; gap:8px; height:34px; padding:0 13px 0 9px; border-radius:18px;
  background:linear-gradient(180deg, rgba(60,46,24,.72), rgba(28,20,10,.86));
  border:1px solid rgba(199,152,68,.34);
  box-shadow:inset 0 1px 0 rgba(247,221,142,.12), 0 2px 5px rgba(0,0,0,.4);
}
.ctr img { width:21px; height:21px; border-radius:0; object-fit:contain; box-shadow:none; filter:drop-shadow(0 1px 1px rgba(0,0,0,.6)); }
.ctr .cv { font-family:'JetBrains Mono',monospace; font-weight:700; font-size:14px; color:var(--parch); font-variant-numeric:tabular-nums; letter-spacing:.02em; }
.ctr .cap { font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(241,230,198,.6); }
.ctr.coin .cv { color:var(--gold-hi); }
/* Production/day view: hover any chip (gold included) to preview, click to pin.
   Both readings live overlaid in one grid cell so the pill sizes to the wider
   of the two and never resizes when the view swaps. */
.ctr { cursor:pointer; }
.ctr-vals { display:grid; align-items:center; }
.ctr-vals > span { grid-area:1/1; display:inline-flex; align-items:center; gap:8px; white-space:nowrap; justify-self:start; }
.ctr .ctr-prod { visibility:hidden; }
.prod-view .ctr .ctr-prod { visibility:visible; }
.prod-view .ctr .ctr-stock { visibility:hidden; }
.ctr .ctr-prod .cv { color:#a9dfae; }
.ctr .ctr-prod .cap { color:rgba(169,223,174,.55); }
.orderbar {
  display:flex; align-items:center; gap:14px; padding:11px 26px;
  background:linear-gradient(90deg, rgba(158,36,24,.42), rgba(60,12,12,.5));
  border-bottom:1px solid rgba(217,178,74,.32);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04);
}
.orderbar.hidden { display:none; }
.orderbar .seal {
  width:34px; height:34px; flex:none; border-radius:50%; display:grid; place-items:center;
  font-family:'Noto Serif SC',serif; font-size:16px; color:#f3dd92;
  background:radial-gradient(circle at 50% 38%, #b13328, #7d160e); border:1px solid var(--gold-soft);
  box-shadow:0 0 0 3px rgba(140,28,20,.3), inset 0 1px 3px rgba(0,0,0,.4);
  animation:sealpulse 0.9s ease-in-out infinite;
}
@keyframes sealpulse {
  0%,100%{
    box-shadow:0 0 0 2px rgba(217,178,74,.35), 0 0 6px 1px rgba(217,178,74,.25), inset 0 1px 3px rgba(0,0,0,.4);
    filter:brightness(1);
  }
  50%{
    box-shadow:0 0 0 6px rgba(246,190,0,.45), 0 0 22px 6px rgba(246,190,0,.7), inset 0 1px 3px rgba(0,0,0,.4);
    filter:brightness(1.5);
  }
}
.orderbar .otxt { display:flex; flex-direction:column; gap:2px; min-width:0; }
.orderbar .olab { font-family:'JetBrains Mono',monospace; font-size:9.5px; letter-spacing:.2em; text-transform:uppercase; color:var(--gold-soft); }
.orderbar .oname { font-family:'Cinzel',serif; font-weight:700; font-size:15px; color:var(--parch); }
.orderbar .oname b { color:var(--gold-hi); }
.orderbar .spacer { flex:1; }
.orderbar .ocount {
  display:inline-flex; align-items:center; gap:8px; font-family:'JetBrains Mono',monospace;
  font-size:13px; font-weight:700; color:var(--gold-hi); font-variant-numeric:tabular-nums;
  padding:7px 13px; border-radius:9px; background:rgba(0,0,0,.3); border:1px solid var(--line);
}
.orderbar .ocount svg { width:14px; height:14px; opacity:.8; }
.layout {
  display:grid; grid-template-columns:1fr 336px; gap:26px;
  /* the left sidebar (.railbar) is in-flow now, so content only needs even side
     gutters — the top gap comes from .main-area's shared 25px padding */
  padding:0 26px 46px;
  align-items:start; max-width:1680px; width:100%; margin:0 auto;
}
.col { display:flex; flex-direction:column; gap:var(--gap); min-width:0; }
.panel {
  position:relative; border-radius:16px; padding:20px 22px 22px; overflow:hidden;
  background:linear-gradient(180deg, var(--panel), var(--panel-2));
  border:1px solid var(--line); box-shadow:0 30px 70px -38px rgba(0,0,0,.85), inset 0 1px 0 rgba(255,255,255,.04);
}
.panel .watermark {
  position:absolute; right:20px; top:-14px; font-family:'Noto Serif SC',serif; font-weight:900;
  font-size:84px; line-height:1; color:rgba(217,178,74,.05); pointer-events:none; user-select:none; z-index:0;
}
.pbody { position:relative; z-index:1; }
.hero {
  position:relative; border-radius:16px; padding:22px 24px; overflow:hidden;
  background:linear-gradient(120deg, rgba(90,20,20,.66), rgba(40,8,8,.66));
  border:1px solid var(--line); box-shadow:0 30px 70px -40px rgba(0,0,0,.85), inset 0 1px 0 rgba(255,255,255,.05);
  display:flex; align-items:center; gap:22px; flex-wrap:wrap;
}
.hero h2 { font-family:'Cinzel',serif; font-weight:700; font-size:25px; color:var(--gold-hi); margin:0 0 9px; letter-spacing:.01em; }
.ledger { display:grid; grid-template-columns:repeat(4, 1fr); gap:14px; }
@media (max-width:1320px) {
  .ledger { grid-template-columns:repeat(2, 1fr); }
}
.build { display:flex; gap:14px; align-items:stretch; }
@keyframes flow { to{ background-position:14px 0; } }
.market .price { font-family:'Cinzel',serif; font-weight:700; font-size:34px; color:var(--gold); line-height:1; }
.market .price .cur { font-size:15px; color:var(--gold-dim); font-weight:600; margin-right:3px; }
.mbar-chart {
  flex:1 1 0; min-height:60px;
  display:flex; align-items:flex-end; gap:3px;
  padding:4px 0 0;
}
.mbar-col {
  flex:1; height:100%; display:flex; flex-direction:column; justify-content:flex-end;
  position:relative; cursor:default; min-width:0;
}
.mbar-fill {
  width:100%; border-radius:3px 3px 0 0; transition:opacity .15s ease;
  min-height:4px;
}
.mbar-fill.up { background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft)); opacity:.55; }
.mbar-fill.down { background:linear-gradient(180deg, #c04030, #8a2018); opacity:.55; }
.mbar-fill.cur.up { opacity:1; box-shadow:0 0 8px rgba(240,209,120,.5); }
.mbar-fill.cur.down { opacity:1; box-shadow:0 0 8px rgba(158,36,24,.5); }
.mbar-tip {
  position:absolute; bottom:calc(100% + 5px); left:50%; transform:translateX(-50%);
  white-space:nowrap; pointer-events:none;
  font-family:'JetBrains Mono',monospace; font-weight:700; font-size:10px; color:var(--parch);
  background:rgba(20,5,5,.9); border:1px solid var(--gold-dim); border-radius:5px;
  padding:3px 6px;
  opacity:0; transition:opacity .12s ease;
  z-index:10;
}
.mbar-col:hover .mbar-fill { opacity:1; }
.mbar-col:hover .mbar-tip { opacity:1; }
.market .refresh { font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(243,231,196,.45); letter-spacing:.04em; }
.market .refresh b { color:var(--gold-soft); font-variant-numeric:tabular-nums; }
.btn {
  position:relative; overflow:hidden; font-family:'Cinzel',serif; font-weight:600; letter-spacing:.05em;
  border-radius:8px; padding:11px 20px; font-size:14px; cursor:pointer; border:1px solid transparent;
  transition:transform .12s ease, box-shadow .2s ease, filter .18s ease;
  display:inline-flex; align-items:center; justify-content:center; gap:8px; text-shadow:0 1px 1px rgba(0,0,0,.26);
}
.btn svg { width:15px; height:15px; }
.btn::before { content:""; position:absolute; inset:0; z-index:-1; border-radius:inherit; pointer-events:none;
  background:linear-gradient(180deg, rgba(255,255,255,.26), rgba(255,255,255,.05) 44%, transparent 58%); }
.btn::after { content:""; position:absolute; top:0; bottom:0; left:-70%; width:42%; z-index:-1; pointer-events:none;
  background:linear-gradient(100deg, transparent, rgba(255,255,255,.4), transparent); transform:skewX(-18deg); }
.btn:hover::after { animation:glint .8s ease; }
@keyframes glint { 0%{ left:-70%; } 100%{ left:150%; } }
.btn.sm { padding:8px 15px; font-size:12.5px; }
.btn-gold {
  color:#2a0d0a; background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  border-color:var(--gold-soft); box-shadow:0 3px 0 var(--gold-dim), 0 8px 18px -6px rgba(217,178,74,.5), inset 0 1px 0 rgba(255,255,255,.4);
}
.btn-gold:hover { filter:brightness(1.05); }
.btn-gold:active { transform:translateY(3px); box-shadow:0 0 0 var(--gold-dim), inset 0 1px 0 rgba(255,255,255,.3); }
.btn-plaque {
  position:relative; overflow:hidden; border:0; border-radius:0; cursor:pointer;
  width:100%; padding:12px; display:flex; align-items:center; justify-content:center; gap:12px;
  font-family:'Cinzel',serif; font-weight:700; font-size:14px; letter-spacing:.05em;
  text-transform:uppercase; color:#3a1008;
  background:url(/assets/ui/golden-button-texture.png?v=8f41a3c587) center/100% 100% no-repeat;
  box-shadow:0 8px 18px -6px rgba(217,178,74,.5), 0 6px 16px -9px rgba(0,0,0,.65);
  transition:all .14s ease;
}
.btn-plaque svg { width:15px; height:15px; }
.btn-plaque::after { content:""; position:absolute; top:0; bottom:0; left:-70%; width:42%; pointer-events:none;
  background:linear-gradient(100deg, transparent, rgba(255,255,255,.4), transparent); transform:skewX(-18deg); }
.btn-plaque:hover { filter:brightness(1.07); }
.btn-plaque:hover::after { animation:glint .8s ease; }
.btn-plaque:active { transform:translateY(1px); }
.btn-plaque:disabled { filter:grayscale(.7) brightness(.6); color:rgba(58,16,8,.55); box-shadow:none; cursor:not-allowed; }
.btn-plaque:disabled:hover { filter:grayscale(.7) brightness(.6); }
.btn-plaque:disabled::after { display:none; }
.btn-plaque.ruby {
  background-image:url(/assets/ui/button-ruby.png?v=8f41a3c587); color:#3f0a08;
  box-shadow:0 8px 18px -6px rgba(198,62,48,.5), 0 6px 16px -9px rgba(0,0,0,.65);
}
.btn-plaque.emerald {
  background-image:url(/assets/ui/button-emerald.png?v=8f41a3c587); color:#0c2f20;
  box-shadow:0 8px 18px -6px rgba(63,174,134,.5), 0 6px 16px -9px rgba(0,0,0,.65);
}
.btn-plaque.ruby:disabled,
.btn-plaque.emerald:disabled { box-shadow:none; color:rgba(20,10,8,.55); }
.btn-ghost { color:rgba(243,231,196,.7); background:rgba(0,0,0,.24); border-color:var(--line); box-shadow:inset 0 1px 0 rgba(255,255,255,.03); }
.btn-ghost::before,
.btn-ghost::after { display:none; }
.btn-ghost:hover { color:var(--gold-hi); border-color:var(--gold-soft); }
.btn-danger { color:rgba(238,180,168,.9); background:rgba(158,36,24,.14); border-color:rgba(158,36,24,.5); box-shadow:inset 0 1px 0 rgba(255,255,255,.03); }
.btn-danger::before,
.btn-danger::after { display:none; }
.btn-danger:hover { color:#ffd8cf; background:rgba(158,36,24,.26); border-color:rgba(190,52,38,.75); }
.btn-danger:active { transform:translateY(1px); }
.gold-frame {
  --gf-bw:18px; --gf-r:28px; --gf-band:39px;
  isolation:isolate;   /* own stacking context so the frame art stays behind content */
  border-style:solid; border-width:var(--gf-bw); border-radius:var(--gf-r);
  border-image:url(/assets/ui/broder-tileset-gold.png?v=8f41a3c587) 170 / var(--gf-band) round;
  background:
    linear-gradient(180deg, rgba(20,15,9,.22), rgba(8,6,3,.42)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat,
    linear-gradient(180deg,#241a10 0%, #19130c 52%, #120d08 100%);
  box-shadow:0 14px 34px rgba(0,0,0,.6);
}
.gold-frame.sm { --gf-bw:9px; --gf-r:14px; --gf-band:20px; }
.gold-frame::before { content:none; }
.wall-donate-btn { width:100%; margin-top:16px; }
.wd-slider::-webkit-slider-thumb {
  background:radial-gradient(120% 110% at 50% 28%, var(--gold-hi), var(--gold-soft)) !important;
  border-color:var(--gold-dim) !important;
}
.wd-slider::-moz-range-thumb {
  background:radial-gradient(120% 110% at 50% 28%, var(--gold-hi), var(--gold-soft)) !important;
  border-color:var(--gold-dim) !important;
}
.wall-ledger .cl-amt { color:var(--gold-hi); }
.toast {
  position:fixed; left:50%; bottom:34px; transform:translateX(-50%) translateY(20px); z-index:40;
  display:flex; align-items:center; gap:10px; padding:12px 20px; border-radius:10px;
  font-family:'Cinzel',serif; font-weight:600; font-size:13.5px; color:var(--parch);
  background:linear-gradient(180deg, rgba(40,64,52,.97), rgba(26,44,36,.97)); border:1px solid rgba(63,174,134,.5);
  box-shadow:0 18px 40px -12px rgba(0,0,0,.7); opacity:0; pointer-events:none; transition:opacity .25s ease, transform .25s ease;
}
.toast svg { width:18px; height:18px; color:var(--jade-1); flex:none; }
.toast.gold { background:linear-gradient(180deg, rgba(72,56,26,.97), rgba(48,36,16,.97)); border-color:var(--gold-soft); }
.toast.gold svg { color:var(--gold-hi); }
.toast.show { opacity:1; transform:translateX(-50%) translateY(0); }
.terr-map {
  position:relative; border-radius:16px; padding:18px 20px 22px; overflow:hidden;
  background:linear-gradient(180deg, var(--panel), var(--panel-2));
  border:1px solid var(--line); box-shadow:0 30px 70px -38px rgba(0,0,0,.85), inset 0 1px 0 rgba(255,255,255,.04);
}
.layout.layout-single { grid-template-columns:1fr; }
.layout-single:has(.world-map) { display:flex; flex-direction:column; align-items:stretch; height:100%; min-height:0; max-width:none; width:100%; margin:0; padding:0; }
.layout-single:has(.world-map) > .col { flex:1 1 auto; min-width:0; min-height:0; gap:0; }
.terr-map.world-map { padding:0; border:0; border-radius:0; background:none; box-shadow:none; }
.world-map { flex:1 1 auto; min-width:0; min-height:0; display:flex; flex-direction:column; position:relative; }
.world-map .world-canvas-wrap {
  position:relative; flex:1 1 auto; min-height:0;
  border:0; border-radius:0; overflow:hidden;
  background:#7E783C;
  isolation:isolate;   /* scope the fog layer's screen blend to the map */
}
/* Ambient night fog — a few pale blue/lavender wisps that slowly drift and flicker
   over the map at night, on top of the canvas's blue night wash. Opacity is driven
   from JS (worldDraw) by the day/night phase; the drift + flicker run purely in CSS,
   so nothing is redrawn on the canvas. Sits above the canvas but below the
   vignette (::after) and the HUD/banner, so the UI stays crisp. screen blend makes
   the wisps read as faint moonlit haze rather than extra darkening. */
/* Night fog — three drifting wisps. Each wisp is its own child element moved
   with transform + faded with opacity ONLY (compositor-friendly): the old
   single-layer version animated background-position AND filter:brightness,
   which forced a full-viewport repaint every frame all night long. The wisps
   are oversized (inset:-40%) so their soft gradients never show an edge while
   drifting; the container clips them and carries the screen blend + the
   JS-driven master opacity (worldDraw fades it with the night). */
.world-map .world-fog {
  position:absolute; inset:0; pointer-events:none; z-index:1;
  display:none; opacity:0;
  mix-blend-mode:screen;
  overflow:hidden;
}
.world-map .world-fog i {
  position:absolute; inset:-40%;
  background-repeat:no-repeat; background-size:100% 100%;
  will-change:transform, opacity;
}
.world-map .world-fog i:nth-child(1) {
  background-image:radial-gradient(38% 26% at 34% 38%, rgba(140,150,235,.13), transparent 62%);
  animation:world-fog-drift-a 32s ease-in-out infinite alternate,
            world-fog-flicker 7s ease-in-out infinite;
}
.world-map .world-fog i:nth-child(2) {
  background-image:radial-gradient(33% 24% at 66% 56%, rgba(178,140,228,.12), transparent 62%);
  animation:world-fog-drift-b 32s ease-in-out infinite alternate,
            world-fog-flicker 7s ease-in-out infinite -2.4s;
}
.world-map .world-fog i:nth-child(3) {
  background-image:radial-gradient(41% 30% at 50% 74%, rgba(120,140,225,.13), transparent 58%);
  animation:world-fog-drift-c 32s ease-in-out infinite alternate,
            world-fog-flicker 7s ease-in-out infinite -4.7s;
}
@keyframes world-fog-drift-a {
  0%   { transform:translate3d(-3.5%, -2.2%, 0) scale(1.04); }
  100% { transform:translate3d( 3.5%,  2.2%, 0) scale(1.08); }
}
@keyframes world-fog-drift-b {
  0%   { transform:translate3d( 3.2%,  2.8%, 0) scale(1.05); }
  100% { transform:translate3d(-3.2%, -2.4%, 0) scale(1.09); }
}
@keyframes world-fog-drift-c {
  0%   { transform:translate3d(-1.4%,  2.4%, 0) scale(1.04); }
  100% { transform:translate3d( 1.6%, -2.6%, 0) scale(1.07); }
}
/* The "flicker": an uneven breathing so the haze feels alive/eerie rather than
   a smooth sine pulse — the old brightness curve, remapped onto opacity. */
@keyframes world-fog-flicker {
  0%   { opacity:.62; }
  18%  { opacity:.89; }
  30%  { opacity:.72; }
  47%  { opacity:1; }
  61%  { opacity:.77; }
  78%  { opacity:.92; }
  100% { opacity:.62; }
}
/* Passing cloud — a CLUSTER of overlapping soft puffs (denser where they overlap →
   a solid cloud body with wispy edges) that drifts horizontally across the view,
   exits the right side, then stays off-screen for the rest of the loop (clear sky)
   before the next pass. The element spans the full map width and is moved by % with
   translateX, so the cluster crosses the whole view on any screen size; the puff
   cluster is authored around centre-x. The loop wraps while it's fully off-screen,
   so there's no visible pop. Puff widths are a smaller %-of-width than their %-of-
   height to offset the map's landscape aspect, so they render roughly round. Pure
   CSS, day and night, clipped by the wrap's overflow. Above the canvas, below the
   vignette + HUD. NOTE: 40s is still a TEST cadence — raise it later. */
.world-map .world-clouds {
  position:absolute; inset:0; pointer-events:none; z-index:1;
  background-repeat:no-repeat;
  /* The blur(7px) that used to soften the cluster is BAKED into the gradients
     (lower peaks, feathered mid stop, long transparent tail): a live filter on
     a full-viewport layer kept the GPU re-filtering it for the whole 40s pass. */
  background-image:
    radial-gradient(12% 33% at 50% 52%, rgba(246,249,255,.44), rgba(246,249,255,.19) 46%, transparent 86%),  /* body */
    radial-gradient(9.5% 27% at 57% 53%, rgba(246,249,255,.40), rgba(246,249,255,.17) 46%, transparent 87%), /* right lobe */
    radial-gradient(9% 25% at 43% 54%, rgba(246,249,255,.40), rgba(246,249,255,.17) 46%, transparent 87%),   /* left lobe */
    radial-gradient(8% 23% at 50% 44%, rgba(250,252,255,.38), rgba(250,252,255,.16) 46%, transparent 87%),   /* top lump */
    radial-gradient(6.5% 19% at 55% 47%, rgba(250,252,255,.34), rgba(250,252,255,.14) 46%, transparent 88%), /* top-right lump */
    radial-gradient(6.5% 19% at 45% 47%, rgba(250,252,255,.34), rgba(250,252,255,.14) 46%, transparent 88%), /* top-left lump */
    radial-gradient(7% 19% at 62% 55%, rgba(244,248,255,.30), rgba(244,248,255,.12) 46%, transparent 88%),   /* right wisp */
    radial-gradient(7% 19% at 38% 55%, rgba(244,248,255,.30), rgba(244,248,255,.12) 46%, transparent 88%);   /* left wisp */
  transform:translateX(-105%);   /* parked off the left until the animation runs */
  animation:world-clouds-pass 40s linear infinite;
  will-change:transform;
}
@keyframes world-clouds-pass {
  0%   { transform:translateX(-105%); }   /* cluster off the left */
  45%  { transform:translateX(105%);  }   /* crossed to off the right */
  100% { transform:translateX(105%);  }   /* parked off-right = clear sky, then wraps */
}
.world-map .world-canvas-wrap::after {
  content:""; position:absolute; inset:0; pointer-events:none; z-index:2;
  background:
    radial-gradient(80% 60% at 50% 50%, transparent 42%, rgba(14,16,8,.5) 90%, rgba(10,11,6,.82) 100%),
    radial-gradient(42% 120% at 0% 50%, rgba(18,20,10,.85) 0%, transparent 44%),
    radial-gradient(42% 120% at 100% 50%, rgba(18,20,10,.85) 0%, transparent 44%),
    radial-gradient(70% 50% at 50% 0%, rgba(12,13,7,.62) 0%, transparent 46%),
    radial-gradient(80% 50% at 50% 100%, rgba(12,13,7,.7) 0%, transparent 52%);
  box-shadow:inset 0 0 160px 40px rgba(0,0,0,.5);
}
#worldCanvas { display:block; width:100%; touch-action:none; user-select:none; cursor:grab; }
/* Frame-cost meter (top-left) — reads the render engine's counters. */
.world-perf {
  position:absolute; top:14px; left:14px; z-index:5; pointer-events:none;
  font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.02em;
  color:#cfe3b8; background:rgba(10,14,8,.72); border:1px solid rgba(214,222,170,.18);
  border-radius:8px; padding:4px 9px;
  text-shadow:0 1px 2px rgba(0,0,0,.8);
}
.world-banner {
  display:flex; align-items:center; gap:9px; padding:11px 14px; border-radius:10px;
  border:1px solid rgba(150,235,185,.4); background:rgba(110,200,150,.12);
  font-family:'JetBrains Mono',monospace; font-size:12px; color:#bff0d2; letter-spacing:.01em;
}
.world-map .world-banner {
  position:absolute; top:14px; left:50%; transform:translateX(-50%); z-index:4;
  margin:0; max-width:calc(100% - 28px); box-shadow:0 10px 28px -14px rgba(0,0,0,.9);
  background:rgba(16,28,20,.92); backdrop-filter:blur(3px);
}
.world-banner b { color:#daffe9; }
.world-banner svg { width:16px; height:16px; flex:none; }
/* Strategic Plan queue-select mode — the floating confirm bar. Sits above the
   hero HUD so the picking flow reads as a temporary command layer. */
.world-planbar {
  position:absolute; left:50%; top:14px; transform:translateX(-50%); z-index:5;
  display:flex; align-items:center; gap:14px; max-width:calc(100% - 28px);
  padding:10px 16px; border-radius:12px;
  border:1px solid rgba(217,178,74,.55); background:rgba(24,17,7,.94);
  box-shadow:0 10px 28px -14px rgba(0,0,0,.9), 0 0 18px rgba(217,178,74,.18);
  backdrop-filter:blur(3px);
}
/* The `display:flex` above beats the UA `[hidden]{display:none}` — restore it so
   the bar honours its `hidden` attribute (only shown in Strategic Plan mode). */
.world-planbar[hidden] { display:none; }
.world-planbar .wpb-count { font-family:'Cinzel',serif; font-weight:700; font-size:12px; letter-spacing:.08em; color:var(--gold-soft); }
.world-planbar .wpb-eta { font-family:'JetBrains Mono',monospace; font-size:12px; color:rgba(243,231,196,.8); }
.world-hud {
  position:absolute; left:50%; bottom:24px; transform:translateX(-50%); z-index:3;
  display:flex; align-items:center; gap:20px; max-width:calc(100% - 24px);
  padding:14px 36px; min-height:128px;
  backdrop-filter:blur(4px);
  pointer-events:auto;   /* scoped to the bar; the canvas around it stays draggable */
}
.world-hud-empty { font-family:'JetBrains Mono',monospace; font-size:13px; color:var(--gold-soft); }
.world-hud-empty span { display:inline-flex; align-items:center; gap:8px; }
.world-hud-empty svg { width:18px; height:18px; }
/* Mini-portrait hero-switch roster — SHARED by the world HUD and the hero
   dossier: the OTHER seated governors stacked left of the active hero in
   columns of two, level badges centred on the bottom rim; clicking one makes
   that hero active / opens its dossier. */
.hroster {
  display:flex; flex-direction:column; flex-wrap:wrap;
  justify-content:center; align-content:center;
  gap:16px 10px; max-height:104px; flex:none;
}
.world-hud-mini {
  position:relative; width:44px; height:44px; padding:0; flex:none;
  border:none; background:transparent; cursor:pointer; border-radius:50%;
}
.world-hud-mini img {
  display:block; width:100%; height:100%; border-radius:50%;
  object-fit:cover; object-position:50% 12%;
  border:2px solid var(--gold-soft); box-shadow:0 0 0 1px #000, 0 3px 6px rgba(0,0,0,.5);
  filter:saturate(.7) brightness(.8); transition:filter .15s, transform .15s, border-color .15s;
}
.world-hud-mini:hover img { filter:none; transform:scale(1.08); border-color:var(--gold-hi); }
.world-hud-mini-lvl {
  position:absolute; left:50%; bottom:-6px; transform:translateX(-50%); min-width:16px; height:16px; padding:0 3px;
  display:grid; place-items:center; border-radius:8px; font-family:'Cinzel',serif; font-weight:700;
  font-size:10px; color:#2a0d0a; background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  border:1px solid #3d0b0b; box-shadow:0 1px 2px rgba(0,0,0,.55); pointer-events:none;
}
.world-hud-id { display:flex; align-items:center; gap:15px; }
/* The big portrait is the shared .hport ring (defined with the dossier styles). */
.world-hud-id .hport { --hp:84px; --hpb:28px; }
/* Fixed width so cycling heroes (short "+30% marcha" vs a long combat-buff label, or a
   longer/shorter name) never grows or shrinks the centred bar. */
.world-hud-meta { display:flex; flex-direction:column; gap:3px; flex:none; width:172px; }
.world-hud-meta > * { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.world-hud-name { font-family:'Cinzel',serif; font-weight:700; font-size:18px; letter-spacing:.05em; color:var(--gold-hi); line-height:1.1; text-shadow:0 1px 4px #000; }
.world-hud-speed { font-family:'JetBrains Mono',monospace; font-size:12px; color:var(--parch-dim, rgba(243,231,196,.6)); }
.world-hud-status { font-family:'JetBrains Mono',monospace; font-size:12px; }
.world-hud-status.marching { color:#ffd98a; }
.world-hud-status.home { color:rgba(191,238,218,.9); }
.world-hud-status.idle { color:rgba(240,209,120,.5); }
/* Cancel-current-action button (generic — label comes from the action registry). */
.world-hud-cancel {
  align-self:flex-start; margin-top:2px; padding:3px 9px; cursor:pointer;
  font-family:'JetBrains Mono',monospace; font-size:11px; color:#e8b4a8;
  background:rgba(90,26,18,.35); border:1px solid rgba(170,70,50,.5); border-radius:6px;
  transition:background .15s, border-color .15s;
}
.world-hud-cancel:hover:not(:disabled) { background:rgba(120,32,22,.55); border-color:rgba(210,90,64,.7); }
.world-hud-cancel:disabled { opacity:.5; cursor:default; }
.world-hud-troops { flex:none; position:relative; padding-left:22px; }
.world-hud-troops::before {
  content:""; position:absolute; left:0; top:8px; bottom:8px; width:1px;
  background:linear-gradient(180deg,transparent,rgba(199,152,68,.45),transparent);
}
.world-hud-noarmy { font-family:'JetBrains Mono',monospace; font-size:13px; color:rgba(240,209,120,.5); padding:0 6px; }
.world-hud .army-stack { gap:6px; }
.world-hud .slot-row.army-grid { grid-template-columns:repeat(3, 56px); grid-auto-rows:56px; gap:8px; }
.world-hud .tslot { width:56px; height:56px; border-radius:7px; }
.world-hud .tslot-art { border-radius:5px; }
.world-hud .tslot-n { font-size:13px; left:4px; right:auto; bottom:2px; }
.world-hud .tslot-line { display:none; }
.world-hud .army-stack { --tsz:56px; --tgap:8px; --msz:20px; }
.world-hud .row-medal svg { width:11px; height:11px; }
.world-popup {
  position:fixed; z-index:150; width:min(392px, calc(100vw - 12px));
  max-height:min(72vh, calc(100vh - 24px)); overflow-y:auto; overflow-x:hidden;
  padding:15px 17px 16px;
  box-shadow:0 24px 60px -18px rgba(0,0,0,.95);
  animation:modalFade .14s ease; scrollbar-width:thin;
}
.world-popup::-webkit-scrollbar { width:8px; }
.world-popup::-webkit-scrollbar-thumb { background:rgba(217,178,74,.32); border-radius:5px; }
.world-popup::-webkit-scrollbar-track { background:rgba(0,0,0,.25); }
.world-popup .whc-title { padding:0 22px; }
.world-popup .modal-close {
  top:3px; right:3px; width:30px; height:30px; z-index:5;
  border:none; border-radius:50%; background:transparent;
  color:var(--gold-soft); font-size:18px; font-weight:700;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.9));
  transition:color .14s ease, filter .14s ease, transform .14s ease;
}
.world-popup .modal-close:hover {
  color:#ffe9a8; border:none; background:transparent;
  filter:drop-shadow(0 0 7px rgba(240,209,120,.7)); transform:scale(1.12);
}
.world-popup .modal-stats {
  justify-content:center; gap:7px; margin-bottom:13px; padding-bottom:0; border-bottom:none;
}
.world-popup .modal-stats > span {
  display:inline-flex; align-items:center; gap:6px; padding:5px 11px; border-radius:8px;
  background:rgba(0,0,0,.3); border:1px solid var(--line-soft);
  font-family:'JetBrains Mono',monospace; font-weight:700; font-size:11px; color:var(--parch);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}
.world-popup .modal-note { text-align:center; color:rgba(243,231,196,.66); }
.world-popup .modal-err { text-align:center; }
.world-popup-actions { display:flex; flex-direction:column; gap:9px; margin-top:14px; }
.world-popup-actions .v2btn,
.world-popup-actions .btn { width:100%; justify-content:center; }
/* ── Action wheel (map objectives) ─────────────────────────────────────────
   Radial DONUT around the clicked hex: an SVG ring of wedge segments (one per
   action, coloured by its tint) around a hub medallion naming the objective.
   Uniform constant-width gaps; an icon (+ count) sits at each wedge's mid-radius;
   hovering a wedge washes it and lights an outer arc in the action's colour.
   OPENING: the wheel GROWS OUT OF THE HEX CENTRE — a pure radial expansion from
   near-zero (no spin), easing into a soft overshoot as it reaches full size —
   and every icon pops in TOGETHER as the ring expands (a per-icon stagger read
   as inconsistent timing, not a wave). Icons animate via KEYFRAMES, not
   transitions, so the entrance never delays the hover effects. The container is
   0×0 at the wheel's centre, so the transform expands from the hex itself. */
.awheel { position:fixed; z-index:150; width:0; height:0; --awh-glow:rgba(217,178,74,.32);
  opacity:0; transform:scale(.08);
  transition:opacity .12s ease, transform .32s cubic-bezier(.24,1.25,.3,1); }
.awheel.on { opacity:1; transform:scale(1); }
.awheel.on .awheel-ic { animation:awIcPop .3s cubic-bezier(.2,1.6,.4,1); }
@keyframes awIcPop { from { opacity:0; transform:translate(-50%,-50%) scale(.3); } }
@media (prefers-reduced-motion: reduce) {
  .awheel { transform:none; transition:opacity .1s ease; }
  .awheel.on .awheel-ic { animation:none; }
}
.awheel.f-enemy  { --awh-glow:rgba(224,86,60,.5); }
.awheel.f-player { --awh-glow:rgba(111,174,111,.5); }
.awheel.f-ally   { --awh-glow:rgba(79,143,208,.5); }
.awheel.f-hub    { --awh-glow:rgba(240,209,120,.5); }
/* The donut ring (SVG): wedges, hover-arcs and the inner/outer rims. The donut's
   own dark wedges are the backdrop — there's no separate veil/halo behind it. */
.awheel-donut { position:absolute; left:0; top:0; transform:translate(-50%,-50%); overflow:visible; }
.awheel-seg { fill:#17100a; cursor:pointer; transition:fill .15s ease; }
.awheel-seg.on { fill:color-mix(in srgb, var(--sc) 22%, #17100a); }
.awheel-seg.off { cursor:default; }
.awheel-arc { fill:none; stroke:var(--sc); stroke-width:3.4; opacity:0; stroke-linecap:round;
  pointer-events:none; transition:opacity .15s ease; filter:drop-shadow(0 0 5px var(--sc)); }
.awheel-arc.on { opacity:.92; }
.awheel-rim { fill:none; stroke:rgba(217,178,74,.26); stroke-width:1.3; pointer-events:none; }
/* Icon (+ count) over each wedge — tinted by the action's colour (--sc). */
.awheel-ic { position:absolute; transform:translate(-50%,-50%); pointer-events:none;
  display:flex; flex-direction:column; align-items:center; gap:1px; color:var(--sc);
  transition:color .15s ease, transform .15s ease; }
.awheel-ic svg { width:25px; height:25px; display:block; }
/* Image-based spoke icons (e.g. the scout horse-head) — sized like the svg glyphs. */
.awheel-ic .aw-ic-img { width:27px; height:27px; display:block; object-fit:contain; filter:drop-shadow(0 1px 1px rgba(0,0,0,.6)); }
.awheel-ic.off .aw-ic-img { opacity:.55; filter:grayscale(.5) drop-shadow(0 1px 1px rgba(0,0,0,.6)); }
.awheel-ic.on { color:color-mix(in srgb, var(--sc) 42%, #fff);
  transform:translate(-50%,-50%) scale(1.13); filter:drop-shadow(0 0 6px var(--sc)); }
.awheel-ic.off { color:#8a8069; opacity:.5; }
.awheel-ic.off.on { opacity:.68; }
.awheel-sub {
  font-family:'JetBrains Mono',monospace; font-size:9.5px; font-weight:700; line-height:1;
  color:var(--parch); font-variant-numeric:tabular-nums; text-shadow:0 1px 2px rgba(0,0,0,.85);
}
/* Async pick in flight: dim the rest, pulse the chosen wedge. */
.awheel.busy .awheel-seg { pointer-events:none; }
.awheel.busy .awheel-seg:not(.picked) { opacity:.5; }
.awheel.busy .awheel-ic:not(.on) { opacity:.45; }
.awheel-seg.picked { animation:awPulse 1.1s ease-in-out infinite; }
@keyframes awPulse {
  0%,100% { fill:color-mix(in srgb, var(--sc) 18%, #17100a); }
  50%     { fill:color-mix(in srgb, var(--sc) 42%, #17100a); }
}
/* Centre hub: the objective medallion filling the donut hole; the faction glow
   (--awh-glow) blooms off its gold frame. */
.awheel-hub {
  position:absolute; left:0; top:0; box-sizing:border-box; width:132px; height:132px; margin:-66px 0 0 -66px;
  border-radius:50%; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:2px; padding:13px; text-align:center; pointer-events:none; border:2px solid transparent;
  background:radial-gradient(circle at 50% 30%, #241c12, #120e09 76%) padding-box, var(--slot-frame) border-box;
  box-shadow:var(--slot-outline), 0 0 26px -5px var(--awh-glow), inset 0 2px 10px rgba(0,0,0,.5);
}
.awheel-hub-lb {
  font-family:'Cinzel',serif; font-weight:700; font-size:12px; line-height:1.25;
  color:var(--parch); letter-spacing:.03em; max-height:3.6em; overflow:hidden;
}
.awheel-hub-lb.err { color:#e0563c; }
/* Hub portrait fills: a portrait covers the disc, a building icon is contained
   whole, the label centred over it on a scrim + text-halo. */
.awheel-hub.has-portrait { justify-content:center; padding:11px 13px; }
.awheel-hub.has-portrait .awheel-hub-lb {
  position:relative; z-index:1;
  text-shadow:0 0 6px rgba(0,0,0,.95), 0 1px 3px rgba(0,0,0,.95), 0 0 13px rgba(0,0,0,.72);
}
.awheel-hub.fill-cover {
  background:
    radial-gradient(ellipse 88% 44% at 50% 50%, rgba(9,6,4,.44) 0%, rgba(9,6,4,.12) 58%, transparent 82%) padding-box,
    var(--portrait) center/contain no-repeat padding-box,
    radial-gradient(circle at 50% 30%, #241c12, #120e09 76%) padding-box,
    var(--slot-frame) border-box;
}
.awheel-hub.fill-contain {
  background:
    radial-gradient(ellipse 84% 48% at 50% 50%, rgba(9,6,4,.6) 0%, rgba(9,6,4,.14) 58%, transparent 80%) padding-box,
    var(--portrait) center/74% no-repeat padding-box,
    radial-gradient(circle at 50% 40%, #2b2216, #120e09 80%) padding-box,
    var(--slot-frame) border-box;
}
/* ── Taverna (hero roster + placement) ── */
.tavern-view { overflow:auto; }
/* Togglable hero PROFILE cards — the whole realm's roster, styled after the Exército
   recruitment cards (.rcard). Also reused, compact, by the founding picker. */
.tv-heroes { display:flex; gap:15px; flex-wrap:wrap; justify-content:center; margin:0 auto 16px; width:100%; }
.thc {
  flex:none; width:228px; position:relative; display:flex; flex-direction:column; padding:0 0 14px;
  text-align:left; cursor:pointer; color:inherit; font:inherit; -webkit-appearance:none; appearance:none;
  transition:box-shadow .16s ease, transform .16s ease, border-color .16s ease;
}
.thc:hover { transform:translateY(-2px); }
/* Selected card (roster + founding picker) — gold ring highlight. */
.thc.sel { box-shadow:0 0 0 2px var(--gold-soft), 0 8px 22px rgba(0,0,0,.5); }
.thc.sel:hover { transform:none; }
/* A hero that can't be picked in the founding roster (already governing / marching). */
.thc.thc-off { filter:grayscale(.72) brightness(.66); cursor:default; }
.thc.thc-off:hover { transform:none; }
.thc-head { display:flex; align-items:center; justify-content:center; gap:6px; padding:16px 16px 12px; }
.thc-name {
  min-width:0; max-width:100%; text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  font-family:'Cinzel',serif; font-weight:700; font-size:14px; line-height:1.1; color:var(--parch);
  letter-spacing:.02em; text-transform:uppercase; text-shadow:0 1px 3px rgba(0,0,0,.6);
}
.thc-lock { flex:none; font-size:12px; }
.thc-stage {
  position:relative; aspect-ratio:1/1; height:auto; overflow:hidden; margin:0 16px; border-radius:10px;
  background:#222428 url('/assets/ui/recruitment-card-background.png?v=8f41a3c587') center/cover no-repeat;
  border-bottom:1px solid var(--line);
}
.thc-stage::before {
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:url('/assets/slot-texture.png?v=8f41a3c587') center/cover no-repeat; mix-blend-mode:multiply; opacity:.55;
}
.thc-art { position:absolute; inset:0; z-index:2; width:100%; height:100%; object-fit:cover; object-position:50% 12%; }
.thc-glyph { position:absolute; inset:0; z-index:2; display:grid; place-items:center; font-size:60px; color:rgba(243,231,196,.35); }
.thc-lvl {
  position:absolute; z-index:3; right:8px; top:8px; padding:2px 8px; border-radius:9px;
  background:rgba(20,12,6,.82); border:1px solid var(--gold-soft); color:var(--gold-soft);
  font-family:'Cinzel',serif; font-weight:700; font-size:11px; letter-spacing:.03em;
  text-shadow:0 1px 2px rgba(0,0,0,.8); font-variant-numeric:tabular-nums;
}
.thc-body { flex:1 1 auto; display:flex; flex-direction:column; gap:8px; padding:11px 16px 0; }
.thc-title { text-align:center; font-size:11.5px; letter-spacing:.03em; color:var(--gold-soft); font-style:italic; }
.thc-bonus {
  font-size:12px; line-height:1.4; color:rgba(243,231,196,.82); text-align:center;
  background:rgba(0,0,0,.24); border:1px solid var(--line-soft); border-radius:8px; padding:8px 10px;
}
.thc-loc {
  display:flex; align-items:center; justify-content:center; gap:5px; text-align:center;
  font-size:11px; letter-spacing:.02em; color:rgba(243,231,196,.62);
}
.thc-loc svg { width:13px; height:13px; opacity:.8; color:var(--gold-soft); }
.thc-foot { margin-top:auto; padding-top:10px; display:flex; justify-content:center; gap:16px; }
.thc-stat { display:inline-flex; align-items:center; gap:5px; font-size:13px; color:rgba(243,231,196,.72); font-variant-numeric:tabular-nums; }
.thc-stat svg { width:14px; height:14px; opacity:.85; color:var(--gold-soft); }
.thc-stat b { color:var(--parch); font-weight:700; }
/* ── Found (full-page founding hero chooser — tavern cards side by side) ── */
.found-banner { margin:0 auto 18px; max-width:960px; }
.found-actions { margin-top:6px; }
.found-actions .v2btn { min-width:180px; }
.tv-actions { display:flex; align-items:center; justify-content:center; gap:8px; flex-wrap:wrap; margin:0 auto 12px; max-width:960px; width:100%; }
.tv-actions:empty { margin:0; }
.tv-locked { display:inline-flex; align-items:center; gap:6px; font-size:12.5px; color:rgba(243,231,196,.6); }
.tv-locked svg { width:14px; height:14px; }
.tv-move-pick { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.tv-move-label { font-size:12.5px; color:rgba(243,231,196,.7); }
.v2btn.tv-move-dest[disabled] { opacity:.5; cursor:default; }
/* Ghost variant: secondary Cancelar/Voltar actions — the base .v2btn dark text is
   made for the gold gradient; on a transparent body it needs parchment instead. */
.v2btn.ghost { background:transparent; color:rgba(243,231,196,.85); box-shadow:none; }
.v2btn.ghost:hover { color:var(--gold-hi); }
/* Plano Estrategico variant (Batalha modal): an azure-accented secondary so the
   alternative multi-camp path reads clearly as a button (blue rim, tinted fill +
   glow, the decree seal) without stealing the solid-gold Confirmar's primacy —
   blue is the player's own faction colour on the map (your general's campaign). */
.v2btn.plan {
  color:#dfeeff; border-color:rgba(90,160,224,.85);
  background:linear-gradient(180deg, rgba(74,144,217,.32), rgba(21,53,94,.20));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 0 16px -5px rgba(90,160,224,.8);
  text-shadow:0 1px 2px rgba(0,0,0,.5);
}
.v2btn.plan svg { color:#8fbdf0; }
.v2btn.plan:hover { filter:none; color:#fff; border-color:#6aa8e6;
  background:linear-gradient(180deg, rgba(74,144,217,.48), rgba(21,53,94,.30)); }
.v2btn.plan:active { box-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 0 10px -5px rgba(90,160,224,.65); }
/* Confirmar variant (Batalha modal): the same outlined-glow treatment as .plan,
   in jade — the primary "march" action. Dims cleanly when disabled (no legal
   attack), unlike .plan which is simply hidden then. */
.v2btn.go {
  color:#dbf6e6; border-color:rgba(63,174,134,.85);
  background:linear-gradient(180deg, rgba(63,174,134,.32), rgba(29,87,66,.22));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 0 16px -5px rgba(63,174,134,.8);
  text-shadow:0 1px 2px rgba(0,0,0,.5);
}
.v2btn.go svg { color:#7fd8b0; }
.v2btn.go:hover { filter:none; color:#fff; border-color:#5fc79b;
  background:linear-gradient(180deg, rgba(63,174,134,.48), rgba(29,87,66,.32)); }
.v2btn.go:active { box-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 0 10px -5px rgba(63,174,134,.65); }
.v2btn.go:disabled, .v2btn.go:disabled:hover {
  cursor:not-allowed; filter:none; color:rgba(219,246,230,.4); text-shadow:none;
  border-color:rgba(63,174,134,.28); box-shadow:none;
  background:linear-gradient(180deg, rgba(63,174,134,.1), rgba(29,87,66,.06));
}
.tv-moves { display:flex; flex-direction:column; gap:6px; margin:6px 0 12px; }
.tv-move-row {
  display:flex; align-items:center; gap:10px; padding:7px 11px; border-radius:9px;
  background:rgba(243,231,196,.05); border:1px solid rgba(243,231,196,.12);
}
.tv-move-av { flex:none; width:30px; height:30px; border-radius:50%; object-fit:cover; border:1px solid rgba(243,231,196,.2); }
.tv-move-txt { flex:1; min-width:0; font-size:13px; }
.tv-move-eta { font-size:12px; color:var(--gold-soft); font-variant-numeric:tabular-nums; white-space:nowrap; }
.card-tk {
  flex:none; width:34px; height:34px; border-radius:50%;
  border:2px solid transparent; object-fit:cover; object-position:50% 25%;
  background:
    linear-gradient(180deg, #34200f, #171009) padding-box,
    linear-gradient(150deg, var(--gold-hi) 0%, #6e4a17 62%, var(--gold-soft) 100%) border-box;
  box-shadow:0 3px 8px rgba(0,0,0,.55);
}
.card-tk.pad { object-fit:contain; padding:4px; }
.card-tk.glyph { display:inline-grid; place-items:center; font-size:16px; line-height:1; }
.card-tk.glyph svg { width:15px; height:15px; color:var(--gold-hi); }
@media (max-width:820px) {
  .world-hud { gap:12px; padding:10px 24px; min-height:0; bottom:10px; }
  .world-hud-id .hport { --hp:58px; --hpb:22px; }
  .world-hud-meta { min-width:92px; }
  .world-hud-name { font-size:17px; }
  .world-hud-troops { padding-left:14px; }
  .world-hud-mini { width:34px; height:34px; }
  .world-hud .hroster { gap:12px 8px; max-height:80px; }
  .world-hud .slot-row.army-grid { grid-template-columns:repeat(3, 34px); grid-auto-rows:34px; gap:4px; }
  .world-hud .tslot { width:34px; height:34px; }
  .world-hud .row-medal { display:none; }
  .world-hud .tslot-n { font-size:11px; }
  .world-popup { width:calc(100vw - 12px); --gf-bw:9px; --gf-r:14px; --gf-band:20px; }
}
.world-popup.whc-enemy {  box-shadow:0 22px 52px -18px rgba(0,0,0,.95), 0 0 30px -6px rgba(224,86,60,.55); }
.world-popup.whc-player { box-shadow:0 22px 52px -18px rgba(0,0,0,.95), 0 0 30px -6px rgba(111,174,111,.55); }
.world-popup.whc-ally {   box-shadow:0 22px 52px -18px rgba(0,0,0,.95), 0 0 30px -6px rgba(79,143,208,.55); }
.world-popup.whc-hub {    box-shadow:0 22px 52px -18px rgba(0,0,0,.95), 0 0 30px -6px rgba(240,209,120,.55); }
.whc-head { position:relative; margin-bottom:10px; padding-bottom:10px; }
.whc-head::after {
  content:""; position:absolute; left:12%; right:12%; bottom:0; height:1px;
  background:linear-gradient(90deg, transparent, var(--gold-soft), transparent); opacity:.8;
}
.whc-enemy .whc-head::after {  background:linear-gradient(90deg, transparent, #e0563c, transparent); }
.whc-player .whc-head::after { background:linear-gradient(90deg, transparent, #6fae6f, transparent); }
.whc-ally .whc-head::after {   background:linear-gradient(90deg, transparent, #4f8fd0, transparent); }
.whc-hub .whc-head::after {    background:linear-gradient(90deg, transparent, var(--gold-hi), transparent); }
.whc-title {
  margin:0; font-family:'Cinzel',serif; font-weight:700; font-size:15px; line-height:1.25;
  color:var(--parch); text-shadow:0 1px 3px rgba(0,0,0,.75);
  display:flex; align-items:center; justify-content:center; text-align:center; gap:8px;
}
/* Enemy camp cards stack the portrait token ABOVE the name (below the difficulty
   gauge) instead of inline beside it. */
.whc-enemy .whc-title { flex-direction:column; gap:7px; }
.whc-enemy .whc-title .card-tk { width:42px; height:42px; }
.whc-title svg { width:16px; height:16px; color:var(--gold-soft); flex:none; filter:drop-shadow(0 1px 1px rgba(0,0,0,.6)); }
.whc-sub {
  margin:-4px 0 10px; text-align:center; font-family:'JetBrains Mono',monospace;
  font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:rgba(243,231,196,.55);
}
.whc-note-c { margin:10px 0 0; text-align:center; font-size:12px; line-height:1.5; color:rgba(243,231,196,.62); }
.whc-stats { display:flex; flex-wrap:wrap; justify-content:center; gap:6px; }
.whc-stats span {
  display:inline-flex; align-items:center; gap:6px; padding:4px 10px; border-radius:8px;
  background:rgba(0,0,0,.3); border:1px solid var(--line-soft);
  font-family:'JetBrains Mono',monospace; font-weight:700; font-size:10.5px; color:var(--parch);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}
.whc-stats svg { width:12px; height:12px; color:var(--gold-soft); }
.whc-loot { display:flex; flex-wrap:wrap; justify-content:center; gap:10px; margin:2px 0 4px; }
.whc-loot span {
  display:inline-flex; align-items:center; gap:9px; padding:9px 18px; border-radius:11px;
  background:rgba(0,0,0,.3); border:1px solid var(--line-soft);
  font-family:'JetBrains Mono',monospace; font-weight:700; font-size:15px; color:var(--parch);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}
.whc-loot b { font-weight:700; color:var(--gold-hi); }
.whc-loot svg { width:18px; height:18px; color:var(--gold-soft); }
/* Scouted-camp difficulty gauge: always 4 skulls (filled up to the tier, band-
   colored; the rest grayed) stacked over a label. Sits at the top of the card
   header, above the camp name. */
.whc-diff {
  display:flex; flex-direction:column; align-items:center; gap:5px; margin:0 0 9px;
}
.whc-skulls { display:inline-flex; gap:6px; }
.whc-skull { width:24px; height:24px; color:#54545f; }        /* empty = grayed */
.whc-skull-svg { width:100%; height:100%; display:block; filter:drop-shadow(0 1px 1px rgba(0,0,0,.55)); }
.whc-diff-lbl {
  font-family:'Cinzel',serif; font-weight:700; font-size:14px; letter-spacing:.04em;
}
/* Filled-skull + label color per band: white → green → yellow → red. */
.whc-diff.diff-easy   .whc-skull.on, .whc-diff.diff-easy   .whc-diff-lbl { color:#eef0ea; }
.whc-diff.diff-normal .whc-skull.on, .whc-diff.diff-normal .whc-diff-lbl { color:#79c25b; }
.whc-diff.diff-hard   .whc-skull.on, .whc-diff.diff-hard   .whc-diff-lbl { color:#e8c24a; }
.whc-diff.diff-imposs .whc-skull.on, .whc-diff.diff-imposs .whc-diff-lbl { color:#dc4b3c; }
@media (max-width:1120px) {
  .layout { grid-template-columns:1fr; }
  .sidebar { order:2; }
  .sidebar { display:grid; grid-template-columns:1fr 1fr; gap:18px; align-items:start; }
}
@media (max-width:760px) {
  .brandbar { padding:11px 16px; flex-wrap:wrap; }
  .brand .plan { display:none; }
  .layout { padding:16px 13px 30px; }
  .ledger { grid-template-columns:1fr 1fr; }
  .sidebar { grid-template-columns:1fr; }
  .hero { gap:14px; }
  .counters .ctr .cap { display:none; }
}
@media (max-width:480px) {
  .ledger { grid-template-columns:1fr; }
  .merit-pill .lab { display:none; }
}
.tech-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:16px; align-items:stretch; }
@media (max-width:1100px) {
  .tech-grid { grid-template-columns:repeat(2, 1fr); }
}
@media (max-width:820px) {
  .tech-grid { grid-template-columns:1fr; }
}
.decree {
  flex:none; font-family:'Cinzel',serif; font-weight:600; font-size:12.5px; letter-spacing:.04em; cursor:pointer;
  color:#2a0d0a; border:1px solid var(--gold-soft); border-radius:8px; padding:8px 16px;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  box-shadow:0 2px 0 var(--gold-dim), inset 0 1px 0 rgba(255,255,255,.4); transition:transform .12s ease, filter .15s ease;
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
}
.decree svg { width:14px; height:14px; }
.decree:hover { filter:brightness(1.05); }
.decree:active { transform:translateY(2px); box-shadow:0 0 0 var(--gold-dim), inset 0 1px 0 rgba(255,255,255,.3); }
.v2card {
  position:relative; display:flex; flex-direction:column;
  border-radius:14px; padding:4px; border:none; overflow:visible;
  background:linear-gradient(150deg, var(--gold-hi) 0%, var(--gold-dim) 35%, #6e4a17 62%, var(--gold-soft) 100%);
  box-shadow:0 8px 28px -14px rgba(0,0,0,.85);
  transition:transform .15s ease, box-shadow .2s ease;
}
.v2card::before { display:none; }
.v2card.avail:hover { transform:translateY(-3px); box-shadow:0 24px 50px -22px rgba(0,0,0,1); }
.v2card-inner {
  border-radius:10px; overflow:hidden;
  display:flex; flex-direction:column; width:100%; height:100%;
}
.scroll-rod { display:none; }
.scroll-body {
  flex:1; display:flex; flex-direction:column; position:relative; overflow:hidden;
  background:linear-gradient(180deg,
    #c0b090 0%, #d0c0a0 6%,
    #e4d8b8 16%, #eee4cc 30%,
    #f2ead8 50%,
    #eee4cc 70%, #e4d8b8 84%,
    #d0c0a0 94%, #c0b090 100%
  );
}
.scroll-body::after {
  content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(90deg, rgba(80,40,0,.14) 0%, transparent 18%, transparent 82%, rgba(80,40,0,.14) 100%);
}
.v2wm {
  position:absolute; right:-10px; bottom:-30px; z-index:0; pointer-events:none; user-select:none;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:140px; line-height:1;
  color:rgba(100,55,5,.07);
}
.v2head { position:relative; z-index:1; display:flex; align-items:flex-start; gap:13px; padding:18px 18px 0; }
.v2seal {
  width:46px; height:46px; flex:none; border-radius:13px; display:grid; place-items:center;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:24px; color:var(--gold-hi);
  background:radial-gradient(120% 90% at 50% 28%, #7d2a1c, #4a0f0b);
  border:1px solid var(--gold-soft); box-shadow:inset 0 1px 5px rgba(0,0,0,.5), 0 0 0 3px rgba(140,28,20,.18);
}
.v2seal svg { width:20px; height:20px; color:rgba(255,220,180,.6); }
.v2titles { flex:1; min-width:0; padding-top:2px; }
.v2titles h4 { font-family:'Cinzel',serif; font-weight:700; font-size:17px; color:#3a1800; margin:0; line-height:1.24; letter-spacing:.01em; }
.v2tier { font-family:'JetBrains Mono',monospace; font-weight:700; font-size:9px; letter-spacing:.2em; text-transform:uppercase; color:rgba(100,55,5,.6); margin-top:6px; }
.v2done-seal {
  flex:none; align-self:flex-start; display:inline-flex; align-items:center; gap:5px; margin-top:2px;
  font-family:'JetBrains Mono',monospace; font-weight:700; font-size:9.5px; letter-spacing:.1em; text-transform:uppercase;
  color:#145c38; padding:5px 9px; border-radius:8px; background:rgba(30,100,65,.14); border:1px solid rgba(30,100,65,.4);
}
.v2done-seal svg { width:12px; height:12px; }
.v2foot .v2done-seal { font-size:13px; letter-spacing:.04em; padding:9px 17px; border-radius:9px; margin-left:auto; }
.v2foot .v2done-seal svg { width:15px; height:15px; }
.v2badge {
  position:relative; z-index:1; align-self:flex-start; display:inline-flex; align-items:center; gap:8px; margin:14px 18px 0;
  font-family:'JetBrains Mono',monospace; font-weight:700; font-size:12.5px; color:#5a2e00;
  padding:6px 12px 6px 8px; border-radius:10px;
  border:1px solid rgba(140,80,10,.38); background:rgba(160,100,10,.12);
}
.v2badge img { width:28px; height:28px; border-radius:6px; object-fit:cover; box-shadow:0 1px 4px rgba(0,0,0,.3); }
.v2badge svg { width:22px; height:22px; color:#7a4510; }
.v2quote {
  position:relative; z-index:1; font-family:'Noto Serif',serif; font-style:italic; font-size:13px; line-height:1.55;
  color:rgba(60,28,5,.7); margin:14px 18px 0; padding-left:17px; text-wrap:pretty;
}
.v2quote::before { content:"\201C"; position:absolute; left:-3px; top:-8px; font-size:34px; color:rgba(140,90,10,.45); font-family:Georgia,serif; line-height:1; }
.v2foot {
  position:relative; z-index:1; display:flex; align-items:center; justify-content:space-between; gap:12px;
  margin:auto 18px 18px; padding-top:14px; border-top:1px solid rgba(140,90,10,.25); min-height:38px; box-sizing:content-box;
}
.v2cost { display:inline-flex; align-items:center; gap:9px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:17px; color:#5a2e00; font-variant-numeric:tabular-nums; }
.v2cost img { width:28px; height:28px; border-radius:7px; object-fit:cover; box-shadow:0 1px 4px rgba(0,0,0,.35); }
.v2cost.lack { color:#9e2418; }
.v2locknote { font-family:'Noto Serif',serif; font-style:italic; font-size:13px; color:rgba(60,28,5,.45); }
.v2btn {
  flex:none; font-family:'Cinzel',serif; font-weight:600; font-size:13px; letter-spacing:.04em; cursor:pointer;
  color:#2a0d0a; border:1px solid var(--gold-soft); border-radius:9px; padding:9px 17px;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  box-shadow:0 2px 0 var(--gold-dim), inset 0 1px 0 rgba(255,255,255,.4); transition:transform .12s ease, filter .15s ease;
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
}
.v2btn svg { width:15px; height:15px; }
.v2btn:hover { filter:brightness(1.05); }
.v2btn:active { transform:translateY(2px); box-shadow:0 0 0 var(--gold-dim), inset 0 1px 0 rgba(255,255,255,.3); }
.v2card.done {
  background:linear-gradient(150deg, var(--gold-hi) 0%, var(--gold-dim) 35%, #6e4a17 62%, var(--gold-soft) 100%);
}
.v2card.done .scroll-body::before {
  content:"\2713";
  position:absolute; top:50%; left:50%;
  transform:translate(-44%, -52%) rotate(-22deg);
  z-index:3; pointer-events:none;
  width:96px; height:96px; border-radius:50%;
  border:3.5px solid rgba(168,14,14,.5);
  box-shadow:0 0 0 2px rgba(168,14,14,.12), inset 0 0 0 5px rgba(168,14,14,.07);
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:40px; color:rgba(168,14,14,.5);
  line-height:90px; text-align:center;
  text-shadow:0 0 8px rgba(168,14,14,.18);
}
.v2card.done .v2done-seal {
  color:#8a1010; border-color:rgba(168,14,14,.38); background:rgba(168,14,14,.1);
}
.v2card.locked { opacity:.5; filter:saturate(.45); }
.layout.emp-only { grid-template-columns:1fr; }
.emp-shell { display:flex; flex-direction:column; }
.imp-tabs { display:flex; gap:2px; flex-wrap:wrap; position:relative; padding:0; }
.imp-tab {
  position:relative; display:inline-flex; align-items:center; gap:9px; cursor:pointer;
  font-family:'Cinzel',serif; font-weight:600; font-size:14.5px; letter-spacing:.01em;
  color:rgba(243,231,196,.56); padding:11px 16px; border:1px solid transparent; border-radius:10px 10px 0 0;
  background:none; transition:color .15s ease, background .15s ease;
}
.imp-tab svg { width:16px; height:16px; opacity:.78; flex:none; }
.imp-tab:hover { color:var(--parch); }
.imp-tab.on {
  color:var(--gold-hi); z-index:1; margin-bottom:-1px;
  background:linear-gradient(180deg, rgba(217,178,74,.18), rgba(217,178,74,.05));
  border-color:var(--line); border-bottom:0;
}
.imp-panel { padding:24px 26px 26px; border-top-left-radius:0; }
.imp-panel .watermark { font-size:120px; right:28px; top:6px; }
.imp-intro { font-size:14px; line-height:1.62; color:rgba(243,231,196,.66); margin:0 0 22px; max-width:820px; text-wrap:pretty; }
.imp-intro b { color:var(--parch); font-weight:600; }
.v2badges { position:relative; z-index:1; display:flex; flex-direction:column; align-items:flex-start; gap:8px; margin:15px 19px 0; }
.v2badges .v2badge { margin:0; padding:6px 13px; }
.v2btn.cant {
  cursor:not-allowed; color:rgba(243,231,196,.6); border:1px solid rgba(217,178,74,.28);
  background:linear-gradient(180deg, rgba(122,96,50,.5), rgba(86,66,36,.5)); box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
}
.v2btn.cant::before,
.v2btn.cant::after { display:none; }
.research-tier-header {
    display:flex; align-items:center; justify-content:space-between; gap:12px;
    padding:10px 14px; margin:22px 0 12px;
    background:rgba(217,178,74,.07); border:1px solid rgba(217,178,74,.22);
    border-radius:8px;
}
.research-tier-header.locked {
    background:rgba(80,60,30,.18); border-color:rgba(140,100,40,.18);
    opacity:.72;
}
.rtier-left { display:flex; align-items:center; gap:10px; }
.rtier-label {
    font-family:'JetBrains Mono',monospace; font-weight:700; font-size:11px;
    letter-spacing:.12em; text-transform:uppercase;
    color:var(--gold); background:rgba(217,178,74,.14);
    border:1px solid rgba(217,178,74,.3); border-radius:4px;
    padding:3px 8px; white-space:nowrap;
}
.research-tier-header.locked .rtier-label {
    color:rgba(243,231,196,.4); background:rgba(140,100,40,.12);
    border-color:rgba(140,100,40,.22);
}
.rtier-name { font-family:'Cinzel',serif; font-weight:600; font-size:13px; color:var(--parch); }
.research-tier-header.locked .rtier-name { color:rgba(243,231,196,.42); }
.rtier-status { font-size:11px; color:rgba(243,231,196,.5); white-space:nowrap; display:flex; align-items:center; gap:6px; }
.rtier-status svg { width:12px; height:12px; opacity:.7; }
.research-tier-header.locked .rtier-status { color:rgba(243,231,196,.38); }
.research-tier-grid { margin-bottom:24px; }
.research-tier-grid.tier-locked { pointer-events:none; }
.page-banner {
  position:relative; width:100%; height:clamp(210px, 24vw, 320px);
  border-radius:14px; overflow:hidden; margin:0 0 20px;
  border:1px solid var(--line); box-shadow:0 22px 50px -28px rgba(0,0,0,.9), inset 0 0 0 1px rgba(0,0,0,.4);
  background:#0a0907;
}
.page-banner-bg { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
.page-banner-scrim { position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(180deg, rgba(10,6,4,.5) 0%, transparent 26% 52%, rgba(10,6,4,.82) 100%); }
.page-banner-top { position:absolute; top:14px; left:16px; right:16px; z-index:3; display:flex; align-items:center; justify-content:space-between; gap:12px; }
.page-banner-foot { position:absolute; left:18px; right:18px; bottom:14px; z-index:3; }
.page-banner--wall .page-banner-bg { filter:grayscale(.92) brightness(.42) contrast(.95); }
.page-banner--wall .wlhero-fill img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; filter:saturate(1.04) brightness(.92); }
.page-banner--cofre { border-radius:16px; box-shadow:0 20px 44px -28px rgba(0,0,0,.92), inset 0 0 0 1px rgba(217,178,74,.12); }
.page-banner--cofre .page-banner-bg { object-position:50% 30%; }
.page-banner--cofre .page-banner-scrim { background:linear-gradient(90deg, rgba(18,5,5,.82) 0%, rgba(18,5,5,.22) 44%, rgba(18,5,5,.04) 72%), linear-gradient(0deg, rgba(13,4,4,.94) 0%, rgba(13,4,4,.28) 40%, transparent 64%); }
.page-banner--cofre .page-banner-top { justify-content:flex-end; }
.wlhero-fill { position:absolute; inset:0; transition:clip-path 1s cubic-bezier(.4,0,.2,1); }
.wlhero-edge {
  position:absolute; top:0; bottom:0; width:2px; transform:translateX(-1px); z-index:2;
  background:linear-gradient(180deg, transparent, rgba(240,209,120,.9) 18%, rgba(240,209,120,.9) 82%, transparent);
  box-shadow:0 0 14px 2px rgba(240,209,120,.5); transition:left 1s cubic-bezier(.4,0,.2,1);
}
.wlhero-seal {
  width:30px; height:30px; flex:none; border-radius:7px; display:grid; place-items:center;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:17px; color:var(--gold-hi);
  background:radial-gradient(120% 90% at 50% 30%, #7d2a1c, #4a0f0b); border:1px solid var(--gold-soft);
  box-shadow:inset 0 1px 4px rgba(0,0,0,.5);
}
.wlhero-lvl {
  display:inline-flex; align-items:center; gap:9px; padding:5px 14px 5px 5px; border-radius:9px;
  font-family:'Cinzel',serif; font-weight:700; font-size:13px; letter-spacing:.05em; color:var(--gold-hi);
  background:rgba(20,8,8,.7); border:1px solid var(--line); backdrop-filter:blur(3px);
}
.wlhero-lvl .wlhero-seal { width:28px; height:28px; font-size:16px; }
.wlhero-name { font-family:'Cinzel',serif; font-weight:700; font-size:22px; color:var(--parch); text-shadow:0 2px 10px rgba(0,0,0,.7); margin-bottom:10px; }
.wlhero-res { display:grid; grid-template-columns:repeat(3, 1fr); gap:22px; margin-top:10px; }
@media (max-width:680px) {
  .wlhero-res { grid-template-columns:1fr; gap:14px; }
}
.wlhero-resblock .banner-track { max-width:none; }
.wl-grid { display:grid; grid-template-columns:1.4fr 1fr; gap:20px; align-items:start; }
@media (max-width:920px) {
  .wl-grid { grid-template-columns:1fr; }
}
.wl-build { min-width:0; border-radius:15px; padding:18px 20px 20px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(0,0,0,.2), rgba(0,0,0,.06)); }
.wl-build .cofre-topbar { margin-bottom:16px; }
.wl-lvlpill { display:inline-flex; align-items:center; gap:6px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:11px; color:var(--gold-hi); padding:4px 10px; border-radius:7px; background:linear-gradient(180deg, rgba(217,178,74,.2), rgba(217,178,74,.07)); border:1px solid var(--gold-soft); }
.wl-lvlpill svg { width:13px; height:13px; }
.wl-contrib { border-top:1px solid var(--line-soft); padding-top:16px; margin-top:18px; display:flex; flex-direction:column; }
.wl-contrib .ct-k { display:block; margin-bottom:4px; }
.wl-row { margin-top:11px; }
.wl-row .dep-inputbox { width:128px; }
.wl-avail { flex:none; font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(243,231,196,.42); min-width:62px; text-align:right; }
.wl-side { display:flex; flex-direction:column; gap:18px; min-width:0; }
.wl-card { border-radius:15px; padding:16px 18px 14px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(70,16,15,.4), rgba(40,9,9,.4)); }
.wl-card .cl-head { margin-bottom:12px; }
.wl-steps { display:flex; flex-direction:column; position:relative; }
.wl-step { display:flex; gap:13px; padding:11px 2px; position:relative; }
.wl-step:not(:last-child)::before { content:""; position:absolute; left:8px; top:26px; bottom:-4px; width:2px; background:var(--line-soft); }
.wl-step.done:not(:last-child)::before { background:rgba(217,178,74,.4); }
.wl-step-dot {
  position:relative; z-index:1; flex:none; width:18px; height:18px; margin-top:2px; border-radius:50%;
  display:grid; place-items:center; background:rgba(0,0,0,.4); border:2px solid var(--line);
}
.wl-step-dot svg { width:11px; height:11px; }
.wl-step.active .wl-step-dot { border-color:var(--gold-hi); background:radial-gradient(circle, var(--gold-hi) 0 40%, transparent 46%); box-shadow:0 0 0 4px rgba(217,178,74,.16); }
.wl-step.done .wl-step-dot { border-color:var(--gold-soft); background:rgba(217,178,74,.18); color:var(--gold-hi); }
.wl-step.locked .wl-step-dot { color:rgba(243,231,196,.32); }
.wl-step-name { font-family:'Cinzel',serif; font-weight:700; font-size:14px; color:rgba(243,231,196,.55); margin-bottom:3px; }
.wl-step.active .wl-step-name { color:var(--gold-hi); }
.wl-step.done .wl-step-name { color:rgba(243,231,196,.78); }
.wl-step-meta { font-family:'JetBrains Mono',monospace; font-size:11px; line-height:1.45; color:rgba(243,231,196,.4); }
.wl-step.active .wl-step-meta { color:var(--gold-soft); }
.wl-empty { font-size:13px; color:rgba(243,231,196,.45); margin:4px 2px 8px; font-style:italic; }
.wall-ledger .cl-amt svg { width:15px; height:15px; }
.banner-members { display:inline-flex; align-items:center; gap:6px; font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(243,231,196,.85); padding:6px 11px; border-radius:8px; background:rgba(13,4,4,.55); border:1px solid var(--line-soft); }
.banner-members svg { width:14px; height:14px; color:var(--gold-soft); }
.banner-kicker { display:block; font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.18em; text-transform:uppercase; color:var(--gold-soft); margin-bottom:8px; }
.banner-val { display:flex; align-items:baseline; gap:13px; }
.banner-val img { width:36px; height:36px; border-radius:8px; object-fit:cover; align-self:center; box-shadow:0 2px 7px rgba(0,0,0,.65); position:static; inset:auto; }
.banner-val b { font-family:'Cinzel',serif; font-weight:700; font-size:clamp(34px, 4vw, 46px); line-height:.9; color:var(--gold-hi); text-shadow:0 2px 12px rgba(0,0,0,.75); font-variant-numeric:tabular-nums; }
.banner-cap { font-family:'JetBrains Mono',monospace; font-size:13px; color:rgba(243,231,196,.62); }
.banner-track { height:8px; border-radius:6px; margin-top:13px; max-width:min(420px, 62%); background:rgba(0,0,0,.5); overflow:hidden; box-shadow:inset 0 1px 2px rgba(0,0,0,.6), inset 0 0 0 1px var(--line-soft); }
.banner-track i { display:block; height:100%; border-radius:6px; background:linear-gradient(90deg, var(--gold-dim), var(--gold-hi)); box-shadow:0 0 10px rgba(217,178,74,.55); transition:width .6s ease; }
.cofre-grid { display:grid; grid-template-columns:1.3fr 1fr; gap:20px; align-items:start; }
@media (max-width:920px) {
  .cofre-grid { grid-template-columns:1fr; }
}
.cofre-depo { border-radius:15px; padding:20px 22px 22px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(0,0,0,.2), rgba(0,0,0,.06)); }
.cofre-depo .ct-k { display:inline-flex; align-items:center; gap:7px; }
.cofre-depo .ct-k svg { width:14px; height:14px; }
.cofre-depo-note { font-size:12.5px; line-height:1.55; color:rgba(243,231,196,.58); margin:13px 0 4px; }
.cofre-depo .dep-row { margin-top:16px; }
.cofre-depo .dep-btn { width:100%; margin-top:16px; justify-content:center; }
.cofre-topbar { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:14px; }
.ct-k { font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.16em; text-transform:uppercase; color:var(--gold-soft); }
.ct-members { display:inline-flex; align-items:center; gap:6px; font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(243,231,196,.5); }
.ct-members svg { width:14px; height:14px; color:var(--gold-soft); }
.cofre-ledger { border-radius:15px; padding:18px 18px 12px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(70,16,15,.4), rgba(40,9,9,.4)); }
.cl-head { display:flex; align-items:center; gap:9px; margin-bottom:10px; }
.cl-head svg { width:17px; height:17px; color:var(--gold-soft); flex:none; }
.cl-head h4 { font-family:'Cinzel',serif; font-weight:700; font-size:14px; color:var(--parch); margin:0; }
.cofre-ledger ul { list-style:none; margin:0; padding:0; }
.cofre-ledger li { display:flex; align-items:center; gap:11px; padding:9px 6px; border-bottom:1px solid var(--line-soft); }
.cofre-ledger li:last-child { border-bottom:0; }
.cl-who { flex:1; min-width:0; display:flex; align-items:baseline; gap:7px; }
.cl-who .nm { font-family:'Noto Serif',serif; font-weight:600; font-size:13.5px; color:var(--parch); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cl-who .cn { font-family:'Noto Serif SC',serif; font-size:11px; color:var(--gold-soft); opacity:.72; white-space:nowrap; }
.cl-who .you-tag { font-family:'JetBrains Mono',monospace; font-size:9px; letter-spacing:.1em; color:var(--gold-soft); text-transform:uppercase; }
.cl-amt { flex:none; display:inline-flex; align-items:center; gap:6px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:13px; color:var(--gold); font-variant-numeric:tabular-nums; }
.cl-amt img { width:18px; height:18px; border-radius:5px; object-fit:cover; }
.cl-t { flex:none; font-family:'JetBrains Mono',monospace; font-size:9.5px; color:rgba(243,231,196,.38); width:54px; text-align:right; }
.cofre-ledger li.you { background:linear-gradient(90deg, rgba(217,178,74,.1), transparent); border-radius:8px; border-bottom:0; }
.cofre-ledger li.you .nm { color:var(--gold-hi); }
.imposto-grid { display:grid; grid-template-columns:1.5fr 1fr; gap:20px; align-items:start; }
@media (max-width:920px) {
  .imposto-grid { grid-template-columns:1fr; }
}
.tax-side { border-radius:15px; padding:18px 20px 20px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(70,16,15,.4), rgba(40,9,9,.4)); }
.tax-side .cl-head { margin-bottom:14px; }
.tax-side-note { font-size:12px; line-height:1.55; color:rgba(243,231,196,.55); margin:14px 0 0; }
.tax-card { border-radius:15px; padding:20px 22px 22px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(0,0,0,.2), rgba(0,0,0,.06)); }
.tax-head { display:flex; align-items:center; gap:12px; margin-bottom:18px; flex-wrap:wrap; }
.tax-ico {
  width:38px; height:38px; flex:none; border-radius:10px; display:grid; place-items:center; color:var(--gold-hi);
  background:radial-gradient(120% 90% at 50% 28%, #7d2a1c, #4a0f0b); border:1px solid var(--gold-soft);
  box-shadow:inset 0 1px 5px rgba(0,0,0,.5), 0 0 0 3px rgba(140,28,20,.22);
}
.tax-ico svg { width:21px; height:21px; }
.tax-head h4 { font-family:'Cinzel',serif; font-weight:700; font-size:17px; color:var(--parch); margin:0; }
.tax-sub { font-size:12.5px; font-style:italic; color:rgba(243,231,196,.5); }
.tax-rows { display:flex; flex-direction:column; gap:16px; margin-bottom:18px; }
.tax-row { display:flex; align-items:center; gap:14px; }
.tax-rlead { display:flex; align-items:center; gap:9px; flex:none; width:170px; }
.tax-rlead img { width:26px; height:26px; border-radius:6px; object-fit:cover; box-shadow:0 1px 3px rgba(0,0,0,.5); flex:none; }
.tax-rname { font-family:'Cinzel',serif; font-weight:600; font-size:13.5px; line-height:1.2; color:rgba(243,231,196,.82); }
.tax-slider {
  -webkit-appearance:none; appearance:none; flex:1; min-width:0; height:8px; border-radius:6px; outline:none; cursor:pointer;
  background:rgba(0,0,0,.72); box-shadow:inset 0 1px 2px rgba(0,0,0,.7), inset 0 0 0 1px var(--line-soft);
}
.dep-slider {
  -webkit-appearance:none; appearance:none; flex:1; min-width:60px; height:8px; border-radius:6px; outline:none; cursor:pointer;
  background:rgba(0,0,0,.72); box-shadow:inset 0 1px 2px rgba(0,0,0,.7), inset 0 0 0 1px var(--line-soft);
}
.tax-slider::-webkit-slider-thumb,
.dep-slider::-webkit-slider-thumb,
.wall-dep-slider::-webkit-slider-thumb {
  -webkit-appearance:none; appearance:none; width:20px; height:20px; border-radius:50%;
  background:radial-gradient(120% 110% at 50% 28%, var(--gold-hi), var(--gold-soft)); border:1px solid var(--gold-hi);
  box-shadow:0 2px 7px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.55); cursor:pointer; margin-top:-6px;
}
.tax-slider::-moz-range-thumb,
.dep-slider::-moz-range-thumb,
.wall-dep-slider::-moz-range-thumb {
  width:20px; height:20px; border-radius:50%; background:radial-gradient(120% 110% at 50% 28%, var(--gold-hi), var(--gold-soft));
  border:1px solid var(--gold-hi); box-shadow:0 2px 7px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.55); cursor:pointer;
}
.tax-slider::-webkit-slider-runnable-track,
.dep-slider::-webkit-slider-runnable-track,
.wall-dep-slider::-webkit-slider-runnable-track { height:8px; border-radius:6px; background:transparent; }
.tax-slider::-moz-range-track,
.dep-slider::-moz-range-track,
.wall-dep-slider::-moz-range-track { height:8px; border-radius:6px; background:transparent; }
.tax-rpct { flex:none; width:50px; text-align:right; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:15px; color:var(--gold); font-variant-numeric:tabular-nums; }
.tax-confirm { width:100%; }
@media (max-width:520px) {
  .tax-rlead { width:128px; }
  .tax-rname { font-size:12.5px; }
}
.dep-row { display:flex; align-items:center; gap:12px; margin-top:15px; }
.dep-inputbox { flex:none; width:150px; display:flex; align-items:center; gap:9px; padding:8px 13px; border-radius:10px; background:rgba(0,0,0,.72); border:1px solid var(--line); }
.dep-inputbox img { width:24px; height:24px; border-radius:6px; object-fit:cover; flex:none; }
.dep-input { flex:1; min-width:0; width:100%; background:none; border:0; outline:none; color:var(--gold); font-family:'JetBrains Mono',monospace; font-weight:700; font-size:17px; font-variant-numeric:tabular-nums; -moz-appearance:textfield; appearance:textfield; }
.dep-input::-webkit-outer-spin-button,
.dep-input::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
.dep-btn { flex:none; }
.ord-active {
  display:flex; align-items:center; gap:14px; padding:14px 16px; border-radius:13px; margin-bottom:20px;
  background:linear-gradient(90deg, rgba(158,36,24,.4), rgba(60,12,12,.5)); border:1px solid rgba(217,178,74,.34);
}
.ord-seal {
  width:38px; height:38px; flex:none; border-radius:50%; display:grid; place-items:center;
  font-family:'Noto Serif SC',serif; font-size:18px; color:#f3dd92;
  background:radial-gradient(circle at 50% 38%, #b13328, #7d160e); border:1px solid var(--gold-soft);
  box-shadow:0 0 0 3px rgba(140,28,20,.3), inset 0 1px 3px rgba(0,0,0,.4);
}
.ord-atxt { display:flex; flex-direction:column; gap:3px; }
.ord-alab { font-family:'JetBrains Mono',monospace; font-size:9.5px; letter-spacing:.2em; text-transform:uppercase; color:var(--gold-soft); }
.ord-aname { font-family:'Cinzel',serif; font-weight:700; font-size:15px; color:var(--parch); }
.ord-aname b { color:var(--gold-hi); }
.ord-active .spacer { flex:1; }
.ord-acount { display:inline-flex; align-items:center; gap:8px; font-family:'JetBrains Mono',monospace; font-size:13px; font-weight:700; color:var(--gold-hi); font-variant-numeric:tabular-nums; padding:7px 13px; border-radius:9px; background:rgba(0,0,0,.3); border:1px solid var(--line); }
.ord-acount svg { width:14px; height:14px; opacity:.8; }
.ord-none { display:flex; align-items:center; gap:10px; padding:14px 16px; border-radius:12px; margin-bottom:20px; border:1px dashed var(--line); color:rgba(243,231,196,.6); font-size:13px; }
.ord-none svg { width:18px; height:18px; color:var(--gold-dim); flex:none; }
.ord-none b { color:var(--gold-hi); }
.ocard-grid { display:grid; grid-template-columns:repeat(4, 1fr); gap:18px; }
@media (max-width:1080px) {
  .ocard-grid { grid-template-columns:repeat(2, 1fr); }
}
@media (max-width:560px) {
  .ocard-grid { grid-template-columns:1fr; }
}
.ocard {
  position:relative; border-radius:16px; padding:5px; aspect-ratio:3 / 4.35;
  background:linear-gradient(150deg, var(--gold-hi) 0%, var(--gold-dim) 32%, #6e4a17 62%, var(--gold-soft) 100%);
  box-shadow:0 26px 52px -30px rgba(0,0,0,.95), inset 0 1px 0 rgba(255,255,255,.25);
  transition:transform .16s ease, box-shadow .2s ease;
}
.ocard:hover { transform:translateY(-5px) rotate(-.5deg); box-shadow:0 36px 60px -28px rgba(0,0,0,1); }
.ocard.on {
  z-index:2;
  animation:cardglow 2s ease-in-out infinite;
}
@keyframes cardglow {
  0%,100%{ box-shadow:0 0 0 2.5px var(--gold-hi), 0 0 26px rgba(240,209,120,.45), 0 36px 70px -26px rgba(0,0,0,1); }
  50%{     box-shadow:0 0 0 3px   var(--gold-hi), 0 0 56px rgba(240,209,120,.80), 0 36px 70px -26px rgba(0,0,0,1); }
}
.ocard.on .ocard-inner {
  border-color:rgba(168,14,14,.55);
  box-shadow:inset 0 0 0 1px rgba(168,14,14,.15), inset 0 0 40px rgba(168,14,14,.06);
}
.ocard.on::before {
  content:"EM VIGOR"; position:absolute; top:-14px; left:50%; transform:translateX(-50%); z-index:4;
  font-family:'Cinzel',serif; font-weight:700; font-size:9px; letter-spacing:.22em; white-space:nowrap;
  color:#2a0d0a; padding:5px 14px; border-radius:20px;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  border:1px solid var(--gold-hi); box-shadow:0 2px 10px rgba(0,0,0,.55);
}
.ocard.on .ocard-seal { animation:sealpulse .9s ease-in-out infinite; }
.ocard.on .ocard-name { color:#3a1800; }
.ocard.on .ocard-dur { color:rgba(168,14,14,.85); font-size:13px; font-weight:700; }
.ocard.on .ocard-face::after {
  content:""; position:absolute; top:50%; left:50%;
  transform:translate(-50%,-50%) rotate(-20deg);
  z-index:4; pointer-events:none;
  width:80px; height:80px; border-radius:50%;
  border:3px solid rgba(168,14,14,.5);
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:34px; color:rgba(168,14,14,.5);
  line-height:76px; text-align:center;
  display:flex; align-items:center; justify-content:center;
}
.ocard.lack { filter:saturate(.55) brightness(.9); }
.ocard-inner {
  position:relative; height:100%; border-radius:12px; overflow:hidden; display:flex; flex-direction:column;
  padding:16px 14px 14px; text-align:center;
  background:linear-gradient(180deg, #c0b090 0%, #d0c0a0 6%, #e4d8b8 16%, #eee4cc 30%, #f2ead8 50%, #eee4cc 70%, #e4d8b8 84%, #d0c0a0 94%, #c0b090 100%);
  border:1px solid rgba(180,140,60,.5);
}
.ocard-corner { position:absolute; z-index:3; font-family:'Noto Serif SC',serif; font-weight:900; font-size:17px; color:rgba(168,14,14,.7); line-height:1; }
.ocard-corner.tl { top:9px; left:11px; }
.ocard-corner.br { bottom:9px; right:11px; transform:rotate(180deg); }
.ocard-face { position:relative; flex:1; display:grid; place-items:center; min-height:0; margin:6px 0 10px; }
.ocard-face::before {
  content:""; position:absolute; inset:6px 14px; border-radius:50%;
  background:radial-gradient(circle at 50% 42%, rgba(168,14,14,.1), transparent 68%);
}
.ocard-seal {
  position:relative; width:84px; height:84px; border-radius:50%; display:grid; place-items:center;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:44px; color:#f3dd92;
  background:radial-gradient(circle at 50% 34%, #b13328, #7d160e 70%, #4a0f0b);
  border:2px solid var(--gold-soft); box-shadow:0 0 0 4px rgba(140,28,20,.4), inset 0 2px 6px rgba(0,0,0,.5), 0 6px 16px rgba(0,0,0,.6);
}
.ocard-body { flex:none; }
.ocard-name { font-family:'Cinzel',serif; font-weight:700; font-size:15px; line-height:1.2; color:#3a1800; margin:0; letter-spacing:.01em; text-wrap:balance; }
.ocard-effect {
  display:inline-block; margin:9px auto 0; font-family:'Noto Serif',serif; font-size:12px; line-height:1.3; color:#5a2e00;
  padding:4px 11px; border-radius:7px; border:1px solid rgba(140,80,10,.35); background:rgba(160,100,10,.1);
}
.ocard-dur { display:flex; align-items:center; justify-content:center; gap:6px; margin-top:9px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:11px; letter-spacing:.04em; color:rgba(60,28,5,.65); }
.ocard-dur svg { width:13px; height:13px; opacity:.8; }
.ocard-foot { flex:none; display:flex; flex-direction:column; gap:10px; margin-top:13px; padding-top:13px; border-top:1px solid rgba(140,90,10,.25); }
.ocard-cost { display:inline-flex; align-items:center; justify-content:center; gap:7px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:15px; color:#5a2e00; font-variant-numeric:tabular-nums; }
.ocard-cost img { width:22px; height:22px; border-radius:6px; object-fit:cover; box-shadow:0 1px 3px rgba(0,0,0,.5); }
.ocard-cost.lack { color:var(--down); }
.ocard-btn {
  display:inline-flex; align-items:center; justify-content:center; gap:7px; width:100%;
  font-family:'Cinzel',serif; font-weight:600; font-size:12.5px; letter-spacing:.04em; border-radius:9px; padding:9px 12px;
}
.ocard-btn svg { width:14px; height:14px; }
.ocard-btn.can {
  cursor:pointer; color:#2a0d0a; border:1px solid var(--gold-soft);
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  box-shadow:0 2px 0 var(--gold-dim), inset 0 1px 0 rgba(255,255,255,.4); transition:transform .12s ease, filter .15s ease;
}
.ocard-btn.can:hover { filter:brightness(1.05); }
.ocard-btn.can:active { transform:translateY(2px); box-shadow:0 0 0 var(--gold-dim), inset 0 1px 0 rgba(255,255,255,.3); }
.ocard-btn.cant { cursor:not-allowed; color:rgba(60,28,5,.45); border:1px solid rgba(140,90,10,.28); background:rgba(160,120,60,.15); }
.ocard-btn.done { color:#8a1010; border:1px solid rgba(168,14,14,.38); background:rgba(168,14,14,.1); }
.prisobar {
  display:flex; align-items:center; gap:12px; padding:10px 26px;
  background:linear-gradient(90deg, rgba(100,10,10,.85), rgba(60,8,8,.9));
  border-bottom:1px solid rgba(232,99,63,.45);
  color:var(--warn); font-family:'Cinzel',serif; font-size:13.5px; font-weight:600; letter-spacing:.02em;
}
.prisobar.hidden { display:none; }
.prisobar svg { width:18px; height:18px; flex:none; color:var(--down); }
.page-banner--prison .page-banner-scrim {
  background:linear-gradient(90deg, rgba(13,4,4,.55) 0%, rgba(13,4,4,.12) 48%, rgba(13,4,4,0) 76%),
             linear-gradient(0deg, rgba(10,3,3,.92) 0%, rgba(10,3,3,.22) 44%, transparent 66%);
}
.page-banner--prison { background:#0a0303; }
.page-banner--prison .page-banner-bg { object-position:50% 36%; }
.page-banner--prison .page-banner-top { justify-content:space-between; }
.pris-hero-val { display:flex; align-items:baseline; gap:13px; }
.pris-hero-val svg { width:34px; height:34px; color:var(--gold-hi); align-self:center; filter:drop-shadow(0 2px 7px rgba(0,0,0,.7)); }
.pris-hero-val b { font-family:'Cinzel',serif; font-weight:700; font-size:clamp(34px, 4vw, 46px); line-height:.9; color:var(--gold-hi); text-shadow:0 2px 12px rgba(0,0,0,.75); font-variant-numeric:tabular-nums; }
.pris-hero-cap { font-family:'JetBrains Mono',monospace; font-size:13px; color:rgba(243,231,196,.62); }
.pris-grid { display:grid; grid-template-columns:1.5fr 1fr; gap:20px; align-items:start; }
@media (max-width:920px) {
  .pris-grid { grid-template-columns:1fr; }
}
.pris-list { min-width:0; border-radius:15px; padding:18px 20px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(0,0,0,.2), rgba(0,0,0,.06)); }
.pris-list .ct-k,
.pris-order .ct-k { display:inline-flex; align-items:center; gap:7px; }
.pris-list .ct-k svg,
.pris-order .ct-k svg { width:14px; height:14px; flex:none; color:var(--gold-soft); }
.pris-cards { display:flex; flex-direction:column; gap:11px; margin-top:14px; }
.pris-card { display:flex; align-items:center; gap:14px; padding:13px 14px; border-radius:13px;
  border:1px solid rgba(158,36,24,.4); background:linear-gradient(180deg, rgba(70,16,15,.5), rgba(40,9,9,.5)); }
.pris-ava {
  width:48px; height:48px; flex:none; border-radius:50%; display:grid; place-items:center;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:23px; color:#f3dd92;
  background:radial-gradient(circle at 50% 34%, #b13328, #7d160e 70%, #4a0f0b);
  border:2px solid var(--gold-soft); box-shadow:0 0 0 3px rgba(140,28,20,.34), inset 0 2px 6px rgba(0,0,0,.5);
}
.pris-meta { flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; }
.pris-name { font-family:'Cinzel',serif; font-weight:700; font-size:15px; color:var(--parch); display:flex; align-items:baseline; gap:8px; }
.pris-reason { display:flex; align-items:center; gap:6px; font-family:'Noto Serif',serif; font-size:12.5px; color:var(--warn); }
.pris-reason svg { width:13px; height:13px; flex:none; color:rgba(232,169,143,.8); }
.pris-sub { font-family:'JetBrains Mono',monospace; font-size:10.5px; letter-spacing:.02em; color:rgba(243,231,196,.45); display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
.pris-tag { font-family:'JetBrains Mono',monospace; font-size:9px; letter-spacing:.08em; text-transform:uppercase; color:rgba(232,169,143,.85);
  padding:2px 7px; border-radius:6px; border:1px solid rgba(158,36,24,.45); background:rgba(158,36,24,.16); }
.pris-free { flex:none; }
.pris-empty { display:flex; align-items:center; gap:9px; padding:22px 18px; border-radius:12px; border:1px dashed var(--line);
  background:rgba(0,0,0,.18); font-size:13.5px; color:rgba(243,231,196,.6); margin-top:14px; }
.pris-empty svg { width:18px; height:18px; color:var(--gold-soft); flex:none; }
.pris-empty.sm { padding:14px; font-size:12.5px; margin-top:0; }
.pris-order { border-radius:15px; padding:18px 20px 20px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(70,16,15,.4), rgba(40,9,9,.4)); }
.pris-order-note { font-size:12.5px; line-height:1.55; color:rgba(243,231,196,.58); margin:12px 0 16px; }
.pris-flabel { display:block; font-family:'JetBrains Mono',monospace; font-size:9.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--gold-soft); margin:0 0 7px; }
.pris-selwrap { position:relative; margin-bottom:16px; }
.pris-selwrap::after { content:"▾"; position:absolute; right:13px; top:50%; transform:translateY(-50%); pointer-events:none; color:var(--gold-soft); font-size:12px; }
.pris-select {
  width:100%; appearance:none; -webkit-appearance:none; cursor:pointer;
  font-family:'Noto Serif',serif; font-size:13.5px; color:var(--parch);
  padding:11px 34px 11px 13px; border-radius:10px; border:1px solid var(--line);
  background:rgba(0,0,0,.32); box-shadow:inset 0 1px 2px rgba(0,0,0,.4); outline:none;
}
.pris-select:focus { border-color:var(--gold-soft); }
.pris-select option { background:#2a0808; color:var(--parch); }
.pris-jail-btn { width:100%; justify-content:center; margin-top:2px; }
/* Imperial largesse — admin gold grant (Ouro tab). Mirrors .pris-order but
   gold-tinted, not blood-red, and width-capped for the lone form column. */
.gold-grant { max-width:520px; border-radius:15px; padding:18px 20px 20px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(70,54,16,.4), rgba(40,32,9,.4)); }
.gold-grant .ct-k { display:inline-flex; align-items:center; gap:7px; }
.gold-grant .ct-k svg { width:14px; height:14px; flex:none; color:var(--gold-soft); }
.gold-grant .dep-inputbox { width:100%; margin-bottom:16px; }
.gold-grant-btn { width:100%; justify-content:center; margin-top:2px; }
.army-sec-head { margin:0 0 16px; }
.army-sec-head h3 {
  display:flex; align-items:center; gap:9px; margin:0 0 6px;
  font-family:'Cinzel',serif; font-weight:700; font-size:19px; color:var(--gold-hi); letter-spacing:.01em;
}
.army-sec-head h3 svg { width:20px; height:20px; color:var(--gold-soft); }
.army-sec-head .panel-caption { margin:0; font-size:13px; line-height:1.55; color:rgba(243,231,196,.6); max-width:780px; }
.v2btn.lack { opacity:.5; filter:saturate(.6); }
.army-row { display:grid; grid-template-columns:repeat(var(--cols,3),1fr); gap:14px; }
@media (max-width:820px) {
  .army-row { grid-template-columns:1fr; }
}

/* ── Battle-report pages (#combate + #assalto) — shared bits. Both render the
   canvas replay stage (see Registro de Assalto below); these are the floating
   "Voltar" that rides over the stage and the empty/error state. */
.combat-back-float {
  position:absolute; z-index:12; top:12px; left:12px;
  padding:7px 14px; font-size:12.5px;
  box-shadow:0 6px 18px -6px rgba(0,0,0,.85);
}
.combat-empty {
  display:flex; flex-direction:column; align-items:center; gap:14px;
  padding:70px 20px; text-align:center;
  font-family:'Cinzel',serif; font-size:15px; color:rgba(243,231,196,.7);
}

.modal-overlay {
  position:fixed; inset:0; z-index:200; display:flex; align-items:center; justify-content:center;
  padding:24px; background:rgba(10,3,3,.72); backdrop-filter:blur(2px);
  animation:modalFade .15s ease;
}
@keyframes modalFade { from{ opacity:0; } to{ opacity:1; } }
.modal-card {
  position:relative; width:min(680px,100%); max-height:88vh; overflow-y:auto;
  border-radius:16px; border:1px solid var(--gold-dim); padding:26px 26px 24px;
  background:linear-gradient(180deg, var(--panel), var(--panel-2));
  box-shadow:0 30px 80px -30px rgba(0,0,0,1);
}
.modal-close {
  position:absolute; top:12px; right:13px; cursor:pointer; width:30px; height:30px;
  display:inline-flex; align-items:center; justify-content:center; font-size:15px;
  border-radius:8px; border:1px solid var(--line); background:rgba(0,0,0,.3); color:var(--parch);
}
.modal-close:hover { border-color:var(--gold-soft); color:var(--gold-hi); }
/* Objective inspection ("Detalhes") — every objective's dossier wears the
   send-card shell; `.inspect-mdl` survives on the card root purely as the JS
   marker (closeLocationPopup/popupIsOpenFor) and scopes the wilderness
   fallback's stat/note lines below. */
.inspect-mdl .modal-stats { display:flex; justify-content:center; gap:16px; margin:4px 0 8px; font-size:13px; color:rgba(243,231,196,.8); }
.inspect-mdl .modal-note { text-align:center; color:rgba(243,231,196,.66); }
.inspect-mdl .modal-err { text-align:center; }
.pm-list { display:flex; flex-direction:column; gap:8px; max-height:52vh; overflow-y:auto; }
.pm-empty { text-align:center; color:rgba(241,230,198,.5); font-size:13px; padding:18px 8px; }
/* Roster row (shared: pile scouts + corpse priests) — a lacquer plate with a
   phase accent stripe on its leading edge. flex-shrink:0 keeps a full roster
   (a corpse pools priests from every province) at natural height so the list
   scrolls instead of the flex column crushing the rows into each other. */
.pm-scout { flex:none; position:relative; overflow:hidden; display:flex; align-items:center; gap:11px; padding:9px 10px 9px 12px; border-radius:11px;
  background:linear-gradient(180deg, rgba(34,23,13,.72), rgba(17,11,6,.72));
  border:1px solid rgba(217,178,74,.15); box-shadow:inset 0 1px 0 rgba(247,221,142,.05); }
.pm-scout:hover { border-color:rgba(217,178,74,.28); }
/* Phase stripe — only phase-tagged rows (pile scouts) light it; priest rows stay plain. */
.pm-scout.enroute::before, .pm-scout.gathering::before, .pm-scout.returning::before {
  content:""; position:absolute; left:0; top:0; bottom:0; width:3px; }
.pm-scout.enroute::before { background:linear-gradient(180deg,#e6bd57,#a9791f); }
.pm-scout.gathering::before { background:linear-gradient(180deg,#7fd0a0,#3f7a4a); }
.pm-scout.returning::before { background:linear-gradient(180deg,#8fb0dc,#3f5a7a); }
/* Scout token — the marching unit's face in a gold-ringed disc (pile rows only). */
.pm-sc-ava { flex:none; width:38px; height:38px; border-radius:50%; overflow:hidden;
  border:1px solid rgba(217,178,74,.4); background:#0d0805;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.55), 0 1px 3px rgba(0,0,0,.5); }
.pm-sc-ava img { width:100%; height:100%; object-fit:cover; object-position:50% 16%; }
.pm-sc-main { flex:1; min-width:0; }
.pm-sc-top { display:flex; justify-content:space-between; align-items:baseline; gap:8px; margin-bottom:5px; }
.pm-sc-prov { font-family:'Cinzel',serif; font-size:13px; color:var(--parch); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.pm-sc-status { font-family:'JetBrains Mono',monospace; font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:rgba(191,230,160,.75); white-space:nowrap; }
.pm-scout.enroute .pm-sc-status { color:#e8c583; }
.pm-scout.gathering .pm-sc-status { color:#8fd7a5; }
.pm-scout.returning .pm-sc-status { color:#9fb9df; }
.pm-sc-bar { position:relative; height:16px; border-radius:8px; background:rgba(0,0,0,.5); overflow:hidden; box-shadow:inset 0 1px 2px rgba(0,0,0,.6); }
.pm-sc-bar i { position:absolute; inset:0 auto 0 0; background:linear-gradient(90deg,#3f5a2a,#6fae6f); transition:width .3s ease; }
.pm-scout.enroute .pm-sc-bar i { background:linear-gradient(90deg,#8a6420,#e6bd57); }
.pm-scout.returning .pm-sc-bar i { background:linear-gradient(90deg,#3f5a7a,#8fb0dc); }
.pm-sc-bar span { position:relative; display:block; text-align:center; font-family:'JetBrains Mono',monospace; font-size:11px; line-height:16px; color:#f0ead8; text-shadow:0 1px 1px rgba(0,0,0,.7); }
.pm-remove { flex:none; width:32px; height:32px; display:inline-flex; align-items:center; justify-content:center; border-radius:8px; border:1px solid rgba(224,86,60,.4); background:rgba(60,20,16,.45); color:#e8956a; cursor:pointer; }
.pm-remove:hover { border-color:#e0563c; color:#ffb08a; background:rgba(80,26,20,.6); }
.pm-remove.off { opacity:.28; cursor:default; }
.pm-remove svg { width:16px; height:16px; }
/* ── World-map send modals (default action card) ────────────────────────────
   openPileSendModal / openCorpseSendModal reuse the recruit card's inner anatomy
   (band header, recessed stage, plaque) on a NEUTRAL shell. The modal shell goes
   fully transparent so the framed card itself IS the dialog (like the dossier). */
.modal-card:has(.send-card) { width:max-content; max-width:96vw; padding:0; border:none; background:none; box-shadow:none; }
/* The card shell: neutral slot-frame (the .tslot convention — parchment-silver
   gradient border + 1px black outline) over the recruit card's lacquered body.
   No golden band, ring or glow. */
.rcard.send-card {
  width:340px; max-width:88vw;
  border:2px solid transparent; border-radius:18px; border-image:none;
  background:
    radial-gradient(130% 70% at 50% -6%, rgba(240,209,120,.16), rgba(240,209,120,0) 58%) padding-box,
    linear-gradient(180deg, rgba(58,42,22,.25), rgba(16,10,5,.5)) padding-box,
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat padding-box,
    linear-gradient(180deg,#3b2b17 0%, #2a1d0f 52%, #1c1309 100%) padding-box,
    var(--slot-frame) border-box;
  box-shadow:
    var(--slot-outline),
    0 14px 34px rgba(0,0,0,.6),
    inset 0 1px 0 rgba(247,221,142,.16),
    inset 0 0 26px rgba(0,0,0,.42);
}
/* The close disc rides inside the frame (a flat one drowns in the band art). */
.modal-card:has(.send-card) .modal-close {
  top:14px; right:14px; z-index:6; width:30px; height:30px; border-radius:50%;
  border:1px solid rgba(217,178,74,.4);
  background:radial-gradient(120% 120% at 50% 32%, rgba(34,20,10,.92), rgba(10,5,2,.94));
}
.modal-card:has(.send-card) .modal-close:hover { color:#ffe9a8; border-color:var(--gold-soft); transform:scale(1.08); }
/* Title: larger than the recruit-card name — the band must outsize the close disc. */
.send-card .rc-name { font-size:16px; }
/* Objective gauge — the strip between the header band and the stage: the corpse
   pool (jade fill = purged share, ☠ remaining/total) and the resource pile stock
   (fill = remaining share, remaining/total) share the design. Its fill + text
   are absolute (it sizes by its own height), edges aligned with the stage window. */
.send-gauge { position:relative; height:26px; border-radius:6px; overflow:hidden;
  background:rgba(0,0,0,.45); box-shadow:inset 0 0 0 1px rgba(176,142,74,.35); }
/* Flat jade fill — deliberately no bevel/gloss, just the soft ambient glow. */
.send-gauge > i { position:absolute; inset:0 auto 0 0; height:100%; display:block;
  background:linear-gradient(90deg, rgba(63,174,134,.85), rgba(143,215,165,.95));
  box-shadow:0 0 8px rgba(143,215,165,.35); }
.send-gauge-txt { position:absolute; inset:0; z-index:1; display:flex; align-items:center; justify-content:center; gap:7px;
  font-family:'Cinzel',serif; font-weight:700; font-size:15px; color:#fff; letter-spacing:.02em;
  text-shadow:0 1px 2px rgba(0,0,0,.92), 0 0 3px rgba(0,0,0,.7); }
/* The pile gauge's resource icon — rides inline before the count (the corpse
   gauge's ☠, in icon form). Sized to nearly fill the bar so it holds up over
   the jade fill. */
.send-gauge-res { width:22px; height:22px; object-fit:contain; filter:drop-shadow(0 1px 3px rgba(0,0,0,.85)); }
/* The rally gauge's clock glyph — the corpse ☠ / pile resource-icon, in svg form. */
.send-gauge-txt svg { width:18px; height:18px; filter:drop-shadow(0 1px 2px rgba(0,0,0,.85)); }
.send-card > .send-gauge { margin:0 19px 12px; }
/* Gauge caption — the objective's status line (pile deplete ETA / corpse purge
   crews), tucked right under the strip. */
.send-card .send-gauge-cap { margin:0 19px 12px; text-align:center; font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(241,230,198,.62); }
/* March ETA — qualifies the order plaque it sits above in the foot. */
.send-card .send-trav { margin:0; text-align:center; font-family:'JetBrains Mono',monospace; font-size:12px; color:var(--gold-soft); letter-spacing:.02em; }
/* ── Send-card control skin (shared with the army recruit grid — market keeps
   the base rc-* looks). The count keeps the base .rc-avail look (plain floating
   figures, recruit-style). */
/* Stepper: gold-ringed round discs for the arrows; the range is a recessed groove
   whose gold fill tracks the picked share (--pct, set by wireSendStepper on send
   cards and by the recruit grid's setRecruitPick on army cards). */
.send-card .rc-slider, #recruitGrid .rc-slider { bottom:12px; gap:10px; padding:0 14px; }
.send-card .rc-arrow, #recruitGrid .rc-arrow { width:30px; height:30px; border-radius:50%;
  border:1px solid rgba(217,178,74,.5);
  background:radial-gradient(120% 120% at 50% 32%, rgba(38,23,11,.95), rgba(10,5,2,.96));
  box-shadow:0 2px 7px rgba(0,0,0,.6), inset 0 1px 0 rgba(247,221,142,.16); }
.send-card .rc-arrow:hover, #recruitGrid .rc-arrow:hover { color:#2a0d0a; background:linear-gradient(180deg, var(--gold-hi), var(--gold)); border-color:var(--gold); }
.send-card .rc-range, #recruitGrid .rc-range { --pct:0%; height:8px; border:0; background:none; box-shadow:none; }
.send-card .rc-range::-webkit-slider-runnable-track, #recruitGrid .rc-range::-webkit-slider-runnable-track { height:8px; border-radius:8px;
  background:linear-gradient(90deg, var(--gold) 0, var(--gold-hi) var(--pct), rgba(14,8,4,.78) var(--pct));
  box-shadow:inset 0 1px 3px rgba(0,0,0,.7), inset 0 0 0 1px rgba(0,0,0,.55), 0 1px 0 rgba(247,221,142,.12); }
.send-card .rc-range::-moz-range-track, #recruitGrid .rc-range::-moz-range-track { height:8px; border-radius:8px; background:rgba(14,8,4,.78);
  box-shadow:inset 0 1px 3px rgba(0,0,0,.7), inset 0 0 0 1px rgba(0,0,0,.55); }
.send-card .rc-range::-moz-range-progress, #recruitGrid .rc-range::-moz-range-progress { height:8px; border-radius:8px 0 0 8px;
  background:linear-gradient(90deg, var(--gold), var(--gold-hi)); }
.send-card .rc-range::-webkit-slider-thumb, #recruitGrid .rc-range::-webkit-slider-thumb { width:20px; height:20px; margin-top:-6px;
  background:radial-gradient(circle at 35% 28%, #fff8e2, var(--gold) 60%, #8a5b14);
  border:1px solid #3c1410;
  box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 2px 6px rgba(0,0,0,.6), 0 0 9px rgba(240,209,120,.4); }
.send-card .rc-range::-moz-range-thumb, #recruitGrid .rc-range::-moz-range-thumb { width:20px; height:20px;
  background:radial-gradient(circle at 35% 28%, #fff8e2, var(--gold) 60%, #8a5b14);
  border:1px solid #3c1410;
  box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 2px 6px rgba(0,0,0,.6), 0 0 9px rgba(240,209,120,.4); }
/* Order plaque: jade lacquer bevel + gold rim (replaces the stretched texture). */
.send-card .btn-plaque { border-radius:12px; }
.send-card .btn-plaque.emerald {
  color:#0b2c1e; text-shadow:0 1px 0 rgba(255,255,255,.28);
  background:
    linear-gradient(180deg, rgba(255,255,255,.30), rgba(255,255,255,0) 44%),
    radial-gradient(130% 170% at 50% -35%, #b8f0cd, rgba(184,240,205,0) 58%),
    linear-gradient(180deg, #57c496 0%, #2f9068 55%, #1c6b4c 100%);
  box-shadow:
    0 0 0 1px #0b3524,
    0 0 0 2px rgba(247,221,142,.42),
    0 10px 22px -8px rgba(63,174,134,.55),
    0 6px 16px -9px rgba(0,0,0,.65),
    inset 0 1px 0 rgba(255,255,255,.45),
    inset 0 -2px 0 rgba(8,40,26,.55);
}
.send-card .btn-plaque.emerald:disabled { box-shadow:none; }
/* Recruit grid's order plaque: the emerald recipe re-tinted gold — same lacquer
   bevel + gold rim; the batch's gold price rides inside it (.plq-cost). */
#recruitGrid .btn-plaque { border-radius:12px;
  color:#3a1008; text-shadow:0 1px 0 rgba(255,255,255,.28);
  background:
    linear-gradient(180deg, rgba(255,255,255,.30), rgba(255,255,255,0) 44%),
    radial-gradient(130% 170% at 50% -35%, #ffe9a8, rgba(255,233,168,0) 58%),
    linear-gradient(180deg, #f0d178 0%, #d9b24a 55%, #96702a 100%);
  box-shadow:
    0 0 0 1px #4a2c08,
    0 0 0 2px rgba(247,221,142,.42),
    0 10px 22px -8px rgba(217,178,74,.55),
    0 6px 16px -9px rgba(0,0,0,.65),
    inset 0 1px 0 rgba(255,255,255,.45),
    inset 0 -2px 0 rgba(58,34,8,.55);
}
#recruitGrid .btn-plaque:disabled { box-shadow:none; }
/* The price IS the plaque's label (the recruit card's old rc-cost-row, folded
   into the order button; the action name lives on as the button's aria-label). */
.btn-plaque .plq-cost { display:inline-flex; align-items:center;
  font-family:'JetBrains Mono',monospace; font-size:15px; font-weight:700; font-variant-numeric:tabular-nums; }
.btn-plaque .plq-cost .ci { display:inline-flex; align-items:center; gap:8px; }
/* The coin carries the plaque (the price is the only label), so it outsizes the
   cost-chip icon; contain + no rounding since the art is a square coin. */
.btn-plaque .plq-cost .res-img { width:24px; height:24px; object-fit:contain;
  filter:drop-shadow(0 1px 2px rgba(58,34,8,.45)); }
.btn-plaque .plq-cost .ci.lack { color:#8e1a0c; }
/* Band: taller than the 30px close disc riding its corner (padding grows it past
   ~58px) with side room so the centred title clears the disc. */
.rcard.send-card .rc-head { padding:18px 46px 16px; }
/* Stage window: the shell's own slot-frame convention (parchment-silver gradient
   rim + black outline) around a deep recess; no silk backdrop by default — cutout
   units sit straight on the card's lacquer body. A modal opts into its own scene
   backdrop via a modifier below (composed under the border-box frame). */
.send-card .rc-stage {
  border:2px solid transparent;
  background:var(--slot-frame) border-box;
  box-shadow:var(--slot-outline), 0 1px 0 rgba(247,221,142,.16),
    inset 0 3px 16px rgba(0,0,0,.72), inset 0 0 34px rgba(0,0,0,.45);
}
/* Coletar: the scout rides a steppe-trail vista (2:3 art, cover-cropped; the
   slot-texture overlay above it keeps the house grain). */
.send-card .send-scout-stage {
  background:url('/assets/ui/scout-background.jpg?v=8f41a3c587') center/cover no-repeat padding-box,
    var(--slot-frame) border-box;
}
/* Purga: the priest stands before a temple-hall vista (same 2:3 cover-crop recipe). */
.send-card .send-priest-stage {
  background:url('/assets/ui/priest-background.jpg?v=8f41a3c587') center/cover no-repeat padding-box,
    var(--slot-frame) border-box;
}
/* Foot note (no scouts/camp, no priests/temple) — centred, flush against the foot's gap. */
.send-card .rc-foot .modal-note { margin:0; text-align:center; }
/* Recall roster (the pile Detalhes modal's scout rows) inside the card (capped, own scroll). */
.send-card .send-roster { max-height:34vh; overflow-y:auto; padding:0 16px 16px; }
/* Objective dossier ("Detalhes" on the send-card): the objective's own strip —
   difficulty gauge / stock / pool gauge — rides under the band; the body
   (garrison grids, raid rosters, sub/note lines) flows in a padded column. */
.send-card .whc-diff { margin:0 19px 12px; }
.send-card .send-dossier { padding:2px 19px 16px; }
/* Error slot: flush when idle, gapped only when it speaks. */
.send-card .send-err { margin:0 16px; }
.send-card .send-err.visible { margin:2px 16px 14px; }
#terrModal, #dtModal { position:fixed; inset:0; z-index:200; display:flex; align-items:center; justify-content:center;
  opacity:0; pointer-events:none; transition:opacity .2s ease; }
#terrModal.show, #dtModal.show { opacity:1; pointer-events:auto; }
.lm-backdrop { position:absolute; inset:0; background:rgba(8,3,3,.64); backdrop-filter:blur(3px); }
.lm-card {
  position:relative; width:min(460px, calc(100vw - 36px)); max-height:90vh; overflow:auto;
  border-radius:18px;
  background:
    linear-gradient(180deg, rgba(20,15,9,.45), rgba(8,6,3,.72)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat,
    linear-gradient(180deg,#241a10 0%, #19130c 52%, #120d08 100%);
  border:1px solid var(--gold-dim);
  box-shadow:0 44px 100px -30px rgba(0,0,0,.9), 0 0 0 1px rgba(0,0,0,.4);
  animation:modalIn .24s cubic-bezier(.22,1,.36,1); scrollbar-width:thin;
}
@keyframes modalIn { from{ opacity:0; transform:translateY(14px) scale(.97); } to{ opacity:1; transform:none; } }
.lui-close {
  position:absolute; top:14px; right:14px; z-index:6; display:grid; place-items:center; cursor:pointer;
  width:30px; height:30px; border-radius:8px;
  color:#fff; background:rgba(8,3,3,.5); border:1px solid rgba(255,255,255,.14);
  transition:color .15s, border-color .15s, background .15s;
}
.lui-close svg { width:16px; height:16px; transform:rotate(45deg); }
.lui-close:hover { color:var(--gold-hi); border-color:var(--gold-soft); background:rgba(8,3,3,.7); }
.lmf-hero { position:relative; height:174px; background-size:cover; background-position:center 42%; background-color:#2c1d0c; border-radius:18px 18px 0 0; }
.lmf-hero.under { filter:grayscale(.45) brightness(.84); }
.lmf-hero-grad { position:absolute; inset:0; background:linear-gradient(180deg, rgba(10,6,3,.12) 0%, rgba(10,6,3,.04) 38%, rgba(22,15,9,.74) 78%, rgba(17,12,7,.97) 100%); }
.lmf-herofoot { position:absolute; left:0; right:0; bottom:0; display:flex; align-items:flex-end; justify-content:space-between; gap:12px; padding:16px 18px; }
.lmf-title h3 { font-family:'Cinzel',serif; font-weight:700; font-size:24px; color:var(--parch); margin:0 0 5px; text-shadow:0 2px 10px rgba(0,0,0,.8); }
.lmf-lot { font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:rgba(243,231,196,.72); }
.lmf-lv { flex:none; display:inline-flex; align-items:center; gap:5px; padding:6px 13px; border-radius:9px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:12px; color:#2a0d0a;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft)); border:1px solid var(--gold-hi); box-shadow:0 3px 10px rgba(0,0,0,.5); }
.lmf-lv svg { width:12px; height:12px; flex:none; }
.lmf-lv.building { color:#fff4e9; background:linear-gradient(180deg, rgba(232,169,143,.95), rgba(158,36,24,.95)); border-color:var(--warn); }
.lmf-body { padding:18px; display:flex; flex-direction:column; gap:16px; }
.lmf-stats { display:flex; align-items:center; gap:12px; }
.lmf-stat { flex:1; display:flex; flex-direction:column; gap:7px; padding:13px 15px; border-radius:13px; background:rgba(0,0,0,.26); border:1px solid var(--line-soft); }
.lmf-stat .k { font-family:'JetBrains Mono',monospace; font-size:9.5px; letter-spacing:.12em; text-transform:uppercase; color:rgba(243,231,196,.45); }
.lmf-stat .v { font-family:'JetBrains Mono',monospace; font-weight:700; font-size:24px; color:var(--parch); font-variant-numeric:tabular-nums; line-height:1; }
.lmf-stat .v.gold { color:var(--gold); }
.lmf-stat .v.up { color:var(--up); }
.lmf-stat .v .u { font-weight:400; font-size:12px; color:rgba(243,231,196,.42); margin-left:2px; }
.lmf-arrow { width:22px; height:22px; color:var(--gold-soft); flex:none; opacity:.7; }
.lmf-section { display:flex; flex-direction:column; gap:11px; padding-top:2px; border-top:1px solid var(--line-soft); }
.lmf-sechead { display:flex; align-items:center; justify-content:space-between; margin-top:5px; }
.lmf-sechead > span:first-child { font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--gold-soft); }
.lmf-time { display:inline-flex; align-items:center; gap:6px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:12px; color:var(--gold-soft); }
.lmf-time svg { width:14px; height:14px; }
.lmf-costgrid { display:grid; grid-template-columns:repeat(auto-fit, minmax(72px,1fr)); gap:9px; }
.lmf-cost { display:flex; flex-direction:column; align-items:center; gap:5px; padding:12px 6px; border-radius:12px; background:rgba(0,0,0,.26); border:1px solid var(--line-soft); }
.lmf-cost img { width:26px; height:26px; border-radius:7px; object-fit:cover; box-shadow:0 1px 3px rgba(0,0,0,.5); }
.lmf-cost-v { font-family:'JetBrains Mono',monospace; font-weight:700; font-size:15px; color:var(--gold); font-variant-numeric:tabular-nums; }
.lmf-cost-k { font-family:'JetBrains Mono',monospace; font-size:9px; letter-spacing:.08em; text-transform:uppercase; color:rgba(243,231,196,.45); }
.lmf-cost.lack { border-color:rgba(158,36,24,.5); background:rgba(158,36,24,.12); }
.lmf-cost.lack .lmf-cost-v { color:var(--warn); }
.lmf-cost.lack img { filter:grayscale(.6) opacity(.75); }
.lmf-actions { display:flex; flex-direction:column; gap:9px; }
.lmf-primary { width:100%; padding:13px; font-size:15px; }
.lmf-maxed { display:flex; align-items:center; justify-content:center; gap:9px; padding:14px; border-radius:13px;
  border:1px solid rgba(63,174,134,.3); background:rgba(63,174,134,.1); color:var(--jade-soft); font-family:'Cinzel',serif; font-weight:600; font-size:14px; }
.lmf-maxed svg { width:18px; height:18px; }
.lmf-buildstate { display:flex; flex-direction:column; gap:12px; }
.lmf-buildtop { display:flex; align-items:baseline; justify-content:space-between; }
.lmf-buildtop .k { font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(243,231,196,.6); }
.lmf-buildtop .v { font-family:'JetBrains Mono',monospace; font-weight:700; font-size:18px; color:var(--jade-soft); font-variant-numeric:tabular-nums; }
.lmf-bigbar { position:relative; height:14px; border-radius:8px; background:rgba(0,0,0,.45); overflow:hidden; box-shadow:inset 0 1px 2px rgba(0,0,0,.5), inset 0 0 0 1px var(--line-soft); }
.lmf-bigbar i { position:absolute; inset:0 auto 0 0; background:linear-gradient(90deg, var(--jade-2), var(--jade-1)); box-shadow:0 0 12px rgba(63,174,134,.5); transition:width 1s linear; }
.lmf-bigbar i::after { content:""; position:absolute; inset:0; background:repeating-linear-gradient(60deg, rgba(255,255,255,.13) 0 7px, transparent 7px 14px); animation:flow 1s linear infinite; }
.lmf-cjk { position:absolute; top:13px; left:18px; font-family:'Noto Serif SC',serif; font-weight:900; font-size:30px; color:rgba(243,231,196,.22); letter-spacing:.12em; }
.ld-busy { display:flex; align-items:center; gap:8px; padding:8px 12px; border-radius:10px;
  background:rgba(158,36,24,.12); border:1px solid rgba(158,36,24,.4); color:rgba(243,231,196,.8); font-size:12px; }
.ld-busy svg { width:15px; height:15px; flex:none; color:var(--gold-soft); }
.ld-busy b { color:var(--parch); }
.lmf .terr-special-quote { margin:0; font-style:italic; color:rgba(243,231,196,.74); font-size:13.5px; line-height:1.55; }
.lmf-primary:disabled:not(.btn-plaque) { cursor:not-allowed; filter:grayscale(.55) brightness(.82); opacity:.6; }
.lmf-primary:disabled:not(.btn-plaque):hover { filter:grayscale(.55) brightness(.82); transform:none; }
@media (max-width:480px) {
  .lmf-stats { flex-direction:column; align-items:stretch; }
  .lmf-arrow { transform:rotate(90deg); align-self:center; }
}
.modal-stats {
  display:flex; gap:16px; flex-wrap:wrap; margin-bottom:16px; padding-bottom:14px;
  border-bottom:1px solid var(--line); font-size:13px; color:rgba(243,231,196,.85);
}
.modal-stats svg { width:14px; height:14px; vertical-align:-2px; color:var(--gold-soft); }
.modal-note { font-size:12.5px; line-height:1.5; color:rgba(243,231,196,.6); margin:0 0 14px; }
.modal-err { color:var(--warn); font-size:12.5px; margin-bottom:10px; min-height:0; }
.modal-err.visible { min-height:18px; }
.campaign-panel { padding:22px 24px 24px; margin-top:var(--gap); }
.campaign-panel .watermark { font-size:120px; right:28px; top:6px; }
.camp-row {
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  padding:12px 14px; border-radius:11px; margin-bottom:10px;
  border:1px solid var(--line); background:linear-gradient(180deg, rgba(0,0,0,.2), rgba(0,0,0,.06));
}
.camp-row:last-child { margin-bottom:0; }
.camp-info { display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:13.5px; color:var(--parch); }
.camp-info b { font-family:'Cinzel',serif; color:var(--gold-hi); }
.camp-phase { font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(243,231,196,.6); }
.camp-rem { color:var(--gold-soft); }
.camp-win { font-family:'Cinzel',serif; font-weight:600; font-size:12.5px; color:var(--up); }
.scout-report {
  border:1px solid var(--jade-edge); border-radius:11px;
  background:linear-gradient(180deg, rgba(63,174,134,.12), rgba(0,0,0,.1));
}
.camp-row.scout { border-color:var(--jade-edge); }
.army-stack.form-def,
.army-stack.form-atk { align-items:center; gap:9px; }
.tslot.ro.filled { cursor:default; }
.tslot.ro.filled:active { cursor:default; }
.tslot.ro.filled:hover { transform:none; box-shadow:var(--slot-outline); }
.tslot.mystery {
  display:grid; place-items:center;
  background:
    var(--slot-body) padding-box,
    var(--slot-frame) border-box;
}
.tslot-q {
  font-family:'Cinzel',serif; font-weight:700; font-size:34px; color:rgba(243,231,196,.45);
  text-shadow:0 1px 4px rgba(0,0,0,.8);
}
.facing-formation { display:flex; flex-direction:column; align-items:stretch; gap:8px; margin:6px 0 4px; }
.army-row { display:flex; flex-direction:row; align-items:center; justify-content:center; gap:16px; flex-wrap:wrap; }
.army-row > .ex-ident { flex:none; padding-right:0; }
.bt-ident .ab-ident-stack,
.camp-ident .ab-ident-stack { gap:7px; }
.camp-ident .ab-glyph,
.camp-ident .ab-avatar {
  color:var(--jade-soft);
  background:
    linear-gradient(180deg, rgba(20,40,32,.72), rgba(12,28,22,.55)) padding-box,
    linear-gradient(150deg, var(--jade-soft) 0%, var(--jade-edge) 58%, #2c6b52 100%) border-box;
}
.camp-avatar { object-position:50% 30%; }
.scout-report { display:flex; flex-direction:column; align-items:center; gap:8px; padding:14px; }
.army-page {
  position:relative; height:100%; overflow:hidden; isolation:isolate;
  display:flex; flex-direction:column;
}
.hero-view { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.recruit-area { flex:1 1 auto; min-height:0; overflow:auto; position:relative; }
/* ── Dev/Admin page (special testing actions) ── */
.dev-admin { max-width:640px; margin:0 auto; padding:8px 0 24px; display:flex; flex-direction:column; gap:16px; }
.dev-admin-title { font-family:'Cinzel',serif; font-size:22px; color:var(--parch); margin:0; letter-spacing:.02em; }
.dev-admin .panel { padding:18px 20px; }
.dev-admin .army-sec-head { margin:0 0 14px; }
.dev-admin .v2btn, .dev-admin .btn { align-self:flex-start; }
.dev-item-row { display:flex; gap:10px; flex-wrap:wrap; align-items:center; }
.dev-item-row .mkas-select { max-width:100%; }
#dev-item-id { max-width:360px; }
/* War-front admin panel (dev page) */
.dev-input {
  background:rgba(0,0,0,.3); border:1px solid rgba(217,178,74,.25); border-radius:8px;
  color:var(--parch); padding:8px 10px; font:inherit; font-size:13px; min-width:150px;
}
.dev-input::placeholder { color:rgba(243,231,196,.35); }
.dev-srv-row {
  display:flex; align-items:center; gap:12px; padding:10px 12px; margin-bottom:8px;
  border:1px solid rgba(217,178,74,.15); border-radius:10px;
  background:rgba(0,0,0,.18);
}
.dev-srv-row.closed { opacity:.6; }
.dev-srv-info { flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; }
.dev-srv-meta { font-family:'JetBrains Mono',monospace; font-size:10.5px; color:rgba(243,231,196,.55); }
.dev-srv-row .v2btn { flex:none; }
/* ═══════════════════════════════════════════════════════════════════════
   LEFT SIDEBAR (.railbar) — one lacquered panel holding the three nav
   sections. In FLOW as the shell-body's first flex column (2 × --rail-w wide),
   so .main-area starts to its right and no page ever underlaps it — pages just
   need their own even gutters. position:relative + z-index keeps it above the
   page-transition loader.
   ═══════════════════════════════════════════════════════════════════════ */
.railbar {
  position:relative; z-index:24; flex:none;
  width:calc(var(--rail-w) * 2); box-sizing:border-box;
  display:flex; flex-direction:column; min-height:0;
  padding:40px 12px 14px;          /* top pad clears the overhanging brand crest */
  background:
    linear-gradient(180deg, rgba(20,15,9,.32), rgba(8,6,3,.58)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat,
    linear-gradient(180deg,#241a10 0%, #19130c 52%, #120d08 100%);
  border-right:1px solid rgba(199,152,68,.35);
  box-shadow:6px 0 24px rgba(0,0,0,.5), inset -1px 0 0 rgba(247,221,142,.05);
}
.rb-scroll {
  flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden;
  display:flex; flex-direction:column; gap:16px;
}
.rb-scroll::-webkit-scrollbar { width:6px; }
.rb-scroll::-webkit-scrollbar-thumb { background:rgba(199,152,68,.34); border-radius:3px; }
.rb-scroll::-webkit-scrollbar-track { background:transparent; }
.rb-sec {
  display:flex; flex-direction:column; gap:6px;
  padding:8px 8px 10px; border:1px solid rgba(199,152,68,.30); border-radius:12px;
  background:rgba(0,0,0,.18); box-shadow:inset 0 1px 0 rgba(247,221,142,.05);
}
/* Collapse a section whose list is empty (e.g. no provinces yet) — no naked box. */
.rb-sec:has(> .rb-list:empty) { display:none; }
.rb-head {
  display:flex; align-items:center; justify-content:center; gap:8px; white-space:nowrap; overflow:hidden;
  padding:0 4px 3px; font-family:'Cinzel',serif; font-weight:700; font-size:9px;
  letter-spacing:.1em; text-transform:uppercase; color:var(--gold-soft); text-shadow:0 1px 2px #000;
}
/* Centered title flanked by two fading rules. */
.rb-head::before,
.rb-head::after { content:""; flex:1 1 auto; height:1px; }
.rb-head::before { background:linear-gradient(90deg, transparent, rgba(199,152,68,.4)); }
.rb-head::after  { background:linear-gradient(90deg, rgba(199,152,68,.4), transparent); }
.rb-list { display:flex; flex-direction:column; gap:5px; }

/* A nav row: full-width lacquer plaque, icon + label, whole thing clickable. */
.rb-item {
  display:flex; align-items:center; gap:10px; width:100%; position:relative;
  appearance:none; -webkit-appearance:none; cursor:pointer; text-align:left;
  padding:7px 10px; border-radius:9999px; line-height:1.2;   /* pill — same shape as the selected plaque */
  font-family:'Cinzel',serif; font-weight:600; font-size:11px; letter-spacing:.02em;
  color:rgba(241,230,198,.82);
  border:1px solid rgba(199,152,68,.28);
  background:linear-gradient(180deg, rgba(40,28,16,.5), rgba(20,14,8,.55));
  box-shadow:inset 0 1px 0 rgba(247,221,142,.06);
  transition:border-color .15s ease, background .15s ease, color .15s ease, transform .1s ease;
}
.rb-item:hover {
  color:#ffe9a8; border-color:var(--gold-hi);
  background:linear-gradient(180deg, rgba(58,40,20,.6), rgba(28,19,10,.62));
}
.rb-item:active { transform:translateY(1px); }
.rb-item.active {
  --sel-gold-hi:#f3b45e;                                  /* orangish gold text + icon */
  --rb-cap:21px;                                          /* gold cap width ≈ half the row height (~42px) */
  color:var(--sel-gold-hi); isolation:isolate;           /* isolate: keeps the ::before behind content, not behind the rail */
  border:1px solid transparent;                          /* 1px like inactive → activating a row shifts nothing */
  background:none;                                        /* the whole plaque is now the ::before texture */
}
/* Selected plaque = ONE flattened texture (gold frame + red leather baked together),
   drawn as a horizontal 3-slice border-image: the rounded end-caps (left/right slices)
   are NEVER stretched, only the straight middle stretches → caps stay perfectly round
   at any width. Source art button-navbar-selected.png is 1270×376, a true pill (cap
   radius 188 = height/2), so the slice is 188 and the rendered cap width (--rb-cap)
   must equal half the row height. Absolutely-positioned overlay → no layout impact. */
.rb-item.active::before {
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  border-style:solid; border-color:transparent; border-width:0 var(--rb-cap);
  border-image:url(/assets/ui/button-navbar-selected.png?v=8f41a3c587) 0 188 fill / 0 var(--rb-cap) / 0 stretch;
  filter:drop-shadow(0 2px 6px rgba(0,0,0,.5));          /* pill-shaped depth (follows the PNG alpha) */
}
/* Gold frame drawn in CSS (the PNG is red leather only). Kept separate from the
   texture so it stays crisp at any width and hugs the pill exactly. A gradient
   ring — light gold up top easing to a softer gold at the bottom — painted with the
   padding + mask trick so it follows the pill radius (border-image can't clip round). */
.rb-item.active::after {
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  border-radius:9999px; padding:2px;                     /* padding width = ring thickness */
  background:linear-gradient(180deg, #fdf1c8 0%, var(--gold-hi) 50%, var(--gold-soft) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude;    /* punch out the centre → only the ring shows */
  box-shadow:
    0 0 0 1px rgba(0,0,0,.32),                           /* crisp dark separation from the panel */
    0 0 8px rgba(240,190,90,.28);                        /* soft warm glow */
}
/* Foot rows (Decretos etc.) are a bit taller → slightly wider caps. */
.rb-foot .rb-item.active { --rb-cap:23px; }
.rb-ico { flex:none; width:26px; height:26px; display:grid; place-items:center; }
.rb-ico svg { width:20px; height:20px; color:var(--gold-hi); filter:drop-shadow(0 1px 2px rgba(0,0,0,.5)); }
.rb-ico img { width:22px; height:22px; object-fit:contain; filter:drop-shadow(0 1px 2px rgba(0,0,0,.5)); }
.rb-item.active .rb-ico svg { color:var(--sel-gold-hi); }
.rb-item.active .rb-ico img { filter:drop-shadow(0 0 6px rgba(240,170,80,.7)); }
.rb-label {
  flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  text-transform:uppercase;
}
/* Province names read as proper nouns (Luoyang, Jingzhou…), not shouted caps. */
.rb-item.seat .rb-label { text-transform:capitalize; letter-spacing:.01em; }
/* Flat lists — just icon + text, no plaque/border until hovered or active.
   Province seats plus the Menu-da-Província (#navRail) rows; the realm foot
   (#globalRail) keeps its plaque. */
.rb-item.seat:not(.active),
#navRail .rb-item:not(.active) { background:none; border-color:transparent; box-shadow:none; }
.rb-item.seat:not(.active):hover,
#navRail .rb-item:not(.active):hover { background:rgba(247,221,142,.07); border-color:transparent; color:#ffe9a8; }
/* "Fundar nova província" reads as a dashed ghost row. */
.rb-item.add-prov { border-style:dashed; color:var(--gold-soft); }
.rb-item.add-prov:hover { background:rgba(217,178,74,.16); }

/* Realm shortcuts pinned to the foot, below a divider. */
.rb-foot {
  flex:none; margin-top:12px; padding-top:12px; gap:6px;
  border-top:1px solid rgba(199,152,68,.22);
}
.rb-foot .rb-item { font-size:11.5px; padding:9px 11px; }

/* Selos badge on the Decretos row (Selos Imperiais disponíveis). */
.rb-item .rail-badge {
  position:absolute; right:9px; top:50%; transform:translateY(-50%); margin:0;
  min-width:19px; height:19px; padding:0 5px; box-sizing:border-box; border-radius:10px;
  display:grid; place-items:center; z-index:4; pointer-events:none;
  font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; line-height:1;
  color:#ffe9a8; background:linear-gradient(180deg,#c0392b,#7a1f17);
  border:1.5px solid rgba(247,221,142,.65); box-shadow:0 2px 6px rgba(0,0,0,.55);
}
.rb-item .rail-badge.empty { display:none; }

/* Honor→next-seal meter along the Decretos pill's bottom edge: fills as honor
   accumulates toward minting the next Selo (same seal-red as the Decretos page
   meter). Absolutely positioned inside the pill → no layout shift, and the
   insets keep it clear of the rounded end-caps. */
.rb-item .rail-meter {
  position:absolute; left:18px; right:18px; bottom:4px; height:3px;
  border-radius:2px; overflow:hidden; z-index:4; pointer-events:none;
  background:rgba(0,0,0,.5); box-shadow:0 0 0 1px rgba(247,221,142,.16);
}
.rb-item .rail-meter i {
  display:block; height:100%;
  background:linear-gradient(90deg, rgba(158,36,24,.92), rgba(224,86,66,.98));
  box-shadow:0 0 6px rgba(224,86,66,.45);
  transition:width .5s ease;
}

.rail-shell {
  position:absolute; top:0; bottom:0; width:auto; z-index:24;
  display:flex; flex-direction:column; min-height:0;
  pointer-events:none;            /* the page behind stays interactive… */
}
.rail-shell .nav,
.rail-shell .prov-item { pointer-events:auto; }
.banner {
  flex:1 1 auto; position:relative; display:flex; align-items:stretch; justify-content:center;
  padding:30px 14px; box-sizing:border-box; max-width:100%;
  border:0; border-radius:0; background:none; box-shadow:none;
}
#provinceRail { align-self:stretch; flex:1 1 auto; }
.banner .nav,
.banner .prov-item {
  width:56px; height:56px; flex:none; cursor:pointer; padding:0; border-radius:50%;
  display:grid; place-items:center; position:relative; color:var(--gold-hi); font-size:0;
  border:1.5px solid rgba(199,152,68,.55);
  background:
    linear-gradient(180deg, rgba(20,15,9,.35), rgba(8,6,3,.55)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat,
    linear-gradient(180deg,#241a10 0%, #19130c 52%, #120d08 100%);
  box-shadow:0 3px 8px rgba(0,0,0,.5), inset 0 1px 0 rgba(247,221,142,.12);
  transition:transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.banner .nav svg,
.banner .prov-item svg { width:24px; height:24px; display:block; opacity:1; color:var(--gold-hi); filter:drop-shadow(0 1px 2px rgba(0,0,0,.5)); }
.banner .nav:hover,
.banner .prov-item:hover { border-color:var(--gold-hi); transform:translateY(-2px);
  box-shadow:0 0 14px rgba(247,221,142,.4), 0 4px 8px rgba(0,0,0,.5); }
.banner .nav.active,
.banner .prov-item.active {
  width:64px; height:64px; color:#ffe9a8; border:2px solid var(--gold-hi);
  box-shadow:0 0 0 4px rgba(247,221,142,.12), 0 0 22px 3px rgba(247,221,142,.36), inset 0 1px 0 rgba(247,221,142,.2);
}
.banner .nav.active svg,
.banner .prov-item.active svg { width:28px; height:28px; filter:drop-shadow(0 0 6px rgba(240,209,120,.6)); }
.banner .nav.active::after { content:none; }
@keyframes worldTokPulse { 0%,100%{ opacity:.35; transform:scale(.96); } 50%{ opacity:.95; transform:scale(1.05); } }
@media (max-width:900px) {
  .shell-body { flex-direction:column; }
  .rail-shell { position:static; z-index:auto; align-self:stretch; width:auto; flex-direction:row; padding:8px 10px; pointer-events:auto; }
  .layout { padding-left:16px; padding-right:16px; }
  .banner { display:block; padding:0; border:0; background:none; box-shadow:none; border-radius:0; }
  /* Sidebar collapses to a wrapping top strip on narrow screens. */
  .railbar {
    position:static; width:100%; padding:10px 12px; box-shadow:none;
    border-right:0; border-bottom:1px solid rgba(199,152,68,.35);
  }
  .rb-scroll { overflow:visible; gap:10px; }
  .rb-list { flex-direction:row; flex-wrap:wrap; }
  .rb-item { width:auto; }
  .rb-foot { flex-direction:row; flex-wrap:wrap; margin-top:10px; }
  .rb-head::after { display:none; }
}
/* Shared column: sized by the widest block (in practice the exchange board).
   The board stretches to the column, and the CARDS flex-grow to the same limits —
   first/last card edges land exactly on the board's border (the board's 14px side
   margins mirror the grid's side padding). */
.recruit-col { width:max-content; margin:0 auto; }
.recruit-col .army-bar2 { width:auto; margin:14px 14px 0; }
.recruit-col .recruit-grid { width:auto; }
.recruit-col .rcard { flex:1 1 310px; width:auto; min-width:310px; }
/* Top/side padding keeps the cards' outer keyline + gold aura clear of the
   scroll container's clipping edge (.recruit-area is overflow:auto). */
.recruit-grid { display:flex; gap:15px; flex-wrap:nowrap; width:max-content; margin:0 auto; padding:14px 14px 4px; }
.rcard {
  flex:none; width:310px; position:relative; display:flex; flex-direction:column;
  transition:box-shadow .16s ease, transform .16s ease;
}
/* Recruit card shell: the send-card's neutral slot-frame dress (parchment-silver
   gradient border + 1px black outline, .rcard.send-card's exact recipe) over the
   lacquered chestnut body. Scoped to the recruit grid so market / founding cards
   keep the ornate tiled frame. */
#recruitGrid .rcard {
  border:2px solid transparent; border-radius:18px; border-image:none;
  background:
    radial-gradient(130% 70% at 50% -6%, rgba(240,209,120,.16), rgba(240,209,120,0) 58%) padding-box,
    linear-gradient(180deg, rgba(58,42,22,.25), rgba(16,10,5,.5)) padding-box,
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat padding-box,
    linear-gradient(180deg,#3b2b17 0%, #2a1d0f 52%, #1c1309 100%) padding-box,
    var(--slot-frame) border-box;
  box-shadow:
    var(--slot-outline),
    0 14px 34px rgba(0,0,0,.6),
    inset 0 1px 0 rgba(247,221,142,.16),
    inset 0 0 26px rgba(0,0,0,.42);
}
/* Army board: a quiet stage for the cards — dark lacquer (the recruit-card
   header's tone over the same texture), one thin gold hairline pinched by a dark
   keyline, soft depth. No band, no glow: the cards carry the shine. */
.army-bar2.gold-frame, .infirmary-panel.gold-frame {
  border:1px solid rgba(217,178,74,.45); border-radius:18px; border-image:none;
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(240,209,120,.08), rgba(240,209,120,0) 55%),
    linear-gradient(180deg, rgba(12,6,3,.72), rgba(24,14,8,.55)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat #3b2b17;
  box-shadow:
    0 0 0 1px rgba(14,7,4,.85),
    0 12px 30px rgba(0,0,0,.45),
    inset 0 1px 0 rgba(247,221,142,.07);
}
/* ─── Infirmary panel (army page): wounded convalescing back to the reserve ── */
.infirmary-panel { padding:12px 18px 14px; }
.recruit-col .infirmary-panel { width:auto; margin:14px 14px 0; }
.inf-head { display:flex; align-items:baseline; justify-content:space-between; gap:12px; }
.inf-head h3 { margin:0; font-size:15px; color:var(--gold-hi); letter-spacing:.04em; }
.inf-beds { font-size:12px; color:var(--parch); opacity:.85; white-space:nowrap; }
.inf-rows { display:flex; flex-direction:column; gap:6px; margin-top:10px; }
.inf-row {
  display:flex; align-items:center; gap:10px; padding:6px 10px;
  border:1px solid rgba(217,178,74,.22); border-radius:10px;
  background:linear-gradient(180deg, rgba(0,0,0,.28), rgba(0,0,0,.16));
}
.inf-art { width:30px; height:30px; object-fit:contain; filter:drop-shadow(0 2px 3px rgba(0,0,0,.6)); }
.inf-name { flex:1 1 auto; min-width:0; font-size:13px; color:var(--parch); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.inf-count { font-size:13px; color:var(--gold-hi); font-variant-numeric:tabular-nums; }
.inf-eta { display:inline-flex; align-items:center; gap:5px; font-size:12px; color:var(--parch); opacity:.9; font-variant-numeric:tabular-nums; }
.inf-eta svg { width:12px; height:12px; }
.inf-empty, .inf-note { margin:8px 0 0; font-size:12px; color:var(--parch); opacity:.75; }
.inf-note.inf-warn { color:#e9a08a; opacity:.95; }
.rcard .rc-name { color:var(--parch); text-shadow:0 1px 3px rgba(0,0,0,.6); }
.rc-pips i { color:var(--parch); }
.rc-pips i.on { box-shadow:none; }
/* Recruit card star + name use the same gold styling as the troop hover card
   (.tc-pips / .tc-name). Scoped to #recruitGrid so market cards stay untouched. */
#recruitGrid .rc-name, .send-card .rc-name { color:var(--gold-hi); }
#recruitGrid .rc-pips i { color:#f7c832; }
#recruitGrid .rc-pips i.on { color:#f7c832; filter:drop-shadow(0 0 5px rgba(247,200,50,.6)); }
.rc-head {
  position:relative;
  display:flex; align-items:center; gap:8px; padding:20px 19px 18px;
  background:transparent; border-bottom:none; border-radius:14px 14px 0 0;
}
.rc-head-mid { flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; gap:4px; }
.rc-name { min-width:0; max-width:100%; text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-family:'Cinzel',serif; font-weight:700; font-size:13px; line-height:1.1; color:var(--parch); letter-spacing:.02em; text-transform:uppercase; }
.rc-tnav {
  flex:none; width:32px; height:32px; border-radius:50%; padding:0; border:0;
  background:rgba(20,12,6,.35);
  display:grid; place-items:center; cursor:pointer; color:rgba(231,196,95,.62);
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.55));
  transition:transform .14s ease, color .14s ease, filter .14s ease;
}
.rc-tnav svg { width:22px; height:22px; }
.rc-tnav:hover { transform:scale(1.18); color:#ffe9a8; filter:drop-shadow(0 0 7px rgba(240,209,120,.7)); }
.rc-tnav:active { transform:scale(.9); }
.rc-tnav:disabled { cursor:default; color:rgba(231,196,95,.26); filter:none; transform:none; }
.rc-pips { display:flex; justify-content:center; gap:6px; }
.rc-pips i { width:17px; height:17px; display:block; color:var(--parch); opacity:.32; filter:drop-shadow(0 1px 0 rgba(0,0,0,.4)); }
.rc-pips i svg { width:100%; height:100%; fill:currentColor; }
.rc-pips i.on { color:var(--parch); opacity:1; filter:drop-shadow(0 0 4px rgba(243,231,196,.55)); }
.rc-stage {
  position:relative; aspect-ratio:1/1; height:auto; overflow:hidden; margin:0 19px; border-radius:10px;
  /* Backdrop is per-consumer (recruit grid / market / send stages each paint
     their own) — the base only carries the dark fallback. */
  background:#222428;
  /* Art window: dark recessed frame — the art sits sunken into the card, a deep
     shadowed rim with a faint gold hairline below it catching the light. */
  border:3px solid rgba(14,7,4,.9);
  box-shadow:
    0 1px 0 rgba(247,221,142,.22),
    inset 0 3px 14px rgba(0,0,0,.7),
    inset 0 0 30px rgba(0,0,0,.4);
}
.rc-stage::before {
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:url('/assets/slot-texture.png?v=8f41a3c587') center/cover no-repeat;
  mix-blend-mode:multiply; opacity:.55;
}
/* Recruit grid stage: full-bleed and unframed — no rim, no outline, no rounding;
   the art runs edge to edge between the header band and the foot, sunken only by
   its own inner shadow (the card's slot-frame shell carries the metal). */
#recruitGrid .rc-stage {
  border:0; margin:0; border-radius:0;
  /* The window takes the backdrop's own proportions (814×1024 art), so cover
     shows the full painting edge to edge — no crop. */
  aspect-ratio:814/1024;
  background:url('/assets/ui/recruitment-card-background.png?v=8f41a3c587') center/cover no-repeat;
  box-shadow:inset 0 3px 16px rgba(0,0,0,.72), inset 0 0 34px rgba(0,0,0,.45);
}
/* Bottom scrim: shadow rising from the foot of the art window so the available
   count and slider keep contrast over the bright backdrop. Same stacking level
   as the art but painted after it (::after is the last child); the z-index:3
   controls ride on top. Recruit grid only — market/send stages wear their own
   backdrops. */
#recruitGrid .rc-stage::after {
  content:""; position:absolute; left:0; right:0; bottom:0; height:30%;
  z-index:2; pointer-events:none;
  background:linear-gradient(to top, rgba(0,0,0,.82), rgba(0,0,0,.46) 34%, rgba(0,0,0,.14) 66%, rgba(0,0,0,0));
}
.rc-art { position:absolute; inset:0; z-index:2; width:100%; height:100%; object-fit:contain; object-position:50% 100%; }
/* Locked patente: the unit portrait reads as unavailable (drained of colour). */
.rcard.locked .rc-art { filter:grayscale(1) brightness(.5); opacity:.85; }
.rc-avail {
  position:absolute; left:50%; bottom:40px; transform:translateX(-50%); z-index:3;
  font-family:'Cinzel',serif; font-weight:700; font-variant-numeric:tabular-nums; white-space:nowrap;
  text-shadow:0 2px 6px rgba(0,0,0,.9);
}
.rc-avail .big { font-size:26px; color:#fff; }
.rc-avail .max { font-size:15px; color:var(--gold-soft); }
.rc-statrow { display:grid; grid-template-columns:repeat(4,1fr); gap:7px; }
/* Header band: dark lacquer strip setting the name/stars apart from the chestnut
   body — gold hairline underneath, faint sheen falling from the top edge. */
#recruitGrid .rc-head, .send-card .rc-head {
  padding:14px 14px 12px; margin-bottom:19px;
  /* Top radius = the slot-frame shells' inner curve (18px outer − 2px border). */
  border-radius:16px 16px 0 0;
  background:
    radial-gradient(120% 90% at 50% -30%, rgba(240,209,120,.10), transparent 60%),
    linear-gradient(180deg, rgba(12,6,3,.72), rgba(24,14,8,.5));
  border-bottom:3px solid rgba(14,7,4,.9);
  box-shadow:inset 0 1px 0 rgba(247,221,142,.08), 0 1px 0 rgba(247,221,142,.22);
}
/* Recruit cards run the art nearly flush under the band — a 1px hairline of
   body; the send modals keep the 19px breather above their gauge strip. */
#recruitGrid .rc-head { margin-bottom:1px; }
/* Recruit grid: the stat plaques ride INSIDE the art window, a strip along its
   top edge (above the art, under the lock pill); chips darken to hold up over
   the painting. */
#recruitGrid .rc-stage .rc-statrow { position:absolute; top:8px; left:8px; right:8px; z-index:3; gap:6px; }
#recruitGrid .rc-stage .rc-stat { background:rgba(14,8,4,.58); }
.rc-stat { display:flex; flex-direction:column; align-items:center; gap:3px; padding:7px 4px; border-radius:8px; background:rgba(0,0,0,.34); border:1px solid var(--line-soft); }
/* Stat icons share one gold — no per-stat color coding. */
.rc-stat svg { width:16px; height:16px; color:var(--gold-soft); }
.rc-stat .v { font-family:'JetBrains Mono',monospace; font-weight:700; font-size:13px; color:var(--parch); font-variant-numeric:tabular-nums; }
.rc-quote { margin-top:auto; font-style:italic; font-size:11.5px; line-height:1.5; color:rgba(243,231,196,.6); text-wrap:pretty; }
.rc-slider { position:absolute; left:0; right:0; bottom:9px; z-index:3; display:flex; align-items:center; gap:9px; padding:0 12px; }
.rc-arrow { flex:none; width:28px; height:28px; display:grid; place-items:center; cursor:pointer; border-radius:7px; color:var(--gold-hi); background:rgba(20,12,6,.6); border:1px solid rgba(217,178,74,.45); transition:all .12s ease; }
.rc-arrow svg { width:14px; height:14px; }
.rc-arrow:hover { color:#2a0d0a; background:linear-gradient(180deg, var(--gold-hi), var(--gold)); border-color:var(--gold); }
.rc-arrow:active { transform:scale(.92); }
.rc-range { flex:1; -webkit-appearance:none; appearance:none; height:7px; border-radius:7px; outline:none; background:rgba(255,255,255,.22); border:1px solid rgba(0,0,0,.4); cursor:pointer; }
.rc-range::-webkit-slider-runnable-track { height:7px; border-radius:7px; background:linear-gradient(90deg, var(--gold), var(--gold-hi)); }
.rc-range::-moz-range-track { height:7px; border-radius:7px; background:linear-gradient(90deg, var(--gold), var(--gold-hi)); }
.rc-range::-webkit-slider-thumb { -webkit-appearance:none; width:18px; height:18px; margin-top:-7px; border-radius:50%; background:radial-gradient(circle at 35% 30%, #fff, var(--gold)); border:1px solid #5c1410; box-shadow:0 2px 5px rgba(0,0,0,.5); cursor:grab; }
.rc-range::-moz-range-thumb { width:18px; height:18px; border-radius:50%; background:radial-gradient(circle at 35% 30%, #fff, var(--gold)); border:1px solid #5c1410; cursor:grab; }
.rc-foot { padding:18px 19px 19px; display:flex; flex-direction:column; gap:18px; }
.rc-cost-row { display:flex; align-items:center; justify-content:center; gap:14px; }
.rc-cost-row .ci { display:inline-flex; align-items:center; gap:6px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:13px; color:var(--parch); font-variant-numeric:tabular-nums; }
.rc-cost-row .ci img,
.rc-cost-row .ci .res-img { width:16px; height:16px; border-radius:4px; object-fit:cover; }
.rc-cost-row .ci.coin { color:var(--gold-soft); }
.rc-cost-row .ci.lack { color:#e0563c; }
.recruit-area .panel { max-width:960px; margin:24px auto 0; }
.army-bar2 {
  flex:none; margin:14px auto 0; width:fit-content; max-width:100%; box-sizing:border-box;
  overflow:visible; position:relative;
}
.exchange { display:flex; flex-direction:row; align-items:stretch; justify-content:center; }
.ex-col { display:flex; flex-direction:row; align-items:center; gap:16px; padding:14px 18px; }
.active-col { flex:0 0 auto; min-width:0; }
.reserve-col { flex:0 0 auto; align-self:stretch; flex-direction:row-reverse; }
.army-sep {
  flex:none; align-self:stretch; width:34px;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:7px;
  padding:18px 0;
}
.cn-line {
  flex:0 0 auto; width:1px; height:26px;
  background:linear-gradient(180deg, transparent, var(--gold-soft) 22%, var(--gold-hi) 50%, var(--gold-soft) 78%, transparent);
  box-shadow:0 0 8px -2px rgba(217,178,74,.5);
}
.cn-coin { flex:none; line-height:0; filter:drop-shadow(0 4px 10px rgba(0,0,0,.55)); }
.cn-coin svg { width:26px; height:26px; }
.ex-ident { position:relative; width:212px; flex:none; display:flex; align-items:center; gap:12px; padding-right:6px; }
/* Formation save/load — a slim vertical rail between the ident and the army grid. */
.ex-actions { display:flex; flex-direction:column; gap:8px; justify-content:center; flex:none; }
.reserve-ident { flex-direction:row; align-items:center; gap:12px; padding:6px 10px 6px 6px; }
.reserve-glyph { color:var(--jade-soft); border-color:var(--jade-edge); }
.reserve-gate-img { width:68px; height:68px; object-fit:contain; display:block; }
.ab-ident-stack { display:flex; flex-direction:column; align-items:center; gap:9px; width:100%; }
.ab-ident-stack .hname { font-family:'Cinzel',serif; font-weight:700; font-size:15px; color:var(--gold-hi); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hname-row { display:flex; align-items:center; justify-content:center; gap:6px; max-width:100%; }
.ab-ident-txt { min-width:0; text-align:center; }
.ab-ident-txt .htitle { font-family:'Noto Serif',serif; font-size:10.5px; color:rgba(243,231,196,.55); margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ab-portrait { position:relative; display:inline-block; line-height:0; }
/* Shared hero-dossier link affordance for ANY hero portrait (wired by
   army-kit.js wireHeroLink — army board ident, world HUD, ...). */
.hero-link { cursor:pointer; transition:transform .14s ease, filter .14s ease; }
.hero-link:hover { transform:scale(1.04); filter:drop-shadow(0 0 9px rgba(240,209,120,.55)); }
.hero-link:focus-visible { outline:2px solid var(--gold-hi); outline-offset:3px; border-radius:50%; }
/* Hero armies wear the shared .hport ring at the army-bar size (camps keep the
   flat .ab-avatar look below). */
.ab-hport { --hp:104px; --hpb:32px; }
.ab-avatar {
  width:104px; height:104px; flex:none; border-radius:50%; object-fit:cover; object-position:50% 18%;
  border:3px solid transparent;
  background:
    linear-gradient(180deg, var(--card, rgba(60,12,12,.72)), var(--card-2, rgba(40,9,9,.55))) padding-box,
    linear-gradient(150deg, var(--gold-hi) 0%, var(--gold-dim) 35%, #6e4a17 62%, var(--gold-soft) 100%) border-box;
  box-shadow:0 8px 20px -10px rgba(0,0,0,.9);
}
.ab-glyph {
  width:104px; height:104px; flex:none; border-radius:50%; display:grid; place-items:center;
  border:3px solid transparent;
  background:
    linear-gradient(180deg, var(--card, rgba(60,12,12,.72)), var(--card-2, rgba(40,9,9,.55))) padding-box,
    linear-gradient(150deg, var(--gold-hi) 0%, var(--gold-dim) 35%, #6e4a17 62%, var(--gold-soft) 100%) border-box;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:27px; color:var(--gold-hi);
  box-shadow:0 8px 20px -10px rgba(0,0,0,.9), inset 0 2px 8px rgba(0,0,0,.4);
}
.ab-glyph svg { width:44%; height:44%; color:rgba(243,231,196,.4); }
.ab-hero-meta { display:flex; gap:6px; margin-top:2px; justify-content:center; flex-wrap:wrap; }
/* Exchange/Batalha boards: the ident's troop + power chips are a fixed 2-up row —
   never let them wrap. On drag the counts change width, and a wrap would grow the
   ident's height and jitter the modal's size as troops move (side-by-side always). */
.exchange .ab-hero-meta { flex-wrap:nowrap; }
.ab-chip { display:inline-flex; align-items:center; gap:5px; padding:3px 8px; border-radius:7px; background:rgba(0,0,0,.3); border:1px solid var(--line-soft); font-family:'JetBrains Mono',monospace; font-weight:700; font-size:10.5px; color:var(--parch); font-variant-numeric:tabular-nums; }
.ab-chip svg { width:11px; height:11px; color:var(--gold-soft); }
.ab-chip.over { color:var(--warn); }
.ab-chip.over svg { color:var(--warn); }
.ab-xp { margin-top:6px; width:100%; }
.ab-xp-bar { width:100%; height:6px; border-radius:5px; overflow:hidden; background:rgba(0,0,0,.4); border:1px solid var(--line); }
.ab-xp-bar span { display:block; height:100%; background:linear-gradient(90deg, var(--jade-soft), var(--gold-soft)); }
.ab-xp-txt { display:block; margin-top:3px; text-align:center; font-family:'JetBrains Mono',monospace; font-size:9px; color:rgba(243,231,196,.5); }
.army-stack { display:flex; flex-direction:column; position:relative; --tsz:74px; --tgap:9px; --msz:26px; }
.slot-row { display:flex; gap:9px; flex-wrap:wrap; }
.slot-row.army-grid { display:grid; grid-template-columns:repeat(3, 74px); grid-auto-rows:74px; gap:9px; }
.row-medal {
  position:absolute; left:calc(var(--msz) / -2); z-index:3;
  width:var(--msz); height:var(--msz); border-radius:50%;
  display:grid; place-items:center; border:1px solid transparent;
  background:
    linear-gradient(180deg, rgba(30,12,10,.96), rgba(14,6,5,.92)) padding-box,
    linear-gradient(150deg, var(--gold-hi) 0%, #6e4a17 55%, var(--gold-soft) 100%) border-box;
  box-shadow:0 2px 6px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.08);
}
.row-medal svg { width:14px; height:14px; color:var(--gold-hi); filter:drop-shadow(0 1px 1px rgba(0,0,0,.7)); }
.row-medal.back svg { color:rgba(240,209,120,.72); }
.row-medal.r1 { top:calc(var(--tsz)/2 - var(--msz)/2); }
.row-medal.r2 { top:calc(var(--tsz)*1.5 + var(--tgap) - var(--msz)/2); }
@keyframes pop-in { from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:none; } }
/* ── Generic slot frame ── the app-wide tile chrome: a 2px gold GRADIENT
   border (transparent border + var(--slot-frame) painted border-box behind
   the state's own padding-box body) ringed by a 1px black outline shadow
   (var(--slot-outline)). Army squads (.tslot), hero skills (.skill-slot),
   the skill-modal seal (.hxk-tile) and item tiles (.islot) all share it —
   state rules only swap the BODY layers (items tint theirs by rarity), never
   the frame. Rules that restate box-shadow must compose var(--slot-outline)
   back in, or the outline blinks out. */
.tslot, .skill-slot, .hxk-tile, .islot {
  border:2px solid transparent;
  box-shadow:var(--slot-outline);
}
.tslot {
  width:74px; height:74px; flex:none; border-radius:14px; position:relative; overflow:hidden;
  background:
    var(--slot-body) padding-box,
    var(--slot-frame) border-box;
  transition:border-color .18s ease, box-shadow .2s ease, transform .14s ease;
}
.tslot.empty {
  background:
    var(--slot-body) padding-box,
    var(--slot-frame) border-box;
}
.tslot.filled {
  cursor:grab;
  background:
    var(--slot-body) padding-box,
    var(--slot-frame) border-box;
}
.tslot.filled:hover { box-shadow:var(--slot-outline), 0 14px 32px -22px rgba(0,0,0,.8); transform:translateY(-1px); }
.tslot.filled:active { cursor:grabbing; }
.tslot-art { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:50% 22%; pointer-events:none; border-radius:11px; }
.tslot-grad { position:absolute; inset:0; background:linear-gradient(0deg, rgba(0,0,0,.82) 0%, rgba(0,0,0,.1) 46%); pointer-events:none; }
.tslot-n {
  position:absolute; left:0; right:0; bottom:4px; text-align:center; z-index:2; pointer-events:none;
  font-family:'Cinzel',serif; font-weight:700; font-size:16px; color:#fff; font-variant-numeric:tabular-nums;
  text-shadow:0 1px 4px rgba(0,0,0,.95);
}
.tslot-line { position:absolute; top:4px; left:4px; z-index:2; display:grid; place-items:center; width:18px; height:18px; border-radius:6px; color:var(--gold-hi); background:rgba(0,0,0,.55); box-shadow:inset 0 0 0 1px rgba(217,178,74,.35); pointer-events:none; }
.tslot-line svg { width:12px; height:12px; }
.tslot.drop-ok { border-color:var(--gold-hi); box-shadow:var(--slot-outline), 0 0 0 2px rgba(217,178,74,.55), inset 0 0 16px rgba(217,178,74,.2); }
.tslot.drop-bad { border-color:var(--warn); box-shadow:var(--slot-outline), 0 0 0 2px rgba(158,36,24,.55); }
.tslot.dragging { opacity:.4; }
.army-bar2 .tslot { border-radius:7px; }
.army-bar2 .tslot-art { border-radius:5px; }
.army-bar2 .tslot-n { left:4px; right:auto; bottom:2px; font-size:13px; }
@media (max-width:1180px) {
  .ex-ident { width:170px; }
}
@media (max-width:1024px) {
  .exchange { flex-direction:column; align-items:center; }
  .army-sep { width:auto; flex-direction:row; padding:0; }
  .army-sep .cn-line { width:60px; height:1px; }
  .ex-col { flex-direction:column; align-items:center; }
  .reserve-col { flex-direction:column; align-self:auto; }
  .ex-ident { width:auto; }
  .ex-actions { flex-direction:row; }
}
.split-overlay { position:fixed; inset:0; z-index:240; display:none; align-items:center; justify-content:center; padding:24px; background:rgba(10,3,3,.72); backdrop-filter:blur(3px); }
.split-overlay.show { display:flex; }
.split-modal { width:100%; max-width:400px; border-radius:16px; position:relative; overflow:hidden;
  background:linear-gradient(180deg,#2c0a0a,#200707); border:1px solid var(--gold-soft);
  box-shadow:0 40px 90px -30px rgba(0,0,0,.9); animation:modal-in .2s cubic-bezier(.2,.9,.3,1); }
@keyframes modal-in { from{ opacity:0; transform:translateY(12px) scale(.97);} to{ opacity:1; transform:none; } }
.sm-head { display:flex; align-items:center; gap:12px; padding:16px 18px; border-bottom:1px solid var(--line); }
.sm-head img { width:46px; height:46px; border-radius:9px; object-fit:cover; border:1px solid var(--gold-soft); }
.sm-head .t { font-family:'Cinzel',serif; font-weight:700; font-size:16px; color:var(--gold-hi); }
.sm-head .s { font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.08em; text-transform:uppercase; color:rgba(243,231,196,.5); margin-top:3px; }
.sm-body { padding:18px; }
.sm-two { display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; font-family:'JetBrains Mono',monospace; font-variant-numeric:tabular-nums; }
.sm-two .col { text-align:center; flex:1; }
.sm-two .col .n { font-family:'Cinzel',serif; font-weight:700; font-size:26px; color:var(--parch); }
.sm-two .col .l { font-size:9px; letter-spacing:.12em; text-transform:uppercase; color:rgba(243,231,196,.45); margin-top:2px; }
.sm-two .arrow { flex:none; display:flex; flex-direction:column; align-items:center; gap:1px; color:var(--gold-hi); padding:0 12px; }
.sm-two .arrow span { display:grid; place-items:center; }
/* The moving headcount rides above the arrow; reserved height so nothing jumps. */
.sm-two .arrow .cnt { min-height:15px; font-weight:700; font-size:12.5px; color:var(--parch); }
.sm-two .arrow svg { width:34px; height:34px; filter:drop-shadow(0 2px 4px rgba(0,0,0,.5)); transition:transform .15s ease; }
/* Redistribution: both columns show FINAL totals. While the split matches the
   current counts the arrow rests as a dim two-way swap; once troops move it
   becomes the directional arrow pointing at the gaining side. */
.sm-two .arrow.to-left .dir svg { transform:scaleX(-1); }
.sm-two .arrow .both { display:none; }
.sm-two .arrow.idle .dir { display:none; }
.sm-two .arrow.idle .both { display:grid; opacity:.45; }
.sm-two .arrow .both svg { width:28px; height:28px; }
.sm-range { width:100%; -webkit-appearance:none; appearance:none; height:7px; border-radius:7px; outline:none; background:rgba(0,0,0,.4); cursor:pointer; margin:6px 0 14px; }
.sm-range::-webkit-slider-runnable-track { height:7px; border-radius:7px; background:linear-gradient(90deg,var(--gold-soft),var(--gold-hi)); }
.sm-range::-webkit-slider-thumb { -webkit-appearance:none; width:20px; height:20px; margin-top:-7px; border-radius:50%; background:radial-gradient(circle at 35% 30%,#fff,var(--gold-hi)); border:1px solid #2a0d0a; cursor:grab; }
.sm-range::-moz-range-thumb { width:20px; height:20px; border-radius:50%; background:radial-gradient(circle at 35% 30%,#fff,var(--gold-hi)); border:1px solid #2a0d0a; cursor:grab; }
.sm-two .sm-num { width:100%; background:none; border:0; outline:none; text-align:center; padding:0;
  font-family:'Cinzel',serif; font-weight:700; font-size:26px; color:var(--parch);
  -moz-appearance:textfield; appearance:textfield; }
.sm-num::-webkit-outer-spin-button,
.sm-num::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
/* Army units chip while a reserve stack is mid-drag: shows the room that still fits. */
.ab-chip.room { color:var(--gold-hi); border-color:var(--gold-soft); background:rgba(0,0,0,.55); }
.ab-chip.room svg { color:var(--gold-hi); }
/* Promotion panel (shared/promote.js — hosted by the app modal) */
.pm h3 { font-family:'Cinzel',serif; font-weight:700; font-size:17px; color:var(--gold-hi); margin:0 0 14px; }
.pm-pair { display:flex; align-items:center; justify-content:center; gap:14px; margin-bottom:14px; }
.pm-unit { text-align:center; flex:1; max-width:130px; }
.pm-unit img { width:64px; height:64px; border-radius:10px; object-fit:cover; border:1px solid var(--gold-soft); }
.pm-uname { font-family:'Cinzel',serif; font-weight:700; font-size:12px; color:var(--parch); margin-top:6px; }
.pm-arrow { flex:none; color:var(--gold-soft); }
.pm-arrow svg { width:22px; height:22px; }
.pm-note { display:flex; align-items:center; justify-content:center; gap:7px; font-size:12.5px; color:var(--parch); margin:0 0 14px; }
.pm-note svg { width:14px; height:14px; color:var(--gold-soft); flex:none; }
.pm-count { display:flex; align-items:baseline; justify-content:center; gap:6px; font-family:'JetBrains Mono',monospace; font-variant-numeric:tabular-nums; margin-bottom:2px; }
.pm-num { width:110px; background:none; border:0; outline:none; text-align:right; padding:0;
  font-family:'Cinzel',serif; font-weight:700; font-size:26px; color:var(--gold-hi);
  -moz-appearance:textfield; appearance:textfield; }
.pm-num::-webkit-outer-spin-button,
.pm-num::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
.pm-max { font-size:13px; color:rgba(243,231,196,.5); }
.pm-cost { display:flex; justify-content:center; gap:14px; margin:4px 0 16px; }
.sm-foot { display:flex; gap:10px; }
.sm-foot .btn { flex:1; padding:10px; border-radius:9px; cursor:pointer; font-family:'Cinzel',serif; font-weight:700; font-size:13px; }
.sm-foot .btn-ghost { color:rgba(243,231,196,.72); background:rgba(0,0,0,.25); border:1px solid var(--line); }
.sm-foot .btn-gold { color:#3a1008; background:linear-gradient(180deg, var(--gold-hi), var(--gold)); border:1px solid var(--gold-hi); }
.sm-foot .btn.grow { flex:2; }
.ct-canvas {
  position:relative; height:100%; overflow:hidden; isolation:isolate;
  cursor:grab; touch-action:none; user-select:none; -webkit-user-select:none;
}
.ct-canvas.panning { cursor:grabbing; }
.ct-stage { position:absolute; top:0; left:0; width:max-content; will-change:transform; }
.ct-canvas .dec-error {
  position:absolute; top:12px; left:50%; transform:translateX(-50%); z-index:10;
  margin:0; min-height:0; max-width:min(620px, calc(100% - 32px));
  padding:8px 14px; border-radius:10px; text-align:center;
  background:rgba(20,5,5,.92); border:1px solid rgba(158,36,24,.6);
  box-shadow:0 10px 24px -10px rgba(0,0,0,.85);
}
.lmf-hero.mil { background-position:center 12%; background-color:#221409; }
.lmf-reqs { display:flex; flex-direction:column; gap:7px; }
.lmf-req {
  display:flex; align-items:center; gap:9px; padding:9px 12px; border-radius:10px; cursor:pointer;
  text-align:left; width:100%; font-family:'Noto Serif',serif; font-size:13px; color:var(--parch);
  background:rgba(0,0,0,.26); border:1px solid rgba(158,36,24,.45);
  transition:border-color .14s ease, background .14s ease;
}
.lmf-req svg { width:14px; height:14px; flex:none; color:#e8cd92; }
.lmf-req.ok { border-color:rgba(63,174,134,.35); }
.lmf-req.ok svg { color:var(--jade-soft); }
.lmf-req:hover { border-color:var(--gold-soft); background:rgba(217,178,74,.08); }
.lmf-note { margin:0; font-size:12.5px; line-height:1.55; color:rgba(243,231,196,.62); font-style:italic; }
.ct-board {
  --ct-col:156px; --ct-row:138px;   /* node rows: 92px tile + 46px breathing room */
  position:relative; display:grid; isolation:isolate;
  justify-items:center; align-items:center;
}
.ct-vsep {
  align-self:stretch; justify-self:start; width:1px; z-index:6; pointer-events:none;
  background:linear-gradient(180deg, transparent, rgba(176,142,74,.32) 48px, rgba(176,142,74,.32) calc(100% - 48px), transparent);
}
.ct-lockveil {
  grid-row:2/-1; place-self:stretch; z-index:0; pointer-events:none;
  background:rgba(0,0,0,.28);
}
.ct-tierhead {
  position:relative;   /* anchors the ::after glow overlays of the state rules */
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; z-index:5;
  place-self:stretch; padding:12px 10px 10px; cursor:pointer;
  /* body + frame via the shared .gold-frame.sm component (half scale) */
  color:inherit; font-family:inherit;
  box-shadow:0 10px 22px -12px rgba(0,0,0,.85);
}
.ct-tierhead:hover .ct-tiertitle { color:#ffe9a8; }
.ct-tiertitle {
  font-family:'Cinzel',serif; font-weight:700; font-size:14px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--gold-hi); text-shadow:0 1px 3px #000;
  transition:color .14s ease;
}
.ct-tiersub {
  display:inline-flex; align-items:center; gap:5px;
  font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.08em; color:var(--jade-soft);
}
.ct-tiersub svg { width:12px; height:12px; }
.ct-district {
  grid-column:1/-1; justify-self:stretch; align-self:end; z-index:2; pointer-events:none;
  display:flex; align-items:center; gap:12px; padding:20px 8px 12px;
}
.ct-district::before,
.ct-district::after { content:""; flex:1; height:1px; }
.ct-district::before { background:linear-gradient(90deg, transparent, var(--line)); }
.ct-district::after { background:linear-gradient(90deg, var(--line), transparent); }
.ct-district .band-mono { font-family:'Cinzel',serif; font-weight:700; font-size:19px; color:var(--gold-dim); }
.ct-district .lbl { font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.24em; text-transform:uppercase; color:var(--gold-soft); }
.ct-node {
  position:relative; place-self:center; width:92px; height:92px; padding:0; cursor:pointer; z-index:3;
  border-radius:14px; border:1.5px solid rgba(176,142,74,.4);
  background:none;
  box-shadow:0 10px 22px -10px rgba(0,0,0,.85), inset 0 1px 0 rgba(255,255,255,.06);
  transition:transform .14s ease, border-color .14s ease, box-shadow .14s ease, opacity .18s ease, filter .18s ease;
}
.ct-node img {
  position:absolute; inset:0; z-index:2; width:100%; height:100%; border-radius:12px;
  object-fit:cover; object-position:50% 40%; filter:drop-shadow(0 3px 5px rgba(0,0,0,.6));
  pointer-events:none;
}
.ct-name {
  position:absolute; left:0; right:0; bottom:0; z-index:3; padding:14px 5px 5px;
  font-family:'Cinzel',serif; font-weight:700; font-size:9px; line-height:1.15;
  color:var(--parch); text-align:center; text-shadow:0 1px 3px rgba(0,0,0,.9);
  background:linear-gradient(180deg, rgba(10,7,4,0) 0%, rgba(14,10,5,.88) 60%);
  border-radius:0 0 12px 12px; pointer-events:none;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.ct-node.st-locked .ct-name { color:rgba(220,205,170,.6); }
.ct-tiernum {
  position:absolute; top:5px; left:5px; z-index:4;
  min-width:18px; height:18px; padding:0 4px;
  display:grid; place-items:center; border-radius:6px;
  font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; line-height:1;
  color:var(--gold-hi); pointer-events:none;
  background:linear-gradient(180deg, rgba(28,22,12,.9), rgba(16,12,7,.9));
  border:1px solid rgba(176,142,74,.55);
  box-shadow:0 2px 5px -1px rgba(0,0,0,.7);
}
.ct-node.st-locked .ct-tiernum { color:rgba(200,180,140,.55); border-color:rgba(120,100,70,.4); }
.ct-node:hover { transform:translateY(-3px) scale(1.03); }
.ct-node:active { transform:translateY(-1px); }
.ct-node.st-avail {
  border-color:var(--gold-hi); border-width:2px;
  box-shadow:0 0 0 3px rgba(240,209,120,.14), 0 0 16px 2px rgba(240,209,120,.32), 0 10px 22px -10px rgba(0,0,0,.85);
}
.ct-node.st-avail::before {
  content:""; position:absolute; inset:-7px; z-index:1; border-radius:19px; pointer-events:none;
  border:1px solid rgba(240,209,120,.4);
  animation:ctAvailPulse 2.6s ease-in-out infinite;
}
@keyframes ctAvailPulse { 0%,100%{ opacity:.35; transform:scale(.96); } 50%{ opacity:.95; transform:scale(1.05); } }
.ct-node.st-locked { border-color:rgba(120,100,70,.35); }
.ct-node.st-locked img { filter:grayscale(.85) brightness(.55) drop-shadow(0 3px 5px rgba(0,0,0,.6)); }
.ct-node.st-building {
  border-color:rgba(63,174,134,.75);
  box-shadow:0 0 14px -2px rgba(63,174,134,.45), 0 10px 22px -10px rgba(0,0,0,.85);
}
.ct-tierhead.st-locked .ct-tiertitle { color:rgba(220,205,170,.45); }
.ct-tierhead.st-locked .ct-tiersub { color:rgba(220,205,170,.4); }
.ct-tierhead.st-locked:hover .ct-tiertitle { color:rgba(220,205,170,.6); }
.ct-tierhead.st-avail {
  /* gold glow layered over the same textured body as the base header */
  background:
    linear-gradient(180deg, rgba(240,209,120,.22), rgba(240,209,120,.05)),
    linear-gradient(180deg, rgba(20,15,9,.22), rgba(8,6,3,.42)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat,
    linear-gradient(180deg,#241a10 0%, #19130c 52%, #120d08 100%);
}
.ct-tierhead.st-avail::after {
  content:""; position:absolute; inset:-9px; border-radius:14px; z-index:1; pointer-events:none;
  animation:ctHeadPulse 2.6s ease-in-out infinite;
}
.ct-tierhead.st-avail .ct-tiertitle { color:#ffe9a8; text-shadow:0 0 14px rgba(240,209,120,.95), 0 0 28px rgba(240,209,120,.5), 0 1px 3px #000; }
.ct-tierhead.st-avail .ct-tiersub { color:var(--gold-hi); text-shadow:0 0 10px rgba(240,209,120,.7); }
@keyframes ctHeadPulse {
  0%,100%{ box-shadow:inset 0 0 30px -6px rgba(240,209,120,.5), 0 0 14px -2px rgba(240,209,120,.3); }
  50%{ box-shadow:inset 0 0 40px -4px rgba(240,209,120,.95), 0 0 26px 0 rgba(240,209,120,.6); }
}
.ct-tierhead.st-building::after {
  content:""; position:absolute; inset:-9px; border-radius:14px; z-index:1; pointer-events:none;
  box-shadow:inset 0 0 24px -8px rgba(63,174,134,.5);
}
.ct-tierhead.st-building .ct-tiersub { color:var(--jade-soft); }
.ct-badge {
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); z-index:4;
  min-width:26px; height:26px; padding:0 7px;
  display:grid; place-items:center; border-radius:13px;
  font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; white-space:nowrap;
}
.ct-badge svg { width:13px; height:13px; }
.ct-badge.building { color:#dff7ec; background:linear-gradient(180deg, rgba(42,124,94,.95), rgba(29,87,66,.95)); border:1px solid rgba(120,220,180,.5); }
.ct-prog {
  position:absolute; left:6px; right:6px; bottom:5px; height:5px; z-index:4; border-radius:4px; overflow:hidden;
  background:rgba(0,0,0,.55); box-shadow:inset 0 0 0 1px rgba(0,0,0,.4);
}
.ct-prog i { position:absolute; inset:0 auto 0 0; background:linear-gradient(90deg, var(--jade-2), var(--jade-1)); box-shadow:0 0 8px rgba(63,174,134,.5); transition:width 1s linear; }
.ct-arrows { position:absolute; inset:0; width:100%; height:100%; z-index:2; pointer-events:none; overflow:visible; }
.ct-base { opacity:.46; }
.ct-edge path { fill:none; stroke:rgb(243,231,196); stroke-width:1.6; }
.ct-edge polygon { fill:rgb(243,231,196); }
.ct-edge path,
.ct-edge polygon { transition:opacity .18s ease, stroke .18s ease, fill .18s ease; }
.ct-node.hl { opacity:1; border-color:var(--gold-hi); }
.ct-edge.hl path { stroke:var(--gold-hi); stroke-width:1.9; filter:drop-shadow(0 0 2px rgba(240,209,120,.4)); }
.ct-edge.hl polygon { fill:var(--gold-hi); filter:drop-shadow(0 0 2px rgba(240,209,120,.4)); }
@media (max-width:600px) {
  .ct-board { --ct-col:118px; --ct-row:112px; padding:18px 22px 42px; }
  .ct-node { width:76px; height:76px; }
  .ct-tierhead { padding:9px 8px 8px; }
}
/* ─── Decretos board — ct-* shell with dt-* skins (calligraphy tiles) ─── */
/* Page layout: pannable board grows to fill, selo balance sits in a footer below it. */
.dt-page { height:100%; display:flex; flex-direction:column; min-height:0; }
.dt-page > .ct-canvas { flex:1 1 auto; height:auto; min-height:0; }
.dt-selo { flex:none; align-self:center; width:100%; max-width:100%; box-sizing:border-box;
  padding:12px 0 14px; border-top:1px solid rgba(176,142,74,.16); }
.dt-tierhead { cursor:default; }
.dt-tierhead:hover .ct-tiertitle { color:var(--gold-hi); }
.ct-district .dt-sub { font-family:'Noto Serif',serif; font-style:italic; font-size:11px; color:rgba(243,231,196,.42); }
.dt-node {
  background:
    radial-gradient(120% 100% at 50% 20%, rgba(240,209,120,.10), transparent 58%),
    linear-gradient(180deg, #2b1d0e 0%, #1a1108 62%, #140d07 100%);
}
.dt-glyph {
  position:absolute; inset:0 0 16px; z-index:2; display:grid; place-items:center; pointer-events:none;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:42px; line-height:1;
  color:var(--gold); text-shadow:0 3px 10px rgba(0,0,0,.75);
}
.dt-node.st-built { border-color:rgba(63,174,134,.55); }
.dt-node.st-built .dt-glyph { color:var(--gold-hi); text-shadow:0 0 14px rgba(240,209,120,.45), 0 3px 10px rgba(0,0,0,.75); }
.dt-node.st-locked .dt-glyph { color:rgba(200,180,140,.32); text-shadow:none; }
.dt-chip {
  position:absolute; top:5px; left:5px; z-index:4; height:18px; padding:0 5px;
  display:inline-flex; align-items:center; gap:4px; border-radius:6px;
  font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; line-height:1;
  color:var(--gold-hi); pointer-events:none;
  background:linear-gradient(180deg, rgba(28,22,12,.9), rgba(16,12,7,.9));
  border:1px solid rgba(176,142,74,.55);
  box-shadow:0 2px 5px -1px rgba(0,0,0,.7);
}
.dt-chip img { width:12px; height:12px; border-radius:3px; object-fit:cover; }
.dt-chip svg { width:12px; height:12px; }
.dt-chip.lack { color:#e8a893; border-color:rgba(158,36,24,.55); }
.dt-chip.owned { color:var(--jade-soft); border-color:rgba(63,174,134,.5); }
.dt-node.st-locked .dt-chip { color:rgba(200,180,140,.55); border-color:rgba(120,100,70,.4); }
.dt-node.st-locked .dt-chip img { filter:grayscale(.8) brightness(.6); }
.lmf-hero.dt {
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(240,209,120,.16), transparent 60%),
    linear-gradient(180deg, rgba(30,19,11,.35), rgba(12,8,4,.55)),
    #221409 url(/assets/ui/header-texture.png?v=8f41a3c587) center / cover no-repeat;
}
.dt-hero-glyph {
  position:absolute; inset:0 0 30px; display:grid; place-items:center; pointer-events:none;
  font-family:'Noto Serif SC',serif; font-weight:900; font-size:86px; line-height:1;
  color:rgba(240,209,120,.30); text-shadow:0 6px 22px rgba(0,0,0,.65);
}
.dt-effects { display:flex; flex-wrap:wrap; gap:8px; }
.dt-effects .v2badge { margin:0; color:var(--parch); border-color:rgba(176,142,74,.42); background:rgba(217,178,74,.10); }
.dt-effects .v2badge svg { color:var(--gold-soft); }
@media (max-width:600px) {
  .dt-glyph { font-size:34px; }
  .dt-hero-glyph { font-size:68px; }
}
.tech-honor-bar { display:flex; flex-direction:column; align-items:center; gap:8px;
  color:var(--parch); font-family:'Cinzel',serif; font-size:13px; }
.selo-seals { display:inline-flex; align-items:center; gap:8px; }
.selo-seals img.res-img { width:26px; height:26px; border-radius:0; object-fit:contain;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.6)); }
.selo-seals b { color:var(--gold-hi); font-size:19px; font-family:'Cinzel',serif; text-shadow:0 1px 3px rgba(0,0,0,.7); }
.selo-track { display:flex; align-items:center; gap:12px; width:100%; }
.selo-lv { flex:none; min-width:2ch; text-align:center; color:var(--gold-hi);
  font-family:'Cinzel',serif; font-size:16px; font-weight:600; text-shadow:0 1px 3px rgba(0,0,0,.75); }
.selo-meter { position:relative; flex:1 1 auto; height:24px; border-radius:12px;
  background:rgba(0,0,0,.42); overflow:hidden; box-shadow:inset 0 0 0 1px rgba(158,36,24,.35); }
.selo-meter > i { position:absolute; inset:0 auto 0 0; height:100%; display:block;
  background:linear-gradient(90deg, rgba(158,36,24,.92), rgba(224,86,66,.98));
  box-shadow:0 0 10px rgba(224,86,66,.35); }
.selo-meter .sm-txt { position:relative; display:block; text-align:center; line-height:24px;
  font-size:12px; letter-spacing:.04em; color:#fff; font-family:'JetBrains Mono',monospace;
  text-shadow:0 1px 2px rgba(0,0,0,.65); }
.selo-reset { display:inline-flex; align-items:center; gap:6px; margin-top:2px; cursor:pointer;
  padding:5px 12px; border-radius:8px; font-family:'Cinzel',serif; font-size:12px; letter-spacing:.02em;
  color:rgba(238,180,168,.9); background:rgba(158,36,24,.14); border:1px solid rgba(158,36,24,.5);
  transition:background .14s ease, border-color .14s ease, color .14s ease; }
.selo-reset svg { width:14px; height:14px; }
.selo-reset:hover { color:#ffd8cf; background:rgba(158,36,24,.26); border-color:rgba(190,52,38,.75); }
.selo-reset.armed { color:#fff; background:rgba(158,36,24,.42); border-color:rgba(224,86,66,.9);
  box-shadow:0 0 12px rgba(224,86,66,.4); }
/* Sits below the stat strip riding the stage's top edge (recruit grid). */
.rc-lock { position:absolute; top:64px; left:50%; transform:translateX(-50%);
  z-index:3; display:inline-flex; align-items:center; gap:7px;
  padding:5px 12px; border-radius:7px; font-size:12px; font-weight:700;
  background:rgba(18,9,7,.55); color:var(--parch);
  white-space:nowrap; pointer-events:none; }
.rc-lock svg { width:13px; height:13px; }
.mk-page .panel {
  background:
    linear-gradient(180deg, rgba(20,15,9,.3), rgba(8,6,3,.5)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat,
    linear-gradient(180deg,#241a10 0%, #19130c 52%, #120d08 100%);
  border:1px solid rgba(199,152,68,.4);
  box-shadow:0 14px 34px rgba(0,0,0,.55), inset 0 1px 0 rgba(247,221,142,.1);
}
.mk-page .panel .watermark { color:rgba(240,209,120,.06); }
.mk-card .rc-stage { background:rgba(8,5,3,.3); }
.mk-card .rc-cost-row .ci svg { width:15px; height:15px; color:var(--gold-soft); }
.mk-price { position:absolute; top:12px; left:0; right:0; z-index:3; text-align:center;
  font-family:'JetBrains Mono',monospace; font-weight:700; font-size:30px; color:#fff;
  font-variant-numeric:tabular-nums; text-shadow:0 2px 6px rgba(0,0,0,.9); }
.mk-price .mk-cur { font-size:14px; color:var(--gold-soft); margin-right:5px; }
.mk-price .mk-unit { font-size:12px; color:rgba(243,231,196,.5); }
.mk-price .mk-dir { font-size:15px; margin-left:6px; }
.mk-price.up .mk-dir { color:var(--up); }
.mk-price.down .mk-dir { color:var(--down); }
.mk-art { position:absolute; left:50%; top:50%; transform:translate(-50%,-56%); z-index:1;
  width:120px; height:120px; object-fit:contain; opacity:.38;
  filter:drop-shadow(0 6px 12px rgba(0,0,0,.65)); }
.mk-chart { position:absolute; left:16px; right:16px; bottom:80px; height:62px; z-index:2; }
.mk-card .rc-avail { bottom:44px; }
.mk-info { flex:none; width:24px; height:24px; margin-left:2px; padding:0;
  display:inline-grid; place-items:center; border:0; border-radius:7px; cursor:pointer;
  color:rgba(243,231,196,.6); background:rgba(0,0,0,.3);
  transition:color .14s ease, background .14s ease; }
.mk-info svg { width:14px; height:14px; }
.mk-info:hover { color:var(--gold-hi); background:rgba(0,0,0,.45); }
.mk-info[aria-expanded="true"] { color:var(--gold-hi); box-shadow:0 0 0 1px rgba(240,209,120,.4); }
.mk-route-desc { margin-top:2px; }
/* Market table — one row per reachable region market (header + 7 rows). */
.mk-tbl { display:flex; flex-direction:column; gap:8px; margin:4px 0 16px; overflow-x:auto; }
.mk-tr { display:grid; align-items:center; gap:12px; min-width:660px;
  grid-template-columns:minmax(214px,1.5fr) minmax(172px,1.15fr) repeat(3, minmax(76px,.7fr)); }
.mk-tbl-head { padding:0 14px; font-family:'JetBrains Mono',monospace; font-size:10.5px;
  text-transform:uppercase; letter-spacing:.08em; color:rgba(243,231,196,.45); }
.mk-td-name { display:flex; align-items:center; gap:10px; flex-wrap:wrap; min-width:0; }
.mk-td-name .mk-hub-name { min-width:0; }
.mk-own-tag { flex:none; padding:2px 8px; border-radius:7px; font-size:10.5px;
  font-family:'Cinzel',serif; font-weight:700; color:rgba(243,231,196,.6);
  border:1px solid var(--line); background:rgba(0,0,0,.2); }
.mk-td-price { font-family:'JetBrains Mono',monospace; font-size:12.5px; text-align:right;
  font-variant-numeric:tabular-nums; color:var(--parch); white-space:nowrap; }
.mk-td-price.up { color:var(--up); }
.mk-td-price.down { color:var(--down); }
.mk-td-dir { font-size:10px; margin-left:4px; opacity:.9; }
/* Sortable column headers (click to re-sort the market table). */
.mk-th { display:inline-flex; align-items:center; gap:5px; width:100%; min-width:0;
  background:none; border:0; padding:0; margin:0; cursor:pointer;
  font:inherit; color:inherit; letter-spacing:inherit; text-transform:inherit; text-align:left; }
.mk-th:hover { color:var(--gold-soft); }
.mk-th.on { color:var(--gold-hi); }
.mk-th-price { justify-content:flex-end; text-align:right; }
.mk-th-arr { font-size:9px; opacity:.9; }
.mk-hub { width:100%;
  padding:11px 14px; border-radius:11px; cursor:pointer; text-align:left;
  border:1px solid var(--line); color:var(--parch);
  background:linear-gradient(180deg, rgba(0,0,0,.2), rgba(0,0,0,.06));
  transition:border-color .14s ease, box-shadow .14s ease; }
.mk-hub:hover { border-color:var(--gold-soft); }
.mk-hub.on { border-color:var(--gold-hi);
  box-shadow:0 0 0 1px rgba(247,221,142,.35), inset 0 0 18px rgba(247,221,142,.08); }
.mk-hub-dot { flex:none; width:13px; height:13px; border-radius:50%;
  border:2px solid rgba(199,152,68,.55); background:transparent; }
.mk-hub.on .mk-hub-dot { border-color:var(--gold-hi);
  background:radial-gradient(circle at 35% 30%, #fff, var(--gold));
  box-shadow:0 0 8px rgba(240,209,120,.6); }
.mk-hub-name { font-family:'Cinzel',serif; font-weight:700; font-size:13.5px;
  color:var(--gold-hi); min-width:150px; }
.mk-hub-meta { display:inline-flex; align-items:center; gap:6px;
  font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(243,231,196,.6);
  font-variant-numeric:tabular-nums; }
.mk-hub-meta svg { width:13px; height:13px; color:var(--gold-soft); }
.mk-merch-info { display:flex; align-items:center; gap:8px; font-size:12.5px;
  color:rgba(243,231,196,.65); }
.mk-merch-info svg { width:14px; height:14px; color:var(--gold-soft); }
.mk-merch-info b { color:var(--gold-hi); font-variant-numeric:tabular-nums; }
.mkt-disp-note { margin-top:10px; font-size:12.5px; color:#e3a33a; }
/* Themed <select> (dev-page dropdowns; formerly the auto-sell picker's style). */
.mk-select { background:rgba(0,0,0,.72); border:1px solid var(--line); border-radius:10px;
  color:var(--gold); font-family:'JetBrains Mono',monospace; font-size:13px; padding:8px 11px;
  outline:none; cursor:pointer; max-width:100%; }
.mk-select:focus { border-color:var(--gold-soft); }
.mk-empty { max-width:560px; margin:60px auto 0; }
.mk-nomarket .btn-plaque { max-width:340px; }
.daynight-shell { left:auto; right:0; align-items:flex-end; justify-content:flex-end; }
/* The floating clock + notifications rail belong to the world map only. */
body:not([data-page="world"]) .daynight-shell,
body:not([data-page="world"]) .actions-shell { display:none; }
.daynight-clock {
  position:relative; margin:14px; width:208px; height:208px; user-select:none;
  pointer-events:auto; --dnc-r:95px;
  /* No free-running animations here: core/clock.js derives every visual from
     Date.now() once a second and writes it (inline styles + the --dnc-accent/
     --dnc-glow/--dnc-lit custom properties below) — immune to tab throttling
     and system sleep. The short linear transitions blend the 1s steps. */
}
.dnc-sky { position:absolute; inset:13%; border-radius:50%; overflow:hidden;
  background:#04070d; box-shadow:inset 0 0 12px rgba(0,0,0,.6); }
.dnc-sky img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  /* Identity filter so the eclipse tint TRANSITIONS (both states share the same
     function list) — the blood drains from the sky at dawn instead of snapping. */
  filter:sepia(0) hue-rotate(0deg) saturate(1) brightness(1);
  transition:filter 2.5s ease; }
.dnc-sky .dnc-day { opacity:1; }
/* Night plate over the day plate; clock.js writes its opacity (nightStrength)
   each second. Linear so the stepped writes chain into one smooth fade —
   an ease here would restart its curve on every write and visibly stutter. */
.dnc-sky .dnc-night { opacity:1; transition:opacity 1s linear; }
/* Eclipse (every 9th game day — core/clock.js toggles the classes; the look
   HOLDS through the night the eclipse rolls into, lifting at the next dawn):
   the sky swaps to the clock-*-eclipse.png plates when they exist
   (.eclipse-art); until then this blood-red tint over the normal art carries
   the omen. */
.daynight-clock.eclipse:not(.eclipse-art) .dnc-sky img {
  filter:sepia(.55) hue-rotate(-45deg) saturate(2.4) brightness(.72);
}
/* (Ring + tick colours under the eclipse come from --dnc-accent/--dnc-glow,
   set by clock.js along with the day/night switch.) */
.dnc-frame { position:absolute; inset:0; width:100%; height:100%;
  filter:drop-shadow(0 4px 14px rgba(0,0,0,.55)); }

/* Blood Moon countdown — revealed on the clock face on hover (content set by
   core/clock.js): "{n} dias para a Lua de Sangue". Covers exactly the .dnc-sky
   disc (same inset + circle) and clips to it, so the wrapped text is contained
   inside the frame and never crosses the borders. */
.dnc-badge {
  position:absolute; inset:13%; border-radius:50%; overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  box-sizing:border-box; padding:16%; text-align:center;
  background:radial-gradient(circle, rgba(18,3,5,.9) 55%, rgba(18,3,5,.6) 100%);
  font-family:'Cinzel',serif; font-weight:800; font-size:12px; line-height:1.28;
  letter-spacing:.02em; color:#ff6a58; text-shadow:0 0 9px rgba(220,40,40,.75);
  opacity:0; transition:opacity .18s ease; pointer-events:none; z-index:2;
}
.daynight-clock:hover .dnc-badge { opacity:1; }
/* The eclipse is upon the realm — the disc burns and pulses (glow kept inside). */
.dnc-badge.rising { animation:dnc-badge-pulse 1.6s ease-in-out infinite; }
@keyframes dnc-badge-pulse {
  0%,100% { box-shadow:inset 0 0 18px rgba(150,22,22,.4); }
  50%     { box-shadow:inset 0 0 34px rgba(225,32,32,.62); }
}
@media (max-width:900px) { .dnc-badge { font-size:10px; padding:15%; } }
.dnc-ring { position:absolute; inset:0; width:100%; height:100%; z-index:1; pointer-events:none; }
/* Progress ring: clock.js writes stroke-dashoffset (empty → full per half-day)
   and --dnc-accent (purple night / gold day / red eclipse). The 1s linear
   dashoffset transition blends the per-second steps; the reset at noon and
   midnight is written transition-less (no backward sweep). */
.dnc-ring-fill {
  fill:none; stroke-width:3; stroke-linecap:round;
  stroke-dasharray:596.9; /* 2 * pi * r(95) */
  stroke-dashoffset:596.9; /* empty until the first clock.js paint */
  transform:rotate(-90deg); transform-origin:104px 104px; /* start at 12 o'clock, grow clockwise */
  color:var(--dnc-accent, var(--gold-hi)); stroke:currentColor;
  filter:drop-shadow(0 0 5px currentColor);
  transition:stroke-dashoffset 1s linear, color 1.2s ease;
}
.dnc-ticks { position:absolute; inset:0; z-index:1; }
.dnc-tick {
  position:absolute; top:50%; left:50%; width:9px; height:9px; margin:-4.5px;
  border-radius:50%;
  background:rgba(20,14,8,.7); border:1px solid rgba(199,152,68,.55);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.5);
  transform:rotate(calc(var(--i, 0) * 45deg)) translateY(calc(-1 * var(--dnc-r)));
}
/* Lit dot: clock.js sets --dnc-lit (0/1) per tick — dot 1 marks the half-day's
   start, dots 2..8 light at each eighth — and the shared --dnc-accent/--dnc-glow
   carry the day/night/eclipse colour (custom properties inherit into ::after). */
.dnc-tick::after {
  content:""; position:absolute; inset:-1px; border-radius:50%;
  background:var(--dnc-accent, var(--gold-hi));
  box-shadow:0 0 8px 2px var(--dnc-glow, rgba(247,221,142,.85)), inset 0 0 3px rgba(255,255,255,.6);
  opacity:var(--dnc-lit, 0);
  transition:opacity .8s linear, background 1.2s ease, box-shadow 1.2s ease;
}
@media (max-width:640px) {
  .daynight-clock { width:152px; height:152px; margin:10px; --dnc-r:69px; }
  .dnc-tick { width:7px; height:7px; margin:-3.5px; }
}

/* ── "Ações em andamento" — a floating top-right HUD list (marching armies,
   scouts, caravans + province builds still under construction). Same chromeless
   rail-shell as the day/night clock: the shell has NO background of its own and
   each row carries a soft dark band that fades out to the left and right, so
   nothing boxes the list in. The gaps between rows stay click-through to the map;
   only the rows themselves are interactive (click → centre the world map on it). */
.actions-shell { left:auto; right:0; align-items:flex-end; justify-content:flex-start; }
.actions-list {
  pointer-events:none;                          /* gaps pass clicks through to the map */
  display:flex; flex-direction:column; gap:7px;
  width:min(360px, 33vw); margin:18px 12px 0;
  max-height:calc(100% - 250px); overflow:hidden;   /* never grow into the clock */
}
.actions-list:empty { display:none; }

.act-item {
  pointer-events:auto; position:relative; display:flex; align-items:center; gap:12px;
  width:100%; margin:0; padding:8px 18px; border:0; text-align:left; cursor:pointer;
  color:var(--parch);
  /* the fading band: solid through the middle, transparent at both edges */
  background:linear-gradient(90deg,
    rgba(8,6,3,0) 0%, rgba(8,6,3,.62) 16%, rgba(8,6,3,.66) 50%,
    rgba(8,6,3,.62) 84%, rgba(8,6,3,0) 100%);
  transition:filter .14s ease;
}
.act-item:hover { filter:brightness(1.16); }

.act-ico {
  flex:none; width:34px; height:34px; border-radius:9px; display:grid; place-items:center;
  color:var(--gold-hi);
  background:
    linear-gradient(180deg, rgba(20,15,9,.5), rgba(8,6,3,.6)),
    linear-gradient(180deg,#241a10 0%, #17110b 100%);
  border:1px solid rgba(199,152,68,.5);
  box-shadow:0 2px 5px rgba(0,0,0,.5), inset 0 1px 0 rgba(247,221,142,.12);
}
.act-ico svg { width:20px; height:20px; }
.act-ico img { width:22px; height:22px; object-fit:contain; filter:drop-shadow(0 1px 2px rgba(0,0,0,.5)); }

.act-body { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; line-height:1.28; }
.act-title {
  font-family:'Cinzel',serif; font-weight:700; font-size:12.5px; letter-spacing:.02em;
  color:var(--gold-hi); text-shadow:0 1px 3px #000;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.act-route {
  font-family:'JetBrains Mono',monospace; font-size:10.5px;
  color:rgba(243,231,196,.6); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.act-val {
  flex:none; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:13px;
  color:var(--gold-hi); font-variant-numeric:tabular-nums; text-shadow:0 1px 3px #000;
}

/* Per-type accent on the medallion glyph. */
.act-item.t-army   .act-ico { color:#ef6f5c; border-color:rgba(226,104,90,.5); }
.act-item.t-scout  .act-ico { color:#bfeeda; }
.act-item.t-caravan .act-ico { color:var(--gold-hi); }
.act-item.t-build  .act-ico { color:#e7c05a; }

/* Combat-done notifications — FIXED rows (no countdown) pinned above the live
   actions: they stay until dismissed (✕) and click through to the combat page. */
.act-note.n-win  .act-ico { color:var(--up); border-color:rgba(95,208,160,.5); }
.act-note.n-loss .act-ico { color:var(--down); border-color:rgba(226,144,111,.5); }

/* Category filter chips — small medallions pinned atop the rail (multi-select:
   a dimmed chip mutes its bucket). Right-aligned like the rail; wraps when the
   rail narrows. Rendered only while the rail has content, so an idle list
   still collapses via :empty. */
.act-filters {
  pointer-events:auto; display:flex; flex-wrap:wrap; gap:6px;
  justify-content:flex-end; padding:0 18px 2px;
}
.act-fchip {
  width:26px; height:26px; padding:0; border-radius:8px; cursor:pointer;
  display:grid; place-items:center; color:var(--gold-hi);
  background:
    linear-gradient(180deg, rgba(20,15,9,.5), rgba(8,6,3,.6)),
    linear-gradient(180deg,#241a10 0%, #17110b 100%);
  border:1px solid rgba(199,152,68,.5);
  box-shadow:0 2px 5px rgba(0,0,0,.5), inset 0 1px 0 rgba(247,221,142,.12);
  transition:filter .14s ease, opacity .14s ease;
}
.act-fchip svg { width:15px; height:15px; }
.act-fchip-img { width:16px; height:16px; object-fit:contain; display:block; }
.act-fchip:hover { filter:brightness(1.16); }
.act-fchip[aria-pressed="false"] { opacity:.4; filter:grayscale(.7); }
.act-fchip[aria-pressed="false"]:hover { opacity:.65; filter:grayscale(.4) brightness(1.1); }

/* ═══ VOLUME POPUP (sound button — music / sfx sliders) ═══════════ */
.vol-pop {
  position:fixed; z-index:900; width:280px; padding:14px 16px 16px;
  background:linear-gradient(180deg,#2b1310,#1c0b09);
  border:1px solid rgba(199,152,68,.55); border-radius:10px;
  box-shadow:0 10px 28px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,200,130,.14);
}
.vol-pop h4 {
  margin:0 0 12px; font-family:'Cinzel',serif; font-weight:700; font-size:13px;
  letter-spacing:.06em; color:var(--gold);
}
.vol-head { display:flex; align-items:center; justify-content:space-between; gap:10px; margin:0 0 12px; }
.vol-head h4 { margin:0; }
.vol-mute {
  flex:none; width:30px; height:30px; padding:0; display:grid; place-items:center; cursor:pointer;
  color:var(--parchment,#f3e7c4); background:rgba(255,220,150,.05);
  border:1px solid rgba(199,152,68,.35); border-radius:8px;
  transition:background .12s, border-color .12s, color .12s;
}
.vol-mute svg { width:17px; height:17px; }
.vol-mute:hover { background:rgba(255,220,150,.12); border-color:rgba(199,152,68,.55); }
.vol-mute.on {
  color:var(--gold); background:rgba(255,220,150,.09);
  border-color:var(--gold); box-shadow:inset 0 0 0 1px rgba(199,152,68,.4);
}
.vol-row { display:flex; align-items:center; gap:10px; }
.vol-row + .vol-row { margin-top:12px; }

/* Language picker — narrower popup, one button per available language. */
.lang-btn { font-family:'Cinzel',serif; font-weight:700; font-size:12px; letter-spacing:.04em; }
.login-lang { position:absolute; top:16px; right:64px; z-index:6; }
.lang-pop { width:200px; }
.lang-opt {
  display:block; width:100%; text-align:left; padding:8px 12px; margin:0; cursor:pointer;
  background:rgba(255,220,150,.05); border:1px solid rgba(199,152,68,.28); border-radius:8px;
  color:var(--parchment,#f3e7c4); font-family:'Noto Serif',serif; font-size:14px;
}
.lang-opt + .lang-opt { margin-top:8px; }
.lang-opt:hover { background:rgba(255,220,150,.12); border-color:rgba(199,152,68,.5); }
.lang-opt.on { border-color:var(--gold); color:var(--gold); box-shadow:inset 0 0 0 1px rgba(199,152,68,.4); }
.vol-lab { flex:none; width:58px; font-size:12.5px; color:rgba(243,231,196,.82); }
.vol-pct {
  flex:none; width:42px; text-align:right; font-family:'JetBrains Mono',monospace;
  font-weight:700; font-size:12.5px; color:var(--gold); font-variant-numeric:tabular-nums;
}
.vol-slider {
  -webkit-appearance:none; appearance:none; flex:1; min-width:0; height:8px; border-radius:6px; outline:none; cursor:pointer;
  background:rgba(0,0,0,.72); box-shadow:inset 0 1px 2px rgba(0,0,0,.7), inset 0 0 0 1px var(--line-soft);
}
.vol-slider::-webkit-slider-thumb {
  -webkit-appearance:none; appearance:none; width:18px; height:18px; border-radius:50%;
  background:radial-gradient(120% 110% at 50% 28%, var(--gold-hi), var(--gold-soft)); border:1px solid var(--gold-hi);
  box-shadow:0 2px 7px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.55); cursor:pointer; margin-top:-5px;
}
.vol-slider::-moz-range-thumb {
  width:18px; height:18px; border-radius:50%; background:radial-gradient(120% 110% at 50% 28%, var(--gold-hi), var(--gold-soft));
  border:1px solid var(--gold-hi); box-shadow:0 2px 7px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.55); cursor:pointer;
}
.vol-slider::-webkit-slider-runnable-track { height:8px; border-radius:6px; background:transparent; }

/* ── Registro de Assalto — the shared canvas battle replay, rendered by BOTH
   report pages (#combate/<id> camp battles and #assalto/<id> raids).
   A single gold-framed CANVAS battlefield fills the page; drag pans, the wheel
   zooms (army view ↔ division view), and a floating control bar drives the
   replay clock. The result banner overlays the field when the log ends. */
.assault-page .assault-wrap {
  flex:1 1 auto; min-height:0; display:flex; flex-direction:column;
  width:100%; margin:0; padding:0;
}
/* Frameless, full-bleed battlefield — the stage fills the whole main area. */
.assault-stage {
  position:relative; flex:1 1 auto; min-height:420px; overflow:hidden;
}
.assault-stage canvas {
  position:absolute; inset:0; width:100%; height:100%;
  display:block; cursor:grab; touch-action:none;
}
.assault-stage canvas:active { cursor:grabbing; }
.assault-ctrl {
  position:absolute; z-index:12; left:50%; bottom:14px; transform:translateX(-50%);
  display:flex; align-items:center; gap:10px;
  padding:8px 14px; border-radius:12px;
  background:rgba(14,10,7,.86); border:1px solid var(--line-soft);
  box-shadow:0 10px 26px -8px rgba(0,0,0,.85);
}
.assault-ctrl .v2btn { padding:6px 12px; font-size:12.5px; }
.assault-ctrl input[type=range] { width:min(320px, 34vw); accent-color:var(--gold); }
.assault-ev {
  font-family:'JetBrains Mono',monospace; font-size:11.5px; font-variant-numeric:tabular-nums;
  color:rgba(243,231,196,.8); min-width:74px; text-align:center;
}
.assault-result {
  position:absolute; z-index:11; top:50%; left:50%; transform:translate(-50%,-50%);
  min-width:420px; max-width:min(1240px, 94%); max-height:92%; overflow-y:auto;
  padding:30px 40px; text-align:center;
  background:rgba(12,9,6,.92); border:1px solid var(--line-soft); border-radius:20px;
  box-shadow:0 22px 60px -10px rgba(0,0,0,.9);
}
.assault-result.hidden { display:none; }
.assault-result h2 {
  margin:0 0 6px; font-family:'Cinzel',serif; font-size:36px; letter-spacing:.04em;
}
.assault-result.as-win h2 { color:#ffe9a6; text-shadow:0 0 22px rgba(246,190,0,.45); }
.assault-result.as-loss h2 { color:#ff9d8a; text-shadow:0 0 22px rgba(200,16,46,.45); }
.as-res-list { display:flex; flex-direction:column; gap:9px; margin-top:14px; }
/* Fixed-height rows (the item token is the tallest element) so the list stays
   aligned whether or not a row carries spoils. */
.as-res-row {
  display:flex; align-items:center; gap:13px; justify-content:space-between;
  min-height:56px; padding:6px 14px; border-radius:10px; background:rgba(255,255,255,.04);
  font-size:15px; color:rgba(243,231,196,.88);
}
.as-res-row b { font-family:'Cinzel',serif; }
.as-res-row small { color:rgba(243,231,196,.55); margin-right:auto; }
.as-res-row svg { width:16px; height:16px; vertical-align:-3px; }
/* Damage ranking ordinal opening each raid division row (1º glows gold). */
.as-res-rank {
  flex:none; min-width:30px; text-align:center;
  font-family:'JetBrains Mono',monospace; font-weight:700; font-size:14px;
  color:rgba(243,231,196,.55); font-variant-numeric:tabular-nums;
}
.as-res-rank.top { color:var(--gold-hi); }
/* Small circular commander portrait (shared: battle results, rally rosters…).
   A gold-rimmed coin holding the hero's avatar, or a shield glyph when the
   division has no commander. */
.hero-av {
  flex:none; width:38px; height:38px; border-radius:50%; object-fit:cover; object-position:50% 16%;
  border:1.5px solid var(--gold-soft); background:#1c0606; box-shadow:0 2px 6px rgba(0,0,0,.5);
}
.hero-av-glyph { display:flex; align-items:center; justify-content:center; }
.hero-av-glyph svg { width:55%; height:55%; opacity:.6; }
/* End-of-battle losses: enemy kills pooled by troop type on top, then the
   viewer's hero armies side by side — each the world-map army-row (identity
   card + full formation of real troop slots) with a red per-squad casualty
   badge below each slot and a red skull over wiped squads. */
.as-losses { display:flex; flex-direction:column; align-items:center; gap:16px; margin:2px 0 16px; }
.as-reward .as-losses { margin:0; }   /* the spoils stack's own gap spaces it */
.as-loss-side { display:flex; flex-direction:column; align-items:center; gap:8px; }
.as-loss-side h4 {
  margin:0; font-family:'Cinzel',serif; font-size:11.5px; letter-spacing:.09em;
  text-transform:uppercase; color:rgba(243,231,196,.5); text-align:center;
}
.as-loss-units { display:flex; justify-content:center; align-items:flex-start; gap:9px; flex-wrap:wrap; }
/* Armies side by side; each reuses .army-row (ident left, formation right)
   with a compacted ident so three armies fit the widened overlay. */
.as-loss-row { display:flex; justify-content:center; align-items:flex-start; gap:26px; flex-wrap:wrap; }
.as-loss-army { flex:none; }
.ex-ident.as-loss-ident { width:148px; }
.as-loss-ident .ab-hport { --hp:76px; --hpb:26px; }
.as-loss-ident .hname { font-size:13.5px; }
/* Formation rows grow taller than the 74px tracks (casualty badge below). */
.as-loss-stack .slot-row.army-grid { grid-auto-rows:auto; }
.as-loss-cell { display:inline-flex; flex-direction:column; align-items:center; gap:3px; }
.as-loss-delta {
  min-height:15px; font-style:normal; font-family:'JetBrains Mono',monospace;
  font-size:12px; font-weight:700; color:#ff8d7a; font-variant-numeric:tabular-nums;
}
/* Spoils column at the army's right: item drop(s) + honra/XP chips. The drop
   token shrinks from the hero-reward 104px to sit beside the 74px slots. */
.as-loss-rewards {
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:8px; min-width:104px; align-self:center;
}
.as-loss-rewards .islot.big { width:72px; height:72px; border-radius:14px; }
/* At the 72px size the default-tile lip radius (16) restores the exact original
   corner-gap proportion — the reference look the app-wide lip was copied from. */
.as-loss-rewards .islot.big::before { border-radius:16px; }
.as-loss-rewards .islot.big .islot-glyph { font-size:36px; }
.as-loss-rewards .islot.big .islot-art { inset:4px; width:calc(100% - 8px); height:calc(100% - 8px); }
.as-loss-rewards .as-reward-chip { padding:5px 13px; font-size:13px; }
.as-loss-rewards .as-reward-chip svg { width:14px; height:14px; }
/* Wiped squad: darkened art, no count, red skull over the image. */
.tslot.as-dead .tslot-art { filter:grayscale(.85) brightness(.45); }
.tslot.as-dead .tslot-n { display:none; }
.as-loss-skull {
  position:absolute; inset:0; z-index:2; display:flex; align-items:center; justify-content:center;
  font-size:32px; color:#ff5f48; text-shadow:0 1px 8px rgba(0,0,0,.95); pointer-events:none;
}

/* ═══ Batalha — tactical attack overview, a MODAL over the world map ═══ */
/* Hosted on the inspect/details skin (flat dark card + gold hairline); the arena
   itself is frameless and sits clean on that panel. */
.bt-board { display:flex; flex-direction:column; align-items:center; gap:12px; width:100%; }
/* Wide arenas (big reserves) scroll inside their own strip, never the page. */
.bt-scroll { max-width:100%; overflow-x:auto; padding:8px; }
/* The arena holds both battle lines. Rows share the left edge (flex-start below),
   so the enemy 2×3 grid stacks in the same column as the player's — front rows
   meeting at the clash strip. It sits FLAT on the modal's inspect-style card (no
   frame of its own); the faction washes below tint each battle line. */
.bt-arena {
  position:relative; width:fit-content; margin:0 auto;
  background:none; box-shadow:none;
}
/* Key numbers read at a glance — power/troops (idents) + ETA/honor (clash
   strip): the modal-scale chip, roughly the world-popup size. */
.bt-arena .ab-chip { font-size:14px; padding:6px 12px; gap:6px; border-radius:9px; }
.bt-arena .ab-chip svg { width:16px; height:16px; }
/* Enemy portrait FRAME — the player's .hport ring treatment recolored to
   bone/ash (a dead thing wears no gold): gray conic ring, charcoal disc and
   pale halo shadows. The art itself keeps its true colors. Covers the
   discovered avatar and the undiscovered "?" glyph alike. */
.bt-arena .camp-ident .ab-avatar,
.bt-arena .camp-ident .ab-glyph {
  border-width:6px;
  background:
    linear-gradient(180deg, rgba(26,26,30,.92), rgba(12,12,15,.85)) padding-box,
    conic-gradient(from 200deg, #d9d9de, #55555c 18%, #a4a4ac 34%, #232327 52%, #d9d9de 68%, #55555c 84%, #d9d9de) border-box;
  box-shadow:
    0 0 0 1px #060606,
    0 0 0 2px rgba(214,214,222,.28),
    0 6px 14px rgba(0,0,0,.55),
    0 0 18px -4px rgba(196,196,208,.4);
}
.bt-arena .camp-ident .ab-glyph { color:#d0d0d6; }
/* Notes + confirm bar live INSIDE the card, under the player's line. */
.bt-arena .bt-note { margin:2px 22px 0; }
.bt-arena .bt-actions { margin:10px auto 18px; }
.bt-arena .exchange { justify-content:flex-start; }
/* A touch more room between each line's ident and its formation grid, so the
   always-one-line troop/power chips (never wrapped — .exchange .ab-hero-meta)
   stay clear of the squares. Applied to BOTH lines so their grids keep the same
   left edge. */
.bt-arena .ex-col { gap:22px; }
.bt-arena .army-bar2 { margin:0; }
/* Both battle lines sit bare on the flat inspect card (no wash) — the enemy front
   meets the player front across the clash strip with nothing between them. */
/* Tighten the vertical gap so the two front rows read as adjacent. */
.bt-enemy-ex .ex-col { padding-bottom:4px; }
.bt-arena .army-bar2 .ex-col { padding-top:4px; }
/* Enemy tiles live outside .army-bar2 — mirror its tile styling so both battle
   lines render identically (see the .army-bar2 .tslot overrides). */
.bt-arena .tslot { border-radius:7px; }
.bt-arena .tslot-art { border-radius:5px; }
.bt-arena .tslot-n { left:4px; right:auto; bottom:2px; font-size:13px; }
/* Clash strip — the battle line where the fronts meet: ETA · difficulty · honor. */
.bt-clash { display:flex; align-items:center; justify-content:center; gap:12px; padding:2px 18px; }
.bt-clash .whc-diff { flex:none; margin:0; }
.bt-vs-line { flex:1; height:1px; background:linear-gradient(90deg, transparent, var(--gold-soft) 30%, var(--gold-hi) 50%, var(--gold-soft) 70%, transparent); box-shadow:0 0 8px -2px rgba(217,178,74,.5); }
.bt-vs-seal { font-size:18px; line-height:1; filter:drop-shadow(0 2px 6px rgba(0,0,0,.6)); }
.bt-note { margin:0; font-size:12.5px; color:rgba(243,231,196,.65); text-align:center; }
/* Strategic Plan staging — the ordered leg strip under the arena. */
.bt-queue {
  display:flex; align-items:center; flex-wrap:wrap; gap:8px; justify-content:center;
  margin:10px auto 0; padding:8px 14px; max-width:fit-content; border-radius:10px;
  border:1px solid rgba(217,178,74,.3); background:rgba(0,0,0,.3);
}
.bt-queue-t { font-family:'Cinzel',serif; font-weight:700; font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--gold-soft); margin-right:4px; }
.bt-qchip {
  display:inline-flex; align-items:center; gap:6px; padding:3px 10px 3px 3px; border-radius:999px;
  font-size:11.5px; color:rgba(243,231,196,.85);
  border:1px solid rgba(217,178,74,.3); background:rgba(0,0,0,.35);
}
.bt-qn {
  display:inline-grid; place-items:center; width:18px; height:18px; border-radius:50%;
  font-size:10.5px; font-weight:800; color:#1c1206; background:var(--gold-soft);
}
.bt-actions { margin:4px auto 0; }
.bt-actions .v2btn { min-width:190px; }

/* ─── Troop stat card (hover/click on any filled troop tile) ─── */
.troop-card {
  position:fixed; z-index:230; width:280px; pointer-events:none;
  padding:14px; border-radius:13px;
  background:linear-gradient(180deg, rgba(26,19,11,.97), rgba(14,10,6,.97));
  border:1px solid var(--gold-soft);
  box-shadow:0 14px 34px -8px rgba(0,0,0,.85), inset 0 1px 0 rgba(255,255,255,.05);
  display:flex; flex-direction:column; gap:10px;
  animation:tcFade .12s ease;
}
@keyframes tcFade { from{ opacity:0; transform:translateY(5px) scale(.985); } to{ opacity:1; transform:none; } }
.troop-card[hidden] { display:none; }
.tc-head { display:flex; align-items:center; gap:11px; }
.tc-art { flex:none; width:62px; height:62px; border-radius:10px; object-fit:cover; object-position:50% 22%; border:1px solid var(--line-soft); }
.tc-id { min-width:0; display:flex; flex-direction:column; gap:3px; }
.tc-pips { justify-content:flex-start; gap:3px; }
.tc-pips i { width:16px; height:16px; color:#f7c832; }
.tc-pips i.on { color:#f7c832; filter:drop-shadow(0 0 5px rgba(247,200,50,.6)); }
.tc-name { font-family:'Cinzel',serif; font-weight:700; font-size:15.5px; color:var(--gold-hi); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.tc-sub { display:flex; align-items:center; gap:5px; font-size:12px; color:rgba(243,231,196,.65); }
.tc-sub svg { width:13px; height:13px; color:var(--gold-soft); flex:none; }
.tc-stats { gap:6px; }
.tc-stats .rc-stat { padding:7px 4px; gap:3px; }
.tc-stats .rc-stat svg { width:15px; height:15px; }
.tc-stats .rc-stat .v { font-size:12.5px; }
.tc-quote { margin:0; font-size:11.5px; }
.tc-hint {
  font-family:'JetBrains Mono',monospace; font-size:9.5px; letter-spacing:.08em;
  text-transform:uppercase; color:rgba(243,231,196,.42); text-align:center;
}

/* Division tally — the header line above the roster (was the army-count chip). */
.raid-count { margin:4px 0 2px; text-align:center; font-family:'Cinzel',serif; font-size:13px; letter-spacing:.02em; color:rgba(243,231,196,.72); }
/* Raid gathering roster (flag hover card / popup). */
.raid-roster { list-style:none; margin:8px 0 4px; padding:0; display:flex; flex-direction:column; gap:5px; }
.raid-roster-row {
  display:flex; align-items:center; gap:8px;
  padding:5px 9px; border-radius:8px; background:rgba(255,255,255,.05);
  font-size:12.5px; color:rgba(243,231,196,.9);
}
.raid-roster-body { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:1px; }
.raid-roster-row small { color:rgba(243,231,196,.55); font-size:11px; }
.raid-roster-pow { display:inline-flex; align-items:center; gap:3px; color:#cfe3ff; font-size:12px; white-space:nowrap; }
.raid-roster-pow svg { width:12px; height:12px; }
/* Per-hero withdraw control on my OWN roster rows (rally details). */
.raid-roster-leave {
  flex:none; display:inline-grid; place-items:center; width:26px; height:26px; padding:0;
  border-radius:7px; cursor:pointer; color:var(--down);
  border:1px solid rgba(226,144,111,.32); background:rgba(226,144,111,.1);
  transition:color .14s ease, border-color .14s ease, background .14s ease;
}
.raid-roster-leave:hover { border-color:rgba(226,144,111,.6); background:rgba(226,144,111,.2); }
.raid-roster-leave:disabled { opacity:.5; cursor:default; }
.raid-roster-leave svg { width:13px; height:13px; }
/* Inspect (eye) control on ALLIED roster rows — opens the read-only hero dossier. */
.raid-roster-inspect {
  flex:none; display:inline-grid; place-items:center; width:26px; height:26px; padding:0;
  border-radius:7px; cursor:pointer; color:rgba(243,231,196,.62);
  border:1px solid rgba(243,231,196,.18); background:rgba(255,255,255,.04);
  transition:color .14s ease, border-color .14s ease, background .14s ease;
}
.raid-roster-inspect:hover { color:var(--gold-hi); border-color:rgba(199,152,68,.5); background:rgba(8,6,3,.4); }
.raid-roster-inspect svg { width:14px; height:14px; }
.vol-slider::-moz-range-track { height:8px; border-radius:6px; background:transparent; }
.act-note.n-win  .act-title { color:var(--up); }
.act-note.n-loss .act-title { color:var(--down); }
.act-dismiss {
  flex:none; width:24px; height:24px; display:grid; place-items:center; cursor:pointer;
  font-size:12px; line-height:1; border-radius:7px; padding:0;
  color:rgba(243,231,196,.5); border:1px solid transparent; background:transparent;
  transition:color .14s ease, border-color .14s ease, background .14s ease;
}
.act-dismiss:hover {
  color:var(--gold-hi); border-color:rgba(199,152,68,.5); background:rgba(8,6,3,.55);
}

/* Full-height floating rails collapse to static rows on narrow screens; the
   actions list has no sensible row form, so it steps aside there. */
@media (max-width:900px) { .actions-shell { display:none; } }

/* ═══════════════════════════════════════════════════════════════
   PAGE: HERÓI — dossier: paper-doll + backpack + item tiles
   ═══════════════════════════════════════════════════════════════ */
.hero-dossier { display:flex; flex-direction:column; align-items:center; gap:16px; padding:20px 16px 32px; --tsz:74px; }
/* ONE ornate card holds the whole dossier (header, grids, sets, army). It
   wears the army-page recruit-card dress — the same warm chestnut lacquer
   body (gold sheen falling from the top, grain from the shared header
   texture) — under the ornate 9-slice frame; the recruits' conic gold band
   stays theirs. Also dresses the Arsenal page (same card atoms). */
.hero-card {
  display:flex; flex-direction:column; gap:18px; padding:24px 28px; max-width:100%;
  background:
    radial-gradient(130% 70% at 50% -6%, rgba(240,209,120,.16), rgba(240,209,120,0) 58%),
    linear-gradient(180deg, rgba(58,42,22,.25), rgba(16,10,5,.5)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat,
    linear-gradient(180deg,#3b2b17 0%, #2a1d0f 52%, #1c1309 100%);
  box-shadow:
    0 14px 34px rgba(0,0,0,.6),
    inset 0 1px 0 rgba(247,221,142,.16),
    inset 0 0 26px rgba(0,0,0,.42);
}
/* Header band — the recruit card's dark lacquer strip: bled to the card's
   inner edges (negative margins cancel the card padding; radius matches the
   frame's inner corner, 28px outer − 18px border), gold hairline underneath,
   faint sheen falling from the top edge. */
.hx-head {
  display:flex; align-items:center; gap:18px; align-self:stretch;
  /* Horizontal padding MATCHES the card's (28px) so header content lines up with
     the body columns below — the right-aligned skillbox sits flush over the
     arsenal grid, the portrait over the left column (both inset 28px). */
  margin:-24px -28px 0; padding:16px 28px 14px;
  border-radius:10px 10px 0 0;
  background:
    radial-gradient(120% 90% at 50% -30%, rgba(240,209,120,.10), transparent 60%),
    linear-gradient(180deg, rgba(12,6,3,.72), rgba(24,14,8,.5));
  border-bottom:3px solid rgba(14,7,4,.9);
  box-shadow:inset 0 1px 0 rgba(247,221,142,.08), 0 1px 0 rgba(247,221,142,.22);
}
/* The hero-switch roster left of the portrait is the shared .hroster component
   (defined with the world-HUD styles). */
/* ── Hero portrait ring (SHARED: dossier, world HUD, army identity) ──────────
   Ornate lathed-gold ring — a conic sweep plays light around the band, pinched
   by dark keylines, faint outer hairline, soft aura — with the level badge
   riding centre-bottom on the rim: number only, two-tone bottom-up XP fill
   driven by --xp (0..100). Size via --hp (portrait) and --hpb (badge). */
.hport {
  --hp:96px; --hpb:32px;
  position:relative; width:var(--hp); height:var(--hp); flex:none; border-radius:50%;
  padding:calc(var(--hp) * .063);
  background:conic-gradient(from 200deg,
    var(--gold-hi), var(--gold-dim) 18%, var(--gold-soft) 34%, #6d4f1e 52%,
    var(--gold-hi) 68%, var(--gold-dim) 84%, var(--gold-hi));
  box-shadow:
    0 0 0 1px #1a0705,
    0 0 0 2px rgba(247,221,142,.3),
    0 6px 14px rgba(0,0,0,.55),
    0 0 18px -4px rgba(240,209,120,.45);
}
.hport img {
  width:100%; height:100%; border-radius:50%; object-fit:cover; object-position:50% 12%;
  border:0; background:none;
  box-shadow:0 0 0 1px #1a0705, inset 0 2px 8px rgba(0,0,0,.6);
}
/* Garrison/unknown fallback glyph inside the ring (army identity without a hero). */
.hport .ab-glyph {
  width:100%; height:100%; border:0;
  background:linear-gradient(180deg, var(--card, rgba(60,12,12,.72)), var(--card-2, rgba(40,9,9,.55)));
  box-shadow:0 0 0 1px #1a0705, inset 0 2px 8px rgba(0,0,0,.4);
}
.hport-lvl {
  position:absolute; left:50%; bottom:calc(var(--hpb) * -.375); transform:translateX(-50%); z-index:2;
  width:var(--hpb); height:var(--hpb); border-radius:50%; display:grid; place-items:center;
  font-family:'Cinzel',serif; font-weight:700; font-size:calc(var(--hpb) * .47); color:var(--gold-hi);
  /* Two-tone gauge: ring and inner disc fill together bottom→top to --xp% —
     bright gold over charcoal on the OUTER ring, dark yellow over slate on the
     disc (the ::before). Neutral grays, not lacquer. */
  background:linear-gradient(to top, var(--gold-hi) calc(var(--xp, 0) * 1%), #111 calc(var(--xp, 0) * 1%));
  /* Dark halo ring: masks the portrait's gold border where the badge overlaps
     it, so the XP gauge reads as its own circle. */
  box-shadow:0 0 0 1px #3a3a3a, 0 0 0 4.5px #1a1a1a, 0 2px 5px rgba(0,0,0,.6);
}
.hport-lvl::before {
  content:''; position:absolute; inset:calc(var(--hpb) * .156); border-radius:50%;
  /* The disc is shorter than the badge, so a % stop would put its fill line
     above the ring's. Same line on both: badge-space px (--hpb/100 per XP
     point) shifted down by the disc inset. */
  background:linear-gradient(to top,
    #6b5218 calc(var(--xp, 0) * var(--hpb) / 100 - var(--hpb) * .156),
    #282828 calc(var(--xp, 0) * var(--hpb) / 100 - var(--hpb) * .156));
}
.hport-lvl b { position:relative; z-index:1; font-weight:inherit; }
/* Every identity line is height-clamped (name/title/bonus 1 line, quote a fixed
   2-line box) and the column is FIXED-width — the card shrink-wraps, so a
   flexible column would let a long nowrap name grow it on every hero swap. */
.hx-id { min-width:0; flex:none; width:340px; max-width:100%; }
.hx-name { font-family:'Cinzel',serif; font-weight:700; font-size:21px; color:var(--gold-hi); line-height:1.15; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hx-title { font-family:'JetBrains Mono',monospace; font-size:9.5px; letter-spacing:.14em; text-transform:uppercase; color:rgba(243,231,196,.55); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Combat power of the commanded army (replaced the flavor quote). Fixed
   one-line height so hero swaps keep the header geometry. */
.hx-power { display:flex; align-items:center; gap:6px; margin-top:6px; font-family:'JetBrains Mono',monospace; font-size:13px; color:var(--parch); height:18px; }
.hx-power svg { width:14px; height:14px; color:var(--gold-hi); flex:none; }
.hx-power b { font-weight:700; }
.hx-bonus { display:flex; align-items:center; gap:6px; font-size:12.5px; color:var(--parch); margin-top:6px; }
.hx-bonus-txt { min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hx-bonus svg { width:13px; height:13px; color:var(--gold-hi); fill:currentColor; flex:none; }
/* "Equipment sealed" chip (army out): a compact padlock badge in the equip
   panel header — flags the frozen paper-doll without a full-width banner that
   would grow the card and shift its layout. The mochila ✕ / trash mode stay
   live. Both top headers share a fixed height (the bag's trash button already
   sets ~26px) so the chip appearing never nudges the grids. */
.hx-equippanel h3, .hx-storepanel h3 { display:flex; align-items:center; min-height:26px; }
.hx-lockchip {
  margin-left:auto; display:inline-flex; align-items:center; gap:4px;
  padding:2px 8px; border-radius:999px;
  border:1px solid rgba(158,36,24,.5); background:rgba(158,36,24,.18);
  color:var(--warn); font-family:'Cinzel',serif; font-weight:700;
  font-size:9.5px; letter-spacing:.12em;
}
.hx-lockchip-ico { display:grid; place-items:center; flex:none; }
.hx-lockchip-ico svg { width:12px; height:12px; }
/* Dossier card body — a track grid for the panels under the header. The unified
   Arsenal page renders the `.solo` cut: one equip-track column (doll over sets),
   centered (see the Arsenal block below). */
.hx-cols {
  display:grid; justify-content:space-between; gap:22px 48px;
  grid-template-columns:calc(var(--tsz)*3 + 18px) calc(var(--tsz)*4 + 27px);
}
.hx-panel { padding:0; min-width:0; }
.hx-panel h3 { font-family:'Cinzel',serif; font-weight:700; font-size:11.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--gold-soft); margin:0 0 10px; }
.hx-noarmy { display:grid; place-items:center; min-height:110px; padding:0 18px; font-size:12.5px; color:rgba(243,231,196,.55); }
/* Bônus do Equipamento — aggregated totals (piece buffs + complete set bonuses). */
.hx-bonus .hx-sets { margin-top:14px; }
.hx-sets h4 { font-family:'Cinzel',serif; font-weight:700; font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--gold-soft); margin:0 0 6px; }
/* Skill slots sit on the right side of the header. Every tile opens the skill
   modal; learned tiles show the skill's seal glyph + rank pips; the "add" tile
   alone pulses gold while a point waits to be spent (no pane-level chrome). */
.hx-skillbox { margin-left:auto; align-self:center; flex:none; text-align:center; }
.hx-skillbox-t { font-family:'Cinzel',serif; font-weight:700; font-size:11.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--gold-soft); margin:0 0 8px; }
.hx-skills { display:flex; gap:9px; }
/* EVERY tile — learned, "+" and locked — wears the generic slot frame (the
   shared .tslot/.skill-slot/.hxk-tile rule) over a dark lacquer body. State
   lives in the CONTENT (seal+pips / pulsing + / lock), never in the border. */
.skill-slot {
  width:var(--tsz); height:var(--tsz); border-radius:14px; display:grid; place-items:center;
  cursor:pointer; padding:0; color:inherit; font:inherit;
  background:
    var(--slot-body) padding-box,
    var(--slot-frame) border-box;
  box-shadow:var(--slot-outline), inset 0 0 12px rgba(0,0,0,.5);
}
.skill-slot.learned { position:relative; transition:transform .12s ease, box-shadow .12s ease; }
.skill-slot.learned:hover { transform:translateY(-2px); box-shadow:var(--slot-outline), inset 0 0 12px rgba(0,0,0,.5), 0 0 10px rgba(217,178,74,.3); }
.skill-slot.add {
  color:var(--gold-soft); font-size:26px; font-weight:700; line-height:1;
  animation:skill-pulse 2.2s ease-in-out infinite;
}
/* Open slot with NO point waiting: the "+" sits quiet and dim (still clickable —
   the modal is always browsable); the pulse is reserved for a spendable point. */
.skill-slot.add.idle { animation:none; color:rgba(217,178,74,.4); }
@keyframes skill-pulse {
  0%, 100% { box-shadow:var(--slot-outline), inset 0 0 12px rgba(0,0,0,.5), 0 0 6px rgba(217,178,74,.25); }
  50% { box-shadow:var(--slot-outline), inset 0 0 12px rgba(0,0,0,.5), 0 0 22px rgba(217,178,74,.8); }
}
.skill-glyph { font-size:24px; line-height:1; color:var(--gold-soft); text-shadow:0 0 10px rgba(217,178,74,.35); }
.skill-pips { display:flex; gap:3px; justify-content:center; }
.skill-slot .skill-pips { position:absolute; left:0; right:0; bottom:4px; }
.skill-pip { width:6px; height:6px; border-radius:50%; border:1px solid rgba(217,178,74,.5); background:rgba(0,0,0,.4); }
.skill-pip.on { background:var(--gold-soft); box-shadow:0 0 5px rgba(217,178,74,.6); }
/* Free-points badge beside the skillbox title. */
.skill-pts {
  display:inline-grid; place-items:center; margin-left:7px; min-width:16px; height:16px;
  padding:0 4px; border-radius:999px; font-size:10.5px; font-weight:800; letter-spacing:0;
  color:#1c1206; background:var(--gold-soft); box-shadow:0 0 8px rgba(217,178,74,.55);
  vertical-align:middle;
}

/* "Skill point to spend" pip — a pulsing gold "+" pinned to a hero portrait's
   corner (dossier .hport, HUD/roster .world-hud-mini, tavern .thc-stage). The
   host is position:relative; the pip never intercepts clicks. */
.sp-dot {
  --spd:16px;
  position:absolute; top:0; right:0; z-index:3; width:var(--spd); height:var(--spd);
  display:grid; place-items:center; border-radius:50%; pointer-events:none;
  font-size:calc(var(--spd) * .8); font-weight:800; line-height:1; color:#2a0d0a;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  border:1px solid #3d0b0b;
  animation:sp-pulse 1.8s ease-in-out infinite;
}
@keyframes sp-pulse {
  0%, 100% { box-shadow:0 1px 2px rgba(0,0,0,.55), 0 0 4px rgba(217,178,74,.35); }
  50% { box-shadow:0 1px 2px rgba(0,0,0,.55), 0 0 14px rgba(217,178,74,.95); }
}
.hport .sp-dot { --spd:22px; top:2px; right:2px; }
.thc-stage .sp-dot { --spd:20px; top:6px; right:6px; }

/* Skill modal — the shared pool, one row per skill, dressed in the Arsenal
   card's chestnut lacquer: the hosting modal-card swaps its flat panel for the
   hero-card layers (gold sheen falling from the top, header-texture grain,
   warm chestnut base) via :has(). */
.modal-card:has(.hx-skillmodal) {
  border-color:var(--gold-dim);
  background:
    radial-gradient(130% 70% at 50% -6%, rgba(240,209,120,.16), rgba(240,209,120,0) 58%),
    linear-gradient(180deg, rgba(58,42,22,.25), rgba(16,10,5,.5)),
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat,
    linear-gradient(180deg,#3b2b17 0%, #2a1d0f 52%, #1c1309 100%);
  box-shadow:
    0 30px 80px -30px rgba(0,0,0,1),
    inset 0 1px 0 rgba(247,221,142,.16),
    inset 0 0 26px rgba(0,0,0,.42);
}
.hx-skillmodal { min-width:min(560px, 82vw); }
/* Header band — the hero-card's dark lacquer strip, bled to the card edges
   (negative margins cancel the modal padding; right pad clears the ✕), with
   the gold hairline underneath and the points chip riding the right side. */
.hxk-band {
  display:flex; align-items:center; gap:14px;
  margin:-26px -26px 16px; padding:15px 56px 13px 24px;
  border-radius:16px 16px 0 0;
  background:
    radial-gradient(120% 90% at 50% -30%, rgba(240,209,120,.10), transparent 60%),
    linear-gradient(180deg, rgba(12,6,3,.72), rgba(24,14,8,.5));
  border-bottom:3px solid rgba(14,7,4,.9);
  box-shadow:inset 0 1px 0 rgba(247,221,142,.08), 0 1px 0 rgba(247,221,142,.22);
}
.hxk-band-id { min-width:0; }
.hxk-title { font-family:'Cinzel',serif; font-weight:700; font-size:14px; letter-spacing:.14em; text-transform:uppercase; color:var(--gold-soft); }
.hxk-sub { font-family:'Noto Serif',serif; font-size:11px; color:rgba(243,231,196,.55); margin-top:1px; }
/* Points chip — an armory-cap-style pill; lit gold while a point waits. The
   away note (a full sentence) wraps inside the same chip shape. */
.hxk-pts {
  margin-left:auto; flex:none; max-width:52%; padding:4px 11px; border-radius:11px;
  font-size:10.5px; letter-spacing:.06em; font-weight:700; line-height:1.4; text-align:center;
  color:rgba(243,231,196,.75); border:1px solid rgba(217,178,74,.28); background:rgba(0,0,0,.25);
}
.hxk-pts.has {
  color:#1c1206; border-color:transparent;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  box-shadow:0 0 10px rgba(217,178,74,.45);
}
.hxk-list { display:flex; flex-direction:column; gap:10px; max-height:min(58vh, 520px); overflow-y:auto; padding-right:4px; }
.hxk-list::-webkit-scrollbar { width:8px; }
.hxk-list::-webkit-scrollbar-thumb { background:rgba(217,178,74,.32); border-radius:5px; }
.hxk-list::-webkit-scrollbar-track { background:rgba(0,0,0,.25); }
/* One row per skill: seal tile, name + pips over the rank lines, learn button.
   Dark lacquer body over the textured card; owned rows warm up gold. */
.hxk-row {
  display:flex; gap:13px; align-items:center; padding:11px 13px;
  border:1px solid rgba(217,178,74,.22); border-radius:12px;
  background:linear-gradient(180deg, rgba(12,6,3,.55), rgba(24,14,8,.38));
  box-shadow:inset 0 1px 0 rgba(247,221,142,.05);
}
.hxk-row.owned {
  border-color:rgba(217,178,74,.55);
  background:linear-gradient(180deg, rgba(40,28,13,.6), rgba(24,14,8,.45));
  box-shadow:inset 0 1px 0 rgba(247,221,142,.08), 0 0 14px -6px rgba(217,178,74,.35);
}
/* The modal's seal tile rides the generic slot frame (shared rule above). */
.hxk-tile {
  flex:none; width:52px; height:52px; border-radius:12px; display:grid; place-items:center;
  background:
    var(--slot-body) padding-box,
    var(--slot-frame) border-box;
  box-shadow:var(--slot-outline), inset 0 0 12px rgba(0,0,0,.5);
}
.hxk-main { flex:1; min-width:0; }
.hxk-head { display:flex; align-items:center; gap:10px; margin:0 0 6px; }
.hxk-name { font-family:'Cinzel',serif; font-weight:700; font-size:13px; color:var(--gold-soft); }
.hxk-ranks { display:flex; flex-direction:column; gap:2px; }
.hxk-rank { font-size:11.5px; color:rgba(243,231,196,.42); }
.hxk-rank.on { color:rgba(243,231,196,.9); }
.hxk-rank.next { color:rgba(243,231,196,.66); }
.hxk-rank.next .hxk-rn { border-color:var(--gold-soft); color:var(--gold-soft); }
.hxk-rank.on .hxk-rn { background:rgba(217,178,74,.85); color:#1c1206; border-color:transparent; }
.hxk-rn {
  display:inline-grid; place-items:center; width:20px; height:15px; margin-right:7px;
  border:1px solid rgba(217,178,74,.4); border-radius:4px;
  font-size:9.5px; font-weight:800; letter-spacing:.06em; color:rgba(243,231,196,.6);
}
.hxk-learn { flex:none; align-self:center; }
/* Disabled learn/maxed: the gold plaque goes flat and quiet (no drop, no glint). */
.hxk-learn:disabled { opacity:.45; cursor:default; filter:saturate(.5); box-shadow:none; }
.hxk-learn:disabled::after { display:none; }

/* Item grids: the paper-doll is 3 wide (boots centered on its 4th row); the bag 4×4.
   Both are 4 rows on the same --tsz tile, so the two panels stand equal-height. */
.equip-grid { display:grid; grid-template-columns:repeat(3, var(--tsz)); grid-auto-rows:var(--tsz); gap:9px; }
.equip-grid .islot:nth-child(10) { grid-column:2; }
/* The side columns hold 3 tiles against the middle's 4 — drop them half a row
   so they sit vertically centred on the column (top offset, not transform:
   the hover lift owns transform). Children flow row-major: col 1 = 1,4,7
   (boots, the 10th, is pinned to col 2 above); col 3 = 3,6,9. */
.equip-grid .islot:nth-child(3n+1):nth-child(-n+9),
.equip-grid .islot:nth-child(3n) { top:calc((var(--tsz) + 9px) / 2); }
.bag-grid { display:grid; grid-template-columns:repeat(4, var(--tsz)); grid-auto-rows:var(--tsz); gap:9px; }

/* Armory count chip — stored/capacity pill beside a panel header (hero dossier)
   or in the Arsenal page header meta. */
.hx-armory-cap {
  margin-left:10px; padding:2px 9px; border-radius:999px; flex:none;
  font-size:10.5px; letter-spacing:.08em; font-weight:700;
  color:rgba(243,231,196,.75); border:1px solid rgba(217,178,74,.28); background:rgba(0,0,0,.25);
}

/* PAGE: ARSENAL — ONE unified card: a header (portrait / identity / skills) over a
   3-column body — the governor's command bonuses, the equipment paper-doll and the
   province store side by side — all built from the dossier atoms. */
.armory-meta { margin-left:auto; display:flex; gap:8px; align-self:center; }
/* The card CLAMPS to the view height and its store GRID scrolls inside — the page
   never grows. The duo fills #armoryView so the card's max-height:100% has a
   bounded reference; the card (.hero-card) is a flex column (header + body). */
#armoryView { overflow-y:auto; }
.armory-duo { flex:1 1 auto; min-height:0; display:flex; justify-content:center; align-items:flex-start; max-width:100%; }
.armory-duo > .hero-card { flex:none; max-width:100%; min-height:0; max-height:100%; }
/* The 3-column body: [bonuses over army] | equipment | store, top-aligned and
   centered; fills the card's remaining height so the store column can stretch. */
.hx-arsenal3 { display:flex; justify-content:center; align-items:flex-start; gap:56px; max-width:100%; flex:1 1 auto; min-height:0; }
.hx-arsenal3 > .hx-panel, .hx-arsenal3 > .hx-leftcol { min-width:0; }
/* Store column ALONE stretches to the card's clamped height; only its cell grid
   scrolls — the header, action bar and build hint stay pinned. The bonus/army
   and equipment columns keep their natural height (align-items:flex-start). */
.hx-storepanel { align-self:stretch; display:flex; flex-direction:column; min-height:0; }
/* Vertical scroll ONLY: a hover/selected tile's outline (outline-offset + glow)
   bleeds past its box, and overflow-y:auto alone would let overflow-x compute to
   auto too — so pin overflow-x:hidden. scrollbar-gutter reserves the scrollbar's
   column (the 4 tiles never get squeezed → no right-edge clip, and it's not flush),
   and the padding keeps edge-tile outlines inside the scroll box. */
.hx-storepanel .bag-grid { flex:0 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden; scrollbar-gutter:stable; padding:6px; }
.hx-storepanel .bag-grid::-webkit-scrollbar { width:8px; }
.hx-storepanel .bag-grid::-webkit-scrollbar-thumb { background:rgba(217,178,74,.32); border-radius:5px; }
.hx-storepanel .bag-grid::-webkit-scrollbar-track { background:rgba(0,0,0,.25); }
.hx-arsenal3 .hx-panel h3 { display:flex; align-items:center; min-height:26px; }
.hx-leftcol { display:flex; flex-direction:column; gap:22px; min-width:0; }
/* Left-align the read-only formation so its tiles share the bonus panel's left
   edge (overriding the facing-pair centring); the row-medals hang half a medal left. */
.hx-leftcol .army-stack { align-items:flex-start; }
/* Bônus de Comando — one iconed line per aggregated effect (gear + skills + level);
   the panel matches the doll's 3-tile width so its sentences wrap tidily. */
.hx-bonuspanel { width:calc(var(--tsz)*3 + 18px); }
.hx-bonuslist { display:flex; flex-direction:column; gap:9px; }
.hx-bonus-row { display:flex; align-items:flex-start; gap:8px; font-size:12px; line-height:1.35; color:var(--parch); }
/* fill:currentColor colours the one FILL-based glyph (i-star) gold; the stroke
   icons keep their own fill="none", so it doesn't blob them out (see .hx-bonus). */
.hx-bonus-row > svg { width:14px; height:14px; flex:none; margin-top:1px; color:var(--gold-soft); fill:currentColor; }
/* Governor seat empty: a quiet note stands where the two hero columns would be. */
.hx-nogov { min-width:300px; min-height:200px; }
@media (max-width:960px) {
  /* Stacked: the columns go vertical, so internal store-scroll can't apply —
     let the card grow and #armoryView scroll the whole thing instead. */
  .armory-duo { flex:none; }
  .armory-duo > .hero-card { max-height:none; }
  .hx-arsenal3 { flex-direction:column; align-items:center; flex:none; min-height:auto; }
  .hx-storepanel { align-self:auto; }
  .hx-storepanel .bag-grid { overflow:visible; }
}

/* READ-ONLY GOVERNOR DOSSIER (world-map intel on another player's province) — the
   Arsenal hero card reused inside the modal, minus the store column and every
   editing affordance. Reuses .hero-dossier for --tsz + centering; neutralizes the
   page-fill flex the Arsenal uses (there's no clamped host here) so the card sizes
   to its content, and quiets the read-only skill tiles. */
.gov-dossier { padding:0; gap:14px; }
.gov-dossier .hx-arsenal3 { flex:none; min-height:0; gap:44px; }
.gov-dossier .hero-card { max-height:none; }
.gov-dossier .skill-slot { cursor:default; }
.gov-dossier .skill-slot.learned:hover { transform:none; box-shadow:var(--slot-outline), inset 0 0 12px rgba(0,0,0,.5); }
/* FRAMELESS MODAL — the hero/governor dossier brings its own gold frame; the
   generic modal used to wrap it in a second (red-lacquer) frame. Shed the modal
   chrome entirely so the gold frame floats alone on the dim overlay, sized to the
   content (still capped to the viewport; the dossier's 2-column body stacks under
   960px). The ✕ sits just inside the frame (see below). (Batalha staging moved to
   the flat inspect skin below.) */
.modal-card:has(.gov-dossier) {
  width:max-content; max-width:96vw;
  padding:0; border:none; background:none; border-radius:28px; box-shadow:none;
}
/* Batalha modal wears the inspect/details skin — a flat dark card with a gold
   hairline (no photo-texture frame, no frameless float). The arena below drops
   its ornate chestnut lacquer to sit clean on this panel. */
.modal-card:has(.bt-board) {
  width:max-content; max-width:96vw; padding:16px;
  border:1px solid rgba(217,178,74,.16); border-radius:16px;
  background:linear-gradient(180deg,#1b140c,#120c07);
  box-shadow:0 24px 60px -24px rgba(0,0,0,1);
}
/* Standard ✕ (details look), but lifted above the dense arena content so it stays
   clickable (the arena no longer isolates its stacking context). */
.modal-card:has(.bt-board) .modal-close { z-index:6; }
/* The dossier is ONE full-bleed card: its silhouette shadow moves to the
   invisible scroller (the card's own outer shadow would be clipped by its
   overflow). The battle board now rides the inspect-style card above, which
   carries its own border + shadow and the standard ✕. */
.modal-card:has(.gov-dossier) { box-shadow:0 30px 80px -30px rgba(0,0,0,1); }
/* The dossier ✕ sits INSIDE the gold frame (on the border art it vanished) as a
   small lacquered disc with a gold rim — legible over any card content. */
.modal-card:has(.gov-dossier) .modal-close {
  top:24px; right:25px; z-index:6; width:32px; height:32px;
  border:1px solid rgba(217,178,74,.4); border-radius:50%;
  background:radial-gradient(120% 120% at 50% 32%, rgba(34,20,10,.92), rgba(10,5,2,.94));
  color:var(--gold-soft); font-size:15px; font-weight:700;
  box-shadow:0 2px 8px rgba(0,0,0,.6), inset 0 1px 0 rgba(247,221,142,.14);
  transition:color .14s ease, border-color .14s ease, transform .14s ease;
}
.modal-card:has(.gov-dossier) .modal-close:hover {
  color:#ffe9a8; border-color:var(--gold-soft);
  background:radial-gradient(120% 120% at 50% 32%, rgba(44,26,12,.95), rgba(12,6,3,.96));
  transform:scale(1.08);
}
.gov-dossier-note { padding:36px 20px; text-align:center; color:var(--parch); font-size:14px; }

/* Selection-action buttons (send cart + destroy bin) — SQUARE icon buttons (the
   label lives in title/aria) with the marked count riding the corner as a badge. */
.armory-sq {
  position:relative; width:38px; height:38px; padding:0; min-width:0;
  display:inline-flex; align-items:center; justify-content:center;
}
.armory-sq [data-icon] { display:grid; place-items:center; }
.armory-sq svg { width:17px; height:17px; }
.armory-sq .armory-sq-img { width:19px; height:19px; object-fit:contain; }
.armory-sq-count {
  position:absolute; top:-7px; right:-7px; z-index:1;
  min-width:18px; height:18px; padding:0 5px; border-radius:999px;
  display:grid; place-items:center;
  font-family:'JetBrains Mono',monospace; font-size:10px; font-weight:700;
  color:var(--parch); background:rgba(0,0,0,.88); border:1px solid rgba(217,178,74,.5);
}
.armory-sq-count:empty { display:none; }

/* Convoy tile styles live with the item-tile recipe (before the rarity frames,
   so an outbound tile keeps its rarity frame) — see ".islot.ghost" below. */

/* Clicked item — SELECTED (the upgrade mechanics will act on it): gold ring. */
.islot.selected { outline:2.5px solid var(--gold-hi); outline-offset:1.5px; box-shadow:0 0 14px rgba(240,209,120,.4); }
/* Whole-panel drop target (dropping anywhere on the doll equips the dragged bag
   item, anywhere on the backpack stows the piece) — no visual: the cursor and
   the tile-level marks carry the affordance. */

/* Selection action bar — the Arsenal page's cart + bin buttons, right-aligned
   under the store grid (discarding lives on the Arsenal page, not the dossier). */
.hx-trashbar { display:flex; justify-content:flex-end; gap:10px; margin-top:12px; }

/* Item tile — the .tslot recipe re-cut for items (CJK seal + rarity frame; the
   ItemDef.icon field is reserved for painted art later). */
.islot {
  --rar:var(--gold-soft);   /* rarity accent (loot-up glow) — comum stays gold */
  --rar-deep:#545c64;       /* dark frame stop — the inner lip ring (comum steel) */
  position:relative; width:var(--tsz); height:var(--tsz); overflow:hidden; border-radius:14px;
  transition:border-color .18s ease, box-shadow .2s ease, transform .14s ease;
}
.islot.empty {
  background:
    var(--slot-body) padding-box,
    var(--slot-frame) border-box;
}
.islot-type { position:absolute; left:0; right:0; bottom:3px; z-index:2; text-align:center; font-family:'JetBrains Mono',monospace; font-size:7.5px; letter-spacing:.07em; text-transform:uppercase; color:rgba(243,231,196,.45); pointer-events:none; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; padding:0 3px; }
/* Empty slots have no art — the slot's PT name centers as the whole label. */
.islot.empty .islot-type { inset:0; display:grid; place-items:center; white-space:normal; line-height:1.6; padding:0 7px; }
.islot.filled {
  cursor:grab;
  background:
    linear-gradient(180deg, #262b30, #12161a) padding-box,
    linear-gradient(145deg, #eef2f5 0%, #b9c2cb 22%, #545c64 50%, #b9c2cb 78%, #eef2f5 100%) border-box;
}
.islot.filled:hover { box-shadow:var(--slot-outline), 0 14px 32px -22px rgba(0,0,0,.8); transform:translateY(-1px); }
.islot.filled:active { cursor:grabbing; }
.islot.filled .islot-type { color:rgba(243,231,196,.6); text-shadow:0 1px 3px rgba(0,0,0,.9); }
.islot-glyph { position:absolute; inset:0 0 8px; display:grid; place-items:center; z-index:1; font-family:'Noto Serif SC',serif; font-weight:900; font-size:32px; color:var(--parch); text-shadow:0 2px 8px rgba(0,0,0,.85); pointer-events:none; }
.islot-art { position:absolute; inset:2px 2px 10px; width:calc(100% - 4px); object-fit:contain; z-index:2; pointer-events:none; }
/* Faint slot-type silhouette in empty equipment cells (self-removes if the PNG is missing). */
.islot-ph { position:absolute; inset:2px 2px 10px; width:calc(100% - 4px); object-fit:contain; z-index:1; pointer-events:none; opacity:.28; filter:grayscale(1) brightness(1.15); }
/* Convoy tiles — the item art AND its rarity frame stay untouched (a rare stays
   blue, a common stays lacquer — the rar-* rules below override the default body
   here exactly as they do a filled tile); the transit state reads only from the
   dashed gold ring + the corner badge: ⏳ = GHOST (inbound reservation at the
   destination), 🔒 = OUTBOUND (sealed at home; clicking it on the Arsenal page
   opens the cancel-transfer confirm). */
.islot.ghost, .islot.outbound {
  background:
    linear-gradient(180deg, #262b30, #12161a) padding-box,
    linear-gradient(145deg, #eef2f5 0%, #b9c2cb 22%, #545c64 50%, #b9c2cb 78%, #eef2f5 100%) border-box;
  outline:2px dashed rgba(240,209,120,.75); outline-offset:1.5px;
}
.islot.outbound { cursor:pointer; }
.islot.ghost::after, .islot.outbound::after {
  position:absolute; right:3px; bottom:3px; z-index:3; pointer-events:none;
  width:18px; height:18px; display:grid; place-items:center; font-size:11px;
  border-radius:6px; background:rgba(0,0,0,.82); border:1px solid rgba(217,178,74,.55);
}
.islot.ghost::after { content:'⏳'; }
.islot.outbound::after { content:'🔒'; }
/* Inner lip — a thin ring in the frame's DARK stop just inside the metal, plus
   a soft top shade, so the body reads recessed below the bevel (depth). A
   pseudo-element, not box-shadow: state rules restate box-shadow freely
   (hover/drop/reveal) and the lip must survive them. The ring's radius is
   DELIBERATELY larger than the padding-box corner (+4px at the 74px tile): it
   hugs the frame along the edges but lets go around the corners, floating a
   sliver of body between frame and ring — a double-frame "mat" detail (born as
   a happy accident in the replay spoils token, now the standard look). */
.islot.filled::before, .islot.ghost::before, .islot.outbound::before {
  content:''; position:absolute; inset:0; z-index:2; pointer-events:none;
  border-radius:16px;
  box-shadow:inset 0 0 0 1.5px var(--rar-deep), inset 0 2px 6px rgba(0,0,0,.55);
}
.islot.mini::before { border-radius:9px; }
.islot.big::before { border-radius:22px; }
/* Rarity frames — the tier reads from a polished metallic BORDER: a bevel
   gradient (bright→base→dark→base→bright, top-lit) that catches light on the
   top-left and bottom-right edges, tinted per rarity. The body stays a solid
   per-rarity tint: comum steel/silver, incomum green, raro blue, épico purple
   + glow, lendário red + glow. */
.islot.rar-uncommon {
  --rar:#58c98a; --rar-deep:#1d5c3c;
  background:
    linear-gradient(180deg, #17331f, #0d2013) padding-box,
    linear-gradient(145deg, #b6f0d0 0%, #58c98a 22%, #1d5c3c 50%, #58c98a 78%, #b6f0d0 100%) border-box;
}
.islot.rar-uncommon .islot-glyph { color:#bfeeda; }
.islot.rar-rare {
  --rar:#5b8ddb; --rar-deep:#24446e;
  background:
    linear-gradient(180deg, #16283f, #0c1728) padding-box,
    linear-gradient(145deg, #c4dcfb 0%, #5b8ddb 22%, #24446e 50%, #5b8ddb 78%, #c4dcfb 100%) border-box;
}
.islot.rar-rare .islot-glyph { color:#bcd7f5; }
.islot.rar-epic {
  --rar:#a86fd9; --rar-deep:#4d2a70;
  background:
    linear-gradient(180deg, #261636, #150b20) padding-box,
    linear-gradient(145deg, #e6d1f7 0%, #a86fd9 22%, #4d2a70 50%, #a86fd9 78%, #e6d1f7 100%) border-box;
  box-shadow:var(--slot-outline), inset 0 1px 0 rgba(255,255,255,.08);
}
.islot.rar-epic .islot-glyph { color:#dcc2f2; }
.islot.rar-legendary {
  --rar:#e0564d; --rar-deep:#7e1f18;
  background:
    linear-gradient(180deg, #331210, #1f0908) padding-box,
    linear-gradient(145deg, #f8c2bc 0%, #e0564d 22%, #7e1f18 50%, #e0564d 78%, #f8c2bc 100%) border-box;
  box-shadow:var(--slot-outline), inset 0 1px 0 rgba(255,255,255,.08);
}
.islot.rar-legendary .islot-glyph { color:#f5b6ae; }
.islot.drop-ok { border-color:var(--gold-hi); box-shadow:var(--slot-outline), 0 0 0 2px rgba(217,178,74,.55), inset 0 0 16px rgba(217,178,74,.2); }
.islot.drop-bad { border-color:var(--warn); box-shadow:var(--slot-outline), 0 0 0 2px rgba(158,36,24,.55); }
.islot.dragging { opacity:.4; }
.islot.ro.filled { cursor:default; }
.islot.ro.filled:hover { transform:none; box-shadow:var(--slot-outline); }
/* Item hover popup — dossier tiles: name / rarity·slot header, buff line, and
   the set collection (unequipped pieces darkened) + full-set bonus + count. */
.item-tip {
  position:fixed; z-index:1300; width:300px; opacity:0; pointer-events:none;
  border-radius:14px; border:1.5px solid var(--gold-soft);
  background:linear-gradient(180deg, #26100c, #170806);
  box-shadow:0 22px 52px -18px rgba(0,0,0,.95), inset 0 1px 0 rgba(247,221,142,.08);
  transition:opacity .12s ease;
}
.item-tip.show { opacity:1; }
.item-tip .it-head { padding:10px 14px 8px; background:rgba(0,0,0,.35); border-bottom:1px solid var(--line-soft); border-radius:12px 12px 0 0; }
.item-tip .it-name { font-weight:800; font-size:15px; color:var(--parch); }
.item-tip .it-name.rar-uncommon { color:#bfeeda; }
.item-tip .it-name.rar-rare { color:#bcd7f5; }
.item-tip .it-name.rar-epic { color:#dcc2f2; }
.item-tip .it-name.rar-legendary { color:#f5b6ae; }
.item-tip .it-sub { margin-top:1px; font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.06em; text-transform:uppercase; color:rgba(243,231,196,.55); }
.item-tip .it-buff { padding:10px 14px; font-size:12.5px; color:var(--parch); }
.item-tip .it-set-name { padding:2px 14px 8px; text-align:center; font-weight:800; font-size:13px; color:var(--gold-hi); }
/* Set-only popup (Conjuntos rows): no header band above — give the name room. */
.item-tip .it-set-name:first-child { padding-top:12px; }
.item-tip .it-pieces { display:flex; justify-content:center; gap:6px; padding:0 12px 10px; flex-wrap:wrap; }
/* Set-piece chips mirror the .islot rarity dress: a per-rarity dark body under
   the metallic bevel border (comum steel/silver, tiers coloured). Transparent
   border + padding-box/border-box gradient, same recipe as the tiles. */
.item-tip .it-piece {
  position:relative; width:40px; height:40px; overflow:hidden; border-radius:9px;
  border:1.5px solid transparent;
  background:
    linear-gradient(180deg, #262b30, #12161a) padding-box,
    linear-gradient(145deg, #eef2f5 0%, #b9c2cb 22%, #545c64 50%, #b9c2cb 78%, #eef2f5 100%) border-box;
}
.item-tip .it-piece.rar-uncommon {
  background:
    linear-gradient(180deg, #17331f, #0d2013) padding-box,
    linear-gradient(145deg, #b6f0d0 0%, #58c98a 22%, #1d5c3c 50%, #58c98a 78%, #b6f0d0 100%) border-box;
}
.item-tip .it-piece.rar-rare {
  background:
    linear-gradient(180deg, #16283f, #0c1728) padding-box,
    linear-gradient(145deg, #c4dcfb 0%, #5b8ddb 22%, #24446e 50%, #5b8ddb 78%, #c4dcfb 100%) border-box;
}
.item-tip .it-piece.rar-epic {
  background:
    linear-gradient(180deg, #261636, #150b20) padding-box,
    linear-gradient(145deg, #e6d1f7 0%, #a86fd9 22%, #4d2a70 50%, #a86fd9 78%, #e6d1f7 100%) border-box;
}
.item-tip .it-piece.rar-legendary {
  background:
    linear-gradient(180deg, #331210, #1f0908) padding-box,
    linear-gradient(145deg, #f8c2bc 0%, #e0564d 22%, #7e1f18 50%, #e0564d 78%, #f8c2bc 100%) border-box;
}
.item-tip .it-piece img { position:absolute; inset:2px; width:calc(100% - 4px); height:calc(100% - 4px); object-fit:contain; }
.item-tip .it-piece-glyph { position:absolute; inset:0; display:grid; place-items:center; font-family:'Noto Serif SC',serif; font-weight:900; font-size:18px; color:var(--parch); }
/* Darken mask over the pieces the hero is NOT wearing. */
.item-tip .it-piece.dim { filter:brightness(.38) saturate(.5); }
.item-tip .it-bonus { display:flex; gap:9px; padding:2px 14px 10px; font-size:12px; color:rgba(243,231,196,.6); }
.item-tip .it-bonus b { font-weight:700; color:rgba(243,231,196,.75); }
.item-tip .it-dot { flex:none; width:11px; height:11px; margin-top:2px; border-radius:50%; border:1.5px solid rgba(243,231,196,.45); }
.item-tip .it-bonus.on { color:var(--parch); }
.item-tip .it-bonus.on b { color:var(--gold-hi); }
.item-tip .it-bonus.on .it-dot { border-color:var(--gold-hi); background:radial-gradient(circle, var(--gold-hi) 0 55%, transparent 62%); box-shadow:0 0 6px rgba(240,209,120,.5); }
.item-tip .it-foot { padding:7px 14px; border-top:1px solid var(--line-soft); background:rgba(0,0,0,.3); border-radius:0 0 12px 12px; text-align:right; font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; color:var(--gold-hi); }
.islot.rar-epic.ro.filled:hover, .islot.rar-legendary.ro.filled:hover { box-shadow:var(--slot-outline), inset 0 1px 0 rgba(255,255,255,.08); }
/* Mini token — the same rarity frame at chip scale, for summary rows
   (replay result overlay). Always paired with .ro (no drag affordances). */
.islot.mini { display:inline-flex; flex:none; width:32px; height:32px; border-radius:9px; }
.islot.mini .islot-glyph { inset:0; font-size:16px; }
.islot.mini .islot-art { inset:2px; width:calc(100% - 4px); height:calc(100% - 4px); }
/* Big token — the personal spoils popup (rewardStageHTML). */
.islot.big { display:inline-flex; flex:none; width:104px; height:104px; border-radius:18px; }
.islot.big .islot-glyph { inset:0; font-size:52px; }
.islot.big .islot-art { inset:5px; width:calc(100% - 10px); height:calc(100% - 10px); }
/* Loot reveal (rollLootReveal): the token keeps its art while its rarity frame
   climbs the ladder — one glow pulse per level, tinted by that level's accent
   (--rar) — then lands on the true rarity with a golden pop. Any token size. */
.islot.up { animation:loot-up .55s ease-out; z-index:2; }
@keyframes loot-up {
  0%   { transform:scale(1); }
  30%  { transform:scale(1.14); box-shadow:var(--slot-outline), 0 0 0 3px var(--rar), 0 0 24px var(--rar); }
  100% { transform:scale(1); box-shadow:var(--slot-outline); }
}
.islot.landed { animation:loot-pop .5s cubic-bezier(.2,1.7,.4,1); z-index:2; }
@keyframes loot-pop {
  0%  { transform:scale(1.55); box-shadow:var(--slot-outline), 0 0 0 4px var(--rar), 0 0 26px var(--rar); }
  60% { box-shadow:var(--slot-outline), 0 0 0 2px var(--rar), 0 0 16px var(--rar); }
  100%{ transform:scale(1); box-shadow:var(--slot-outline); }
}
.islot-x {
  position:absolute; top:3px; right:3px; z-index:3; width:18px; height:18px; border:none; border-radius:6px;
  display:grid; place-items:center; cursor:pointer; font-size:10px; line-height:1; color:#fff;
  background:rgba(158,36,24,.9); box-shadow:0 1px 4px rgba(0,0,0,.6); opacity:0; transition:opacity .15s ease;
}
.islot.filled:hover .islot-x, .islot-x:focus-visible { opacity:1; }
/* Destruction-safeguard padlock — the passive gold badge a LOCKED item wears
   (store cells and the worn paper-doll alike; it replaces the ✕ on store tiles).
   The lock/unlock TOGGLE is the action-bar button beside the cart and the bin —
   it acts on the selection, so the badge itself never intercepts clicks. */
.islot-prot {
  position:absolute; top:3px; left:3px; z-index:2; width:18px; height:18px; border-radius:6px;
  display:grid; place-items:center; pointer-events:none; color:#1c1206;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  box-shadow:0 1px 3px rgba(0,0,0,.6), 0 0 8px rgba(217,178,74,.4);
}
.islot-prot svg { width:11px; height:11px; }
/* "On the shelf" badge — a small gold swap glyph on a store cell listed on the
   transfer shelf (bottom-left; the padlock owns top-left, the discard ✕ top-right). */
.islot-shared {
  position:absolute; bottom:3px; left:3px; z-index:2; width:17px; height:17px; border-radius:6px;
  display:grid; place-items:center; pointer-events:none; color:#1c1206;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft));
  box-shadow:0 1px 3px rgba(0,0,0,.6), 0 0 8px rgba(217,178,74,.35);
}
.islot-shared svg { width:11px; height:11px; }

/* ── Área de Transferência — a strip under the store grid listing gear the player
   shared across provinces. The item stays in its home cell (still counts against
   capacity); it also surfaces here, where a sibling can grab it (a click convoys
   it over). flex:none, so it steals a row's height from the scrolling grid. ── */
.hx-transferarea { flex:none; margin-top:14px; padding-top:12px; border-top:1px solid rgba(217,178,74,.22); display:flex; flex-direction:column; gap:8px; }
.hx-transferarea > h4 { display:flex; align-items:center; gap:7px; margin:0; min-height:22px; font-family:'Cinzel',serif; font-weight:700; font-size:12px; letter-spacing:.07em; text-transform:uppercase; color:var(--gold-soft); }
.hx-transferarea > h4 [data-icon] { display:grid; place-items:center; color:var(--gold-soft); }
.hx-transferarea > h4 [data-icon] svg { width:14px; height:14px; }
.hx-transferarea > h4 .hx-armory-cap { margin-left:2px; }
/* width:0 + min-width:100% pins the strip to the store column's grid width: the
   long hint / a full row of tiles can't stretch the shrink-to-fit column wider
   than the 4-tile grid (their max-content is taken out of the column's sizing). */
.ta-row { display:flex; gap:9px; overflow-x:auto; overflow-y:hidden; padding:6px 4px 8px; width:0; min-width:100%; }
.ta-row::-webkit-scrollbar { height:8px; }
.ta-row::-webkit-scrollbar-thumb { background:rgba(217,178,74,.32); border-radius:5px; }
.ta-row::-webkit-scrollbar-track { background:rgba(0,0,0,.25); }
.ta-empty { width:0; min-width:100%; display:grid; place-items:center; text-align:center; min-height:calc(var(--tsz) + 6px); padding:8px 14px; font-size:11.5px; line-height:1.5; color:rgba(243,231,196,.5); border:1.5px dashed rgba(217,178,74,.22); border-radius:12px; }
/* A shelf tile reuses the rarity-framed .islot; a bottom pill names its home
   province, a click grabs (sibling) or unlists (own). */
.ta-tile { flex:none; cursor:pointer; }
.ta-tile.ta-far:hover { box-shadow:var(--slot-outline), 0 0 0 2px rgba(217,178,74,.55), 0 12px 26px -20px rgba(0,0,0,.8); transform:translateY(-1px); }
.ta-tile.ta-full { opacity:.42; cursor:not-allowed; }
.ta-tile.ta-full:hover { transform:none; box-shadow:var(--slot-outline); }
.ta-prov { position:absolute; left:0; right:0; bottom:0; z-index:3; padding:1px 3px; text-align:center; font-family:'JetBrains Mono',monospace; font-size:8px; letter-spacing:.03em; color:var(--parch); background:linear-gradient(180deg, transparent, rgba(0,0,0,.85)); text-shadow:0 1px 2px #000; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; pointer-events:none; }
/* The own-province unlist ✕ — neutral gold, not the destructive red of the store ✕. */
.ta-x { background:rgba(20,14,6,.9); color:var(--gold-hi); border:1px solid rgba(217,178,74,.45); box-shadow:0 1px 4px rgba(0,0,0,.6); }
/* Drag a store item over the strip → highlight it as a listing drop target. */
.hx-transferarea.drop-ok .ta-row, .hx-transferarea.drop-ok .ta-empty { border:1.5px dashed var(--gold-hi); border-radius:12px; box-shadow:inset 0 0 16px rgba(217,178,74,.18); }

/* Conjuntos — collection progress (a row appears once a piece is worn): one
   compact name + worn/total line per set; the collection icons and bonus
   descriptions live in the row's hover popup. */
.hx-set { padding:5px 2px; min-width:0; }
.hx-set-name { font-family:'Cinzel',serif; font-weight:700; font-size:12.5px; letter-spacing:.05em; color:var(--parch); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.hx-set-count { font-family:'JetBrains Mono',monospace; font-size:10.5px; color:rgba(243,231,196,.55); margin-left:6px; }
.hx-set.complete .hx-set-count { color:#8fe3b4; }
.hx-set.complete .hx-set-name { color:var(--gold-hi); }

/* Discard confirm (inside the generic app modal). */
.hx-discard h3 { font-family:'Cinzel',serif; font-weight:700; font-size:17px; color:var(--gold-hi); margin:0 0 10px; }
.hx-discard p { font-size:13px; color:var(--parch); margin:0 0 16px; }
.hx-discard-foot { display:flex; gap:10px; justify-content:flex-end; }

/* Fixed-width value columns so damage/honra/espólio align across the rows. */
.as-res-val {
  flex:none; min-width:90px; display:inline-flex; align-items:center; justify-content:flex-end;
  gap:6px; font-variant-numeric:tabular-nums;
}
/* Loot in the replay result overlay: the rarity-framed item token (name/buff
   live in its tooltip); dimmed when the backpack was full. Inside the ranking
   rows it is a fixed-width column even when empty. */
.as-res-loot { display:inline-flex; align-items:center; justify-content:center; }
.as-res-row .as-res-loot { flex:none; width:40px; }
.as-res-loot.lost .islot { filter:grayscale(.6) brightness(.75); }
/* Stage-1 personal spoils popup (rewardStageHTML): the viewer's army rows with
   their spoils columns (tokens climbing the rarity ladder); the whole overlay
   is one big button to the full summary. */
.assault-result.as-reward-stage { cursor:pointer; }
.as-reward { display:flex; flex-direction:column; align-items:center; gap:18px; margin:18px 0 4px; }
.as-reward-chip {
  display:inline-flex; align-items:center; gap:7px; padding:7px 17px; border-radius:999px;
  border:1px solid var(--gold-dim); background:rgba(0,0,0,.4);
  font-family:'JetBrains Mono',monospace; font-weight:700; font-size:15px; color:var(--gold-hi);
  font-variant-numeric:tabular-nums;
}
.as-reward-chip svg { width:16px; height:16px; }
.as-reward-lost { margin:0; font-size:13px; color:rgba(243,231,196,.55); }
.as-continue {
  margin:18px 0 0; font-family:'JetBrains Mono',monospace; font-size:12px; letter-spacing:.12em;
  text-transform:uppercase; color:rgba(243,231,196,.6); animation:as-continue-pulse 1.6s ease-in-out infinite;
}
@keyframes as-continue-pulse { 0%,100% { opacity:.45; } 50% { opacity:.95; } }

/* Big world-HUD portrait doubles as the dossier button. */

/* Narrow screens: the dossier header wraps so the skill slots drop under the
   identity block. */
@media (max-width:900px) {
  .hx-head { flex-wrap:wrap; }
  .hx-skillbox { margin-left:0; }
}

/* ═══════════════════════════════════════════════════════════════
   CHAT — world-map global chat (decoupled). Docked bottom-left inside
   .world-canvas-wrap; collapses to a slim header bar. Reuses the
   gold-frame chrome. Sits above the hero HUD (z3), below the fixed
   world popups (z150).
   ═══════════════════════════════════════════════════════════════ */
.chat-mount { position:absolute; left:14px; bottom:16px; z-index:6; pointer-events:none; }
.chat-panel {
  --gf-bw:9px; --gf-r:14px; --gf-band:20px;   /* the .sm gold-frame scale */
  width:min(460px, calc(100vw - 28px));
  display:flex; flex-direction:column;
  pointer-events:auto;                         /* the panel is interactive; the mount stays click-through around it */
  /* No backdrop-filter here: the gold-frame lacquer body is already opaque, so
     the blur was invisible — yet it re-sampled the canvas beneath on EVERY map
     repaint (a per-frame GPU tax over the busiest surface in the game). */
}
.chat-panel[data-collapsed="true"] { width:auto; }
.chat-panel[data-collapsed="true"] .chat-body { display:none; }
.chat-head {
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  width:100%; padding:8px 12px; cursor:pointer;
  background:transparent; border:none; color:var(--gold-hi);
  font-family:'Cinzel',serif; font-weight:700; font-size:14px; letter-spacing:.05em;
}
.chat-head:hover { color:#ffe9a8; }
.chat-chevron { font-size:10px; color:var(--gold-soft); }
.chat-body { display:flex; flex-direction:column; gap:8px; padding:0 10px 10px; }
.chat-tabs { display:flex; gap:6px; }
.chat-tab {
  padding:3px 10px; border-radius:7px;
  font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.05em; text-transform:uppercase;
  color:#2a0d0a; background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft)); border:1px solid var(--gold-dim);
}
.chat-log {
  height:min(38vh, 300px); overflow-y:auto; overflow-x:hidden;
  display:flex; flex-direction:column; gap:10px; padding:7px 9px;
  background:rgba(0,0,0,.26); border-radius:8px; border:1px solid var(--line-soft);
  scrollbar-width:thin;
}
.chat-log::-webkit-scrollbar { width:7px; }
.chat-log::-webkit-scrollbar-thumb { background:rgba(217,178,74,.3); border-radius:5px; }
.chat-log::-webkit-scrollbar-track { background:rgba(0,0,0,.22); }
.chat-empty { margin:auto; padding:18px 10px; text-align:center; font-family:'JetBrains Mono',monospace; font-size:11.5px; color:rgba(240,209,120,.5); }
.chat-msg { display:flex; flex-direction:column; gap:3px; }
.chat-meta { display:flex; align-items:baseline; gap:8px; }
.chat-author { font-family:'Cinzel',serif; font-weight:700; font-size:12.5px; color:var(--gold-hi); }
.chat-msg.mine .chat-author { color:var(--jade-soft); }
.chat-time { font-family:'JetBrains Mono',monospace; font-size:9.5px; color:rgba(243,231,196,.4); }
.chat-line { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.chat-text { font-size:13px; line-height:1.5; color:var(--parch); word-break:break-word; overflow-wrap:anywhere; }
/* Location pin — an inline `<label>` token rendered as a clickable pill (click pans the map). */
.chat-loc-tag {
  padding:1px 6px; margin:0 1px; border-radius:5px; cursor:pointer;
  font-family:'JetBrains Mono',monospace; font-size:12px; font-weight:600;
  color:var(--gold-hi); background:rgba(240,209,120,.12); border:1px solid var(--gold-soft);
  transition:background .14s, border-color .14s;
}
.chat-loc-tag:hover { background:rgba(240,209,120,.24); border-color:var(--gold-hi); }
/* Equipment embed — clickable chip (opens the item view modal). */
.chat-embed {
  display:inline-flex; align-items:center; gap:7px; max-width:100%;
  padding:3px 10px 3px 4px; border-radius:8px; cursor:pointer;
  background:rgba(0,0,0,.3); border:1px solid var(--gold-soft); color:var(--parch);
  font-family:'JetBrains Mono',monospace; font-size:11px;
  transition:border-color .14s, background .14s, transform .12s;
}
.chat-embed:hover { border-color:var(--gold-hi); background:rgba(40,28,12,.55); transform:translateY(-1px); }
.chat-embed-label { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:170px; }
/* Compose row */
.chat-compose { display:flex; align-items:center; gap:6px; }
.chat-attach {
  flex:none; width:31px; height:31px; border-radius:7px; cursor:pointer; font-size:14px; line-height:1;
  display:inline-flex; align-items:center; justify-content:center;
  background:rgba(0,0,0,.3); border:1px solid var(--line); color:var(--gold-hi);
  transition:border-color .14s, background .14s;
}
.chat-attach:hover { border-color:var(--gold-hi); background:rgba(40,28,12,.5); }
.chat-input {
  flex:1 1 auto; min-width:0; min-height:20px; max-height:84px; overflow-y:auto;
  padding:7px 10px; border-radius:8px;
  background:rgba(0,0,0,.34); border:1px solid var(--line); color:var(--parch);
  font-family:'Noto Serif',Georgia,serif; font-size:13px; line-height:1.5;
  white-space:pre-wrap; word-break:break-word;
}
.chat-input:focus { outline:none; border-color:var(--gold-soft); }
.chat-input:empty::before { content:attr(data-placeholder); color:rgba(243,231,196,.35); pointer-events:none; }
/* Atomic pin chip inside the composer (location or equipment): contenteditable=false
   makes the browser select/delete it as one character; user-select:all reinforces the
   whole-unit grab. Locations read gold, equipment jade, to tell them apart while typing. */
.chat-tag-atom {
  display:inline-block; padding:0 5px; margin:0 1px; border-radius:5px;
  font-family:'JetBrains Mono',monospace; font-size:12px; font-weight:600; line-height:1.5;
  color:var(--gold-hi); background:rgba(240,209,120,.16); border:1px solid var(--gold-soft);
  white-space:nowrap; -webkit-user-select:all; user-select:all; cursor:default;
}
.chat-tag-atom[data-kind="item"] { color:var(--jade-soft); background:rgba(63,174,134,.15); border-color:var(--jade-2); }
.chat-send {
  flex:none; padding:7px 14px; border-radius:8px; cursor:pointer;
  font-family:'Cinzel',serif; font-weight:700; font-size:12px; letter-spacing:.04em; color:#2a0d0a;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold-soft)); border:1px solid var(--gold-dim);
  transition:filter .14s, transform .08s;
}
.chat-send:hover:not(:disabled) { filter:brightness(1.08); }
.chat-send:disabled { opacity:.5; cursor:default; }
.chat-send.cooldown { animation:chat-shake .4s ease; }
@keyframes chat-shake { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-3px);} 75%{transform:translateX(3px);} }
/* Owned-item picker (rendered in the shared modal) */
.chat-picker-h { margin:0 0 12px; text-align:center; font-family:'Cinzel',serif; font-weight:700; font-size:16px; color:var(--gold-hi); }
.chat-pick-grid { display:flex; flex-wrap:wrap; gap:10px; justify-content:center; max-width:340px; }
.chat-pick { padding:0; border:none; background:transparent; cursor:pointer; border-radius:9px; transition:transform .12s; }
.chat-pick:hover { transform:translateY(-2px) scale(1.06); }
.chat-picker-empty { padding:24px 12px; text-align:center; font-family:'JetBrains Mono',monospace; font-size:12.5px; color:rgba(240,209,120,.6); }
/* The reused hero item card (its .it-* markup) rendered inline in the view modal. */
.item-tip.static { position:static; width:100%; max-width:320px; opacity:1; pointer-events:auto; box-shadow:none; }

@media (max-width:560px) {
  .chat-mount { left:8px; right:8px; bottom:10px; }
  .chat-panel { width:auto; }
  .chat-log { height:32vh; }
}

/* ─── The Purge — Temple page ────────────────────────────────────────────── */
/* (The world-map corpse/pile send modals live with the .send-card rules; their
   shared objective gauge is .send-gauge.) */

/* Temple page layout (realm page: blessings + the faith footer only). */
.tpl-page { height:100%; display:flex; flex-direction:column; gap:14px; min-height:0;
  padding:14px 16px 0; overflow-y:auto; }
.tpl-head { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.tpl-head h2 { display:inline-flex; align-items:center; gap:8px; margin:0;
  font-family:'Cinzel',serif; font-size:17px; color:var(--gold-hi); }
.tpl-head h2 svg { width:20px; height:20px; }

/* Blessing cards — the ARMY RECRUIT-CARD design (name header on top → image →
   info → rite), one celestial guardian per card (the Four Symbols). The recruit
   card's lathed conic-gold band, warm chestnut body, dark header band and
   recessed stage are reproduced here — but the "stage" stays a LIGHT element-
   tinted silk: the art is a 500x250 image on a WHITE ground, knocked out via
   mix-blend multiply with a faint seal-glyph watermark showing through. Per-card
   element palette comes from the .g-* theme classes below. */
.tpl-blessings-wrap { flex:1 1 auto; }
.tpl-blessings { display:grid; grid-template-columns:repeat(auto-fit, minmax(238px, 1fr));
  gap:18px; margin-top:10px; }

/* Card frame: recruit conic-gold band (border-box) over the chestnut body
   (padding-box); a --tpl-fshadow base so hover/active can append a guardian aura. */
.tpl-card { position:relative; display:flex; flex-direction:column;
  border:6px solid transparent; border-radius:18px;
  transition:transform .16s ease, box-shadow .16s ease;
  --tpl-fshadow:
    0 0 0 1px #1a0705, 0 0 0 2px rgba(247,221,142,.3), 0 14px 34px rgba(0,0,0,.6),
    0 0 22px -6px rgba(240,209,120,.4),
    inset 0 1px 0 rgba(247,221,142,.16), inset 0 0 26px rgba(0,0,0,.42);
  background:
    radial-gradient(130% 70% at 50% -6%, rgba(240,209,120,.16), rgba(240,209,120,0) 58%) padding-box,
    linear-gradient(180deg, rgba(58,42,22,.25), rgba(16,10,5,.5)) padding-box,
    url(/assets/ui/header-texture.png?v=8f41a3c587) center/cover no-repeat padding-box,
    linear-gradient(180deg,#3b2b17 0%, #2a1d0f 52%, #1c1309 100%) padding-box,
    conic-gradient(from 0deg,
      var(--gold-hi) 0deg, var(--gold-soft) 20deg, #6d4f1e 45deg, var(--gold-soft) 70deg,
      var(--gold-hi) 90deg, var(--gold-soft) 110deg, #6d4f1e 135deg, var(--gold-soft) 160deg,
      var(--gold-hi) 180deg, var(--gold-soft) 200deg, #6d4f1e 225deg, var(--gold-soft) 250deg,
      var(--gold-hi) 270deg, var(--gold-soft) 290deg, #6d4f1e 315deg, var(--gold-soft) 340deg,
      var(--gold-hi) 360deg) border-box;
  box-shadow:var(--tpl-fshadow); }
.tpl-card:hover { transform:translateY(-3px);
  box-shadow:var(--tpl-fshadow), 0 0 26px var(--g-glow, rgba(240,209,120,.4)); }

/* Header band — recruit dark-lacquer name strip: gold name centered, gold
   hairline underneath, guardian glyph at the left. */
.tpl-bl-head { display:flex; align-items:center; justify-content:center; gap:8px;
  padding:12px 14px 11px; border-radius:12px 12px 0 0;
  background:
    radial-gradient(120% 90% at 50% -30%, rgba(240,209,120,.10), transparent 60%),
    linear-gradient(180deg, rgba(12,6,3,.72), rgba(24,14,8,.5));
  border-bottom:3px solid rgba(14,7,4,.9);
  box-shadow:inset 0 1px 0 rgba(247,221,142,.08), 0 1px 0 rgba(247,221,142,.22); }
.tpl-bl-name { min-width:0; text-align:center; font-family:'Cinzel',serif; font-weight:700;
  font-size:12.5px; line-height:1.15; letter-spacing:.03em; text-transform:uppercase;
  color:var(--gold-hi); text-shadow:0 1px 3px rgba(0,0,0,.6); }

/* Stage — the silk portrait, inset with a dark recessed rim (recruit .rc-stage);
   element-tinted silk + seal watermark inside, creature knocked out via multiply. */
.tpl-portrait { position:relative; isolation:isolate; margin:12px 14px 0; border-radius:10px;
  overflow:hidden; padding:9px 11px 7px; display:flex; align-items:flex-end; justify-content:center;
  background:radial-gradient(122% 132% at 50% 24%, var(--g-silk1,#f2ece0) 0%, var(--g-silk2,#d9cdb2) 100%);
  border:3px solid rgba(14,7,4,.9);
  box-shadow:0 1px 0 rgba(247,221,142,.22),
    inset 0 0 0 1px var(--g-frame, rgba(140,110,60,.5)),
    inset 0 3px 14px rgba(0,0,0,.34); }
.tpl-seal { position:absolute; top:4px; right:9px; z-index:0; margin:0; pointer-events:none;
  writing-mode:vertical-rl; font-family:'Noto Serif SC','Noto Serif',serif; font-weight:900;
  font-size:26px; line-height:1.02; letter-spacing:1px; color:var(--g-deep,#7a5c1e); opacity:.16; }
.tpl-bl-art { position:relative; z-index:1; width:100%; height:auto; display:block;
  mix-blend-mode:multiply; filter:drop-shadow(0 3px 5px rgba(24,16,6,.2));
  transition:transform .32s ease; }
.tpl-card:hover .tpl-bl-art { transform:scale(1.04); }

/* Info — effect chip(s) + flavor quote, between stage and rite. */
.tpl-bl-info { display:flex; flex-direction:column; align-items:center; gap:7px;
  padding:12px 16px 2px; text-align:center; }
.tpl-bl-fx { display:flex; flex-wrap:wrap; justify-content:center; gap:6px; }
.tpl-bl-fx .v2badge { margin:0; padding:5px 11px; font-size:11.5px;
  color:var(--g-lite, var(--parch)); border-color:var(--g-line, rgba(176,142,74,.42));
  background:var(--g-chip, rgba(217,178,74,.10)); }
.tpl-bl-quote { margin:0; font-family:'Noto Serif',serif; font-style:italic; font-size:11.5px;
  line-height:1.5; color:rgba(243,231,196,.6); max-width:32ch; text-wrap:pretty; }

/* Foot — the rite: invoke plaque or the live countdown (recruit .rc-foot shape). */
.tpl-foot { margin-top:auto; padding:14px 16px 16px; display:flex; flex-direction:column;
  align-items:center; gap:10px; }
.tpl-bl-buy { display:inline-flex; align-items:center; justify-content:center; gap:7px; width:100%; }
.tpl-bl-buy img.res-img { width:18px; height:18px; object-fit:contain; }
.tpl-bl-active { display:inline-flex; align-items:center; gap:6px;
  color:var(--g-lite, var(--jade-soft)); font-family:'JetBrains Mono',monospace; font-size:13px; }
.tpl-bl-active svg { width:14px; height:14px; }

/* Consecrated — a blessing is in force: a persistent guardian aura + the stage
   glows its element colour. */
.tpl-card.active { box-shadow:var(--tpl-fshadow), 0 0 22px var(--g-glow, rgba(63,174,134,.4)); }
.tpl-card.active .tpl-portrait::after { content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  box-shadow:inset 0 0 28px var(--g-glow, rgba(63,174,134,.4)); }

/* ── Per-guardian element palettes (the Four Symbols) ────────────────────────
   --g-silk1/2: silk gradient · --g-frame: window inner frame · --g-deep: seal
   ink · --g-line: hairlines · --g-glow: aura · --g-lite: chip/eta text on
   lacquer · --g-chip: chip fill. */
.tpl-card.g-azure {
  --g-silk1:#eef6fc; --g-silk2:#cbe1f2; --g-frame:rgba(52,110,160,.5); --g-deep:#164a72;
  --g-line:rgba(96,168,222,.5); --g-glow:rgba(74,151,214,.3); --g-lite:#c7e4f7; --g-chip:rgba(74,151,214,.12); }
.tpl-card.g-vermilion {
  --g-silk1:#fdf2ea; --g-silk2:#f4d6c4; --g-frame:rgba(178,74,44,.5); --g-deep:#8a2a14;
  --g-line:rgba(224,90,48,.5); --g-glow:rgba(224,90,48,.32); --g-lite:#f6c3ad; --g-chip:rgba(224,90,48,.12); }
.tpl-card.g-tiger {   /* White Tiger — West / Metal: moonlit silver, not gold */
  --g-silk1:#edf1f6; --g-silk2:#d3dce6; --g-frame:rgba(120,140,162,.5); --g-deep:#33465c;
  --g-line:rgba(150,172,196,.55); --g-glow:rgba(190,206,224,.34); --g-lite:#dce7f1; --g-chip:rgba(150,172,196,.13); }
.tpl-card.g-tortoise {
  --g-silk1:#edf4ef; --g-silk2:#d0e0d6; --g-frame:rgba(63,138,114,.5); --g-deep:#22493a;
  --g-line:rgba(79,138,114,.55); --g-glow:rgba(79,138,114,.3); --g-lite:#bfe6d3; --g-chip:rgba(79,138,114,.12); }

/* Faith footer — the Decretos seal bar verbatim (.tech-honor-bar), pinned
   below the blessings like the .dt-selo footer under the decree board. */
.tpl-faith { flex:none; align-self:center; width:100%; max-width:720px; box-sizing:border-box;
  padding:12px 0 14px; border-top:1px solid rgba(176,142,74,.16); }
