/* AgeUp UI v2 (2026-09-29): simple clean cartoon. Cream cards, thick soft-brown outline, chunky rounded
   buttons with a flat drop, muted palette. Tokens = theme.css only. Icons = /assets/ui2 (Icons.jsx).
   Layout: canvas full-bleed; .vitals top-left, .dock menu column right, .hotbar bottom-center, .panel right
   (bottom stops above .hotbar), mobile <=calc(620 * var(--u)) = panel full sheet over everything. Docs: docs/UI.md, UI-SKIN.md. */

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--page); color: var(--ink);
  font: 400 var(--body-size)/1.45 var(--font);
  -webkit-tap-highlight-color: transparent;
}
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--blue-dk); font-weight: 500; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; }
.muted { color: var(--ink-dim); }
.small { font-size: .88em; }
.center { text-align: center; }
.err { color: var(--locked); font-weight: 600; margin: 0; }
.spacer { flex: 1; }
.row { display: flex; align-items: center; gap: calc(8 * var(--u)); flex-wrap: wrap; }
.ic { width: calc(28 * var(--u)); height: calc(28 * var(--u)); flex: none; object-fit: contain; }
svg.ic.glyph { width: calc(22 * var(--u)); height: calc(22 * var(--u)); fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
svg.ic.glyph .fillg { fill: currentColor; }
.sheet-icon { display: inline-block; background-repeat: no-repeat; }
/* gear weapon art is a thin horizontal strip -> show diagonal so it fills a square slot */
img.ic[src*="/weapon/"]:not([src*="shield"]) { transform: rotate(-45deg) scale(1.3); }
kbd { font: inherit; }

/* ============ CARD: panels, sheets, popups, modals ============ */
.panel, .sheet, .popup, .item-modal {
  position: relative; color: var(--ink);
  background: var(--cream);
  border: var(--line-w) solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow), inset 0 calc(3 * var(--u)) 0 var(--cream-lt);
}

/* ============ BUTTONS ============ */
.btn {
  --face: var(--sage);
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: calc(6 * var(--u));
  min-height: var(--btn-h); padding: calc(6 * var(--u)) calc(18 * var(--u)); cursor: inherit; user-select: none; touch-action: manipulation;
  font-weight: 500; font-size: var(--body-size); color: var(--line); text-decoration: none;
  background: var(--face); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--gloss), 0 calc(3 * var(--u)) 0 var(--line);
  transition: transform var(--anim-ms) var(--ease), filter var(--anim-ms);
}
.btn .ic { width: calc(24 * var(--u)); height: calc(24 * var(--u)); }
.btn:hover { filter: brightness(1.05); }
.btn:active { transform: translateY(calc(3 * var(--u))); box-shadow: var(--gloss), 0 0 0 var(--line); }
.btn:focus-visible, .mbtn:focus-visible, .hk:focus-visible, .attack:focus-visible, .rbtn:focus-visible, .ui-tab:focus-visible, .slot:focus-visible { outline: calc(3 * var(--u)) solid var(--blue-dk); outline-offset: calc(2 * var(--u)); }
.btn:disabled { filter: grayscale(.7) opacity(.6); cursor: inherit; transform: none; }
.btn.ghost { --face: var(--cream-lt); }
.btn.brass { --face: var(--gold); }
.btn.mint, .btn.ok { --face: var(--sage); }
.btn.rose, .btn.danger { --face: var(--coral); }
.btn.sky { --face: var(--blue); }
.btn.active, .btn.ghost.active { --face: var(--blue); }
.btn.sm { min-height: calc(34 * var(--u)); padding: calc(3 * var(--u)) calc(12 * var(--u)); font-size: .9em; border-width: calc(2 * var(--u)); box-shadow: var(--gloss), 0 calc(2 * var(--u)) 0 var(--line); }
.btn.big { min-height: calc(52 * var(--u)); font-size: calc(18 * var(--u)); font-weight: 600; }
.btn kbd { font-size: calc(11 * var(--u)); padding: 0 calc(6 * var(--u)); border-radius: calc(6 * var(--u)); background: rgba(255,255,255,.55); border: calc(2 * var(--u)) solid var(--line); }

/* round icon button (back, chat) */
.rbtn {
  width: var(--btn-h); height: var(--btn-h); padding: 0; border-radius: 50%; cursor: inherit;
  display: inline-grid; place-items: center; color: var(--line);
  background: var(--cream-lt); border: var(--line-w) solid var(--line); box-shadow: var(--gloss), 0 calc(3 * var(--u)) 0 var(--line);
}
.rbtn:active { transform: translateY(calc(3 * var(--u))); box-shadow: var(--gloss); }
.rbtn .ic { width: calc(26 * var(--u)); height: calc(26 * var(--u)); }

/* close: coral disc on the card corner */
.ui-close {
  position: absolute; z-index: 3; top: calc(-12 * var(--u)); right: calc(-12 * var(--u));
  width: calc(40 * var(--u)); height: calc(40 * var(--u)); padding: 0; border-radius: 50%; cursor: inherit;
  display: grid; place-items: center; color: var(--line);
  background: var(--coral); border: var(--line-w) solid var(--line); box-shadow: var(--gloss), 0 calc(3 * var(--u)) 0 var(--line);
}
.ui-close:active { transform: translateY(calc(3 * var(--u))); box-shadow: var(--gloss); }
.ui-close svg.ic.glyph { width: calc(18 * var(--u)); height: calc(18 * var(--u)); stroke-width: 4; }

/* ============ TABS / SEGMENTED ============ */
/* K-125 side tab rail (Panels.jsx Tabs): steel slot buttons outside the panel's right edge; active = lit + arrow pointing into the panel */
.panel.has-side-tabs { right: calc(var(--menu-btn) + calc(44 * var(--u)) + var(--side-tab) + calc(30 * var(--u)) + env(safe-area-inset-right)); }
.side-tabs { position: absolute; left: calc(100% + calc(14 * var(--u))); top: calc(24 * var(--u)); z-index: 2; display: flex; flex-direction: column; gap: calc(14 * var(--u)); }
.side-tab-group { display: flex; flex-direction: column; gap: calc(8 * var(--u)); }
.side-tab { position: relative; width: var(--side-tab); height: var(--side-tab); padding: calc(10 * var(--u)); cursor: inherit; display: grid; place-items: center;
  border: 0 solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; background: none;
  filter: brightness(.82) saturate(.85); transition: filter var(--anim-ms), transform var(--anim-ms); }
.side-tab .ic { width: 100%; height: 100%; object-fit: contain; }
.side-tab .ic.glyph { color: var(--cream-lt); stroke-width: 2.4; }
.side-tab svg.ic.glyph { width: 100%; height: 100%; }   /* beat svg.ic.glyph 22u: glyph tabs fit the frame like PNG tabs */
.side-tab:hover { filter: none; }
.side-tab.active { filter: brightness(1.12) drop-shadow(0 0 calc(5 * var(--u)) rgba(255, 214, 120, .75)); transform: translateX(calc(-4 * var(--u))); }
.side-tab.active::before { content: ""; position: absolute; left: calc(-17 * var(--u)); top: 50%; transform: translateY(-50%);
  border: calc(9 * var(--u)) solid transparent; border-right: calc(10 * var(--u)) solid #3a3f48; filter: drop-shadow(-1px 0 0 #1d2128); }
.side-tab .badge { position: absolute; right: calc(-8 * var(--u)); top: calc(-8 * var(--u)); min-width: calc(18 * var(--u)); height: calc(18 * var(--u)); padding: 0 calc(4 * var(--u));
  border-radius: calc(9 * var(--u)); background: var(--coral); color: #fff; font-size: calc(11 * var(--u)); font-weight: 700; display: grid; place-items: center; border: calc(2 * var(--u)) solid #1d2128; }
.tab-title { margin: 0; padding-bottom: calc(6 * var(--u)); border-bottom: calc(2 * var(--u)) solid rgba(139, 107, 78, .35); font-size: calc(19 * var(--u)) !important; }
@media (max-width: 620px) {   /* K-363b (user 2026-10-09): phone rail stays OUTSIDE the parchment like desktop (was inside .body); smaller tabs, panel gives up the room */
  :root { --side-tab: calc(44 * var(--u)); }   /* knob: phone tab size */
  .panel.has-side-tabs { right: calc(var(--side-tab) + calc(14 * var(--u)) - var(--pnl-r) + calc(8 * var(--u)) + env(safe-area-inset-right)); }   /* rail right edge + 8u */
  .side-tabs { top: calc(78 * var(--u)); gap: calc(10 * var(--u)); }
  .side-tab { padding: calc(8 * var(--u)); }
}
.ui-tabs, .seg { display: flex; gap: calc(6 * var(--u)); flex-wrap: wrap; }
.ui-tab {
  display: inline-flex; align-items: center; gap: calc(6 * var(--u)); min-height: calc(40 * var(--u)); padding: calc(4 * var(--u)) calc(14 * var(--u)); cursor: inherit;
  font-weight: 500; color: var(--ink-dim);
  background: var(--cream-dk); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--gloss);
}
.ui-tab .ic { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
.ui-tab.active { color: var(--line); background: var(--sage); box-shadow: var(--gloss), 0 calc(3 * var(--u)) 0 var(--line); transform: translateY(calc(-2 * var(--u))); }
.seg .btn { flex: 1; --face: var(--cream-lt); }
.seg .btn.active { --face: var(--blue); }

/* ============ FORMS ============ */
.sheet form { display: flex; flex-direction: column; gap: calc(10 * var(--u)); }
label, .field label { font-size: .9em; font-weight: 500; color: var(--ink-dim); }
input, select, textarea {
  min-height: var(--btn-h); min-width: 0; padding: calc(6 * var(--u)) calc(12 * var(--u));
  background: var(--cream-lt); color: var(--ink);
  border: var(--line-w) solid var(--brown); border-radius: var(--radius-sm); box-shadow: var(--well);
}
textarea { min-height: calc(64 * var(--u)); resize: vertical; }
.field { display: flex; flex-direction: column; gap: calc(4 * var(--u)); }
.field.inline { flex-direction: row; align-items: center; justify-content: space-between; gap: calc(10 * var(--u)); }
.field.inline input[type=number], .field.inline select { width: calc(110 * var(--u)); }
.field.inline input[type=text] { width: calc(170 * var(--u)); }

/* ============ PRE-GAME: title screen (login / create / map picker) ============ */
.title-screen {
  min-height: 100vh; min-height: 100dvh; padding: max(calc(20 * var(--u)), env(safe-area-inset-top)) calc(16 * var(--u)) max(calc(20 * var(--u)), env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: calc(8 * var(--u));
  background: var(--page) url(/assets/ui2/login_bg_k344.webp?v=k344) center / cover no-repeat fixed;
}
.title-screen .logo { width: min(calc(300 * var(--u)), 60vw, 34vh); height: auto;   /* K-243 square AgeUp emblem (was 720x336 wordmark) */ margin-top: 3vh; filter: drop-shadow(0 calc(6 * var(--u)) 0 rgba(59,42,30,.25)); }
.sheet {
  width: min(calc(400 * var(--u)), 100%); margin-top: 1vh; padding: calc(20 * var(--u));
  display: flex; flex-direction: column; gap: calc(12 * var(--u));
}
.sheet.wide { width: min(calc(640 * var(--u)), 100%); }
.sheet > h2 { text-align: center; font-size: var(--title-size); }
.sheet p { margin: 0; }
.sheet .muted { color: var(--ink-dim); }
.create { align-items: stretch; }
.create-portrait {
  align-self: center; width: calc(180 * var(--u)); height: calc(220 * var(--u)); display: grid; place-items: end center; overflow: hidden;
  background: radial-gradient(circle at 50% 70%, var(--cream-lt) 0 55%, var(--cream-dk) 56%);
  border: var(--line-w) solid var(--line); border-radius: 50% 50% var(--radius) var(--radius); box-shadow: var(--well);
}
.create-portrait img { width: calc(180 * var(--u)); height: calc(240 * var(--u)); object-fit: contain; margin-bottom: calc(-14 * var(--u)); }
.maps { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(8 * var(--u)); max-height: 50vh; overflow: auto; }

/* list-row card (map picker, quest rows) */
.maps .map, .ui-quest-row {
  width: 100%; text-align: left; cursor: inherit; padding: calc(10 * var(--u)) calc(14 * var(--u)); display: grid; gap: calc(2 * var(--u));
  background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm);
  box-shadow: 0 calc(3 * var(--u)) 0 var(--line);
}
.maps .map:active, .ui-quest-row:active { transform: translateY(calc(3 * var(--u))); box-shadow: none; }
.maps .map strong { font-weight: 600; font-size: calc(17 * var(--u)); }
.ui-quest-row { position: relative; display: flex; align-items: center; gap: calc(8 * var(--u)); padding-left: calc(44 * var(--u)); }
.ui-quest-row > .ui-mark { position: absolute; left: calc(8 * var(--u)); top: 50%; transform: translateY(-50%); }
.ui-quest-row .nm { flex: 1; font-weight: 500; }
.ui-quest-row.sel { background: var(--blue); }
.ui-mark { display: inline-grid; place-items: center; width: calc(28 * var(--u)); height: calc(28 * var(--u)); }
.ui-mark .ic { width: calc(28 * var(--u)); height: calc(28 * var(--u)); }
.ui-mark.quest { filter: hue-rotate(160deg) saturate(.6); }

/* ============ IN-GAME ============ */
.game { position: fixed; inset: 0; overflow: hidden; background: #2E3B34; }
.stage { position: absolute; inset: 0; margin: 0; }
.stage canvas { display: block; width: 100%; height: 100%; touch-action: none; }
.hud { position: absolute; left: 0; right: 0; z-index: 4; display: flex; align-items: center; gap: calc(10 * var(--u)); pointer-events: none;
  padding: calc(10 * var(--u)) max(calc(12 * var(--u)), env(safe-area-inset-right)) calc(10 * var(--u)) max(calc(12 * var(--u)), env(safe-area-inset-left)); }
.hud > * { pointer-events: auto; }
.hud.top { top: 0; padding-top: max(calc(10 * var(--u)), env(safe-area-inset-top)); }
.hud.bottom { bottom: 0; justify-content: center; }
.hud.bottom .err { padding: calc(4 * var(--u)) calc(12 * var(--u)); background: var(--cream); border: calc(2 * var(--u)) solid var(--line); border-radius: var(--radius-sm); }
.mapname {
  display: inline-flex; align-items: center; gap: calc(8 * var(--u)); height: calc(38 * var(--u)); padding: 0 calc(16 * var(--u)) 0 calc(12 * var(--u));
  font-weight: 600; font-size: calc(17 * var(--u)); background: var(--cream); border: var(--line-w) solid var(--line); border-radius: calc(999 * var(--u)); box-shadow: var(--lift);
}
/* K-005 zone label next to the map name (map doc zone.color) */
.zonetag { display: inline-flex; align-items: center; height: calc(28 * var(--u)); padding: 0 calc(10 * var(--u)); font-weight: 700; font-size: calc(13 * var(--u));
  border: var(--line-w) solid var(--line); border-radius: calc(999 * var(--u)); box-shadow: var(--lift); color: #fff; text-shadow: 0 1px 0 #0006; }
.zonetag.z-blue { background: #4f9fd8; } .zonetag.z-yellow { background: #e0b43a; color: #3a2a10; text-shadow: none; }
.zonetag.z-red { background: #d0574a; } .zonetag.z-black { background: #2c2630; }
/* K-036 G2 dungeon = purple FRAME (user 2026-10-02), no zone colour */
.zonetag.z-dungeon { background: #2e2140; border: calc(3 * var(--u)) solid #9b6bd6; color: #efe2ff; }
.dot { width: calc(12 * var(--u)); height: calc(12 * var(--u)); border-radius: 50%; background: var(--cream-dk); border: calc(2 * var(--u)) solid var(--line); }
.dot.online { background: var(--sage); }
.dot.offline, .dot.connecting { background: var(--coral); }
.dotl { display: inline-block; width: calc(10 * var(--u)); height: calc(10 * var(--u)); margin-right: calc(6 * var(--u)); border-radius: 50%; background: var(--cream-dk); border: calc(2 * var(--u)) solid var(--line); vertical-align: middle; }
.dotl.on { background: var(--sage); }

/* ---- K-157 minimap (top-right): round map + name / zone / PvP row under it ---- */
.minimap { position: absolute; z-index: 4; top: max(calc(12 * var(--u)), env(safe-area-inset-top)); right: max(calc(12 * var(--u)), env(safe-area-inset-right));
  display: flex; flex-direction: column; align-items: flex-end; gap: calc(6 * var(--u)); pointer-events: none; }
.minimap canvas { width: var(--mm); height: var(--mm); border-radius: 50%; background: #2f3a2a; }
/* K-227 (user 2026-10-06 "Map เอา UI วงกลมเหล็ก" -> v1 portrait_ring too thick -> picked variant A): minimap_ring.png 512px, hole d ~.773 box, studs reach ~.99 box.
   knob --mm-ring: ring box / --mm (1.24 -> hole ~.96mm just covers the canvas edge; studs poke ~.1mm out; margin/dock/pvpflag offsets follow) */
.minimap { --mm-ring: 1.24; margin: calc(22 * var(--u)) calc(22 * var(--u)) 0 0; }
.minimap::after { content: ""; position: absolute; z-index: 1; top: calc(var(--mm) / 2); left: 50%; width: calc(var(--mm) * var(--mm-ring)); height: calc(var(--mm) * var(--mm-ring));
  transform: translate(-50%, -50%); background: url(/assets/ui3/minimap_ring.png) center / contain no-repeat; filter: drop-shadow(0 calc(3 * var(--u)) calc(4 * var(--u)) rgba(40, 26, 14, .45)); pointer-events: none; }
.minimap .mm-label { z-index: 2; }
.minimap .mm-label { display: flex; flex-wrap: nowrap; justify-content: flex-end; align-items: center; gap: calc(6 * var(--u)); white-space: nowrap; pointer-events: auto; }
:root { --mm: calc(168 * var(--u)); }

/* ---- vitals card ---- */
.vitals {
  position: absolute; z-index: 3; top: max(calc(12 * var(--u)), env(safe-area-inset-top)); left: max(calc(12 * var(--u)), env(safe-area-inset-left));
  display: flex; align-items: flex-start; gap: calc(10 * var(--u)); padding: calc(10 * var(--u)) calc(12 * var(--u)) calc(10 * var(--u)) calc(10 * var(--u)); pointer-events: none;
  background: var(--cream); border: var(--line-w) solid var(--line); border-radius: var(--radius); box-shadow: var(--lift);
}
.vitals .avatar { position: relative; flex: none; width: calc(60 * var(--u)); height: calc(60 * var(--u)); }
.vitals .avatar .ic { width: calc(60 * var(--u)); height: calc(60 * var(--u)); }
.vitals .avatar b {
  position: absolute; left: 50%; bottom: calc(-8 * var(--u)); transform: translateX(-50%);
  padding: 0 calc(8 * var(--u)); font-size: calc(13 * var(--u)); font-weight: 600; line-height: calc(20 * var(--u));
  background: var(--gold); border: calc(2 * var(--u)) solid var(--line); border-radius: calc(999 * var(--u));
}
.vitals .bars { display: flex; flex-direction: column; gap: calc(4 * var(--u)); width: calc(190 * var(--u)); }
.vitals .who { font-weight: 600; line-height: 1.1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- bars: cream track, thick outline, flat fill with a soft top shine ---- */
.bar, .odds .o .t, .craft-job .t, .partybar .pm .t, .bossbar .t {
  position: relative; display: block; overflow: hidden; height: calc(18 * var(--u));
  background: var(--cream-dk); border: calc(2 * var(--u)) solid var(--line); border-radius: calc(999 * var(--u)); box-shadow: var(--well);
}
.bar i, .odds .o .t i, .craft-job .t i, .partybar .pm .t i, .bossbar .t i {
  display: block; height: 100%; border-radius: calc(999 * var(--u)); background: var(--sage);
  box-shadow: inset 0 calc(3 * var(--u)) 0 rgba(255,255,255,.35); transition: width var(--anim-ms) linear;
}
.bar b, .bossbar .t b {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: calc(11 * var(--u)); font-weight: 500; line-height: 1; color: var(--line); font-variant-numeric: tabular-nums;
}
.bar.hp i { background: var(--coral); }
.bar.mp i { background: var(--blue); }
.bar.sta { height: calc(10 * var(--u)); }
.bar.sta i { background: var(--gold); }
.bar.sta.winded i { background: var(--coral-dk); }
.bar.xp i { background: var(--sage); }
.vitals .bar.xp { height: calc(16 * var(--u)); margin-top: calc(2 * var(--u)); }
.vitals .bar.xp b { font-size: calc(10 * var(--u)); }

.partybar { display: flex; flex-direction: column; gap: calc(3 * var(--u)); margin-top: calc(4 * var(--u)); }
.partybar .pm { display: grid; grid-template-columns: 1fr calc(70 * var(--u)); align-items: center; gap: calc(6 * var(--u)); font-size: calc(12 * var(--u)); }
.partybar .pm .t { height: calc(10 * var(--u)); }
.partybar .pm .t i { background: var(--coral); }
.partybar .pm .t.na { opacity: .4; }
.partybar .lead { font-weight: 600; }

.bossbar {
  position: absolute; z-index: 3; left: 50%; top: calc(calc(12 * var(--u)) + env(safe-area-inset-top)); transform: translateX(-50%);
  width: min(calc(420 * var(--u)), calc(100vw - calc(32 * var(--u)))); display: flex; flex-direction: column; align-items: center; gap: calc(3 * var(--u)); pointer-events: none;
  padding: calc(6 * var(--u)) calc(12 * var(--u)) calc(8 * var(--u)); background: var(--cream); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--lift);
}
.bossbar .nm { font-weight: 600; font-size: calc(13 * var(--u)); }
.bossbar .t { width: 100%; height: calc(16 * var(--u)); }
.bossbar .t i { background: var(--coral); }
.bossbar.RECOVERING .t i { background: var(--cream-dk); }

/* ---- menu column (right) ---- */
.dock {
  position: absolute; z-index: 4; right: max(calc(12 * var(--u)), env(safe-area-inset-right)); top: calc(var(--mm) + calc(78 * var(--u)));   /* K-157 below the minimap (K-227 +22 ring margin +14 pvpflag) (K-182 labels overlay the ring) */
  display: flex; flex-direction: column; gap: calc(6 * var(--u)); padding: calc(8 * var(--u)); max-height: calc(100% - var(--mm) - calc(200 * var(--u))); overflow-y: auto; scrollbar-width: none;
  background: var(--cream); border: var(--line-w) solid var(--line); border-radius: var(--radius); box-shadow: var(--lift);
}
.mbtn {
  position: relative; flex: none; width: var(--menu-btn); height: var(--menu-btn); padding: 0; cursor: inherit;
  display: grid; place-items: center; background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--brown); border-radius: var(--radius-sm);
}
.mbtn .ic { width: calc(38 * var(--u)); height: calc(38 * var(--u)); transition: transform var(--anim-ms) var(--ease); }
.mbtn:hover .ic { transform: scale(1.1) rotate(-4deg); }
.mbtn.active { background: var(--blue); border: var(--line-w) solid var(--line); }
.mbtn kbd {
  position: absolute; right: calc(-3 * var(--u)); bottom: calc(-3 * var(--u)); min-width: calc(18 * var(--u)); padding: 0 calc(4 * var(--u)); font-size: calc(10 * var(--u)); line-height: calc(16 * var(--u)); font-weight: 600;
  background: var(--cream); border: calc(2 * var(--u)) solid var(--line); border-radius: calc(6 * var(--u));
}

/* ---- hotbar + attack (bottom-center) ---- */
.hotbar {
  position: absolute; z-index: 4; left: 50%; bottom: calc(calc(12 * var(--u)) + env(safe-area-inset-bottom)); transform: translateX(-50%);
  display: flex; align-items: center; gap: calc(8 * var(--u)); padding: calc(8 * var(--u)) calc(10 * var(--u));
  background: var(--cream); border: var(--line-w) solid var(--line); border-radius: var(--radius); box-shadow: var(--lift);
}
.hk {
  position: relative; width: calc(64 * var(--u)); height: calc(56 * var(--u)); padding: calc(10 * var(--u)) calc(4 * var(--u)) calc(2 * var(--u)); cursor: inherit; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
  background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--gloss), 0 calc(3 * var(--u)) 0 var(--line);
}
.hk:active { transform: translateY(calc(3 * var(--u))); box-shadow: var(--gloss); }
.hk b { font-size: calc(11 * var(--u)); font-weight: 500; line-height: 1.1; text-align: center; }
.hk small { font-size: calc(10 * var(--u)); color: var(--blue-dk); font-weight: 500; }
.hk kbd { position: absolute; top: calc(1 * var(--u)); left: calc(5 * var(--u)); font-size: calc(10 * var(--u)); font-weight: 600; color: var(--ink-dim); }
.hk.empty { background: var(--cream-dk); border-style: dashed; border-color: var(--brown); box-shadow: none; cursor: inherit; }
.hk.nomp small { color: var(--locked); }
/* cooldown: dark wedge sweeps away clockwise (--cd 1 -> 0) */
.hk .cd {
  position: absolute; inset: 0; display: grid; place-items: center; font-weight: 600; font-size: calc(16 * var(--u)); color: var(--cream-lt);
  background: conic-gradient(rgba(59,42,30,.62) calc(var(--cd) * 360deg), transparent 0);
}
.hk .cd span { text-shadow: 0 calc(2 * var(--u)) 0 var(--line); }
.hk .charges { position: absolute; top: calc(1 * var(--u)); right: calc(5 * var(--u)); font-style: normal; font-weight: 700; font-size: calc(11 * var(--u)); color: #fff; text-shadow: 0 1px 0 #000, 0 0 calc(3 * var(--u)) rgba(0, 0, 0, .7); z-index: 1; }   /* K-077 charges ready */
.attack {
  position: relative; width: calc(68 * var(--u)); height: calc(68 * var(--u)); margin: calc(-14 * var(--u)) 0 calc(-14 * var(--u)) calc(4 * var(--u)); padding: 0; border-radius: 50%; cursor: inherit;
  display: grid; place-items: center; background: var(--sage); border: var(--line-w) solid var(--line); box-shadow: var(--gloss), 0 calc(4 * var(--u)) 0 var(--line);
}
.attack .ic { width: calc(50 * var(--u)); height: calc(50 * var(--u)); }
.attack small {
  position: absolute; bottom: calc(-10 * var(--u)); left: 50%; transform: translateX(-50%); white-space: nowrap;
  padding: 0 calc(8 * var(--u)); font-size: calc(11 * var(--u)); font-weight: 600; line-height: calc(18 * var(--u)); background: var(--cream); border: calc(2 * var(--u)) solid var(--line); border-radius: calc(999 * var(--u));
}
.attack:active { transform: translateY(calc(4 * var(--u))); box-shadow: var(--gloss); }

/* ---- gather hint / ring (above hotbar) ---- */
.gather-hint {
  position: absolute; z-index: 4; left: 50%; bottom: calc(var(--hotbar-h) + calc(34 * var(--u)) + env(safe-area-inset-bottom)); transform: translateX(-50%);
  display: flex; align-items: center; gap: calc(8 * var(--u)); white-space: nowrap;
}
.gather-hint > b { padding: calc(2 * var(--u)) calc(12 * var(--u)); background: var(--cream); border: calc(2 * var(--u)) solid var(--line); border-radius: calc(999 * var(--u)); font-weight: 500; }
.gather-ring {
  --p: 0; width: calc(56 * var(--u)); height: calc(56 * var(--u)); border-radius: 50%; display: grid; place-items: center;
  background: conic-gradient(var(--sage) calc(var(--p) * 360deg), var(--cream-dk) 0);
  border: var(--line-w) solid var(--line); box-shadow: var(--lift);
}
.gather-ring .ic { width: calc(36 * var(--u)); height: calc(36 * var(--u)); padding: calc(4 * var(--u)); border-radius: 50%; background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); }

/* ---- banners, toasts ---- */
.downed {
  position: absolute; z-index: 3; left: 50%; top: 42%; transform: translate(-50%, -50%);
  padding: calc(10 * var(--u)) calc(22 * var(--u)); font-weight: 600; background: var(--coral); border: var(--line-w) solid var(--line); border-radius: calc(999 * var(--u)); box-shadow: var(--lift);
}
.downed.safe { top: 30%; background: var(--sage); font-weight: 500; }
.toasts {
  position: absolute; z-index: 6; left: 50%; top: calc(calc(64 * var(--u)) + env(safe-area-inset-top)); transform: translateX(-50%);
  width: min(calc(360 * var(--u)), calc(100vw - calc(32 * var(--u)))); display: flex; flex-direction: column; align-items: center; gap: calc(6 * var(--u)); pointer-events: none;
}
.toasts.shift { top: calc(calc(84 * var(--u)) + env(safe-area-inset-top)); }
.toast {
  padding: calc(6 * var(--u)) calc(16 * var(--u)); font-size: calc(14 * var(--u)); font-weight: 500; text-align: center;
  background: var(--cream); border: var(--line-w) solid var(--line); border-radius: calc(999 * var(--u)); box-shadow: var(--lift);
  animation: pop var(--anim-ms) var(--ease);
}
.toast.rose { background: var(--coral); }
.toast.mint { background: var(--sage); }
.toast.sky { background: var(--blue); }
.toast.brass { background: var(--gold); }
/* user 2026-10-16 "toast ไม่สวย ... bg จาง ๆ": plain toasts = soft dark band fading out at both ends, light text; kind = text colour (request popups .act/.popup keep the card) */
.toast:not(.act, .popup) { background: linear-gradient(90deg, transparent, rgba(22, 15, 8, .6) 18%, rgba(22, 15, 8, .6) 82%, transparent); border: 0; border-radius: 0; box-shadow: none;
  color: #fff4dc; text-shadow: 0 1px 2px #000; padding: calc(7 * var(--u)) calc(48 * var(--u)); }
.toast.rose:not(.act, .popup) { color: #ffb0a2; } .toast.mint:not(.act, .popup) { color: #c4f2a8; } .toast.sky:not(.act, .popup) { color: #b4dcff; } .toast.brass:not(.act, .popup) { color: #ffd98a; }
.toast.act { pointer-events: auto; border-radius: var(--radius); display: flex; flex-direction: column; gap: calc(6 * var(--u)); padding: calc(12 * var(--u)) calc(16 * var(--u)); }
.toast.act .actions { justify-content: center; }
@keyframes pop { from { transform: scale(.85); opacity: 0; } }

/* ---- chat ---- */
.chat-toggle { position: absolute; z-index: 4; left: max(calc(12 * var(--u)), env(safe-area-inset-left)); bottom: calc(calc(18 * var(--u)) + env(safe-area-inset-bottom)); }
.chat-popup {
  position: absolute; z-index: 7; left: max(calc(12 * var(--u)), env(safe-area-inset-left)); bottom: calc(calc(76 * var(--u)) + env(safe-area-inset-bottom));
  width: min(calc(380 * var(--u)), calc(100vw - calc(24 * var(--u)))); padding: calc(12 * var(--u)); display: flex; flex-direction: column; gap: calc(8 * var(--u));
}
.chatlog { list-style: none; margin: 0; padding: calc(8 * var(--u)) calc(10 * var(--u)); max-height: calc(200 * var(--u)); overflow-y: auto; font-size: calc(14 * var(--u));
  background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--brown); border-radius: var(--radius-sm); }
.chatlog:empty::before { content: 'ยังไม่มีข้อความ'; color: var(--ink-dim); }
.chatlog b { color: var(--blue-dk); font-weight: 600; }
.chatbox { display: flex; gap: calc(6 * var(--u)); }
.chatbox input { flex: 1; }

/* ============ PANEL ============ */
.panel {
  position: absolute; z-index: 5;
  right: calc(var(--menu-btn) + calc(44 * var(--u)) + env(safe-area-inset-right)); top: calc(calc(64 * var(--u)) + env(safe-area-inset-top));
  width: min(var(--panel-w), calc(100vw - var(--menu-btn) - calc(72 * var(--u))));
  max-height: calc(100% - calc(64 * var(--u)) - var(--hotbar-h) - calc(34 * var(--u)) - env(safe-area-inset-top) - env(safe-area-inset-bottom));  /* never under the hotbar */
  display: flex; flex-direction: column; container-type: inline-size;
  animation: pop var(--anim-ms) var(--ease);
}
.ui-title {
  flex: none; position: relative; display: flex; align-items: center; justify-content: center; min-height: calc(48 * var(--u)); padding: calc(6 * var(--u)) calc(48 * var(--u));
  border-bottom: var(--line-w) solid var(--line); background: var(--sage); border-radius: calc(var(--radius) - calc(3 * var(--u))) calc(var(--radius) - calc(3 * var(--u))) 0 0;
  box-shadow: inset 0 calc(3 * var(--u)) 0 rgba(255,255,255,.35);
}
.ui-title h2 { font-size: var(--title-size); font-weight: 600; text-align: center; }
/* user 2026-10-12 "หน้าต่าง UI ทั้งหมดตรงกลาง": every panel centred horizontally (was right-anchored by the dock). Desktop / landscape only (<=620px
   = full-width sheet). `translate` (not transform): pop animation (transform: scale) + bpass/cashshop transform centring stay independent
   (those reset translate). Side-tab panels: panel + rail centred together (shift left half the rail). Top unchanged (below top HUD). */
@media (min-width: 621px) {
  /* user 2026-10-16 "กลางจอเลย": also vertically centred in the play area (top HUD 64u .. hotbar), max-height unchanged */
  .panel { left: 50%; right: auto; top: calc((64 * var(--u) + env(safe-area-inset-top) + 100% - var(--hotbar-h) - 34 * var(--u)) / 2); translate: -50% -50%; }
  .panel.has-side-tabs { right: auto; translate: calc(-50% - (var(--side-tab) + 14 * var(--u)) / 2) -50%; }
  .panel.bpass, .panel.cashshop, .panel.mapview { translate: none; }   /* self-centred via transform: no double shift */
}
.panel .body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--pad); display: flex; flex-direction: column; gap: calc(12 * var(--u)); }
.panel .body { margin: 0 calc(6 * var(--u)) calc(4 * var(--u)); border: var(--slot-edge) solid transparent;   /* steel 9-slice rim, no fill: content scrolls inside a fixed frame (user 2026-10-03, every panel) */
  border-image: url(/assets/ui3/slot.png) var(--slot-slice) / var(--slot-edge) / 0 stretch; }
.panel h3 { font-size: calc(16 * var(--u)); font-weight: 600; display: flex; align-items: center; gap: calc(6 * var(--u)); }
.panel h3 .ic { width: calc(24 * var(--u)); height: calc(24 * var(--u)); }
.panel h4 { font-size: calc(14 * var(--u)); font-weight: 600; color: var(--ink-dim); margin-bottom: calc(4 * var(--u)); }
.panel p { margin: 0; }
.note { display: block; font-size: calc(13 * var(--u)); color: var(--ink-dim); margin: 0; }
.actions { display: flex; gap: calc(8 * var(--u)); flex-wrap: wrap; }
.kv { display: grid; grid-template-columns: 1fr auto; gap: calc(6 * var(--u)) calc(12 * var(--u)); margin: 0; font-variant-numeric: tabular-nums; }
.kv dt { color: var(--ink-dim); margin: 0; }
.kv dd { margin: 0; font-weight: 600; text-align: right; }

/* soft inner box (stats block, quest detail, empty states, labelled rows) */
.ui-parchment, .panel .empty, .ui-strip {
  padding: calc(10 * var(--u)) calc(12 * var(--u)); background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--brown); border-radius: var(--radius-sm);
}
.ui-parchment h3 { margin-bottom: calc(6 * var(--u)); }
.panel .empty { text-align: center; color: var(--ink-dim); }
/* K-124 empty-state art: the thing that is missing as a flat black silhouette (any icon: png / svg / item art), no extra art files */
.empty .sil { display: block; width: calc(64 * var(--u)); height: calc(64 * var(--u)); margin: calc(4 * var(--u)) auto calc(6 * var(--u)); filter: brightness(0); opacity: .28; pointer-events: none; }
.empty span.sil > * { width: 100%; height: 100%; }
.empty .sil .ic, .empty span.sil img { width: 100%; height: 100%; object-fit: contain; }
.empty > b { display: block; }
.panel .empty b { display: block; color: var(--ink); font-weight: 600; }
.ui-strip { display: flex; justify-content: space-between; align-items: center; padding: calc(6 * var(--u)) calc(12 * var(--u)); }
.ui-strip b { font-weight: 600; }
.ui-parchment.footer { display: flex; align-items: center; gap: calc(8 * var(--u)); flex-wrap: wrap; background: var(--cream-dk); }
.ui-parchment.footer .cap { font-weight: 600; }
.ui-parchment.footer .slot { aspect-ratio: auto; width: auto; min-height: calc(34 * var(--u)); flex-direction: row; gap: calc(4 * var(--u)); padding: calc(2 * var(--u)) calc(10 * var(--u)); font-size: calc(13 * var(--u)); }
.ui-parchment.footer .slot .ic { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }

/* chips */
.chip {
  display: inline-flex; align-items: center; gap: calc(4 * var(--u)); padding: calc(2 * var(--u)) calc(10 * var(--u)); font-size: calc(13 * var(--u)); font-weight: 500; line-height: calc(22 * var(--u));
  background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); border-radius: calc(999 * var(--u)); font-variant-numeric: tabular-nums;
}
button.chip { cursor: inherit; }
.chip .ic { width: calc(20 * var(--u)); height: calc(20 * var(--u)); }
.chip.brass { background: var(--gold); }
.chip.mint { background: var(--sage); }
.chip.rose, .chip.warn { background: var(--coral); }
.chip.sky { background: var(--blue); }

/* ---- slots ---- */
.gear { display: grid; grid-template-columns: repeat(3, 1fr); gap: calc(8 * var(--u)); }
.bag { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--slot), 1fr)); gap: calc(6 * var(--u)); }
.slot {
  position: relative; aspect-ratio: 1; min-height: var(--slot); padding: calc(4 * var(--u)); cursor: inherit;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(2 * var(--u)); font-size: calc(11 * var(--u)); color: var(--ink-dim);
  background: var(--cream-dk); border: calc(2 * var(--u)) solid var(--brown); border-radius: var(--radius-sm); box-shadow: var(--well);
}
.slot .ic { width: 72%; height: 72%; }
.slot.filled { background: var(--cream-lt); border: var(--line-w) solid var(--line); box-shadow: 0 calc(3 * var(--u)) 0 var(--line); color: var(--ink); }

.slot.sel { background: none; }   /* K-357 selected look = gold frame, end of file */
.slot .qty { position: absolute; right: calc(4 * var(--u)); bottom: calc(1 * var(--u)); font-size: calc(12 * var(--u)); font-weight: 600; color: var(--line); text-shadow: 0 0 calc(3 * var(--u)) var(--cream-lt), 0 0 calc(3 * var(--u)) var(--cream-lt); }
.slot .enh { position: absolute; right: calc(4 * var(--u)); top: calc(2 * var(--u)); font-size: calc(12 * var(--u)); font-weight: 700; color: #ffd97a; text-shadow: 0 0 calc(3 * var(--u)) #000, 0 0 calc(3 * var(--u)) #000; pointer-events: none; }   /* K-121 +N enhance */
.slot .worn { position: absolute; left: calc(4 * var(--u)); bottom: calc(2 * var(--u)); font-size: calc(10 * var(--u)); color: var(--cream-lt); text-shadow: 0 0 calc(3 * var(--u)) #000, 0 0 calc(3 * var(--u)) #000; pointer-events: none; }
.slot.dim .ic { opacity: .35; filter: grayscale(.8); }
.slot .lk { position: absolute; left: calc(2 * var(--u)); top: calc(2 * var(--u)); }
.slot .lk .ic { width: calc(16 * var(--u)); height: calc(16 * var(--u)); }
.gear-vacant .gear-placeholder { opacity: .35; filter: grayscale(.5); }
.gear-label { font-size: calc(11 * var(--u)); line-height: 1; font-weight: 500; }
.slot .gear-label { position: absolute; bottom: calc(-9 * var(--u)); left: 50%; transform: translateX(-50%); white-space: nowrap; padding: calc(1 * var(--u)) calc(6 * var(--u));
  background: var(--cream); border: calc(2 * var(--u)) solid var(--brown); border-radius: calc(999 * var(--u)); font-size: calc(10 * var(--u)); }
.slot .ic + .gear-label { margin: 0; }

/* character layout: gear | portrait | gear, tool row below; stacks in a narrow panel */
.ui-charlay { display: grid; grid-template-columns: 1fr auto 1fr; gap: calc(12 * var(--u)); align-items: center; }
.ui-charlay .gear { grid-template-columns: 1fr; justify-items: center; gap: calc(16 * var(--u)); }
.ui-charlay .gear .slot, .tool-row .slot { width: calc(64 * var(--u)); }
.tool-row { display: flex; justify-content: center; gap: calc(12 * var(--u)); padding-bottom: calc(8 * var(--u)); }
.ui-portrait {
  width: calc(180 * var(--u)); height: calc(230 * var(--u)); display: grid; place-items: end center; overflow: hidden;
  background: radial-gradient(circle at 50% 75%, var(--cream-lt) 0 55%, var(--cream-dk) 56%);
  border: var(--line-w) solid var(--line); border-radius: 50% 50% var(--radius) var(--radius); box-shadow: var(--well);
}
.ui-portrait.bare { background: none; border: 0; box-shadow: none; }   /* character panel: rig only, no frame (user 2026-10-03) */
.ui-portrait img { width: calc(180 * var(--u)); height: calc(236 * var(--u)); object-fit: contain; margin-bottom: calc(-12 * var(--u)); }
.character-power .kv { grid-template-columns: 1fr auto; }
.ui-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: calc(10 * var(--u)); align-items: start; }
@container (max-width: 520px) { .ui-split { grid-template-columns: minmax(0, 1fr); } }
@container (max-width: 430px) {
  .ui-charlay { grid-template-columns: minmax(0, 1fr); justify-items: center; }
  .ui-charlay .gear { grid-template-columns: repeat(3, calc(64 * var(--u))); }
}

/* ---- bag ---- */
.bag-capacity { font-size: calc(13 * var(--u)); color: var(--ink-dim); }
.bag-scroll { padding: calc(2 * var(--u)) calc(2 * var(--u)) calc(6 * var(--u)); }
.bag-wallet { display: flex; align-items: center; gap: calc(14 * var(--u)); flex-wrap: wrap; padding: calc(6 * var(--u)) calc(12 * var(--u)); font-weight: 500;
  background: var(--cream-dk); border-radius: var(--radius-sm); }
.bag-wallet span { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); }
.bag-wallet .ic { width: calc(24 * var(--u)); height: calc(24 * var(--u)); }

/* ---- item details modal ---- */
.item-modal-backdrop { position: fixed; inset: 0; z-index: 20; display: grid; place-items: center; padding: calc(16 * var(--u)); background: var(--scrim); }
.item-modal { width: min(calc(360 * var(--u)), 100%); max-height: calc(100vh - calc(32 * var(--u))); overflow-y: auto; padding: calc(18 * var(--u)); text-align: center;
  display: flex; flex-direction: column; gap: calc(8 * var(--u)); animation: pop var(--anim-ms) var(--ease); }
.item-modal-close { position: absolute; top: calc(8 * var(--u)); right: calc(8 * var(--u)); width: calc(38 * var(--u)); height: calc(38 * var(--u)); padding: 0; border-radius: 50%; cursor: inherit;
  display: grid; place-items: center; background: var(--coral); border: var(--line-w) solid var(--line); box-shadow: 0 calc(3 * var(--u)) 0 var(--line); }
.item-modal-close svg.ic.glyph { width: calc(16 * var(--u)); height: calc(16 * var(--u)); stroke-width: 4; }
.item-modal-icon { align-self: center; width: calc(96 * var(--u)); height: calc(96 * var(--u)); display: grid; place-items: center;
  background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius); box-shadow: 0 calc(4 * var(--u)) 0 var(--line); }
.item-modal-icon .ic { width: calc(76 * var(--u)); height: calc(76 * var(--u)); }
.item-modal .im-sell { position: absolute; z-index: 2; left: calc(6 * var(--u)); top: calc(5 * var(--u)); margin: 0; max-width: 30%; text-align: left; white-space: nowrap; font-size: calc(12 * var(--u)); line-height: 1.3; }   /* user 2026-10-12: sell price top-left */
.item-modal .im-sell small { display: block; opacity: .8; }   /* stack total: ×N = total under the per-piece price */
.item-modal .im-desc { margin: 0 0 calc(6 * var(--u)); font-style: italic; color: var(--ink-dim); }   /* 409 desc_th */
.htip .item-tip { max-width: calc(380 * var(--u)); min-width: calc(260 * var(--u)); }   /* user 2026-10-14 wider tooltips (was max 260u) */
.htip .ht-src { opacity: .8; font-size: .92em; }
.item-modal .im-src { margin: 0 0 calc(6 * var(--u)); padding: 0; list-style: none; font-size: calc(12 * var(--u)); color: var(--ink-dim); }   /* K-511 D2 */
.item-modal h3 { font-size: calc(19 * var(--u)); font-weight: 600; justify-content: center; display: flex; }
.item-modal p { margin: 0; font-size: calc(14 * var(--u)); color: var(--ink-dim); }
.item-modal .actions { justify-content: center; margin-top: calc(4 * var(--u)); }
.mastery-req { padding: calc(4 * var(--u)) calc(10 * var(--u)); border-radius: calc(999 * var(--u)); font-weight: 600; color: var(--sage-dk) !important; background: rgba(157, 184, 138, .25); }
.mastery-req.locked { color: var(--locked) !important; background: rgba(227, 155, 134, .28); }

/* qty keypad */
.qtypad { display: flex; gap: calc(8 * var(--u)); }
.qtypad-keys { flex: 1; display: grid; grid-template-columns: repeat(3, 1fr); gap: calc(6 * var(--u)); }
.qtypad-side { display: grid; grid-template-rows: repeat(4, 1fr); gap: calc(6 * var(--u)); width: calc(80 * var(--u)); }
.qtypad .btn.key { --face: var(--cream-lt); min-height: calc(38 * var(--u)); padding: calc(2 * var(--u)); border-width: calc(2 * var(--u)); box-shadow: 0 calc(2 * var(--u)) 0 var(--line); }
.qtypad .btn.key.wide { grid-column: span 2; }
.qtypad .btn.key.max { --face: var(--gold); }
.qtypad .btn.key.clear { --face: var(--coral); font-size: calc(12 * var(--u)); }

/* ---- mastery ---- */

/* ---- odds / progress / fishing ring ---- */
.odds { display: grid; gap: calc(6 * var(--u)); }
.odds .o { display: grid; grid-template-columns: calc(70 * var(--u)) 1fr calc(48 * var(--u)); align-items: center; gap: calc(8 * var(--u)); font-size: calc(13 * var(--u)); font-variant-numeric: tabular-nums; }
.odds .o .t { height: calc(14 * var(--u)); }
.odds .success i { background: var(--sage); }
.odds .unchanged i { background: var(--cream-lt); }
.odds .downgrade i { background: var(--gold); }
.odds .destroy i { background: var(--coral); }
.odds .o b { text-align: right; font-weight: 600; }
.prog .o { grid-template-columns: 1fr calc(90 * var(--u)) calc(52 * var(--u)); }
.prog .o.done i { background: var(--gold); }
.prog .o.later { opacity: .45; filter: grayscale(1); }   /* user 2026-10-15: steps not reached yet = grey */
.ring { --progress: 0; position: relative; display: inline-block; flex: none; width: calc(64 * var(--u)); height: calc(64 * var(--u)); border-radius: 50%;
  background: conic-gradient(var(--blue) calc(var(--progress) * 360deg), var(--cream-dk) 0); border: var(--line-w) solid var(--line); }
.ring::after { content: ""; position: absolute; inset: calc(9 * var(--u)); border-radius: 50%; background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); }
.ring.bite { background: conic-gradient(var(--coral) calc(var(--progress) * 360deg), var(--cream-dk) 0); }
.ring-fill { display: none; }

/* ---- lists / market cards ---- */
.list { display: flex; flex-direction: column; gap: calc(6 * var(--u)); }
.list .btn { --face: var(--cream-lt); justify-content: flex-start; text-align: left; font-weight: 400; min-height: var(--btn-h); padding: calc(6 * var(--u)) calc(12 * var(--u)); border-width: calc(2 * var(--u)); box-shadow: 0 calc(2 * var(--u)) 0 var(--line); }
.list .btn.active { --face: var(--blue); }
.list .btn .sub { margin-left: auto; font-size: calc(12 * var(--u)); color: var(--ink-dim); }
.mk { display: grid; gap: calc(8 * var(--u)); }
.mk .card { display: flex; flex-wrap: wrap; align-items: center; gap: calc(6 * var(--u)) calc(10 * var(--u)); padding: calc(10 * var(--u)) calc(12 * var(--u));
  background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); border-radius: var(--radius-sm); box-shadow: 0 calc(3 * var(--u)) 0 var(--line); }
.mk .card .nm { flex: 1 1 calc(140 * var(--u)); font-weight: 600; }
.mk .card .meta, .mk .card .sub { flex: 1 1 100%; font-size: calc(12 * var(--u)); color: var(--ink-dim); }
.mk .card .price { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); font-weight: 600; }
.mk .card .price .ic { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
/* K-222 pool potion points-left bar in a bag/bank slot (Panels.jsx PoolBar, --p = left/max) */
.slot .pool { position: absolute; left: calc(6 * var(--u)); right: calc(6 * var(--u)); bottom: calc(4 * var(--u)); height: calc(5 * var(--u)); border-radius: calc(3 * var(--u));
  background: var(--cream-dk); box-shadow: 0 0 0 calc(1 * var(--u)) var(--line); overflow: hidden; pointer-events: none; }
.slot .pool::after { content: ''; position: absolute; inset: 0 auto 0 0; width: calc(var(--p) * 100%); background: var(--coral-dk); }
.slot .pool.mp::after { background: var(--blue-dk); }

/* confirm popup inside a panel / invite toast */
.popup { width: min(calc(340 * var(--u)), 100%); margin: 0 auto; padding: 0; display: flex; flex-direction: column; overflow: hidden; box-shadow: var(--lift); }
.popup > .ui-title { border-radius: 0; background: var(--coral); }
.popup > .ui-parchment { margin: calc(10 * var(--u)); }
.confirm-modal { max-height: calc(100vh - calc(32 * var(--u))); overflow-y: auto; animation: pop var(--anim-ms) var(--ease); }   /* K-123 ConfirmModal */
.popup > .actions { padding: 0 calc(10 * var(--u)) calc(10 * var(--u)); justify-content: center; }
.toast.popup { width: auto; overflow: visible; }

/* scrollbars */
/* K-355: Firefox only (Chromium ignores ::-webkit-scrollbar when these standard props are set) */
@supports not selector(::-webkit-scrollbar) { .panel .body, .maps, .chatlog, .dock, .item-modal, .ui-scroll { scrollbar-width: thin; scrollbar-color: #c9a227 transparent; } }

/* ============ MOBILE (<= 620px, checked at 390) ============ */
@media (max-width: 620px) {
  :root { --menu-btn: calc(44 * var(--u)); --slot: calc(50 * var(--u)); }
  :root { --mm: calc(112 * var(--u)); }
  .minimap .zonetag { height: calc(24 * var(--u)); font-size: calc(11 * var(--u)); padding: 0 calc(7 * var(--u)); }
  .vitals { top: max(calc(8 * var(--u)), env(safe-area-inset-top)); padding: calc(6 * var(--u)) calc(8 * var(--u)) calc(8 * var(--u)) calc(6 * var(--u)); gap: calc(8 * var(--u)); }
  .vitals .avatar, .vitals .avatar .ic { width: calc(44 * var(--u)); height: calc(44 * var(--u)); }
  .vitals .bars { width: calc(150 * var(--u)); gap: calc(3 * var(--u)); }
  .vitals .bar { height: calc(15 * var(--u)); }
  .vitals .bar.sta { height: calc(8 * var(--u)); }
  .vitals .bar b { font-size: calc(10 * var(--u)); }
  .mapname { height: calc(34 * var(--u)); font-size: calc(15 * var(--u)); }
  .dock { top: calc(var(--mm) + calc(34 * var(--u)) + env(safe-area-inset-top)); transform: none; gap: calc(4 * var(--u)); padding: calc(5 * var(--u)); max-height: calc(100% - var(--mm) - calc(250 * var(--u))); }
  .mbtn .ic { width: calc(32 * var(--u)); height: calc(32 * var(--u)); }
  /* hotbar bottom-right: 2x2 skills + attack; d-pad bottom-left */
  .hotbar { left: auto; right: max(calc(10 * var(--u)), env(safe-area-inset-right)); transform: none; display: grid;
    grid-template-columns: calc(52 * var(--u)) calc(52 * var(--u)) calc(72 * var(--u)); grid-template-rows: calc(48 * var(--u)) calc(48 * var(--u)); gap: calc(6 * var(--u)); padding: calc(6 * var(--u)); }
  .hk { width: calc(52 * var(--u)); height: calc(48 * var(--u)); padding: calc(9 * var(--u)) calc(2 * var(--u)) calc(1 * var(--u)); }
  .hk b { font-size: calc(9 * var(--u)); }
  .hk small { font-size: calc(9 * var(--u)); }
  .attack { grid-column: 3; grid-row: 1 / span 2; width: calc(68 * var(--u)); height: calc(68 * var(--u)); margin: 0; align-self: center; }
  .chat-toggle { left: auto; right: max(calc(10 * var(--u)), env(safe-area-inset-right)); bottom: calc(calc(140 * var(--u)) + env(safe-area-inset-bottom)); }
  .chat-popup { bottom: calc(calc(190 * var(--u)) + env(safe-area-inset-bottom)); left: calc(10 * var(--u)); }
  .gather-hint { bottom: calc(calc(190 * var(--u)) + env(safe-area-inset-bottom)); }
  /* panel = full sheet above everything (no hotbar overlap by construction) */
  .panel { z-index: 8; left: calc(8 * var(--u)); right: calc(8 * var(--u)); width: auto; top: calc(calc(8 * var(--u)) + env(safe-area-inset-top));
    max-height: none; bottom: calc(calc(8 * var(--u)) + env(safe-area-inset-bottom)); }
  .ui-close { top: calc(4 * var(--u)); right: calc(4 * var(--u)); }
  .sheet { padding: calc(16 * var(--u)); }
  .title-screen .logo { margin-top: 1vh; }
}

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

/* ---- craft panel (031, WorldPanels.jsx CraftPanel) ---- */
.craft-job { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: calc(10 * var(--u)); margin-bottom: calc(10 * var(--u)); padding: calc(8 * var(--u)) calc(12 * var(--u));
  background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); border-radius: var(--radius-sm); font-variant-numeric: tabular-nums; }
.craft-job .t { height: calc(14 * var(--u)); }
.craft-job .t i { background: var(--sage); }
.craft-list .card .price .ic { width: calc(40 * var(--u)); height: calc(40 * var(--u)); object-fit: contain; }
.craft-list .card.locked { background: var(--cream-dk); }
.boat-list .card.locked { opacity: .55; }   /* K-012 unlit town (ยังไม่ได้จุดเตา) */
.craft-list .card .meta.err { color: var(--locked); font-weight: 600; margin: 0; }
.craft-list .ins { display: flex; flex-wrap: wrap; gap: calc(4 * var(--u)) calc(12 * var(--u)); }
.craft-list .ins .in { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); font-variant-numeric: tabular-nums; }
.craft-list .ins .in .ic { width: calc(22 * var(--u)); height: calc(22 * var(--u)); object-fit: contain; }
.craft-list .field input { width: calc(64 * var(--u)); }

/* ============ UI v3 skin (2026-09-29): parchment scroll + steel slots. Art /assets/ui3 (from design/ui-v3/cut.py).
   9-slice = border-image, Unity-Sliced rule: corner/edge size = fixed token * --u (screen scale only), never the box size;
   only the centre stretches. border-width < border-image-width -> art bleeds over padding, content keeps room.
   Slice numbers = px in the ui3 asset (cut.py NINE halved for panel/inset, *128/278 for slots). ============ */
.panel, .sheet, .popup, .item-modal {
  background: none; border-radius: 0; box-shadow: none;
  border-style: solid; border-color: transparent;
  border-width: var(--pnl-t) var(--pnl-r) var(--pnl-b) var(--pnl-l);
  border-image: url(/assets/ui3/panel.webp) var(--pnl-slice) fill / var(--pnl-t) var(--pnl-r) var(--pnl-b) var(--pnl-l) / 0 stretch round;
  filter: drop-shadow(0 calc(6 * var(--u)) calc(6 * var(--u)) rgba(40, 26, 14, .35));
}
.popup { overflow: visible; }
.ui-title, .popup > .ui-title {
  background: url(/assets/ui3/divider.png) center bottom / calc(220 * var(--u)) calc(42 * var(--u)) no-repeat;
  border: 0; border-radius: 0; box-shadow: none; padding-bottom: calc(26 * var(--u));
}
.ui-close {
  top: calc(-14 * var(--u)); right: calc(-14 * var(--u)); width: calc(46 * var(--u)); height: calc(46 * var(--u));
  background: url(/assets/ui3/close.png) center / contain no-repeat; border: 0; box-shadow: none;
}
.ui-close svg, .item-modal-close svg { display: none; }
.item-modal-close { background: url(/assets/ui3/close.png) center / contain no-repeat; border: 0; box-shadow: none; }

/* slots: faded parchment when empty, dark steel when holding an item */
.slot {
  background: none; border-radius: 0; box-shadow: none; border: 0 solid transparent; padding: 0; overflow: hidden;
  border-image: url(/assets/ui3/slot_empty.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch;
}
.slot.filled {
  background: none; border: 0 solid transparent; box-shadow: none; color: var(--cream-lt);   /* background none: old .slot.filled cream fill showed behind the steel rim corners (user 2026-10-03) */
  border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch;
}
.slot.filled .qty { color: var(--cream-lt); text-shadow: 0 0 calc(3 * var(--u)) #000, 0 0 calc(3 * var(--u)) #000; }
.slot.sel { background: none; }

/* inner boxes: darker parchment inset */
.ui-parchment, .panel .empty, .ui-strip, .ui-parchment.footer {
  background: none; border-radius: 0; border: calc(4 * var(--u)) solid transparent;
  border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch;
}

/* vitals: steel portrait ring + tier badge disc */
.vitals .avatar::after { content: ""; position: absolute; inset: calc(-8 * var(--u)); background: url(/assets/ui3/portrait_ring.png) center / contain no-repeat; pointer-events: none; }
.vitals .avatar b {
  z-index: 1; min-width: calc(30 * var(--u)); height: calc(30 * var(--u)); padding: 0; display: grid; place-items: center; line-height: 1;
  color: var(--gold); background: url(/assets/ui3/tier_badge.png) center / contain no-repeat; border: 0; bottom: calc(-14 * var(--u));
}
/* item art fills the slot box (may cover the frame, never leaves the slot: overflow hidden) */
.slot .ic { width: 100%; height: 100%; }
.slot img.ic[src*="/weapon/"]:not([src*="shield"]) { transform: rotate(-45deg) scale(1.15); }

/* bag = Albion inventory: gear block (areas a..k from Panels.jsx BAG_GEAR) + wallet/load row + capacity label + grid */
.bag-gear {
  position: relative; display: grid; justify-content: center; gap: calc(8 * var(--u)) calc(14 * var(--u));
  grid-template-columns: repeat(3, var(--gear-slot)); grid-template-areas: "a b c" "d e f" "g h k";   /* a = K-250 cape; k = K-119 mount slot, K-255 beside legs h (3x3, no 4th row) */
  padding: calc(4 * var(--u)) 0;
}
.bag-gear::before { content: ""; position: absolute; left: 50%; top: 50%; width: calc(2.9 * var(--gear-slot)); aspect-ratio: 1; transform: translate(-50%, -50%);
  border: calc(2 * var(--u)) solid rgba(139, 107, 78, .28); border-radius: 50%; pointer-events: none; }
.bag-gear .slot { width: var(--gear-slot); min-height: 0; }
.bag-gear .gear-placeholder { width: 62%; height: 62%; }
/* K-119 skin tab: 4-col icon slots, eye toggle on the slot corner, picker strip under the grid */
.bag-skins { display: flex; flex-direction: column; gap: calc(10 * var(--u)); }
.skin-grid { display: grid; grid-template-columns: repeat(4, var(--gear-slot)); justify-content: center; gap: calc(12 * var(--u)) calc(16 * var(--u)); }
@media (max-width: 620px) { .skin-grid { grid-template-columns: repeat(3, var(--gear-slot)); } }   /* K-255: 4 cols overflowed the phone panel (hat/weapon cut) */
.skin-cell { position: relative; display: flex; flex-direction: column; align-items: center; gap: calc(3 * var(--u)); }
.skin-cell .slot { width: var(--gear-slot); min-height: 0; aspect-ratio: 1; }
.skin-cell .slot.dim .ic { opacity: .35; filter: grayscale(.7); }
.skin-cell .gear-placeholder { width: 58%; height: 58%; opacity: .45; }
.skin-cell .lbl { font-size: calc(12 * var(--u)); color: var(--ink-dim); }
.skin-cell .eye { position: absolute; top: calc(-7 * var(--u)); right: calc(-9 * var(--u)); width: calc(24 * var(--u)); height: calc(24 * var(--u)); padding: calc(3 * var(--u));
  display: grid; place-items: center; border-radius: 50%; cursor: inherit; color: var(--cream-lt);
  background: radial-gradient(circle at 35% 30%, #6c7380, #343a44 70%); border: calc(2 * var(--u)) solid #1d2128; box-shadow: 0 calc(2 * var(--u)) 0 rgba(0,0,0,.35); }
.skin-cell .eye .ic { width: 100%; height: 100%; stroke-width: 2.4; }
.skin-cell .eye.off { color: #c99; background: radial-gradient(circle at 35% 30%, #5a4a4a, #2b2224 70%); }
.skin-cell .eye:hover { filter: brightness(1.15); }
.skin-pick { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: calc(8 * var(--u)); padding: calc(8 * var(--u)); }
.skin-pick .slot { width: calc(48 * var(--u)); min-height: 0; aspect-ratio: 1; }
/* K-121 item pickers (ItemList / ItemSlot) + enhance material sections */
.item-pick { display: flex; flex-direction: column; gap: calc(6 * var(--u)); }
.item-peek { display: flex; flex-wrap: wrap; align-items: center; gap: calc(6 * var(--u)); padding: calc(6 * var(--u)) calc(10 * var(--u)); font-size: calc(13 * var(--u)); }
.item-peek .sub { margin-left: auto; color: var(--ink-dim); }
.enh-mats { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: calc(10 * var(--u)) calc(22 * var(--u)); padding: calc(4 * var(--u)) 0; }
.enh-mats .mat { display: flex; flex-direction: column; align-items: flex-start; gap: calc(4 * var(--u)); }
.enh-mats h4 { margin: 0; font-size: calc(13 * var(--u)); color: var(--ink-dim); }
.enh-mats small { font-size: calc(12 * var(--u)); color: var(--ink-dim); }
.enh-mats .slot { width: var(--gear-slot); min-height: 0; aspect-ratio: 1; }
.mat-row { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: calc(8 * var(--u)); }
.mat-row .slot { width: var(--gear-slot); min-height: 0; aspect-ratio: 1; }
/* K-032 tool group: 6 per-line slots, 3x2 = same width as .bag-gear */
.bag-tools { display: flex; flex-direction: column; align-items: center; gap: calc(6 * var(--u)); padding-bottom: calc(4 * var(--u)); }
.bag-tools h4 { margin: 0; font-size: calc(13 * var(--u)); color: var(--ink-dim); }
.bag-tools .grid { display: grid; grid-template-columns: repeat(3, var(--gear-slot)); gap: calc(8 * var(--u)) calc(14 * var(--u)); }
.bag-tools .slot { width: var(--gear-slot); min-height: 0; }
.bag-tools .gear-placeholder { width: 62%; height: 62%; }
.bag-wallet { justify-content: space-between; background: none; padding: 0 calc(4 * var(--u)); }
.bag-wallet .coins { display: flex; flex-direction: column; gap: calc(4 * var(--u)); font-weight: 600; font-variant-numeric: tabular-nums; }
.bag-wallet .load { display: inline-flex; align-items: center; gap: calc(6 * var(--u)); font-weight: 600; color: var(--ink-dim); }
.bag-wallet .weight { display: inline-block; width: calc(26 * var(--u)); height: calc(28 * var(--u)); background: url(/assets/ui3/weight.png) center / contain no-repeat; }
.bag-capacity { display: flex; align-items: center; gap: calc(8 * var(--u)); align-self: flex-start; text-align: left; width: 100%; padding-top: calc(8 * var(--u)); border-top: calc(2 * var(--u)) solid rgba(139, 107, 78, .35); }
.bag-capacity b { color: var(--ink); }
/* short screens (phone landscape, <=520px tall): thinner rolls + panel spans full height, over the hotbar */
@media (max-height: 520px) {
  :root { --pnl-t: calc(42 * var(--u)); --pnl-b: calc(40 * var(--u)); --pnl-l: calc(30 * var(--u)); --pnl-r: calc(28 * var(--u)); }
  .panel { z-index: 8; top: calc(4px + env(safe-area-inset-top)); bottom: calc(4px + env(safe-area-inset-bottom)); max-height: none; }
  .ui-title { min-height: 0; padding-top: 0; padding-bottom: calc(18 * var(--u)); background-size: calc(160 * var(--u)) calc(30 * var(--u)); }
}
/* v3 fixes (ui-editor audit 2026-09-29): gear labels readable + not clipped in the character panel; dock never cuts a button */
.slot .gear-label, .slot.filled .gear-label { color: var(--ink); }
.ui-charlay .slot, .tool-row .slot { overflow: visible; }
.dock { max-height: calc(100% - 120 * var(--u)); }
/* bag wallet + = open market (Panels.jsx BagPanel onMarket) */
.bag-wallet .coins span { display: inline-flex; align-items: center; gap: calc(6 * var(--u)); }
.bag-wallet .plus { width: calc(26 * var(--u)); height: calc(26 * var(--u)); padding: 0; border: 0; cursor: inherit; background: url(/assets/ui3/plus.png) center / contain no-repeat; }
.bag-wallet .plus:active { transform: translateY(calc(2 * var(--u))); }
/* toasts never cover an open panel: centred in the free area left of it; phone (panel = full sheet) -> above it, at the bottom */
/* user 2026-10-16: panels centred -> toasts stay top-centre over the panel on desktop (was left of the panel) */
@media (max-width: 620px), (max-height: 520px) {
  .toasts.beside { z-index: 9; left: 50%; width: min(calc(360 * var(--u)), calc(100vw - 32px)); top: auto; bottom: calc(16px + env(safe-area-inset-bottom)); }
}

/* ============ UI v3 HUD (2026-09-30): vitals/dock/hotbar cards = riveted parchment inset; menu buttons = parchment slot,
   active = steel slot; hotbar skills = steel slot (cream text), empty = parchment slot. Same 9-slice rule as panels. ============ */
.vitals, .dock, .hotbar, .mapname, .bossbar {
  background: none; border-radius: 0; box-shadow: none; border: 0 solid transparent;
  border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch;
  filter: drop-shadow(0 calc(3 * var(--u)) calc(3 * var(--u)) rgba(40, 26, 14, .35));
}
.vitals { padding: calc(12 * var(--u)) calc(16 * var(--u)) calc(12 * var(--u)) calc(12 * var(--u)); }
.dock, .hotbar { padding: calc(12 * var(--u)); }
.mapname { padding: 0 calc(18 * var(--u)) 0 calc(14 * var(--u)); }
.mbtn, .hk {
  background: none; border-radius: 0; box-shadow: none; border: 0 solid transparent;
  border-image: url(/assets/ui3/slot_empty.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch;
}
.mbtn.active, .hk:not(.empty) { border: 0 solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.hk:not(.empty) { color: var(--cream-lt); }
.hk:not(.empty) small { color: var(--blue); }
.hk:not(.empty) kbd { color: var(--gold); }
.hk.empty { border-style: solid; }
.hk:active, .mbtn:active { transform: translateY(calc(2 * var(--u))); }
.mbtn kbd { z-index: 1; }
/* short screens: open panel spans full height -> hide the hotbar behind it instead of letting it stick out */
@media (max-height: 520px) { .game:has(.panel) .hotbar, .game:has(.panel) .joy { visibility: hidden; } }
.bag-wallet .load.over { color: var(--locked); }
/* 043 overload badge next to the name in .vitals (session info.slow < 1) */
.vitals .overload { display: inline-flex; align-items: center; gap: calc(3 * var(--u)); margin-left: calc(8 * var(--u)); font-size: calc(12 * var(--u)); color: var(--locked); font-weight: 600; }
.vitals .overload .weight { display: inline-block; width: calc(16 * var(--u)); height: calc(17 * var(--u)); background: url(/assets/ui3/weight.png) center / contain no-repeat; }
.ui-charlay.solo { grid-template-columns: 1fr; justify-items: center; }
/* K-019 lottery panel (WorldPanels.jsx LotteryPanel): pot + countdown strip, digit spinners, ticket chips, history table */
.lot-head { display: grid; grid-template-columns: 1fr 1fr; gap: calc(8 * var(--u)); }
.lot-head small { display: block; font-size: calc(12 * var(--u)); color: var(--ink-dim); }
.lot-head b { display: inline-flex; align-items: center; gap: calc(6 * var(--u)); font-size: calc(20 * var(--u)); font-weight: 700; font-variant-numeric: tabular-nums; }
.lot-head .ic { width: calc(26 * var(--u)); height: calc(26 * var(--u)); }
.lot-pick { display: grid; justify-items: center; gap: calc(10 * var(--u)); }
.lot-digits { display: flex; gap: calc(10 * var(--u)); }
.lot-digits .dg { display: grid; justify-items: center; gap: calc(4 * var(--u)); }
.lot-digits .dg b { width: calc(56 * var(--u)); height: calc(64 * var(--u)); display: grid; place-items: center; font-size: calc(40 * var(--u)); font-weight: 700; color: var(--cream-lt);
  border: 0 solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.lot-digits .btn.sm { min-height: calc(30 * var(--u)); padding: 0 calc(14 * var(--u)); }
.lot-actions { display: flex; gap: calc(8 * var(--u)); flex-wrap: wrap; justify-content: center; }
.lot-actions .btn .ic { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
.lot-pick .note { text-align: center; }
.lot-src { margin: 0; padding-left: calc(18 * var(--u)); display: grid; gap: calc(2 * var(--u)); }   /* K-479 ticket sources */
.lot-chips { display: flex; flex-wrap: wrap; gap: calc(6 * var(--u)); }
.lot-chips span { min-width: calc(40 * var(--u)); padding: calc(4 * var(--u)) calc(8 * var(--u)); text-align: center; font-weight: 700; color: var(--cream-lt); font-variant-numeric: tabular-nums;
  border: 0 solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.lot-hist { width: 100%; border-collapse: collapse; font-size: calc(13 * var(--u)); font-variant-numeric: tabular-nums; }
.lot-hist th { text-align: left; color: var(--ink-dim); font-weight: 600; padding: calc(2 * var(--u)) calc(4 * var(--u)); border-bottom: calc(2 * var(--u)) solid rgba(139, 107, 78, .35); }
.lot-hist td { padding: calc(3 * var(--u)) calc(4 * var(--u)); border-bottom: calc(1 * var(--u)) solid rgba(139, 107, 78, .18); }
.lot-hist tr.won td { color: var(--ink); background: rgba(232, 184, 76, .28); font-weight: 600; }
/* K-017 world boss timetable (reuses .lot-hist) + system chat line */
.wb-table tr.live td { color: var(--ink); background: rgba(194, 91, 216, .18); font-weight: 600; }
.wb-table td.tnum { white-space: nowrap; }
.chat-sys { color: #e8b84c; font-weight: 700; }
/* K-045 dock: 6 main + ⋯ (Panels.jsx Dock); 7 buttons fit -> no scroll, overflow visible so the ⋯ popover is not clipped.
   ⋯ popover .dock-more = parchment inset, left of the dock, bottom-aligned (grows up). Short screens (<=520 tall) = 2-col grid. */
.dock { overflow: visible; max-height: none; }
.dock:has(.dock-more) { z-index: 9; }
.mbtn.more { color: var(--ink); }
.mbtn.more.active { color: var(--cream-lt); }
.dock-more {
  position: absolute; right: calc(100% + 8 * var(--u)); bottom: 0; z-index: 1; min-width: calc(210 * var(--u)); padding: calc(12 * var(--u));
  display: flex; flex-direction: column; gap: calc(2 * var(--u));
  border: 0 solid transparent; border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch;
  filter: drop-shadow(0 calc(3 * var(--u)) calc(3 * var(--u)) rgba(40, 26, 14, .35));
}
.dm-row {
  display: flex; align-items: center; gap: calc(10 * var(--u)); min-height: calc(44 * var(--u)); padding: 0 calc(8 * var(--u)); cursor: inherit;
  background: none; border: 0; border-radius: calc(6 * var(--u)); color: var(--ink); font: inherit; font-size: calc(15 * var(--u)); font-weight: 600; text-align: left; white-space: nowrap;
}
.dm-row .ic { width: calc(30 * var(--u)); height: calc(30 * var(--u)); flex: none; }
.dm-row span { flex: 1; }
.dm-row kbd { min-width: calc(18 * var(--u)); padding: 0 calc(4 * var(--u)); font-size: calc(10 * var(--u)); line-height: calc(16 * var(--u)); font-weight: 600; text-align: center;
  background: var(--cream); border: calc(2 * var(--u)) solid var(--line); border-radius: calc(6 * var(--u)); }
.dm-row:hover, .dm-row:focus-visible { background: rgba(139, 107, 78, .18); outline: none; }
.dm-row.active { background: rgba(232, 184, 76, .32); }
@media (max-height: 520px) { .dock { display: grid; grid-template-columns: repeat(2, var(--menu-btn)); } }

/* K-047 dialogue box (WorldPanels.jsx DialogueBox): parchment 9-slice (same panel.webp tokens as .panel), bottom-centre above the
   hotbar, over panels (z 12). Portrait = ui3 portrait_ring over npc_defs.portrait or an initial placeholder. */
.dialogue {
  position: absolute; z-index: 12; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--hotbar-h) + calc(24 * var(--u)) + env(safe-area-inset-bottom));
  width: min(calc(760 * var(--u)), calc(100vw - 32px)); min-height: calc(170 * var(--u));
  display: flex; gap: calc(14 * var(--u)); align-items: flex-start; cursor: inherit; animation: pop var(--anim-ms) var(--ease);
  border-style: solid; border-color: transparent; border-width: var(--pnl-t) var(--pnl-r) var(--pnl-b) var(--pnl-l);
  border-image: url(/assets/ui3/panel.webp) var(--pnl-slice) fill / var(--pnl-t) var(--pnl-r) var(--pnl-b) var(--pnl-l) / 0 stretch round;
  filter: drop-shadow(0 calc(6 * var(--u)) calc(6 * var(--u)) rgba(40, 26, 14, .35));
}
.dlg-portrait { flex: none; position: relative; width: calc(96 * var(--u)); aspect-ratio: 1; border-radius: 50%; overflow: visible; background: var(--cream-dk); }
.dlg-portrait img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.dlg-portrait .ph { display: grid; place-items: center; width: 100%; height: 100%; font-size: calc(40 * var(--u)); font-weight: 700; color: var(--brown); }
.dlg-portrait::after { content: ""; position: absolute; inset: calc(-10 * var(--u)); background: url(/assets/ui3/portrait_ring.png) center / contain no-repeat; pointer-events: none; }
.dlg-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: calc(8 * var(--u)); }
.dlg-main header { display: flex; align-items: center; justify-content: space-between; gap: calc(8 * var(--u)); }
.dlg-name { font-size: calc(18 * var(--u)); font-weight: 700; color: var(--brown); }
.dlg-who { display: flex; flex-direction: column; line-height: 1.2; }
.dlg-acts { display: flex; gap: calc(6 * var(--u)); }   /* K-070 ร้านค้า + ข้ามทั้งหมด */
.dlg-role { font-size: calc(13 * var(--u)); color: var(--brown); opacity: .75; }
.dlg-text { margin: 0; font-size: calc(17 * var(--u)); line-height: 1.6; min-height: calc(56 * var(--u)); white-space: pre-wrap; }
.dlg-text .caret { display: inline-block; width: calc(8 * var(--u)); height: 1em; margin-left: 2px; vertical-align: text-bottom; background: var(--brown); animation: blink .8s steps(1) infinite; }
.dlg-choices { display: flex; flex-wrap: wrap; gap: calc(8 * var(--u)); }
.dlg-more { align-self: flex-end; color: var(--brown); font-size: calc(14 * var(--u)); animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }
@media (max-width: 620px) { .dlg-portrait { width: calc(64 * var(--u)); } }
/* K-047 journal log (JournalPanel) */
.journal .jlog { display: flex; flex-direction: column; gap: calc(4 * var(--u)); padding: calc(6 * var(--u)) 0; border-top: calc(2 * var(--u)) solid rgba(139, 107, 78, .3); }
.journal .jlog p { font-size: calc(14 * var(--u)); }
.journal .jlog .btn { align-self: flex-start; }
/* K-014 card wheel (CardPanels.jsx CardWheelPanel) + skin panel. K-407: card_rarity junk/common/rare/great = theme.css --rar-1..4;
   card frames = ui2/cards/frame_<rarity>.png (192x288, 2:3, design/cards-k407-411) on .cw-card + .card-ic. */
.panel.cardwheel { --r-junk: var(--rar-1); --r-common: var(--rar-2); --r-rare: var(--rar-3); --r-great: var(--rar-4); }
.cw-top { display: grid; place-items: center; }   /* user 2026-10-12: wheel alone, centred, bigger */
.cw-wheel { width: 100%; }
.cw-wheel svg { width: 100%; max-width: calc(298 * var(--u));   /* 2026-10-16 steel rim art: viewBox 260 wide (was 208 @238u) -> same wedge size */   /* user 2026-10-16: -30% (was 340u) */ display: block; margin: 0 auto; }
.cw-actions { display: flex; align-items: center; gap: calc(8 * var(--u)); width: 100%; margin: calc(8 * var(--u)) 0; }   /* outside the frame, one row, full width */
.cw-actions .btn { flex: 1; }
.cw-actions .btn.big { flex: 2; }
.cw-count { flex: none; min-width: calc(64 * var(--u)); text-align: center; }
.cw-card.picked { outline: calc(3 * var(--u)) solid var(--gold); outline-offset: calc(2 * var(--u)); border-radius: calc(8 * var(--u)); box-shadow: 0 0 calc(10 * var(--u)) rgba(226, 174, 46, .75); }
.cw-card .cw-in { position: absolute; bottom: 3%; left: 50%; transform: translateX(-50%); padding: 0 calc(6 * var(--u)); font-size: calc(11 * var(--u)); color: #2b2118; background: var(--gold); border-radius: calc(8 * var(--u)); white-space: nowrap; }
.cw-wedge { stroke: var(--brown); stroke-width: 1.5; fill: var(--cream-dk); }
.cw-wedge.r-junk { fill: var(--r-junk); } .cw-wedge.r-common { fill: var(--r-common); } .cw-wedge.r-rare { fill: var(--r-rare); } .cw-wedge.r-great { fill: var(--r-great); }
.cw-wedge.won { stroke: #fff6d8; stroke-width: 4; }
.cw-label { font-size: 9px; font-weight: 700; fill: #2b2118; text-anchor: middle; dominant-baseline: middle; pointer-events: none; }
.cw-hub { fill: var(--brown); stroke: var(--gold); stroke-width: 3; }
.cw-needle { fill: var(--coral-dk); stroke: var(--brown); stroke-width: 1.5; }
.cw-side { display: grid; gap: calc(6 * var(--u)); }
.cw-fill { display: grid; grid-template-columns: repeat(10, 1fr); gap: calc(2 * var(--u)); }
.cw-fill i { height: calc(12 * var(--u)); border-radius: calc(3 * var(--u)); background: rgba(139, 107, 78, .25); }
.cw-fill i.r-junk { background: var(--r-junk); } .cw-fill i.r-common { background: var(--r-common); } .cw-fill i.r-rare { background: var(--r-rare); } .cw-fill i.r-great { background: var(--r-great); }
.cw-odds { display: grid; gap: calc(2 * var(--u)); font-size: calc(13 * var(--u)); }
.cw-odds .o { display: flex; justify-content: space-between; gap: calc(6 * var(--u)); }
.cw-side .actions { display: flex; gap: calc(6 * var(--u)); }
.cw-picks { display: flex; flex-wrap: wrap; gap: calc(4 * var(--u)); }
.cw-chip { cursor: inherit; border: calc(2 * var(--u)) solid var(--r-junk); }
.cw-chip.r-common { border-color: var(--r-common); } .cw-chip.r-rare { border-color: var(--r-rare); } .cw-chip.r-great { border-color: var(--r-great); }
.cw-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(104 * var(--u)), 1fr)); gap: calc(8 * var(--u)); }
.cw-card { position: relative; display: grid; justify-items: center; align-content: center; gap: calc(2 * var(--u)); aspect-ratio: 2 / 3; padding: 18% 14% 12%; cursor: inherit; text-align: center;
  color: var(--ink); border: 0; background: url(/assets/ui2/cards/frame_junk.png) center / 100% 100% no-repeat; }   /* K-407 frame art; padding = frame border (knob) */
.cw-card.r-common { background-image: url(/assets/ui2/cards/frame_common.png); } .cw-card.r-rare { background-image: url(/assets/ui2/cards/frame_rare.png); }
.cw-card.r-great { background-image: url(/assets/ui2/cards/frame_great.png); filter: drop-shadow(0 0 calc(6 * var(--u)) rgba(226, 174, 46, .6)); }
.cw-card:disabled { opacity: .5; cursor: inherit; }
.cw-card .cw-ic .ic { width: calc(36 * var(--u)); height: calc(36 * var(--u)); }
.cw-card .nm { font-size: calc(12 * var(--u)); font-weight: 700; line-height: 1.15; }
.cw-card .meta { font-size: calc(11 * var(--u)); color: var(--ink-dim); }
.cw-card .cnt { position: absolute; top: 4%; right: 6%; padding: 0 calc(4 * var(--u)); font-size: calc(12 * var(--u)); color: #fff; background: var(--line); border-radius: calc(8 * var(--u)); }
.skin-row select { flex: 1; }
.skin-row .chk { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); white-space: nowrap; }

/* K-020 quest board (PassPanels.jsx BoardPanel) + battle pass strip (BattlePassPanel): level columns scroll inside the panel (never the page). */
.qb-sec h3 small { font-weight: 400; color: var(--ink-dim); margin-left: calc(6 * var(--u)); }
.qb-q { display: grid; gap: calc(4 * var(--u)); padding: calc(8 * var(--u)) calc(10 * var(--u)); background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line);
  border-radius: var(--radius-sm); box-shadow: 0 calc(2 * var(--u)) 0 var(--line); }
.qb-q.done { background: rgba(157, 184, 138, .3); }
.qb-q .nm { font-weight: 600; }
.qb-q .meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: calc(6 * var(--u)); font-size: calc(12 * var(--u)); color: var(--ink-dim); }
.qb-q .qb-rw { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); }
.qb-q .qb-rw .ic { width: calc(16 * var(--u)); height: calc(16 * var(--u)); }
.qb-ok { display: inline-block; margin-right: calc(6 * var(--u)); padding: 0 calc(6 * var(--u)); border-radius: calc(999 * var(--u)); font-size: calc(11 * var(--u)); background: var(--sage); color: var(--line); }
.bp-head { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: calc(10 * var(--u)); align-items: center; }
.bp-head h3 { margin: 0; }
.bp-head small { color: var(--ink-dim); font-size: calc(12 * var(--u)); }
.bp-lv { display: grid; grid-template-columns: 1fr auto; align-items: end; gap: calc(3 * var(--u)) calc(8 * var(--u)); }
.bp-lv > .bar { grid-column: 1 / -1; grid-row: 2; } .bp-lv > small { grid-column: 2; grid-row: 1; text-align: right; }   /* user 2026-10-16: points text at the bar top-right */
.bp-lv > b { font-size: calc(20 * var(--u)); }
.bp-lv > b small { font-size: calc(13 * var(--u)); color: var(--ink-dim); }
.bp-prem { display: flex; gap: calc(10 * var(--u)); align-items: center; justify-content: flex-end; flex-wrap: wrap; margin-top: calc(8 * var(--u)); }   /* user 2026-10-16: one row under the reward strip */

.bp-prem .ic { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
.bp-badge { padding: calc(6 * var(--u)) calc(12 * var(--u)); text-align: center; border-radius: var(--radius-sm); background: var(--gold); border: calc(2 * var(--u)) solid var(--line); }
.bp-strip { display: flex; gap: calc(6 * var(--u)); overflow-x: auto; padding-bottom: calc(6 * var(--u)); scroll-snap-type: x proximity; }
.bp-col { flex: 0 0 calc(92 * var(--u)); display: grid; grid-template-rows: auto 1fr 1fr; gap: calc(4 * var(--u)); scroll-snap-align: center; }
.bp-col.bp-legend { flex-basis: calc(58 * var(--u)); position: sticky; left: 0; z-index: 1; background: var(--cream); }
.bp-tr { display: grid; place-items: center; font-size: calc(12 * var(--u)); font-weight: 700; border-radius: var(--radius-sm); background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--brown); }
.bp-tr.prem { background: var(--gold); }
.bp-n { text-align: center; font-weight: 700; font-size: calc(13 * var(--u)); padding: calc(2 * var(--u)) 0; border-radius: calc(999 * var(--u)); background: rgba(139, 107, 78, .2); }
.bp-col.reached .bp-n { background: var(--sage); }
.bp-col.next .bp-n { background: var(--blue); }
.bp-cell { display: grid; justify-items: center; align-content: center; gap: calc(2 * var(--u)); min-height: calc(96 * var(--u)); padding: calc(4 * var(--u)); text-align: center;
  background: var(--cream-lt); color: var(--ink); border: calc(2 * var(--u)) solid var(--brown); border-radius: var(--radius-sm); font: inherit; cursor: inherit; }
.bp-cell.premium { background: linear-gradient(#fff3c4, var(--cream-lt)); border-color: var(--gold); }
.bp-cell.empty { background: transparent; border-style: dashed; border-color: rgba(139, 107, 78, .3); }
.bp-cell.locked { opacity: .55; }
.bp-cell.todo { border-style: dashed; }
.bp-cell.can { cursor: inherit; border-color: var(--line); box-shadow: 0 calc(3 * var(--u)) 0 var(--line), 0 0 0 calc(3 * var(--u)) var(--sage); }
.bp-cell.got { opacity: .7; background: rgba(157, 184, 138, .3); }
.bp-cell .bp-ic .ic { width: calc(32 * var(--u)); height: calc(32 * var(--u)); }
.bp-cell .nm { font-size: calc(11 * var(--u)); line-height: 1.15; max-height: 3.5em; overflow: hidden; }
.bp-cell .st { font-size: calc(11 * var(--u)); font-weight: 700; color: var(--ink-dim); }
.bp-cell.can .st { color: var(--sage-dk); }
@media (max-width: 620px) { .bp-head { grid-template-columns: 1fr; } }

/* ---- K-021 PvP zones: edge tint (pointer-events none, never in the frame loop), yellow flag button, red/black portal confirm, knockdown ---- */
.zone-edge { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.zone-edge.z-yellow { box-shadow: inset 0 0 calc(70 * var(--u)) rgba(224, 180, 58, .32); }
.zone-edge.z-red { box-shadow: inset 0 0 calc(80 * var(--u)) rgba(208, 87, 74, .38); }
.zone-edge.z-black { box-shadow: inset 0 0 calc(90 * var(--u)) rgba(30, 20, 40, .55); }
.pvpflag { margin-left: calc(6 * var(--u)); }
.pvpflag.on { background: #d0574a; color: #fff; }
.zone-confirm { position: absolute; inset: 0; z-index: 8; display: grid; place-items: center; padding: calc(16 * var(--u)); background: rgba(20, 12, 8, .45); }
.zone-confirm .popup.z-black > .ui-title { background: #2c2630; color: #efe2ff; }
.zone-confirm .ui-parchment p { margin: 0 0 calc(6 * var(--u)); }
/* K-431 update log popup (UpdateLog.jsx): above HUD/panels, list scrolls inside, popup capped to viewport (no page scroll) */
.upd-log { z-index: 30; }
.upd-log .popup { width: min(calc(420 * var(--u)), 100%); max-height: calc(100dvh - 32 * var(--u)); }
.game-ver { font-size: calc(11 * var(--u)); opacity: .6; letter-spacing: .02em; }
.title-screen > .game-ver { position: absolute; right: calc(10 * var(--u)); bottom: calc(8 * var(--u)); color: var(--cream); text-shadow: 0 1px 0 #000; pointer-events: none; }
.upd-body { min-height: 0; overflow: hidden auto; }
.upd-body article + article { margin-top: calc(10 * var(--u)); padding-top: calc(8 * var(--u)); border-top: var(--line-w) dashed var(--line); }
.upd-body h3 { margin: 0; font-size: calc(15 * var(--u)); }
.upd-body small { opacity: .7; }
.upd-body ul { margin: calc(6 * var(--u)) 0 0; padding-left: calc(18 * var(--u)); }
.upd-body li { margin: 0 0 calc(4 * var(--u)); line-height: 1.35; }
.downed.knock { display: flex; align-items: center; gap: calc(10 * var(--u)); }

/* ---- K-009 skill book (SkillPanels.jsx) + hotbar aim/drop states ---- */
.sb-slots { display: flex; gap: calc(6 * var(--u)); flex-wrap: wrap; margin: calc(6 * var(--u)) 0; }
.sb-slot { position: relative; width: calc(64 * var(--u)); min-height: calc(46 * var(--u)); padding: calc(12 * var(--u)) calc(4 * var(--u)) calc(4 * var(--u)); display: grid; place-items: center;
  background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); font-size: calc(10 * var(--u)); text-align: center; }
.sb-slot.empty { background: var(--cream-dk); border-style: dashed; border-color: var(--brown); color: var(--ink-dim); }
.sb-slot.target { border-color: var(--blue-dk); cursor: inherit; }
.sb-slot kbd { position: absolute; top: calc(1 * var(--u)); left: calc(5 * var(--u)); font-size: calc(10 * var(--u)); color: var(--ink-dim); }
.sb-slot .ui-close.sm { position: absolute; top: calc(-6 * var(--u)); right: calc(-6 * var(--u)); width: calc(18 * var(--u)); height: calc(18 * var(--u)); font-size: calc(11 * var(--u)); }
.sb-group ul { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(4 * var(--u)); }
.sb-row { display: grid; grid-template-columns: 1fr auto; gap: 0 calc(6 * var(--u)); padding: calc(5 * var(--u)) calc(8 * var(--u)); cursor: inherit;
  background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); }
.sb-row small { grid-column: 1 / -1; color: var(--ink-dim); font-size: calc(10 * var(--u)); }
.sb-row .tier { font-size: calc(10 * var(--u)); color: var(--blue-dk); }
.sb-row.on { border-color: var(--blue-dk); }
.sb-row.picked { box-shadow: 0 0 0 calc(2 * var(--u)) var(--blue-dk); }
.sb-row.locked { opacity: .5; cursor: inherit; }
/* K-178 skill icons (Icons.jsx SkillIcon): art fills the hotbar/book slot, text name = fallback only (img hidden on load error -> :has fails).
   Hotbar: icon under kbd/small (z 1, dark pills) and under .cd (DOM order) -> cooldown wedge + number + MP stay readable. */
.sk-ic { display: block; object-fit: contain; pointer-events: none; }
.sk-ic[hidden] { display: none; }
.hk .sk-ic { position: absolute; inset: calc(3 * var(--u)); width: calc(100% - 6 * var(--u)); height: calc(100% - 6 * var(--u)); }
.hk:has(.sk-ic:not([hidden])) b, .sb-slot:has(.sk-ic:not([hidden])) b { display: none; }
.hk:has(.sk-ic:not([hidden])) :is(kbd, small) { position: absolute; z-index: 1; padding: 0 calc(4 * var(--u)); border-radius: calc(6 * var(--u)); background: rgba(30, 20, 12, .72); line-height: 1.35; }
.hk:has(.sk-ic:not([hidden])) small { bottom: calc(1 * var(--u)); color: var(--cream-lt); }
.hk:has(.sk-ic:not([hidden])) kbd { top: calc(1 * var(--u)); left: calc(2 * var(--u)); }
.hk.nomp .sk-ic { filter: grayscale(.7) brightness(.8); }
.sb-slot .sk-ic { width: calc(40 * var(--u)); height: calc(40 * var(--u)); }
.sb-row:has(.sk-ic) { grid-template-columns: auto 1fr auto; align-items: center; }
.sb-row .sk-ic { grid-row: 1 / 3; width: calc(40 * var(--u)); height: calc(40 * var(--u)); }
.sb-row:has(.sk-ic) small { grid-column: 2 / -1; }
.st-skill .sk-ic { width: calc(56 * var(--u)); height: calc(56 * var(--u)); }

/* ---- K-090 dev arena skill tester (SkillPanels.jsx SkillTester): left column under .vitals ---- */
.skilltester { position: absolute; z-index: 4; top: calc(calc(196 * var(--u)) + env(safe-area-inset-top)); left: max(calc(12 * var(--u)), env(safe-area-inset-left));
  width: calc(320 * var(--u)); max-height: calc(100vh - 300 * var(--u)); overflow: auto; padding: calc(10 * var(--u)); display: grid; gap: calc(6 * var(--u)); font-size: calc(12 * var(--u)); }
.skilltester header { display: flex; align-items: center; gap: calc(6 * var(--u)); } .skilltester header small { flex: 1; color: var(--ink-dim); }
.skilltester kbd { display: inline-block; min-width: calc(18 * var(--u)); padding: 0 calc(4 * var(--u)); text-align: center; border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); background: var(--cream-lt); font-size: calc(10 * var(--u)); }
.st-line, .st-skill { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: calc(6 * var(--u)); }
.st-line span { text-align: center; font-weight: 700; } .st-line small { font-weight: 400; color: var(--ink-dim); }
.st-skill > div { display: grid; gap: calc(2 * var(--u)); padding: calc(6 * var(--u)); background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); }
.st-skill.flagged > div { border-color: #d0574a; box-shadow: 0 0 0 calc(2 * var(--u)) #d0574a55; }
.st-skill b { font-size: calc(15 * var(--u)); } .st-skill code { font-size: calc(10 * var(--u)); color: var(--blue-dk); } .st-skill small { color: var(--ink-dim); font-size: calc(10 * var(--u)); }
.st-note { width: 100%; font: inherit; padding: calc(4 * var(--u)); }
.st-flags { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(3 * var(--u)); }
.st-flags li { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: calc(4 * var(--u)); } .st-flags small { color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-flags .ui-close { position: static; inset: auto; transform: none; }
/* K-101 hair look picker (ui/HairPicker.jsx): creation + character panel */
.rig-preview { width: calc(180 * var(--u)); height: calc(229 * var(--u)); display: block; margin: 0 auto; }
.hair-picker { display: grid; gap: calc(6 * var(--u)); width: 100%; text-align: left; }
.face-step { display: grid; grid-template-columns: auto 1fr auto; gap: calc(4 * var(--u)); align-items: center; }   /* K-247 ‹ select › */
.hair-swatches { display: flex; flex-wrap: wrap; gap: calc(5 * var(--u)); align-items: center; }
.hair-swatch { width: calc(22 * var(--u)); height: calc(22 * var(--u)); border-radius: 50%; padding: 0; border: calc(2 * var(--u)) solid var(--ink, #3b2a1e); cursor: inherit; }
.hair-swatch.on { outline: calc(3 * var(--u)) solid var(--gold, #e8b84a); outline-offset: calc(1 * var(--u)); }
.hair-swatches input[type=color] { width: calc(30 * var(--u)); height: calc(24 * var(--u)); padding: 0; border: 0; background: none; cursor: inherit; }

/* K-125 craft panel (WorldPanels.jsx CraftPanel, Albion refining ref) */
.craft-filter { display: flex; flex-direction: column; gap: calc(8 * var(--u)); }
.pill-search { width: 100%; height: calc(36 * var(--u)); padding: 0 calc(16 * var(--u)); font: inherit; }   /* look = K-358b themed field (end of file) */
.toggle { display: inline-flex; align-items: center; gap: calc(8 * var(--u)); align-self: flex-start; padding: 0; background: none; border: 0; font: inherit; color: var(--ink); cursor: inherit; }
.toggle i { width: calc(22 * var(--u)); height: calc(22 * var(--u)); border-radius: 50%; border: calc(3 * var(--u)) solid #4a4f58; background: radial-gradient(circle at 40% 35%, #9aa1ab, #5d636c); box-shadow: inset 0 0 0 calc(3 * var(--u)) #2b3038; }
.toggle.on i { background: radial-gradient(circle at 40% 35%, #ffe7a3, #d9a33c); box-shadow: inset 0 0 0 calc(3 * var(--u)) #2b3038, 0 0 calc(6 * var(--u)) rgba(255, 200, 90, .7); }
.craft-rows { display: flex; flex-direction: column; }
.craft-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: calc(12 * var(--u)); padding: calc(10 * var(--u)) calc(4 * var(--u));
  border-bottom: calc(2 * var(--u)) solid rgba(139, 107, 78, .25); cursor: inherit; text-align: left; }
.craft-row:hover { background: rgba(255, 255, 255, .25); }
.craft-row > .slot, .sv-row .slot { width: calc(68 * var(--u)); min-height: 0; aspect-ratio: 1; }
.craft-row.locked { opacity: .65; }
.craft-row.sel, .craft-row.sel:hover { background: rgba(40, 28, 16, .22); box-shadow: inset 0 0 0 calc(2 * var(--u)) #c9a24a; }   /* 582 ย่อย picked: dark bg + gold frame + checkbox */
.sv-row { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.sv-row input { pointer-events: none; }
/* gem tab (user 2026-10-16): host slot centre, socket row below, picker modal */
.gem-bench { display: flex; flex-direction: column; align-items: center; gap: calc(10 * var(--u)); padding: calc(12 * var(--u)) 0; text-align: center; }
.gem-host { width: calc(96 * var(--u)); height: calc(96 * var(--u)); display: grid; place-items: center; }
.gem-host > .slot, .gem-target > .slot { width: 100%; height: 100%; min-height: 0; }
.gem-socks { display: flex; gap: calc(10 * var(--u)); }
.gem-socks .slot, .gem-target, .gem-empty { width: calc(56 * var(--u)); height: calc(56 * var(--u)); min-height: 0; display: grid; place-items: center; }
.gem-target { opacity: .7; }
.gem-target.on { opacity: 1; box-shadow: 0 0 0 calc(3 * var(--u)) #c9a24a, 0 0 calc(10 * var(--u)) rgba(255, 200, 90, .6); }
.btn.is-disabled { filter: grayscale(.7) opacity(.6); }   /* MoneyBtn: Acorn short, still tappable (toast) */
.btn.gem-go { width: 100%; justify-content: center; margin-top: calc(8 * var(--u)); }
.gem-pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(110 * var(--u)), 1fr)); gap: calc(10 * var(--u)); }
.gp-cell { display: flex; flex-direction: column; align-items: center; gap: calc(4 * var(--u)); background: none; border: 0; padding: calc(4 * var(--u)); border-radius: calc(8 * var(--u)); cursor: inherit; }
.gem-pick-grid > .gem-go { grid-column: 1 / -1; }
.gp-cell.on { box-shadow: inset 0 0 0 calc(2 * var(--u)) #c9a24a; }
.gp-cell:hover, .gp-cell.on { background: rgba(40, 28, 16, .15); }
.gp-cell .slot { width: calc(64 * var(--u)); height: calc(64 * var(--u)); min-height: 0; }
.gp-cell small { font-size: calc(12 * var(--u)); text-align: center; color: var(--ink); line-height: 1.25; }
.popup.gem-picker { width: min(calc(560 * var(--u)), 100%); max-height: 80vh; overflow: auto; }
.sv-lbl { align-self: center; font-weight: 700; color: var(--ink-dim); }
.sv-fee { display: flex; align-items: center; gap: calc(4 * var(--u)); color: #a33; font-weight: 700; white-space: nowrap; }
.sv-fee .ic { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
.sv-bar { position: sticky; top: 0; z-index: 2; padding: calc(6 * var(--u)) 0; display: flex; justify-content: space-between; gap: calc(8 * var(--u)); margin-bottom: calc(6 * var(--u)); }
.cr-main { display: flex; flex-direction: column; gap: calc(4 * var(--u)); min-width: 0; }
.cr-main > b { font-size: calc(16 * var(--u)); }
.cr-main small { color: var(--ink-dim); }
.cr-ins, .cd-ins { display: flex; flex-wrap: wrap; gap: calc(6 * var(--u)); }
.cr-in { display: flex; flex-direction: column; align-items: center; gap: calc(2 * var(--u)); }
.cr-in .slot { width: calc(36 * var(--u)); min-height: 0; aspect-ratio: 1; }
.cr-in em { font-style: normal; font-size: calc(12 * var(--u)); font-weight: 600; padding: 0 calc(5 * var(--u)); border-radius: calc(3 * var(--u)); background: rgba(139, 107, 78, .18); }
.cr-in.short em { background: rgba(214, 80, 70, .3); color: #8b1f17; }
.craft-detail { position: relative; width: min(calc(420 * var(--u)), 100%); padding: calc(16 * var(--u)); gap: calc(12 * var(--u)); max-height: calc(100vh - calc(32 * var(--u))); overflow-y: auto; animation: pop var(--anim-ms) var(--ease); }
.cd-head { display: flex; gap: calc(14 * var(--u)); align-items: center; padding-right: calc(40 * var(--u)); }
.cd-head .slot { width: calc(96 * var(--u)); min-height: 0; aspect-ratio: 1; flex: none; }
.cd-head h3 { margin: 0; font-size: calc(20 * var(--u)); }
.cd-qty { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.cd-qty > span { font-weight: 600; }
.cd-qty > b { min-width: calc(28 * var(--u)); text-align: center; font-size: calc(18 * var(--u)); }
.cd-ins .slot { width: calc(52 * var(--u)); }
.craft-detail .actions { justify-content: flex-end; }

/* K-125b craft header (Albion ref): station emblem in a steel ring + speech bubble */
.station-head { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: calc(12 * var(--u)); }
.st-ring { position: relative; width: calc(76 * var(--u)); height: calc(76 * var(--u)); border-radius: 50%; display: grid; place-items: center;
  background: radial-gradient(circle at 40% 35%, #f6ead2, #d8c19a); border: calc(4 * var(--u)) solid #3a3f48; box-shadow: 0 0 0 calc(2 * var(--u)) #1d2128, inset 0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(0,0,0,.25); }
.st-ring img { width: 82%; height: 82%; object-fit: contain; }
.st-say { position: relative; margin: 0; padding: calc(8 * var(--u)) calc(12 * var(--u)); border-radius: calc(12 * var(--u)); background: var(--cream-lt);
  box-shadow: 0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(0,0,0,.18); font-size: calc(14 * var(--u)); display: flex; flex-direction: column; gap: calc(2 * var(--u)); }
.st-say::before { content: ""; position: absolute; left: calc(-9 * var(--u)); top: 50%; transform: translateY(-50%); border: calc(8 * var(--u)) solid transparent; border-right: calc(10 * var(--u)) solid var(--cream-lt); border-left: 0; }
.st-say small { color: var(--ink-dim); font-size: calc(12 * var(--u)); }
.st-say .st-rrr { display: block; color: var(--mint-dk, #2f7a4f); font-weight: 600; }   /* K-572 town return rate */

/* K-125c ช่าง (NPC): fixed tall panel, switching tabs never resizes it */
.panel.npc-panel { height: min(calc(760 * var(--u)), calc(100% - calc(64 * var(--u)) - var(--hotbar-h) - calc(34 * var(--u)))); }

/* K-128 card item icon: reward art inside a small card frame. K-407: frame art per card_defs rarity (Icons.jsx r-<rarity>; no rarity = junk) */
.card-ic { display: grid; place-items: center; width: 100%; height: 100%; }
.card-ic > .ic { width: 56%; height: 84%; object-fit: contain; padding: 14% 9% 10%; box-sizing: border-box; background: url(/assets/ui2/cards/frame_junk.png) center / 100% 100% no-repeat; }
.card-ic.r-common > .ic { background-image: url(/assets/ui2/cards/frame_common.png); } .card-ic.r-rare > .ic { background-image: url(/assets/ui2/cards/frame_rare.png); }
.card-ic.r-great > .ic { background-image: url(/assets/ui2/cards/frame_great.png); }

/* K-175 food buff chip (vitals card, under the xp bar) */
.vitals .food-chip { display: flex; align-items: center; gap: calc(4 * var(--u)); font-size: calc(10 * var(--u)); line-height: 1.1; }
.vitals .food-chip .ic { flex: none; width: calc(22 * var(--u)); height: calc(22 * var(--u)); object-fit: contain; }
.vitals .food-chip b { flex: none; font-weight: 600; }
.vitals .food-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--line); opacity: .8; }
/* K-175b craft tier chips (long station menus) + food effect line in recipe rows */
.craft-filter .cf-top { display: flex; align-items: center; gap: calc(8 * var(--u)); }   /* K-375 search grows, tier Dropdown fixed; bag toggle own line below */
.craft-filter .cf-top > .pill-search { flex: 1; min-width: 0; }
.craft-filter .cf-top > .dd { flex: none; field-sizing: content; min-width: 0; }   /* user 2026-10-16: width = selected label (was 140u) */   /* knob: fits 'ทั้งหมด' after the cap rivets */
.craft-row .cr-fx { display: block; font-size: calc(11 * var(--u)); opacity: .8; }

/* K-171b mount assembly: 5 part icons per mount, colour = owned, greyscale = missing */
.mount-combine .card.ready { box-shadow: 0 0 0 calc(2 * var(--u)) #e9c45a inset; }
.mparts { display: flex; gap: calc(6 * var(--u)); flex-wrap: wrap; }
.mpart { position: relative; display: inline-flex; flex-direction: column; align-items: center; gap: calc(2 * var(--u)); width: calc(52 * var(--u)); }
.mpart .ic { width: calc(44 * var(--u)); height: calc(44 * var(--u)); border-radius: calc(8 * var(--u)); background: #f4e8cc; border: calc(2 * var(--u)) solid #6b4f2e; object-fit: contain; }
.mpart small { font-size: calc(10 * var(--u)); line-height: 1; }
.mpart b { position: absolute; top: calc(-4 * var(--u)); right: calc(-2 * var(--u)); font-size: calc(10 * var(--u)); background: #2a1d12; color: #fff3c0; border-radius: calc(6 * var(--u)); padding: 0 calc(3 * var(--u)); }
.mpart.missing .ic { filter: grayscale(1) brightness(1.05) opacity(.5); }
.mpart.missing small { opacity: .6; }

/* K-181 HUD (user 2026-10-05 ref): round face portrait ring at the left, the parchment bar panel slides OUT from behind the ring to the right */
.vitals { background: none !important; border-image: none !important; filter: none !important; padding: 0 !important; gap: 0 !important; align-items: center; }
.vitals .avatar.face { z-index: 2; width: calc(84 * var(--u)); height: calc(84 * var(--u)); border-radius: 50%; overflow: visible;
  background: radial-gradient(circle at 50% 40%, #fbe9c4, #d8b47c); box-shadow: 0 calc(3 * var(--u)) calc(6 * var(--u)) rgba(40, 26, 14, .45); }
.vitals .avatar.face .face-cv { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 50%; }
.vitals .avatar.face::after { inset: calc(-9 * var(--u)); }
.vitals .avatar.face b { display: none; }
.vitals .bars { margin-left: calc(-26 * var(--u)); padding: calc(10 * var(--u)) calc(14 * var(--u)) calc(10 * var(--u)) calc(34 * var(--u)); width: calc(220 * var(--u));
  border: 0 solid transparent; border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch;
  filter: drop-shadow(0 calc(3 * var(--u)) calc(3 * var(--u)) rgba(40, 26, 14, .35)); }
@media (max-width: 620px) {
  .vitals .avatar.face { width: calc(62 * var(--u)); height: calc(62 * var(--u)); }
  .vitals .bars { margin-left: calc(-20 * var(--u)); padding: calc(6 * var(--u)) calc(10 * var(--u)) calc(7 * var(--u)) calc(26 * var(--u)); width: calc(168 * var(--u)); }
}

/* ---- K-177 skill trainer / master panels + rhythm minigame (TrainPanels.jsx) + gated hotbar ---- */
.hk.gated { filter: grayscale(1); opacity: .55; }
.hk.gated::after { content: ''; position: absolute; inset: 0; border-radius: inherit; background: repeating-linear-gradient(135deg, transparent 0 calc(6 * var(--u)), rgba(60, 40, 25, .18) calc(6 * var(--u)) calc(9 * var(--u))); pointer-events: none; }
.sb-pts { display: flex; gap: calc(6 * var(--u)); align-items: center; flex-wrap: wrap; }
.sb-row.unlearned { opacity: .6; cursor: inherit; }
.tr-head { display: flex; gap: calc(6 * var(--u)); align-items: center; flex-wrap: wrap; }
.tr-head .dd { margin-left: auto; }
.tr-prog { position: relative; width: calc(110 * var(--u)); height: calc(16 * var(--u)); border: var(--line-w) solid var(--line); border-radius: calc(8 * var(--u)); background: var(--cream-dk); overflow: hidden; }
.tr-prog i { position: absolute; inset: 0 auto 0 0; background: var(--blue); }
.tr-prog small { position: relative; display: block; text-align: center; font-size: calc(10 * var(--u)); line-height: calc(14 * var(--u)); }
.tr-lock { font-size: calc(11 * var(--u)); color: var(--locked); font-weight: 400; }
.tr-row { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: 0 calc(6 * var(--u)); padding: calc(5 * var(--u)) calc(8 * var(--u));
  background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); }
.tr-row .sk-ic { grid-row: 1 / 3; width: calc(40 * var(--u)); height: calc(40 * var(--u)); }
.tr-row .tier { font-size: calc(10 * var(--u)); color: var(--blue-dk); }
.tr-row small { grid-column: 2 / 4; color: var(--ink-dim); font-size: calc(10 * var(--u)); }
.tr-row button { grid-column: 4; grid-row: 1 / 3; }
.tr-row.locked { opacity: .6; }
.tr-cost { display: inline-flex; gap: calc(4 * var(--u)); flex-wrap: wrap; vertical-align: middle; }
.tr-cost .chip { font-size: calc(10 * var(--u)); padding: 0 calc(5 * var(--u)); }
.skilltrain .tr-skill { display: grid; place-items: center; } .skilltrain .tr-skill .sk-ic { width: 80%; height: 80%; }   /* user 2026-10-15 skill rows = craft rows (TrainPanels Cost .cr-in) */
.skilltrain .cr-main > b small.tier { font-size: calc(11 * var(--u)); color: var(--blue-dk); font-weight: 600; }
.rhythm { position: absolute; z-index: 30; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(calc(560 * var(--u)), calc(100vw - 32px));
  padding: calc(12 * var(--u)); display: grid; gap: calc(8 * var(--u)); justify-items: center; }
.rhythm header { width: 100%; display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 0 calc(8 * var(--u)); }
.rhythm header .sk-ic { grid-row: 1 / 3; width: calc(44 * var(--u)); height: calc(44 * var(--u)); }
.rhythm header small { color: var(--ink-dim); }
/* K-527 skill check: ring + yellow zone + needle (TrainPanels.jsx SkillCheck); svg units 200, sized by --u */
.skillcheck .sc-ring { width: calc(220 * var(--u)); height: calc(220 * var(--u)); }
.sc-track { fill: #2f2418; stroke: #6b5238; stroke-width: 16; }
.sc-zone { fill: none; stroke: #ffd23f; stroke-width: 16; filter: drop-shadow(0 0 4px #ffd23f); }
.sc-needle { stroke: #e9433a; stroke-width: 5; stroke-linecap: round; }
.sc-hub { fill: #e9433a; }
.sc-ready { fill: var(--cream); font-size: 18px; font-weight: 700; text-anchor: middle; }
.sc-dots { display: flex; gap: calc(8 * var(--u)); }
.sc-dots i { width: calc(16 * var(--u)); height: calc(16 * var(--u)); border-radius: 50%; background: var(--cream-dk); border: 2px solid var(--line); }
.sc-dots i.hit { background: #4fbf6a; } .sc-dots i.bad, .sc-dots i.miss { background: #e9433a; }
.skillcheck .sc-btn { min-width: calc(180 * var(--u)); }
.rh-lane { --ring: calc(56 * var(--u)); position: relative; width: 100%; height: calc(72 * var(--u)); overflow: hidden; background: var(--cream-dk);
  border: var(--line-w) solid var(--line); border-radius: calc(36 * var(--u)); }
.rh-ring { position: absolute; left: calc(var(--ring) - 30 * var(--u)); top: calc(6 * var(--u)); width: calc(60 * var(--u)); height: calc(60 * var(--u));
  border: calc(4 * var(--u)) solid var(--gold); border-radius: 50%; box-sizing: border-box; background: rgba(255, 236, 170, .35); }
.rh-note { position: absolute; top: calc(11 * var(--u)); left: calc(var(--ring) - 25 * var(--u) + var(--x) * var(--u)); width: calc(50 * var(--u)); height: calc(50 * var(--u));
  display: grid; place-items: center; border-radius: 50%; background: var(--blue); border: var(--line-w) solid var(--line); color: var(--cream-lt); }
.rh-note .ic { width: calc(32 * var(--u)); height: calc(32 * var(--u)); stroke-width: 3.2; }
.rh-note.hit { background: var(--sage); transform: scale(1.15); opacity: .55; }
.rh-note.bad { background: var(--coral); opacity: .7; }
.rh-note.miss { background: #8a8073; opacity: .45; }
.rh-ready { position: absolute; inset: 0; display: grid; place-items: center; font-size: calc(22 * var(--u)); font-weight: 700; color: var(--ink); }
.rh-pad { display: flex; gap: calc(10 * var(--u)); }
.rh-pad .btn { width: calc(64 * var(--u)); height: calc(56 * var(--u)); padding: 0; display: grid; place-items: center; }
.rh-pad .ic { width: calc(34 * var(--u)); height: calc(34 * var(--u)); }
.rh-res { font-size: calc(18 * var(--u)); font-weight: 700; margin: 0; }
.rh-res.ok { color: #3f7a3a; } .rh-res.bad { color: #b24a3c; }

/* K-182 (user 2026-10-05): zone pill overlays the TOP centre of the minimap, map name the BOTTOM centre; PvP flag button under it */
.minimap { position: absolute; }
.minimap .mm-label { position: absolute; left: 50%; top: 0; width: var(--mm); height: var(--mm); transform: translateX(-50%); pointer-events: none; display: block; }
.minimap .mm-label > * { position: absolute; left: 50%; transform: translateX(-50%); pointer-events: auto; white-space: nowrap; }
.minimap .mm-label .zonetag { top: calc(-16 * var(--u)); }   /* user 2026-10-16: a bit higher over the ring */
.minimap .mm-label .mapname { bottom: calc(-20 * var(--u)); height: calc(30 * var(--u)); font-size: calc(14 * var(--u)); }
.minimap .mm-label .pvpflag { top: calc(var(--mm) + calc(38 * var(--u))); }   /* K-227 clear the steel ring */

/* K-182b (user 2026-10-05): smaller parchment + contents, smaller ring */
.vitals .avatar.face { width: calc(70 * var(--u)); height: calc(70 * var(--u)); }
.vitals .bars { margin-left: calc(-22 * var(--u)); padding: calc(7 * var(--u)) calc(10 * var(--u)) calc(7 * var(--u)) calc(28 * var(--u)); width: calc(165 * var(--u)); gap: calc(3 * var(--u)); }
.vitals .who { font-size: calc(12 * var(--u)); }
.vitals .bar { height: calc(14 * var(--u)); border-width: calc(1.5 * var(--u)); }
.vitals .bar b { font-size: calc(9 * var(--u)); }
.vitals .bar.sta { height: calc(7 * var(--u)); }
@media (max-width: 620px) {
  .vitals .avatar.face { width: calc(54 * var(--u)); height: calc(54 * var(--u)); }
  .vitals .bars { margin-left: calc(-18 * var(--u)); padding: calc(5 * var(--u)) calc(8 * var(--u)) calc(5 * var(--u)) calc(22 * var(--u)); width: calc(140 * var(--u)); }
  .vitals .bar { height: calc(12 * var(--u)); }
  .vitals .bar.sta { height: calc(6 * var(--u)); }
}

/* K-182c (user 2026-10-05): bars + parchment smaller again (ring size kept) */
.vitals .bars { margin-left: calc(-20 * var(--u)); padding: calc(5 * var(--u)) calc(8 * var(--u)) calc(5 * var(--u)) calc(25 * var(--u)); width: calc(132 * var(--u)); gap: calc(2 * var(--u)); }
.vitals .who { font-size: calc(10.5 * var(--u)); }
.vitals .bar { height: calc(11 * var(--u)); border-width: calc(1.2 * var(--u)); }
.vitals .bar b { font-size: calc(8 * var(--u)); }
.vitals .bar.sta { height: calc(5 * var(--u)); }
@media (max-width: 620px) {
  .vitals .bars { margin-left: calc(-16 * var(--u)); padding: calc(4 * var(--u)) calc(6 * var(--u)) calc(4 * var(--u)) calc(20 * var(--u)); width: calc(116 * var(--u)); }
  .vitals .bar { height: calc(10 * var(--u)); }
  .vitals .bar.sta { height: calc(5 * var(--u)); }
}

/* K-182d (user 2026-10-05): bars had no gap to the parchment edge (inset border-image eats ~6u) */
.vitals .bars { padding: calc(9 * var(--u)) calc(13 * var(--u)) calc(9 * var(--u)) calc(27 * var(--u)); width: calc(140 * var(--u)); }
@media (max-width: 620px) { .vitals .bars { padding: calc(7 * var(--u)) calc(11 * var(--u)) calc(7 * var(--u)) calc(22 * var(--u)); width: calc(122 * var(--u)); } }

/* K-187 quest/journal list: always stacked (title row own line, detail below) */
.ui-split.stack { grid-template-columns: minmax(0, 1fr); }
/* K-187 bank hint under each grid (K-226: move = centred ConfirmModal, Panels StoragePanel) */

/* K-189 rhythm countdown 3-2-1-เริ่ม! (pop per number) */
.rh-ready.small { font-size: calc(16 * var(--u)); opacity: .8; }
.rh-ready.count { font-size: calc(46 * var(--u)); color: var(--gold, #e9c45a); text-shadow: 0 calc(2 * var(--u)) 0 #2a1d12, 0 0 calc(10 * var(--u)) rgba(255, 220, 140, .7); animation: rhPop .9s ease-out both; pointer-events: none; }
.rh-ready.count.go { color: #7fe08a; font-size: calc(38 * var(--u)); }
@keyframes rhPop { 0% { transform: scale(1.8); opacity: 0; } 20% { transform: scale(1); opacity: 1; } 80% { opacity: 1; } 100% { transform: scale(.85); opacity: 0; } }

/* K-190 battle pass (user 2026-10-05): near full screen; reward cells = steel item slots (no cream/white box) */
.panel.bpass { width: min(calc(100vw - calc(40 * var(--u))), calc(1500 * var(--u))) !important; max-width: none !important; height: min(calc(100vh - calc(60 * var(--u))), calc(820 * var(--u))); left: 50% !important; right: auto !important; top: 50% !important; max-height: none !important; transform: translate(-50%, -50%) !important; z-index: 8; }
.panel.bpass .body { height: calc(100% - calc(70 * var(--u))); display: flex; flex-direction: column; }
.panel.bpass .bp-strip { flex: 1; align-items: stretch; }
.panel.bpass .bp-col { flex-basis: calc(108 * var(--u)); }
.bp-cell, .bp-cell.premium, .bp-cell.got { background: none; border-radius: 0; border: 0 solid transparent; color: #f6ead0;
  border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; text-shadow: 0 1px 0 #1a120c; }
.bp-cell.premium { filter: drop-shadow(0 0 calc(3 * var(--u)) rgba(233, 196, 90, .85)); }
.bp-cell.empty { border-image: url(/assets/ui3/slot_empty.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; opacity: .45; }
.bp-cell .st { color: #e9d8b0; }
.bp-cell.can { box-shadow: none; filter: drop-shadow(0 0 calc(4 * var(--u)) #9be07f); }
.bp-cell.can .st { color: #b8f59a; }
.bp-cell.got { opacity: .6; }
.bp-col.bp-legend { background: none; }
@media (max-width: 620px) { .panel.bpass { width: calc(100vw - calc(12 * var(--u))) !important; height: calc(100vh - calc(24 * var(--u))); } .panel.bpass .bp-col { flex-basis: calc(86 * var(--u)); } }

/* K-190b legend labels ฟรี / พรีเมียม = steel frames too (user) */
.bp-tr, .bp-tr.prem { background: none; border-radius: 0; border: 0 solid transparent; color: #f6ead0; text-shadow: 0 1px 0 #1a120c; font-size: calc(14 * var(--u));
  border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.bp-tr.prem { color: #ffd76a; filter: drop-shadow(0 0 calc(3 * var(--u)) rgba(233, 196, 90, .85)); }


/* K-188 v2 HUD (user 2026-10-05): round steel-ring pet portrait bottom-right (WorldPanels PetCard); tag above, hunger bar under, round feed/ride left */
.pet-hud { position: absolute; z-index: 4; right: max(calc(18 * var(--u)), env(safe-area-inset-right)); bottom: calc(calc(30 * var(--u)) + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: calc(8 * var(--u)); pointer-events: none; }
.pet-hud > * { pointer-events: auto; }
.ph-main { position: relative; display: flex; flex-direction: column; align-items: center; gap: calc(4 * var(--u)); }
.ph-ring { position: relative; width: calc(64 * var(--u)); height: calc(64 * var(--u)); padding: 0; border: 0; border-radius: 50%; cursor: inherit; display: grid; place-items: center;
  background: radial-gradient(circle at 50% 40%, #fbe9c4, #d8b47c); box-shadow: 0 calc(3 * var(--u)) calc(6 * var(--u)) rgba(40, 26, 14, .45); }
.ph-ring::after { content: ""; position: absolute; inset: calc(-8 * var(--u)); background: url(/assets/ui3/portrait_ring.png) center / contain no-repeat; pointer-events: none; }
.ph-ring img, .ph-ring .ic { width: 78%; height: 78%; object-fit: contain; }
.ph-tag { position: absolute; bottom: calc(100% + 8 * var(--u)); right: 50%; transform: translateX(50%); white-space: nowrap; cursor: inherit;
  padding: calc(1 * var(--u)) calc(8 * var(--u)); font-size: calc(10 * var(--u)); color: #f4efce; background: #1c2b25cc; border-radius: calc(9 * var(--u)); }
.ph-hunger { position: relative; width: calc(64 * var(--u)); height: calc(8 * var(--u)); margin-top: calc(6 * var(--u)); border: calc(1.2 * var(--u)) solid var(--line); border-radius: calc(999 * var(--u)); background: var(--cream-dk); overflow: hidden; }
.ph-hunger i { position: absolute; inset: 0 auto 0 0; border-radius: inherit; background: var(--sage); transition: width var(--anim-ms) linear; }
.ph-ht { font-size: calc(9 * var(--u)); color: #f4efce; text-shadow: 0 0 calc(3 * var(--u)) #25170e, 0 0 calc(2 * var(--u)) #25170e; white-space: nowrap; }
.pet-hud.h-hungry .ph-hunger i { background: var(--gold); }
.pet-hud.h-weak .ph-hunger i, .pet-hud.h-dying .ph-hunger i { background: var(--coral); }
.pet-hud.h-dying .ph-ring { animation: pc-pulse 1.4s ease-in-out infinite; }
@keyframes pc-pulse { 50% { box-shadow: 0 0 calc(10 * var(--u)) calc(3 * var(--u)) rgba(200, 70, 50, .85); } }
.ph-btns { display: flex; flex-direction: column; gap: calc(6 * var(--u)); }
.ph-b { position: relative; width: calc(34 * var(--u)); height: calc(34 * var(--u)); padding: 0; border-radius: 50%; cursor: inherit; display: grid; place-items: center;
  font-size: calc(14 * var(--u)); font-weight: 700; color: var(--ink); background: var(--cream-lt); border: var(--line-w) solid var(--line); box-shadow: var(--gloss), 0 calc(2 * var(--u)) 0 var(--line); }
.ph-b small { position: absolute; right: calc(-6 * var(--u)); bottom: calc(-4 * var(--u)); font-size: calc(8 * var(--u)); font-weight: 600; padding: 0 calc(3 * var(--u)); background: var(--cream); border: calc(1.2 * var(--u)) solid var(--line); border-radius: calc(6 * var(--u)); }
.ph-b.ride { font-size: calc(11 * var(--u)); background: var(--gold); }
.ph-b.ride.on { background: var(--blue); color: var(--cream-lt); }
.ph-b:disabled { filter: grayscale(.9); opacity: .55; cursor: inherit; }
.ph-b:active:not(:disabled) { transform: translateY(calc(2 * var(--u))); box-shadow: var(--gloss); }
.pc-rn { border: 0; background: none; padding: 0 calc(2 * var(--u)); cursor: inherit; font-size: calc(11 * var(--u)); color: var(--ink-dim); line-height: 1; margin-left: calc(4 * var(--u)); }
@media (max-width: 620px) {
  .pet-hud { bottom: calc(calc(196 * var(--u)) + env(safe-area-inset-bottom)); right: max(calc(14 * var(--u)), env(safe-area-inset-right)); gap: calc(6 * var(--u)); }
  .ph-ring, .ph-hunger { width: calc(52 * var(--u)); } .ph-ring { height: calc(52 * var(--u)); }
  .ph-b { width: calc(30 * var(--u)); height: calc(30 * var(--u)); }
}
.pet-list .pet-row { display: flex; align-items: center; flex-wrap: wrap; gap: calc(6 * var(--u)); }
.pet-row.on { box-shadow: inset 0 0 0 calc(2 * var(--u)) var(--sage); }
.pet-row .pr-ic { flex: none; width: calc(36 * var(--u)); height: calc(36 * var(--u)); }
.pet-row .pr-ic img, .pet-row .pr-ic .ic { width: 100%; height: 100%; }
.pet-row .nm { flex: 1; min-width: calc(120 * var(--u)); }
.pet-row .nm small { display: block; color: var(--ink-dim); font-size: calc(10 * var(--u)); }
.chip.h-weak, .chip.h-dying { background: var(--coral); }
.chip.h-hungry { background: var(--gold); }

/* K-188f PET EAT (WorldPanels PetEat, user 2026-10-05 final): TWO separate framed panels side by side (pet | bag), stacked <=620px; no x-scroll anywhere */
.pe-wrap { overflow-x: hidden; }
.pe-pair { display: flex; align-items: flex-start; justify-content: center; gap: calc(12 * var(--u)); width: min(calc(800 * var(--u)), 100%); max-height: calc(100vh - calc(32 * var(--u))); min-width: 0; }
.popup.pe-panel { margin: 0; min-width: 0; max-height: calc(100vh - calc(32 * var(--u))); overflow: hidden auto; animation: pop var(--anim-ms) var(--ease); }
.pe-panel .ui-title { position: relative; }
.pe-left { flex: 0 1 calc(280 * var(--u)); width: auto; }
.pe-right { flex: 1 1 calc(420 * var(--u)); width: auto; display: flex; flex-direction: column; }
.pe-pet { display: flex; flex-direction: column; align-items: center; gap: calc(5 * var(--u)); padding: calc(12 * var(--u)) calc(14 * var(--u)) calc(14 * var(--u)); text-align: center; min-width: 0; }
.pe-pet small { color: var(--ink-dim); font-size: calc(11 * var(--u)); }
.pe-nm { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border: 0; background: none; cursor: inherit; padding: 0; font: inherit; font-size: calc(15 * var(--u)); font-weight: 700; color: var(--ink); }
.pe-ring { width: calc(84 * var(--u)); height: calc(84 * var(--u)); cursor: inherit; margin: calc(8 * var(--u)) 0 calc(4 * var(--u)); }
.pe-lv { display: flex; align-items: center; gap: calc(8 * var(--u)); width: 100%; }
.pe-lv > b { font-size: calc(18 * var(--u)); color: var(--blue-dk); min-width: calc(30 * var(--u)); }
.pe-grow { position: relative; flex: 1; min-width: 0; height: calc(16 * var(--u)); border: calc(1.5 * var(--u)) solid var(--line); border-radius: calc(999 * var(--u)); background: var(--cream-dk); overflow: hidden; }
.pe-grow i { position: absolute; inset: 0 auto 0 0; background: var(--blue); }
.pe-grow i.add { background: var(--gold); opacity: .85; animation: pc-blink 1s ease-in-out infinite; }
@keyframes pc-blink { 50% { opacity: .45; } }
.pe-grow span { position: relative; display: block; text-align: center; font-size: calc(10 * var(--u)); line-height: calc(13 * var(--u)); font-weight: 700; color: var(--ink); }
.pe-hunger { width: 100%; height: calc(10 * var(--u)); margin-top: 0; }
.pe-say { position: relative; margin: 0; max-width: 100%; padding: calc(6 * var(--u)) calc(12 * var(--u)); font-size: calc(12 * var(--u)); background: #fff8e6; border: calc(1.5 * var(--u)) solid var(--line); border-radius: calc(12 * var(--u)); overflow-wrap: anywhere; }
.pe-say::after { content: ""; position: absolute; left: 50%; bottom: calc(-7 * var(--u)); width: calc(10 * var(--u)); height: calc(10 * var(--u)); transform: translateX(-50%) rotate(45deg);
  background: #fff8e6; border-right: calc(1.5 * var(--u)) solid var(--line); border-bottom: calc(1.5 * var(--u)) solid var(--line); }
.pe-slot { width: calc(68 * var(--u)); height: calc(68 * var(--u)); margin-top: calc(6 * var(--u)); display: grid; place-items: center; border: calc(2 * var(--u)) dashed var(--brown); border-radius: var(--radius-sm); background: var(--cream-dk); }
.pe-slot > span { font-size: calc(10 * var(--u)); color: var(--ink-dim); }
.pe-slot.full { border-style: solid; }
.pe-slot.craved, .pe-cell.craved .slot { box-shadow: 0 0 0 calc(2 * var(--u)) var(--gold), 0 0 calc(10 * var(--u)) var(--gold); }
.pe-slot .slot { width: 100%; height: 100%; min-height: 0; }
.pe-gain { min-height: calc(14 * var(--u)); }
.pe-act { display: flex; gap: calc(8 * var(--u)); }
.pe-bag { flex: 1; min-width: 0; overflow: hidden auto; padding: calc(12 * var(--u)); max-height: calc(440 * var(--u)); }
.pe-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--slot), 1fr)); gap: calc(6 * var(--u)); min-width: 0; }
.pe-cell { min-width: 0; } .pe-cell .slot { width: 100%; min-width: 0; }
@media (max-width: 620px) {
  .pe-pair { flex-direction: column; align-items: stretch; overflow: hidden auto; }
  .pe-left, .pe-right { flex: none; width: 100%; max-height: none; overflow: visible; }
  .pe-bag { max-height: calc(260 * var(--u)); }
}
.ph-dot { position: absolute; right: calc(-2 * var(--u)); top: calc(-2 * var(--u)); z-index: 1; width: calc(18 * var(--u)); height: calc(18 * var(--u)); border-radius: 50%; display: grid; place-items: center;
  font-size: calc(12 * var(--u)); font-weight: 800; color: #fff; background: var(--coral); border: calc(1.5 * var(--u)) solid var(--line); animation: pc-pulse 1.4s ease-in-out infinite; }

/* K-196 (user 2026-10-05): no text-select highlight, no long-press callout / image drag; text fields stay selectable */
html, body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }
img, canvas { -webkit-user-drag: none; user-drag: none; }
input, textarea, [contenteditable] { -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }
/* K-188g PET EAT: single close X on the bag panel, fully inside the frame (not clipped by overflow / 9-slice corner); "ยังไม่หิว" note */
.pe-panel .ui-close.pe-close { top: calc(10 * var(--u)); right: calc(10 * var(--u)); width: calc(34 * var(--u)); height: calc(34 * var(--u)); }
.pe-right .ui-title { padding-right: calc(52 * var(--u)); }
.pe-full { font-size: calc(12 * var(--u)); color: var(--ink-dim); padding: calc(6 * var(--u)) calc(10 * var(--u)); border: calc(1.5 * var(--u)) dashed var(--brown); border-radius: var(--radius-sm); }
/* K-188h hunger bar: tick at 30 % (feed_below) = from here the pet can eat */
.ph-hunger::after { content: ""; position: absolute; left: 30%; top: 0; bottom: 0; width: calc(1.5 * var(--u)); background: rgba(40, 26, 14, .45); }

/* ============ K-201 buff bar (round steel slots above the hotbar; K-284 no keys, drag onto hotbar) + buff/debuff strip under the vitals bars ============ */
.buffbar { position: absolute; z-index: 4; left: 50%; transform: translateX(-50%); bottom: calc(var(--hotbar-h) + calc(26 * var(--u)) + env(safe-area-inset-bottom));
  display: flex; gap: calc(6 * var(--u)); max-width: calc(100vw - 32px); }
.bb { position: relative; flex: none; width: calc(44 * var(--u)); height: calc(44 * var(--u)); padding: 0; border-radius: 50%; overflow: hidden; cursor: inherit; touch-action: manipulation;
  background: #2b2f36; border: calc(3 * var(--u)) solid #6f7680; box-shadow: inset 0 0 0 calc(2 * var(--u)) #1d2128, 0 calc(3 * var(--u)) 0 #1d2128; display: grid; place-items: center; }
.bb .sk-ic { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; transform: scale(1.18); }
.bb.on { border-color: var(--gold); box-shadow: inset 0 0 0 calc(2 * var(--u)) #1d2128, 0 0 calc(8 * var(--u)) rgba(255, 214, 120, .8), 0 calc(3 * var(--u)) 0 #1d2128; }
.bb.locked .sk-ic { filter: grayscale(.85) brightness(.75); opacity: .8; }
.bb.nomp:not(.locked) .sk-ic { filter: saturate(.4) brightness(.8); }
.bb kbd { position: absolute; z-index: 2; top: 0; left: 50%; transform: translateX(-50%); font-size: calc(10 * var(--u)); font-weight: 700; line-height: 1; color: var(--gold); text-shadow: 0 1px 0 #000, 0 0 2px #000; }
.bb em { position: absolute; z-index: 2; bottom: calc(1 * var(--u)); left: 50%; transform: translateX(-50%); font-style: normal; font-size: calc(10 * var(--u)); font-weight: 700; line-height: 1; color: var(--cream-lt); text-shadow: 0 1px 0 #000, 0 0 2px #000; }
.bb em::before { content: "Lv"; font-size: .8em; opacity: .85; }
.bb .bb-lock { position: absolute; z-index: 2; right: 0; bottom: 0; width: calc(16 * var(--u)); height: calc(16 * var(--u)); filter: drop-shadow(0 1px 1px #000); }
.bb .cd { position: absolute; inset: 0; z-index: 1; border-radius: 50%; display: grid; place-items: center; font-weight: 700; font-size: calc(13 * var(--u)); color: var(--cream-lt);
  background: conic-gradient(rgba(20, 16, 12, .66) calc(var(--cd) * 360deg), transparent 0); }
.bb .cd span { text-shadow: 0 calc(2 * var(--u)) 0 #000; }
.bb:active { transform: translateY(calc(2 * var(--u))); }
.bb:focus-visible { outline: calc(3 * var(--u)) solid var(--blue-dk); outline-offset: calc(2 * var(--u)); }
.gather-hint { bottom: calc(var(--hotbar-h) + calc(84 * var(--u)) + env(safe-area-inset-bottom)); }
.buffstrip { pointer-events: auto; display: flex; flex-wrap: wrap; gap: calc(4 * var(--u)); margin-top: calc(2 * var(--u)); max-width: calc(190 * var(--u)); }
.bf { position: relative; display: flex; flex-direction: column; align-items: center; width: calc(26 * var(--u)); outline: none; }
.bf-ring { position: relative; width: calc(26 * var(--u)); height: calc(26 * var(--u)); border-radius: 50%; display: grid; place-items: center; overflow: hidden;
  background: conic-gradient(#e9c46a calc(var(--p) * 360deg), rgba(40, 30, 20, .45) 0); padding: calc(2 * var(--u)); box-sizing: border-box; }
.bf-ring > * { width: 100% !important; height: 100% !important; border-radius: 50%; background: #2b2f36; object-fit: cover; }
.bf-ring svg.ic.glyph, .bf-ring .ic { padding: calc(3 * var(--u)); box-sizing: border-box; color: var(--cream-lt); }
.bf.de .bf-ring { background: conic-gradient(#e2504a calc(var(--p) * 360deg), rgba(90, 20, 20, .5) 0); }
.bf.de .bf-ring > * { background: #4a2020; }
.bf small { font-size: calc(9 * var(--u)); font-weight: 700; line-height: 1.1; color: var(--line); }
.bf.de small { color: var(--locked); }
.bf:hover::after, .bf:focus::after { content: attr(data-tip); position: absolute; z-index: 20; top: calc(100% + calc(4 * var(--u))); left: 0; width: max-content; max-width: calc(220 * var(--u));
  padding: calc(4 * var(--u)) calc(8 * var(--u)); font-size: calc(11 * var(--u)); line-height: 1.25; white-space: normal; color: var(--cream-lt); background: rgba(29, 33, 40, .94); border: calc(2 * var(--u)) solid #6f7680; border-radius: calc(6 * var(--u)); }
@media (max-width: 620px) {
  .buffbar { bottom: calc(calc(202 * var(--u)) + env(safe-area-inset-bottom)); gap: calc(4 * var(--u)); }   /* above the 3-row phone hotbar (~192u) */
  .bb { width: calc(36 * var(--u)); height: calc(36 * var(--u)); border-width: calc(2 * var(--u)); }
  .bb kbd { display: none; }
  .gather-hint { bottom: calc(calc(256 * var(--u)) + env(safe-area-inset-bottom)); }
  .chat-toggle { bottom: calc(calc(196 * var(--u)) + env(safe-area-inset-bottom)); }   /* was 140u = on the 3-row hotbar top; bar ends left of it */
  .chat-popup { bottom: calc(calc(246 * var(--u)) + env(safe-area-inset-bottom)); }
  .buffstrip { max-width: calc(150 * var(--u)); }
  .bf, .bf-ring { width: calc(22 * var(--u)); } .bf-ring { height: calc(22 * var(--u)); }
}
/* K-211 (user 2026-10-05 "บัฟให้มันมาเรียงนอกกรอบ user status"): buff/debuff strip sits UNDER the vitals frame (outside it), left-aligned with it */
.vitals .buffstrip { position: absolute; top: 100%; left: 0; margin-top: calc(6 * var(--u)); max-width: calc(260 * var(--u)); }
.vitals .buffstrip .bf small { color: #fff; text-shadow: 0 0 calc(2 * var(--u)) #000, 0 calc(1 * var(--u)) 0 #000; }   /* K-211 timer text white (user 2026-10-05), readable on the map now the strip is outside the frame */
/* K-215 auto panel tabs: skill picks (order badge = priority), item pickers (slot grid), collect lines (tool worn hint) */
.au-skills { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(4 * var(--u)); }
.au-skills li { display: flex; gap: calc(4 * var(--u)); align-items: center; }
.au-skill { flex: 1; min-width: 0; position: relative; display: grid; grid-template-columns: auto 1fr; gap: 0 calc(6 * var(--u)); align-items: center; text-align: left;
  padding: calc(4 * var(--u)) calc(30 * var(--u)) calc(4 * var(--u)) calc(6 * var(--u)); background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); color: var(--ink); font: inherit; cursor: inherit; }
.au-skill .sk-ic { grid-row: 1 / 3; width: calc(34 * var(--u)); height: calc(34 * var(--u)); }
.au-skill small { color: var(--ink-dim); font-size: calc(10 * var(--u)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.au-skill.on { border-color: var(--blue-dk); box-shadow: 0 0 0 calc(2 * var(--u)) var(--blue-dk); }
.au-ord { position: absolute; right: calc(6 * var(--u)); top: 50%; translate: 0 -50%; min-width: calc(20 * var(--u)); height: calc(20 * var(--u)); border-radius: 50%;
  background: var(--blue-dk); color: #fff; font-style: normal; font-weight: 700; font-size: calc(11 * var(--u)); display: grid; place-items: center; }
.au-pick { margin-bottom: calc(6 * var(--u)); }
.au-pick h4 { margin: calc(6 * var(--u)) 0 calc(4 * var(--u)); }
.au-collect { display: grid; gap: calc(4 * var(--u)); }
.au-line { display: grid; grid-template-columns: auto 1fr; gap: 0 calc(8 * var(--u)); align-items: center; padding: calc(5 * var(--u)) calc(8 * var(--u));
  background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); }
.au-line input { grid-row: 1 / 3; width: calc(22 * var(--u)); height: calc(22 * var(--u)); min-height: 0; padding: 0; margin: 0; box-shadow: none; accent-color: var(--blue-dk); }
.au-line small { font-size: calc(10 * var(--u)); }

/* K-212 duel HUD (PvpPanels DuelHud): big countdown (K-189 rh-ready count look, larger) + result banner over the scene; fight pill = .downed pill top */
.duel-hud { position: absolute; inset: 0; z-index: 4; pointer-events: none; display: grid; place-items: center; }
.duel-hud .rh-ready.count { position: static; font-size: calc(140 * var(--u)); transform-origin: center; }
.duel-hud .rh-ready.count.go { font-size: calc(100 * var(--u)); }
.duel-banner { font-size: calc(96 * var(--u)); font-weight: 800; letter-spacing: .02em; text-shadow: 0 calc(3 * var(--u)) 0 #2a1d12, 0 0 calc(14 * var(--u)) rgba(0, 0, 0, .45); animation: duelBan 4s ease-out both; margin-top: -42vh; }
.duel-banner.win { color: var(--gold, #e9c45a); }
.duel-banner.lose { color: #b9bcc4; }
.duel-banner.draw { color: var(--cream-lt, #f4efce); }
@keyframes duelBan { 0% { transform: scale(1.9); opacity: 0; } 12% { transform: scale(1); opacity: 1; } 85% { opacity: 1; } 100% { opacity: 0; } }
.downed.duel-pill { top: 16%; display: flex; align-items: center; gap: calc(8 * var(--u)); background: var(--cream-lt); font-weight: 600; }

/* ---- K-219 chat channels + mail (ChatPanels.jsx). Channel colours = ink on cream (chatlog bg), one per channel. ---- */
.chatlog { max-height: calc(220 * var(--u)); }
.chatlog li { line-height: 1.35; overflow-wrap: anywhere; }
.chatlog li.notice { color: var(--ink-dim); font-style: italic; }
.chat-tag, .chat-dir { font-weight: 700; font-size: .9em; }
.chat-name { padding: 0; font: inherit; font-weight: 700; color: var(--blue-dk); background: none; border: 0; cursor: inherit; text-decoration: underline dotted; }
.ch-world .chat-tag, .chat-to.ch-world { color: #b4570f; }
.ch-party .chat-tag, .chat-to.ch-party { color: #2c66a8; }
.ch-guild .chat-tag, .chat-to.ch-guild { color: #2f7d32; }
.ch-whisper .chat-tag, .ch-whisper .chat-dir, .chat-to.ch-whisper { color: #a3367f; }
.ch-whisper { background: rgba(163, 54, 127, .07); }
.ch-system .chat-tag { color: #9a6a00; }
.chat-to { flex: none; align-self: center; max-width: calc(84 * var(--u)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: calc(12 * var(--u)); font-weight: 700; display: inline-flex; align-items: center; gap: calc(2 * var(--u)); }
.chat-to button { padding: 0; width: calc(18 * var(--u)); height: calc(18 * var(--u)); background: none; border: 0; color: inherit; cursor: inherit; }
.chat-to .ic { width: calc(14 * var(--u)); height: calc(14 * var(--u)); }
.chatbox input { min-width: 0; }
  border-radius: calc(10 * var(--u)); background: var(--coral); color: #fff; font-size: calc(11 * var(--u)); font-weight: 700; display: grid; place-items: center; border: calc(2 * var(--u)) solid var(--line); }
.mail-panel .note.ok { color: #2f7d32; font-weight: 600; }
.mail-acc { display: flex; flex-direction: column; gap: calc(6 * var(--u)); max-height: calc(440 * var(--u)); overflow-y: auto; padding-right: calc(2 * var(--u)); }   /* user 2026-10-13 accordion inbox */
.mail-none { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(8 * var(--u)); padding: calc(24 * var(--u)) 0; text-align: center; color: var(--ink-dim); }
.mail-none img { width: calc(140 * var(--u)); height: calc(140 * var(--u)); object-fit: contain; }
.mail-none b { font-size: calc(15 * var(--u)); }
.mail-item { background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--cream-dk); border-radius: var(--radius-sm); }
.mail-item.open { border-color: var(--brass, #b8862f); }
.mail-row { position: relative; width: 100%; display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; column-gap: calc(8 * var(--u));
  text-align: left; padding: calc(8 * var(--u)) calc(10 * var(--u)); background: none; border: 0; font: inherit; color: var(--ink); cursor: pointer; }
.mail-row .ic { width: calc(26 * var(--u)); height: calc(26 * var(--u)); }
.mail-row .mail-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.mail-item.unread .mail-sub { font-weight: 800; }
.mail-item.unread .mail-row::after { content: ''; position: absolute; left: calc(4 * var(--u)); top: calc(4 * var(--u)); width: calc(8 * var(--u)); height: calc(8 * var(--u)); border-radius: 50%; background: var(--coral); }
.mail-row small { color: var(--ink-dim); font-size: calc(11 * var(--u)); white-space: nowrap; display: flex; align-items: center; gap: calc(4 * var(--u)); }
.mail-chev { width: calc(8 * var(--u)); height: calc(8 * var(--u)); border-right: calc(2 * var(--u)) solid var(--ink-dim); border-bottom: calc(2 * var(--u)) solid var(--ink-dim); rotate: 45deg; transition: rotate .15s; margin: 0 calc(4 * var(--u)); }
.mail-item.open .mail-chev { rotate: 225deg; }
.mail-item .mail-view { padding: 0 calc(10 * var(--u)) calc(10 * var(--u)); border-top: calc(1 * var(--u)) solid var(--cream-dk); }
.mail-view h3 { margin: 0; }
.mail-view .sub { margin: calc(2 * var(--u)) 0 calc(8 * var(--u)); color: var(--ink-dim); font-size: calc(12 * var(--u)); }
.mail-body { white-space: pre-wrap; overflow-wrap: anywhere; background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--cream-dk); border-radius: var(--radius-sm); padding: calc(8 * var(--u)); margin: 0 0 calc(8 * var(--u)); }
.mail-compose textarea { width: 100%; resize: vertical; font: inherit; }
@media (max-width: 620px) {
  .chatlog { max-height: calc(170 * var(--u)); }
}

/* K-213 guild war: panel state line, owner chip, chest card, in-castle HUD banner, capture flash, end card, town owner tag, war screen edge */
.gw-state { padding: calc(6 * var(--u)) calc(10 * var(--u)); margin-bottom: calc(8 * var(--u)); border-radius: calc(8 * var(--u)); background: rgba(139, 107, 78, .15); }
.gw-state.live { background: rgba(208, 87, 74, .22); }
.gw-owner { display: inline-flex; align-items: center; gap: calc(6 * var(--u)); font-weight: 700; }
.gw-owner i { width: calc(12 * var(--u)); height: calc(12 * var(--u)); border-radius: 50%; border: calc(2 * var(--u)) solid rgba(30, 20, 10, .6); }
.gw-chest { display: flex; align-items: center; justify-content: space-between; gap: calc(8 * var(--u)); margin-top: calc(8 * var(--u)); }
.gw-wing { display: flex; align-items: center; gap: calc(6 * var(--u)); margin-top: calc(8 * var(--u)); cursor: pointer; }   /* K-616 castle wing toggle */
.gw-hud { position: absolute; top: calc(10 * var(--u)); left: 50%; transform: translateX(-50%); z-index: 4; min-width: calc(300 * var(--u)); pointer-events: none;
  padding: calc(8 * var(--u)) calc(14 * var(--u)); border-radius: calc(10 * var(--u)); background: rgba(40, 26, 16, .82); color: var(--cream-lt, #f4efce);
  border: calc(2 * var(--u)) solid #c9a227; font-size: calc(13 * var(--u)); text-align: center; }
.gw-hud-top { display: flex; justify-content: space-between; gap: calc(12 * var(--u)); }
.gw-hud-row { margin: calc(3 * var(--u)) 0; }
.gw-hp { position: relative; height: calc(16 * var(--u)); border-radius: calc(4 * var(--u)); background: rgba(0, 0, 0, .5); overflow: hidden; }
.gw-hp i { position: absolute; inset: 0 auto 0 0; background: linear-gradient(#f0cc6a, #c9a227); }
.gw-hp b { position: relative; font-size: calc(11 * var(--u)); }
.gw-flash { position: absolute; inset: 0; z-index: 3; pointer-events: none; background: radial-gradient(circle, rgba(255, 240, 190, .55), rgba(255, 240, 190, 0) 70%); animation: gwFlash 1.2s ease-out forwards; }
@keyframes gwFlash { 0% { opacity: 1; } 100% { opacity: 0; } }
.gw-result { position: absolute; top: 22%; left: 50%; transform: translateX(-50%); z-index: 6; min-width: calc(280 * var(--u)); padding: calc(14 * var(--u)) calc(18 * var(--u));
  border-radius: calc(12 * var(--u)); background: var(--cream-lt, #f4efce); color: var(--ink, #3b2a1f); border: calc(3 * var(--u)) solid #c9a227; text-align: center; }
.gw-result h3 { margin: 0 0 calc(8 * var(--u)); }
.gw-res-row { display: flex; justify-content: space-between; gap: calc(16 * var(--u)); padding: calc(3 * var(--u)) 0; border-bottom: calc(1 * var(--u)) solid rgba(139, 107, 78, .25); }
.zonetag.gw-own { background: #7a5a1e; border: calc(2 * var(--u)) solid #e0b84a; }
.zone-edge.z-null { box-shadow: inset 0 0 calc(80 * var(--u)) rgba(201, 162, 39, .35); }
/* ---- K-220 achievements + collection book (ui/AchievementPanels.jsx). Tier colours: --bronze/--silver (theme.css) + --gold ---- */
.ach-head, .ach-cats, .ach-list, .ach-row, .book-head, .book-grid, .book-detail { flex: none; }
.ach-head { display: flex; flex-wrap: wrap; align-items: center; gap: calc(8 * var(--u)); margin-bottom: calc(8 * var(--u)); }
.ach-pick { display: inline-flex; align-items: center; gap: calc(6 * var(--u)); font-size: calc(13 * var(--u)); }
.ach-pick select { font: inherit; max-width: calc(170 * var(--u)); padding: calc(3 * var(--u)) calc(6 * var(--u)); color: var(--ink); background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); border-radius: var(--radius-sm); }
.ach-frames { display: inline-flex; flex-wrap: wrap; gap: calc(4 * var(--u)); }
.ach-sw { width: calc(24 * var(--u)); height: calc(24 * var(--u)); padding: 0; border-radius: 50%; border: calc(2 * var(--u)) solid var(--line); cursor: inherit; }
.ach-sw.none { background: var(--cream-dk); }
.ach-sw.on { outline: calc(3 * var(--u)) solid var(--blue-dk); outline-offset: calc(1 * var(--u)); }
.ach-cats { display: flex; gap: calc(6 * var(--u)); overflow-x: auto; padding-bottom: calc(6 * var(--u)); margin-bottom: calc(6 * var(--u)); }   /* K-366 Firefox scrollbar-width at end */
.ach-cats button { flex: none; display: flex; flex-direction: column; align-items: center; gap: calc(2 * var(--u)); min-width: calc(58 * var(--u)); padding: calc(4 * var(--u)); font: inherit; font-size: calc(11 * var(--u)); color: var(--ink); background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); border-radius: var(--radius-sm); cursor: inherit; }
.ach-cats button.on { background: var(--gold); }
.ach-cats .ic { width: calc(26 * var(--u)); height: calc(26 * var(--u)); }
.ach-row { display: flex; align-items: center; gap: calc(10 * var(--u)); padding: calc(6 * var(--u)) calc(8 * var(--u)); background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); border-radius: var(--radius-sm); }
.ach-row.done { opacity: .72; }
.ach-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: calc(3 * var(--u)); }
.ach-body .nm { display: flex; align-items: center; gap: calc(6 * var(--u)); font-weight: 600; }
.ach-body .meta { font-size: calc(12 * var(--u)); color: var(--ink-dim); }
.ach-pips { display: inline-flex; gap: calc(3 * var(--u)); }
/* K-411 tier medals (ui2/ach/medal_*.png): pip N = medal N, grey until reached (class bronze/silver/gold = reached) */
.ach-pips i { width: calc(16 * var(--u)); height: calc(16 * var(--u)); background: url(/assets/ui2/ach/medal_bronze.png) center / contain no-repeat; filter: grayscale(1) opacity(.4); }
.ach-pips i:nth-child(2) { background-image: url(/assets/ui2/ach/medal_silver.png); } .ach-pips i:nth-child(3) { background-image: url(/assets/ui2/ach/medal_gold.png); }
.ach-pips i.bronze, .ach-pips i.silver, .ach-pips i.gold { filter: none; }
.ach-badge { flex: none; display: grid; place-items: center; width: calc(52 * var(--u)); height: calc(52 * var(--u)); border-radius: 50%; background: var(--cream-lt); border: calc(4 * var(--u)) solid var(--cream-dk); box-shadow: 0 0 0 calc(2 * var(--u)) var(--line), var(--gloss); }
.ach-badge .ic { width: calc(34 * var(--u)); height: calc(34 * var(--u)); }
.ach-badge.none .ic { filter: grayscale(1) opacity(.55); }
.ach-badge.bronze { border-color: var(--bronze, #C38A5C); }
.ach-badge.silver { border-color: var(--silver, #B8C3CC); }
.ach-badge.gold { border-color: var(--gold); background: var(--cream); }
.ach-pop { position: fixed; z-index: 60; top: calc(90 * var(--u)); left: 50%; display: flex; align-items: center; gap: calc(10 * var(--u)); max-width: calc(100vw - 32px); padding: calc(8 * var(--u)) calc(16 * var(--u)); background: var(--cream); border: var(--line-w) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); pointer-events: none; animation: ach-pop 4s var(--ease) both; }
.ach-pop small { display: block; font-size: calc(12 * var(--u)); color: var(--ink-dim); }
.ach-pop b { font-size: calc(17 * var(--u)); }
@keyframes ach-pop { 0% { opacity: 0; transform: translate(-50%, calc(-20 * var(--u))) scale(.9); } 8%, 85% { opacity: 1; transform: translate(-50%, 0) scale(1); } 100% { opacity: 0; transform: translate(-50%, calc(-10 * var(--u))); } }
.book-head { display: flex; flex-direction: column; gap: calc(6 * var(--u)); margin-bottom: calc(8 * var(--u)); }
.book-head .bar { height: calc(22 * var(--u)); }
.book-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(72 * var(--u)), 1fr)); gap: calc(6 * var(--u)); }
.book-cell { display: flex; flex-direction: column; align-items: center; gap: calc(2 * var(--u)); padding: calc(6 * var(--u)) calc(2 * var(--u)); font: inherit; color: var(--ink); background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); border-radius: var(--radius-sm); cursor: inherit; content-visibility: auto; contain-intrinsic-size: calc(80 * var(--u)); }
.book-cell .ic { width: calc(40 * var(--u)); height: calc(40 * var(--u)); }
.book-cell small { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: calc(10 * var(--u)); line-height: 1.2; text-align: center; word-break: break-word; }
.book-cell.locked .ic { filter: brightness(0) opacity(.35); }
.book-cell.locked small { color: var(--ink-dim); }
.book-cell.on { background: var(--blue); }
.book-detail { display: flex; flex-direction: column; gap: calc(3 * var(--u)); margin-top: calc(8 * var(--u)); padding: calc(8 * var(--u)) calc(12 * var(--u)); }
.book-detail .meta { font-size: calc(12 * var(--u)); color: var(--ink-dim); }

/* K-217 tutorial coach (TutorialCoach.jsx): parchment card LEFT column under .vitals (top-centre = toast/request stack: duel/party/trade
   popups must stay clickable, K-212 QA 2026-10-06); z 5 = under .toasts (6) + dialogue (12). Glow + bouncing arrow on the step's UI anchor. */
.tut-coach {
  position: absolute; z-index: 5; top: calc(108 * var(--u) + env(safe-area-inset-top)); left: calc(12 * var(--u));
  width: min(calc(330 * var(--u)), calc(100vw - 32px)); padding: calc(4 * var(--u)) calc(6 * var(--u)); color: var(--ink, #3b2a1f);
  border-style: solid; border-color: transparent; border-width: var(--pnl-t) var(--pnl-r) var(--pnl-b) var(--pnl-l);
  border-image: url(/assets/ui3/panel.webp) var(--pnl-slice) fill / var(--pnl-t) var(--pnl-r) var(--pnl-b) var(--pnl-l) / 0 stretch round;
  filter: drop-shadow(0 calc(4 * var(--u)) calc(5 * var(--u)) rgba(40, 26, 14, .3)); animation: pop var(--anim-ms) var(--ease); pointer-events: auto;
}
.tut-coach header { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.tut-coach header b { color: var(--brown, #6b4a2b); }
.tut-coach header small { opacity: .7; margin-right: auto; }
.tut-coach .tut-title { margin: calc(4 * var(--u)) 0 0; font-weight: 700; font-size: calc(19 * var(--u)); }
.tut-coach .tut-hint { margin: calc(2 * var(--u)) 0 calc(4 * var(--u)); font-size: calc(15 * var(--u)); line-height: 1.35; }
.tut-glow { outline: calc(3 * var(--u)) solid #f2c84b !important; outline-offset: calc(2 * var(--u)); border-radius: calc(10 * var(--u)); animation: tut-glow 1.1s ease-in-out infinite; }
@keyframes tut-glow { 50% { outline-color: rgba(242, 200, 75, .25); box-shadow: 0 0 calc(18 * var(--u)) rgba(242, 200, 75, .8); } }
.tut-arrow { position: fixed; z-index: 13; width: 0; height: 0; pointer-events: none; border: calc(14 * var(--u)) solid transparent; filter: drop-shadow(0 calc(2 * var(--u)) calc(2 * var(--u)) rgba(40, 26, 14, .5)); }
.tut-arrow.down { border-top-color: #f2c84b; border-bottom: 0; transform: translate(-50%, -100%); animation: tut-bob-y .8s ease-in-out infinite; }
.tut-arrow.right { border-left-color: #f2c84b; border-right: 0; transform: translate(-100%, -50%); animation: tut-bob-x .8s ease-in-out infinite; }
@keyframes tut-bob-y { 50% { margin-top: calc(-8 * var(--u)); } }
@keyframes tut-bob-x { 50% { margin-left: calc(-8 * var(--u)); } }

/* K-223 stall v2 (StallPanel.jsx), K-226 PairPanels. LEFT .st-shop panel: head (name / count / open-close
   or my Acorn) -> long listing rows (<= social_policy.stall_slots) -> chat log | "กำลังดู" column, input under. RIGHT = bag. <=620px stacked. */
.st-head { display: flex; align-items: center; gap: calc(6 * var(--u)); }
.st-head h4 { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-head input { flex: 1; min-width: 0; }
.st-head .st-count { margin-left: 0; font-variant-numeric: tabular-nums; }
.st-head .chip .ic { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
.st-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: calc(4 * var(--u)); max-height: calc(300 * var(--u)); overflow-y: auto; }   /* knob: rows area height (mobile/short screens) */
.st-row { display: grid; grid-template-columns: calc(40 * var(--u)) minmax(0, 1fr) auto auto; align-items: center; gap: calc(4 * var(--u)) calc(8 * var(--u));
  padding: calc(1 * var(--u)) calc(8 * var(--u)) calc(1 * var(--u)) calc(3 * var(--u)); border: calc(4 * var(--u)) solid transparent;
  border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch; flex: none; }
.st-row .slot { width: calc(40 * var(--u)); min-height: 0; cursor: inherit; }
.st-row.empty-row { grid-template-columns: calc(40 * var(--u)) minmax(0, 1fr); opacity: .6; }
.st-info { display: flex; flex-direction: column; min-width: 0; }
.st-info b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-info .note, .st-price .note { font-size: calc(12 * var(--u)); }
.st-price { display: flex; flex-direction: column; align-items: flex-end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.st-price .pp { display: inline-flex; align-items: center; gap: calc(3 * var(--u)); font-weight: 700; }
.st-price .pp .ic { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
.st-price small { font-weight: 500; color: var(--ink-dim); font-size: calc(11 * var(--u)); }
.st-act { display: flex; gap: calc(4 * var(--u)); }
.st-act .btn .ic { width: calc(16 * var(--u)); height: calc(16 * var(--u)); }
.st-chat { display: grid; grid-template-columns: minmax(0, 1fr) calc(124 * var(--u)); grid-template-areas: 'log who' 'say say'; gap: calc(6 * var(--u)); flex: none; }
.st-log { grid-area: log; height: calc(96 * var(--u)); max-height: none; font-size: calc(13 * var(--u)); }   /* knob: chat log height */
.st-log b.own { color: var(--gold-dk); }
.st-viewers { grid-area: who; height: calc(96 * var(--u)); overflow-y: auto; padding: calc(6 * var(--u)) calc(8 * var(--u)); font-size: calc(12 * var(--u)); }
.st-viewers > b { display: flex; align-items: center; gap: calc(4 * var(--u)); font-weight: 600; }
.st-viewers .ic { width: calc(16 * var(--u)); height: calc(16 * var(--u)); }
.st-viewers ul { list-style: none; margin: calc(4 * var(--u)) 0 0; padding: 0; }
.st-viewers li { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stc-say { grid-area: say; flex-direction: row; align-items: center; }   /* .st-say = another panel bubble, keep the name apart */
.st-modal { display: flex; flex-direction: column; gap: calc(8 * var(--u)); padding: 0 calc(12 * var(--u)); }
.st-mitem { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.st-mitem .slot { width: calc(48 * var(--u)); flex: none; cursor: inherit; }
.st-mitem .note { margin-left: auto; }
.st-total { display: flex; align-items: center; gap: calc(4 * var(--u)); margin: 0; font-variant-numeric: tabular-nums; }
.st-total .ic { width: calc(20 * var(--u)); height: calc(20 * var(--u)); }
@media (max-width: 620px) {
  .st-row { grid-template-columns: calc(40 * var(--u)) minmax(0, 1fr) auto; grid-template-areas: 'ic info info' 'ic price act'; }   /* phone: name full width, price + buttons under */
  .st-row > .slot { grid-area: ic; } .st-row .st-info { grid-area: info; } .st-row .st-price { grid-area: price; flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 0 calc(6 * var(--u)); justify-self: start; min-width: 0; white-space: normal; }
  .st-row .slot { width: calc(40 * var(--u)); }
  .st-act { grid-area: act; justify-content: flex-end; }
  .st-row.empty-row { grid-template-areas: none; }
  .st-chat { grid-template-columns: minmax(0, 1fr) calc(96 * var(--u)); }
  .st-list { max-height: none; }
}
@media (max-width: 620px) { .tut-coach { width: min(62vw, calc(330 * var(--u))); } }
.game:has(.toast.act) .tut-coach { visibility: hidden; }   /* K-217: request popup (duel/party/trade) up -> coach steps aside (phone overlap) */

/* K-226 PairPanels (Panels.jsx; bank StoragePanel / StallPanel / NpcShopPanel): pe-* pair (K-188f) sized for two working panes. Desktop = fixed
   tall pair, grids / listing rows take the free height and scroll inside; <=620px stacked, .pe-pair scrolls. .pp-body = panel content box. */
.pp-wrap .pe-pair { width: min(calc(1000 * var(--u)), 100%); height: min(calc(100vh - calc(32 * var(--u))), calc(720 * var(--u))); align-items: stretch; }   /* knob: pair size */
.pp-wrap .pe-left { flex: 1 1 calc(500 * var(--u)); display: flex; flex-direction: column; overflow: hidden; }
.pp-wrap .pe-right { flex: 1 1 calc(420 * var(--u)); overflow: hidden; }
.pp-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: calc(8 * var(--u)); padding: calc(12 * var(--u)); overflow: hidden auto; }
.pp-body .bag-scroll { flex: 1 1 auto; min-height: calc(120 * var(--u)); overflow-y: auto; }
.pp-body .st-list { flex: 1 1 auto; min-height: calc(80 * var(--u)); max-height: none; }
.pp-body .st-chat { flex: none; }
.pp-bar { display: flex; align-items: center; gap: calc(8 * var(--u)); font-variant-numeric: tabular-nums; }
.pp-bar .btn { margin-left: auto; }
.st-tabs .btn { white-space: nowrap; flex: 1 1 0; } .st-tabs .btn.shut { opacity: .5; }   /* tabs = .seg.set-tabs (settings look) */ .st-shut { display: flex; flex-wrap: wrap; align-items: center; gap: calc(6 * var(--u)); margin: 0; }   /* K-662 storage tabs */
.sell-sum { display: flex; align-items: center; justify-content: space-between; gap: calc(8 * var(--u)); flex-wrap: wrap; }
.pp-body .seg .btn .ic { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
@media (max-width: 620px) {
  .pp-wrap .pe-pair { height: auto; }
  .pp-wrap .pe-left, .pp-wrap .pe-right { flex: none; overflow: visible; }
  .pp-body { overflow: visible; }
  .pp-body .bag-scroll { flex: none; max-height: calc(220 * var(--u)); }   /* knob: phone grid height */
  .pp-body .st-list { flex: none; max-height: calc(300 * var(--u)); }
}

/* K-237 stall list modal: qty stepper row [- input + MAX] + price display above the NumPad */
.st-qty { display: grid; grid-template-columns: minmax(0, 1fr); gap: calc(4 * var(--u)); }   /* K-397: label line, then [- input + MAX] */
.st-qty-row > .btn { flex: none; }
.st-qty-row { display: flex; align-items: center; gap: calc(6 * var(--u)); }
.st-qty-row input { flex: 1 1 0; width: auto; min-width: calc(70 * var(--u)); padding-left: calc(4 * var(--u)); padding-right: calc(4 * var(--u)); text-align: center; font-variant-numeric: tabular-nums; }
.st-field { display: flex; align-items: baseline; justify-content: space-between; gap: calc(8 * var(--u)); padding: calc(6 * var(--u)) calc(10 * var(--u));
  border: calc(4 * var(--u)) solid transparent; border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch; }
.st-field small { color: var(--ink-dim); font-size: calc(12 * var(--u)); }
.st-field b { font-size: calc(20 * var(--u)); font-variant-numeric: tabular-nums; }

/* ============ K-238 loading screen (ui/LoadingScreen.jsx) + map title ============ */
.loading-screen { position: fixed; inset: 0; z-index: 100; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(24 * var(--u));
  padding: 0 16px; overflow: hidden; color: var(--cream-lt); transition: opacity .45s ease;
  background: radial-gradient(ellipse at 50% 55%, rgba(40, 27, 16, .25) 0%, rgba(22, 15, 9, .78) 62%, rgba(12, 8, 5, .96) 100%), #2a1d12 url(/assets/ui2/login_bg_k344.webp?v=k344) center / cover no-repeat; }
.loading-screen.out { opacity: 0; pointer-events: none; }
.loading-screen .logo { width: min(calc(240 * var(--u)), 50vw, 28vh); height: auto;   /* K-243 square emblem */ filter: drop-shadow(0 calc(6 * var(--u)) calc(10 * var(--u)) rgba(0, 0, 0, .5)); }
.ld-mid { width: min(calc(600 * var(--u)), 100%); padding: 0 calc(30 * var(--u)); display: flex; flex-direction: column; align-items: center; gap: calc(10 * var(--u)); }
.ld-track { position: relative; width: 100%; margin-top: calc(130 * var(--u)); }   /* room above the bar for the runner */
.ld-runner { position: absolute; bottom: calc(100% - 10 * var(--u)); left: 0; transform: translateX(-50%); pointer-events: none; }
.ld-rig { display: block; width: calc(120 * var(--u)); height: calc(140 * var(--u)); }
.ld-bar { position: relative; height: calc(38 * var(--u)); padding: calc(5 * var(--u));   /* steel inset frame (border-box: fill = 38 - 2x6 - 2x5 = 16u), brass fill */
  border: calc(6 * var(--u)) solid transparent; border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch; }
.ld-bar i { display: block; width: 0; height: 100%; border-radius: calc(999 * var(--u)); min-width: calc(6 * var(--u));
  background: linear-gradient(#ffe7a0, var(--gold) 45%, var(--gold-dk)); box-shadow: inset 0 calc(2 * var(--u)) 0 rgba(255, 255, 255, .55), 0 0 calc(6 * var(--u)) rgba(232, 197, 106, .55); }
.ld-pct { font-size: calc(22 * var(--u)); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--gold); text-shadow: 0 calc(2 * var(--u)) 0 #1c130b; }
.ld-line { display: flex; align-items: center; justify-content: center; box-sizing: border-box; min-height: 3em; margin: 0; max-width: 100%; padding: calc(6 * var(--u)) calc(16 * var(--u)); border-radius: calc(12 * var(--u)); background: rgba(20, 13, 8, .55); text-align: center; font-size: calc(17 * var(--u)); line-height: 1.5; color: var(--cream-lt);
  text-shadow: 0 calc(2 * var(--u)) 0 #1c130b; animation: ld-line 3.6s ease both; overflow-wrap: anywhere; }
.ld-line em { font-style: normal; font-weight: 700; color: var(--gold); }
@keyframes ld-line { 0% { opacity: 0; transform: translateY(calc(4 * var(--u))); } 12%, 86% { opacity: 1; transform: none; } 100% { opacity: 0; } }
.map-title { position: fixed; inset: 0; z-index: 90; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(8 * var(--u));
  padding: 0 16px; margin-top: -18vh; text-align: center; pointer-events: none; animation: map-title 3.6s ease both; }   /* in .36 s, hold ~1.5 s, slow out ~1.7 s */
.map-title b { max-width: 100%; font-size: min(calc(60 * var(--u)), 10vw); font-weight: 700; line-height: 1.2; color: var(--cream-lt); overflow-wrap: anywhere;
  text-shadow: 0 calc(3 * var(--u)) 0 #2a1d12, 0 0 calc(18 * var(--u)) rgba(0, 0, 0, .6); }
.map-title i { width: min(calc(260 * var(--u)), 70vw); height: calc(42 * var(--u)); background: url(/assets/ui3/divider.png) center / contain no-repeat; }
.map-title .zonetag { height: calc(32 * var(--u)); font-size: calc(16 * var(--u)); }
@keyframes map-title { 0% { opacity: 0; transform: scale(.94); } 10% { opacity: 1; transform: none; } 52% { opacity: 1; } 100% { opacity: 0; } }
@media (max-width: 620px) { .ld-mid { padding: 0 calc(40 * var(--u)); }   /* runner sword tip stays on screen at 100% */ .ld-line { font-size: calc(15 * var(--u)); } }

/* K-240 cursors (game/assets/cursors/<name>-32|64.png, design/ui-ref/k240-cursors.py). Hotspot = 32px coords (knob; 64 = 2x art, browsers scale the hotspot by the image-set density).
   3 declarations = cascade fallback: plain url (all) -> -webkit-image-set (Safari 6+, Chrome, Firefox 90+) -> image-set (Chrome 113+, Firefox 89+, Safari 17+); unparsed one is dropped, last parsed wins.
   NO var(): a var()-built cursor that fails = unset, not the previous declaration. Canvas kind = canvas[data-cur] set by three/game.js hoverCursor (K-240); other UI cursor rules in this file = inherit (-> html normal).
   Native HTML5 drag: the OS owns the cursor while dragging -> drag shows on press ([draggable]:active) only. Touch: cursors never show. */
html { cursor: url(/assets/cursors/normal-32.png) 6 2, default;
  cursor: -webkit-image-set(url(/assets/cursors/normal-32.png) 1x, url(/assets/cursors/normal-64.png) 2x) 6 2, default;
  cursor: image-set(url(/assets/cursors/normal-32.png) 1x, url(/assets/cursors/normal-64.png) 2x) 6 2, default; }
canvas[data-cur=talk] { cursor: url(/assets/cursors/talk-32.png) 16 16, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/talk-32.png) 1x, url(/assets/cursors/talk-64.png) 2x) 16 16, pointer;
  cursor: image-set(url(/assets/cursors/talk-32.png) 1x, url(/assets/cursors/talk-64.png) 2x) 16 16, pointer; }
canvas[data-cur=warp] { cursor: url(/assets/cursors/warp-32.png) 16 16, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/warp-32.png) 1x, url(/assets/cursors/warp-64.png) 2x) 16 16, pointer;
  cursor: image-set(url(/assets/cursors/warp-32.png) 1x, url(/assets/cursors/warp-64.png) 2x) 16 16, pointer; }
canvas[data-cur=attack] { cursor: url(/assets/cursors/attack-32.png) 3 2, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/attack-32.png) 1x, url(/assets/cursors/attack-64.png) 2x) 3 2, pointer;
  cursor: image-set(url(/assets/cursors/attack-32.png) 1x, url(/assets/cursors/attack-64.png) 2x) 3 2, pointer; }
canvas[data-cur=wood] { cursor: url(/assets/cursors/wood-32.png) 3 8, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/wood-32.png) 1x, url(/assets/cursors/wood-64.png) 2x) 3 8, pointer;
  cursor: image-set(url(/assets/cursors/wood-32.png) 1x, url(/assets/cursors/wood-64.png) 2x) 3 8, pointer; }
canvas[data-cur=ore] { cursor: url(/assets/cursors/ore-32.png) 10 6, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/ore-32.png) 1x, url(/assets/cursors/ore-64.png) 2x) 10 6, pointer;
  cursor: image-set(url(/assets/cursors/ore-32.png) 1x, url(/assets/cursors/ore-64.png) 2x) 10 6, pointer; }
canvas[data-cur=herb] { cursor: url(/assets/cursors/herb-32.png) 2 11, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/herb-32.png) 1x, url(/assets/cursors/herb-64.png) 2x) 2 11, pointer;
  cursor: image-set(url(/assets/cursors/herb-32.png) 1x, url(/assets/cursors/herb-64.png) 2x) 2 11, pointer; }
canvas[data-cur=skin] { cursor: url(/assets/cursors/skin-32.png) 4 2, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/skin-32.png) 1x, url(/assets/cursors/skin-64.png) 2x) 4 2, pointer;
  cursor: image-set(url(/assets/cursors/skin-32.png) 1x, url(/assets/cursors/skin-64.png) 2x) 4 2, pointer; }
canvas[data-cur=loot] { cursor: url(/assets/cursors/loot-32.png) 16 16, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/loot-32.png) 1x, url(/assets/cursors/loot-64.png) 2x) 16 16, pointer;
  cursor: image-set(url(/assets/cursors/loot-32.png) 1x, url(/assets/cursors/loot-64.png) 2x) 16 16, pointer; }
canvas[data-cur=fish] { cursor: url(/assets/cursors/fish-32.png) 5 3, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/fish-32.png) 1x, url(/assets/cursors/fish-64.png) 2x) 5 3, pointer;
  cursor: image-set(url(/assets/cursors/fish-32.png) 1x, url(/assets/cursors/fish-64.png) 2x) 5 3, pointer; }
canvas[data-cur=craft] { cursor: url(/assets/cursors/craft-32.png) 16 16, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/craft-32.png) 1x, url(/assets/cursors/craft-64.png) 2x) 16 16, pointer;
  cursor: image-set(url(/assets/cursors/craft-32.png) 1x, url(/assets/cursors/craft-64.png) 2x) 16 16, pointer; }
canvas[data-cur=pet] { cursor: url(/assets/cursors/pet-32.png) 16 16, pointer;
  cursor: -webkit-image-set(url(/assets/cursors/pet-32.png) 1x, url(/assets/cursors/pet-64.png) 2x) 16 16, pointer;
  cursor: image-set(url(/assets/cursors/pet-32.png) 1x, url(/assets/cursors/pet-64.png) 2x) 16 16, pointer; }
canvas[data-cur=disabled], .sb-row.locked, .sb-row.unlearned, .ph-b:disabled { cursor: url(/assets/cursors/disabled-32.png) 3 2, not-allowed;
  cursor: -webkit-image-set(url(/assets/cursors/disabled-32.png) 1x, url(/assets/cursors/disabled-64.png) 2x) 3 2, not-allowed;
  cursor: image-set(url(/assets/cursors/disabled-32.png) 1x, url(/assets/cursors/disabled-64.png) 2x) 3 2, not-allowed; }
canvas[data-cur=drag], [draggable=true]:active { cursor: url(/assets/cursors/drag-32.png) 16 16, grabbing;
  cursor: -webkit-image-set(url(/assets/cursors/drag-32.png) 1x, url(/assets/cursors/drag-64.png) 2x) 16 16, grabbing;
  cursor: image-set(url(/assets/cursors/drag-32.png) 1x, url(/assets/cursors/drag-64.png) 2x) 16 16, grabbing; }
input:not([type=range], [type=checkbox], [type=radio], [type=color], [type=button], [type=submit]), textarea, [contenteditable=true] { cursor: url(/assets/cursors/text-32.png) 15 16, text;
  cursor: -webkit-image-set(url(/assets/cursors/text-32.png) 1x, url(/assets/cursors/text-64.png) 2x) 15 16, text;
  cursor: image-set(url(/assets/cursors/text-32.png) 1x, url(/assets/cursors/text-64.png) 2x) 15 16, text; }

/* K-242 fishing session HUD (WorldPanels FishHud / FishPop / FishSummary), catch rows icon + name + count.
   K-288: HUD button = child of .hotbar, centred just above it (desktop bottom-centre bar + phone bottom-right grid); popup centred on screen. */
.hotbar > .fishbar { position: absolute; left: 50%; bottom: 100%; transform: translateX(-50%); margin-bottom: calc(8 * var(--u)); pointer-events: auto; }
.fish-btn { position: relative; overflow: visible; display: grid; place-items: center; width: calc(42 * var(--u)); height: calc(42 * var(--u)); cursor: pointer; min-height: 0; }
.fish-btn .ic { width: calc(28 * var(--u)); height: calc(28 * var(--u)); }
.fish-btn b { position: absolute; top: calc(-8 * var(--u)); right: calc(-6 * var(--u)); font-size: calc(18 * var(--u)); font-weight: 900; color: #ffd04b;
  text-shadow: 0 0 calc(2 * var(--u)) #3b2a1f, 0 calc(1 * var(--u)) 0 #3b2a1f; animation: fish-bang .5s ease-in-out infinite alternate; }
@keyframes fish-bang { to { transform: translateY(calc(-3 * var(--u))) scale(1.15); } }
.fish-pop.float { position: fixed; z-index: 15; inset: 0; margin: auto; height: fit-content; max-height: calc(100% - 32px); overflow-y: auto;
  width: min(calc(380 * var(--u)), calc(100vw - 32px)); animation: pop var(--anim-ms) var(--ease); }
.fp-rod { display: flex; flex-direction: column; align-items: center; gap: calc(4 * var(--u)); padding: calc(4 * var(--u)) calc(10 * var(--u)) 0; }
.fp-rod .slot { width: calc(56 * var(--u)); height: calc(56 * var(--u)); min-height: 0; }
.fp-dur { font-size: calc(13 * var(--u)); text-align: center; }
.fp-say { margin: calc(8 * var(--u)) calc(10 * var(--u)) 0; text-align: center; font-weight: 700; }
.fp-say.bite { color: var(--coral, #c8553d); }   /* K-245b bite = text only (no countdown ring) */
.fish-pop .actions { flex-wrap: nowrap; margin-top: calc(8 * var(--u)); } .fish-pop .actions .btn { flex: 0 1 auto; min-width: 0; white-space: nowrap; }
.fp-auto { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); }
.fp-auto svg { width: calc(16 * var(--u)); height: calc(16 * var(--u)); }
.fp-sum, .fp-none { color: var(--line); opacity: .85; }
.fp-none { margin: calc(4 * var(--u)) calc(10 * var(--u)) 0; font-size: calc(12 * var(--u)); }
.fp-h { margin: calc(8 * var(--u)) calc(10 * var(--u)) calc(4 * var(--u)); font-size: calc(13 * var(--u)); }
.fp-sum { margin: calc(10 * var(--u)) calc(12 * var(--u)) calc(4 * var(--u)); }
.fish-pop .empty, .fp-list { margin: 0 calc(10 * var(--u)) calc(8 * var(--u)); }
.fp-list { display: flex; flex-direction: column; gap: calc(4 * var(--u)); max-height: calc(180 * var(--u)); overflow-y: auto; }
.fp-row { display: flex; align-items: center; gap: calc(8 * var(--u)); padding: calc(3 * var(--u)) calc(6 * var(--u)); border: calc(3 * var(--u)) solid transparent;
  border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch; }
.fp-row .fp-ic { flex: none; width: calc(30 * var(--u)); height: calc(30 * var(--u)); }
.fp-row .fp-ic .ic { width: 100%; height: 100%; object-fit: contain; }
.fp-row .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* K-245 rarity colours (item_defs.rarity) + gem row; bait picker chips. K-407: = theme.css ladder, common/uncommon/rare/legendary -> --rar-1..4, gem -> --rar-gem */
.fish-pop { --r-common: var(--rar-1); --r-uncommon: var(--rar-2); --r-rare: var(--rar-3); --r-legendary: var(--rar-4); --r-gem: var(--rar-gem); }
.fp-row[class*=' r-'] { box-shadow: inset calc(4 * var(--u)) 0 0 var(--rc); } .fp-row[class*=' r-'] .nm { color: var(--rc); font-weight: 700; }
.fp-row.r-common { --rc: var(--r-common); } .fp-row.r-uncommon { --rc: var(--r-uncommon); } .fp-row.r-rare { --rc: var(--r-rare); }
.fp-row.r-legendary { --rc: var(--r-legendary); background: linear-gradient(90deg, rgba(226, 174, 46, .22), transparent 70%); } .fp-row.r-gem { --rc: var(--r-gem); }
.fp-row.r-common .nm { color: inherit; font-weight: 400; }   /* common = plain text, grey bar only */
.fp-bait { display: flex; flex-wrap: wrap; gap: calc(8 * var(--u)); margin: 0 calc(10 * var(--u)); padding: calc(4 * var(--u)); }
.fp-bait .slot { width: calc(48 * var(--u)); height: calc(48 * var(--u)); min-height: 0; }   /* picked = .slot.active gold ring (shared) */

/* K-242b quest book accordion (WorldPanels QuestBook): section + row fold = grid rows 0fr -> 1fr; hidden content leaves the tab order (visibility) */
.qbook { display: flex; flex-direction: column; gap: calc(6 * var(--u)); }
.qb-head { display: flex; align-items: center; gap: calc(8 * var(--u)); width: 100%; padding: calc(8 * var(--u)) calc(10 * var(--u)); font: inherit; font-weight: 700; color: inherit; cursor: pointer; text-align: left; }
.qb-head .nm { flex: 1; }
.qb-car { flex: none; width: calc(8 * var(--u)); height: calc(8 * var(--u)); border-right: calc(2 * var(--u)) solid currentColor; border-bottom: calc(2 * var(--u)) solid currentColor;
  transform: rotate(-45deg); transition: transform .22s ease; opacity: .7; }
.open > .qb-head > .qb-car, .open > .ui-quest-row > .qb-car { transform: rotate(45deg); }
.qb-fold { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .25s ease; }
.open > .qb-fold { grid-template-rows: 1fr; }
.qb-in { min-height: 0; overflow: hidden; visibility: hidden; transition: visibility 0s .25s; }
.open > .qb-fold > .qb-in { visibility: visible; transition-delay: 0s; }
.qb-sec > .qb-fold > .qb-in { display: flex; flex-direction: column; gap: calc(4 * var(--u)); }
.qb-sec.open > .qb-fold > .qb-in { padding-top: calc(4 * var(--u)); }
.qb-q .ui-quest-row { width: 100%; }
.qb-q .ui-quest-row .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qb-q.fin .ui-quest-row { opacity: .7; }
.qb-q .detail { margin-top: calc(4 * var(--u)); }
@media (prefers-reduced-motion: reduce) { .qb-fold, .qb-car { transition: none; } }

/* K-253 slot corner badges (Panels.jsx SlotBadges; ref design/ui-ref/k253-slot-ref.png): TR +N | qty, BR tier Roman steel pill,
   BL gem socket dots (filled .on / hollow) or '?' unidentified, TL lock + worn. Thick outline = text-stroke under fill (paint-order).
   max(Npx, ..) = phone floor (--u clamps to .85px). All absolute + pointer-events none = no layout shift. */
:is(.slot, .item-modal-icon) :is(.qty, .enh, .tier, .sock) { position: absolute; pointer-events: none; line-height: 1; z-index: 1; }
:is(.slot, .item-modal-icon) :is(.qty, .enh) { top: calc(3 * var(--u)); right: calc(4 * var(--u)); bottom: auto; font-size: max(11px, calc(13 * var(--u))); font-weight: 700;
  -webkit-text-stroke: max(2.5px, calc(3 * var(--u))) #000; paint-order: stroke fill; text-shadow: 0 calc(1 * var(--u)) calc(2 * var(--u)) #000; }
:is(.slot, .item-modal-icon) .qty { color: var(--cream-lt); }
:is(.slot, .item-modal-icon) .enh { color: #ffd97a; }
:is(.slot, .item-modal-icon) .tier { right: calc(3 * var(--u)); bottom: calc(3 * var(--u)); min-width: max(14px, calc(16 * var(--u))); height: max(13px, calc(15 * var(--u)));
  padding: 0 calc(3 * var(--u)); display: grid; place-items: center; box-sizing: border-box;
  font: 700 max(9px, calc(10 * var(--u)))/1 Georgia, 'Times New Roman', serif; letter-spacing: -.03em; color: #f6ead0; text-shadow: 0 calc(1 * var(--u)) 0 #000;
  background: radial-gradient(circle at 50% 30%, #5d6470, #23272f 75%); border: max(1px, calc(1.5 * var(--u))) solid #c9a24a; border-radius: calc(999 * var(--u));
  box-shadow: 0 0 0 max(1px, calc(1 * var(--u))) #000, inset 0 calc(1 * var(--u)) 0 rgba(255, 255, 255, .25); }
:is(.slot, .item-modal-icon) .pond { position: absolute; left: calc(3 * var(--u)); bottom: calc(3 * var(--u)); width: max(14px, calc(16 * var(--u))); height: max(14px, calc(16 * var(--u)));
  display: grid; place-items: center; border-radius: 50%; background: #3f8fd0; border: max(1px, calc(1.5 * var(--u))) solid #e9f6ff; color: #fff; font-size: max(10px, calc(12 * var(--u)));
  font-weight: 700; line-height: 1; pointer-events: auto; }   /* pond fish (def.pond, room.mjs publicDefs) */
:is(.slot, .item-modal-icon) .sock { left: calc(4 * var(--u)); bottom: calc(5 * var(--u)); display: flex; gap: max(2px, calc(2 * var(--u))); }
.sock i { width: max(6px, calc(7 * var(--u))); height: max(6px, calc(7 * var(--u))); border-radius: 50%; box-sizing: border-box;
  background: rgba(0, 0, 0, .55); border: max(1px, calc(1.5 * var(--u))) solid #d9ccb0; box-shadow: 0 0 0 max(1px, calc(1 * var(--u))) #000; }   /* hollow = empty socket */
.sock i.on { background: radial-gradient(circle at 35% 30%, #f4ffd8, #6ee08a 40%, #1d7a3a); border-color: #0f3d1d; }   /* gem set */
.sock.unid { width: max(12px, calc(14 * var(--u))); height: max(12px, calc(14 * var(--u))); display: grid; place-items: center; border-radius: 50%;
  font-size: max(9px, calc(10 * var(--u))); font-weight: 700; color: #f6ead0; background: #23272f; border: max(1px, calc(1.5 * var(--u))) solid #c9a24a; box-shadow: 0 0 0 max(1px, calc(1 * var(--u))) #000; }
.slot .worn { left: calc(4 * var(--u)); top: calc(3 * var(--u)); bottom: auto; z-index: 1; }   /* ใส่ moved off BL (sockets) */
.slot .lk ~ .worn { left: calc(20 * var(--u)); }
.slot .lk { z-index: 1; }
.slot:has(> .tier) .pool { right: calc(24 * var(--u)); }   /* K-222 pool bar clears the tier pill */
.item-modal-icon { position: relative; }
.mk .card > .slot { width: calc(44 * var(--u)); min-height: 0; flex: none; }   /* grave item slot */
/* K-258 skill aim stick (touch, ROV-style): base ring centred on the held hotbar button (left/top = its centre, px), knob follows the finger
   (GameCanvas skillMove sets transform); .cancel = release cancels (back to centre / over ยกเลิก). ยกเลิก drop zone top edge centre (clear of the player), .hot = finger on it. Sizes = knobs. */
.hk { touch-action: none; }
.skstick { position: fixed; z-index: 7; width: calc(150 * var(--u)); height: calc(150 * var(--u)); margin: calc(-75 * var(--u)) 0 0 calc(-75 * var(--u)); border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(196, 230, 255, .08) 0 58%, rgba(196, 230, 255, .24) 60% 100%); border: calc(3 * var(--u)) solid rgba(196, 230, 255, .8); box-shadow: 0 0 calc(14 * var(--u)) rgba(0, 0, 0, .35); }
.skstick i { position: absolute; left: 50%; top: 50%; width: calc(58 * var(--u)); height: calc(58 * var(--u)); margin: calc(-29 * var(--u)) 0 0 calc(-29 * var(--u)); border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff, #c4e6ff 45%, #5f9fd2); border: calc(3 * var(--u)) solid var(--line); box-shadow: 0 calc(3 * var(--u)) calc(8 * var(--u)) rgba(0, 0, 0, .4); }
.skstick.cancel { border-color: rgba(255, 74, 46, .9); }
.skstick.cancel i { background: radial-gradient(circle at 35% 30%, #fff, #ffb0a0 45%, #d2483a); }
.skcancel { position: fixed; z-index: 7; left: 50%; top: calc(calc(8 * var(--u)) + env(safe-area-inset-top)); transform: translateX(-50%); min-width: calc(170 * var(--u)); padding: calc(16 * var(--u)) calc(28 * var(--u));
  border-radius: 999px; background: rgba(40, 22, 14, .72); color: var(--cream-lt); border: calc(3 * var(--u)) solid rgba(255, 255, 255, .35); font-size: calc(20 * var(--u)); font-weight: 700; text-align: center; pointer-events: none; }
.skcancel.hot { background: rgba(205, 52, 36, .92); border-color: #fff; }
/* K-259 list card with the item slot left (SlotCard: market listing/catalog, NPC shop buy/buyback, profile gear); body = old .card flex flow */
.mk .card.slot-card { display: grid; grid-template-columns: calc(44 * var(--u)) minmax(0, 1fr); align-items: center; }
.mk .card.slot-card > .slot { align-self: start; }
.slot-card .sc-body { display: flex; flex-wrap: wrap; align-items: center; gap: calc(6 * var(--u)) calc(10 * var(--u)); min-width: 0; }
.mail-view .item-pick { flex: 1 1 100%; }
.mail-att { display: flex; flex-wrap: wrap; align-items: center; gap: calc(6 * var(--u)); }   /* K-259 attachments = ItemList slots + Acorn chip */
.mail-pick { max-height: calc(220 * var(--u)); overflow-y: auto; }
.mk .card.trade-side { flex-direction: column; align-items: stretch; } .mk .card.trade-side > * { flex: none; }   /* K-259 offer side: name, slots, Acorn stacked */
/* K-266 settings: section cards + one-line rows (text left, control right) + pill switch / range in theme colours */
.settings-panel .set-sec { background: var(--cream-lt); border: var(--line-w) solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--lift);
  padding: calc(10 * var(--u)) calc(14 * var(--u)); margin-bottom: calc(12 * var(--u)); display: grid; gap: calc(2 * var(--u)); }
.settings-panel .set-sec h3 { margin: 0 0 calc(4 * var(--u)); }
.settings-panel .set-sec .note { margin: calc(4 * var(--u)) 0 0; }
.set-row { display: flex; align-items: center; justify-content: space-between; gap: calc(10 * var(--u)); min-height: calc(40 * var(--u));
  font-size: 1em; font-weight: 500; color: var(--ink); cursor: pointer; border-top: calc(1 * var(--u)) dashed var(--cream-dk); }
.set-sec h3 + .set-row { border-top: 0; }
.set-row > span { flex: 1; min-width: 0; }
.set-row small { color: var(--ink-dim); font-size: .85em; }
.set-row select, .set-row .dd { width: auto; min-width: min(calc(150 * var(--u)), 100%); border-radius: 999px; }
.set-row .set-val { min-width: calc(44 * var(--u)); text-align: right; font-variant-numeric: tabular-nums; }
/* pill switch: off = cream-dk well, on = sage; knob = cream-lt with outline */
input.sw { appearance: none; -webkit-appearance: none; flex: none; margin: 0; position: relative; cursor: pointer;
  width: calc(52 * var(--u)); height: calc(28 * var(--u)); border-radius: 999px; border: var(--line-w) solid var(--line);
  background: var(--cream-dk); box-shadow: var(--well); transition: background .15s; }
input.sw::after { content: ''; position: absolute; top: calc(2 * var(--u)); left: calc(2 * var(--u)); width: calc(18 * var(--u)); height: calc(18 * var(--u));
  border-radius: 50%; background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); transition: transform .15s; }
input.sw:checked { background: var(--sage); }
input.sw:checked::after { transform: translateX(calc(24 * var(--u))); }
input.sw:focus-visible { outline: calc(3 * var(--u)) solid var(--blue-dk); outline-offset: calc(2 * var(--u)); }
.settings-panel .actions { justify-content: center; }
/* K-266 override the global input box (min-height = --btn-h, padding) for the switch + range */
.set-row input.sw { min-height: 0; padding: 0; box-sizing: border-box; }
.set-row > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.set-row small { text-align: right; }
.set-row select { min-height: calc(36 * var(--u)); padding: 0 calc(10 * var(--u)); }
.set-row > span { flex: 0 0 auto; max-width: 60%; }   /* K-266 text keeps its width, control shrinks */
/* K-272 item detail modal: durability bar row, gem socket rows (frame + text, one per socket), one stat per line, mastery = plain green/red text */
.slot .dur, .dur-track .dur { position: absolute; left: calc(5 * var(--u)); right: calc(5 * var(--u)); bottom: calc(2 * var(--u)); height: calc(4 * var(--u));
  border-radius: 999px; background: rgba(59, 42, 30, .55); overflow: hidden; pointer-events: none; z-index: 1; }   /* z-index: user 2026-10-13 bag icon (.ic) covered the bar */
.slot .dur::after, .dur-track .dur::after { content: ''; position: absolute; inset: 0 auto 0 0; width: calc(var(--p) * 100%); background: var(--sage); }
.slot .dur.mid::after, .dur-track .dur.mid::after { background: var(--gold); }
.slot .dur.low::after, .dur-track .dur.low::after { background: var(--coral-dk); }
/* user 2026-10-12: weapon/armor at 0 durability = broken but worn -> red slot until repaired (tools still vanish at 0) */
.slot:has(.dur.broken) { box-shadow: inset 0 0 0 calc(2 * var(--u)) #d23b2e, inset 0 0 calc(14 * var(--u)) rgba(210, 59, 46, .55); }
.slot .dur.broken { background: #d23b2e; }
.slot:has(> .dur) :is(.sock, .tier) { bottom: calc(7 * var(--u)); }
.slot:has(> .dur) .pool { bottom: calc(8 * var(--u)); }
.im-dur { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: calc(8 * var(--u)); font-size: calc(13 * var(--u)); color: var(--ink-dim); text-align: left; }
.dur-track { position: relative; height: calc(10 * var(--u)); }
.dur-track .dur { inset: 0; height: auto; border: calc(2 * var(--u)) solid var(--line); background: var(--cream-dk); }
.im-gems, .im-stats { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(4 * var(--u)); text-align: left; font-size: calc(14 * var(--u)); }
.im-gems li { display: flex; align-items: center; gap: calc(8 * var(--u)); color: var(--ink); }
.im-gems li .slot { width: calc(34 * var(--u)); height: calc(34 * var(--u)); min-height: 0; flex: none; }
.im-gems li .slot:not(.filled) + span { color: var(--ink-dim); }
.im-gems li .slot .ic { width: 80%; height: 80%; }
.im-stats li { font-weight: 600; color: var(--ink); }
.item-modal .mastery-req { padding: 0; background: none; border-radius: 0; font-weight: 600; color: var(--sage-dk) !important; text-align: left; }
.item-modal .mastery-req.locked { color: var(--locked) !important; background: none; }
.im-gems-none { text-align: left; }
/* K-273 (user 2026-10-07 "เมนูขวา + shortcut bar ลดขนาดลง"): ~-15%. Knobs: menu button, hotbar key, attack button, bar padding; --hotbar-h follows
   (toasts/buffbar/gather hint/panels anchor on it). Phone (<=620px) keeps its own smaller set below. */
:root { --menu-btn: calc(44 * var(--u)); --hotbar-h: calc(64 * var(--u)); }
.mbtn .ic { width: calc(32 * var(--u)); height: calc(32 * var(--u)); }
.dock { gap: calc(5 * var(--u)); }
.dock, .hotbar { padding: calc(9 * var(--u)); }
.hotbar { gap: calc(6 * var(--u)); }
.hk { width: calc(54 * var(--u)); height: calc(47 * var(--u)); padding: calc(8 * var(--u)) calc(3 * var(--u)) calc(2 * var(--u)); }
.attack { width: calc(58 * var(--u)); height: calc(58 * var(--u)); margin: calc(-12 * var(--u)) 0 calc(-12 * var(--u)) calc(3 * var(--u)); }
.attack .ic { width: calc(42 * var(--u)); height: calc(42 * var(--u)); }
@media (max-width: 620px) {
  :root { --menu-btn: calc(38 * var(--u)); }
  .hk { width: calc(45 * var(--u)); height: calc(41 * var(--u)); padding: calc(7 * var(--u)) calc(2 * var(--u)) calc(1 * var(--u)); }
  .mbtn .ic { width: calc(28 * var(--u)); height: calc(28 * var(--u)); }
}

/* K-274 help bubble (Panels.jsx InfoTip): round i beside a title (Frame/PairPanels h2, Tabs .tab-title, section h3) -> fixed speech bubble
   portaled to body (z 70 > item-modal-backdrop 20), left clamped in JS, tail x = --tail. Hit area padded by ::before (touch). */
.info-i { position: relative; display: inline-grid; place-items: center; flex: none; width: calc(22 * var(--u)); height: calc(22 * var(--u)); margin-left: calc(8 * var(--u));
  padding: 0; vertical-align: middle; border-radius: 50%; border: calc(2 * var(--u)) solid var(--line); background: var(--cream-lt); color: var(--ink);
  font: italic 700 calc(14 * var(--u)) / 1 Georgia, 'Times New Roman', serif; text-transform: none; letter-spacing: 0; cursor: pointer; box-shadow: 0 calc(2 * var(--u)) 0 rgba(59, 42, 30, .3); }
.info-i::before { content: ""; position: absolute; inset: calc(-10 * var(--u)); }
.info-i:hover, .info-i.on { background: var(--gold); }
.info-i:focus-visible { outline: calc(2 * var(--u)) solid var(--blue-dk); outline-offset: calc(2 * var(--u)); }
.info-tip { position: fixed; z-index: 70; max-width: min(calc(280 * var(--u)), calc(100vw - 16px)); padding: calc(10 * var(--u)) calc(14 * var(--u));
  background: var(--cream-lt); color: var(--ink); border: calc(2 * var(--u)) solid var(--line); border-radius: calc(14 * var(--u)); box-shadow: var(--shadow);
  font: 400 calc(14 * var(--u)) / 1.5 var(--font); text-align: left; white-space: normal; overflow-wrap: anywhere; animation: pop var(--anim-ms) var(--ease); transform-origin: var(--tail) 0; }
.info-tip::after { content: ""; position: absolute; top: calc(-7 * var(--u)); left: calc(var(--tail) - 6 * var(--u)); width: calc(12 * var(--u)); height: calc(12 * var(--u));
  background: var(--cream-lt); border: solid var(--line); border-width: calc(2 * var(--u)) 0 0 calc(2 * var(--u)); transform: rotate(45deg); }
/* K-276 (user 2026-10-07): modal item icon = steel slot frame (= .slot.filled); durability = bar only, under the icon (SlotBadges .dur) */
.item-modal-icon { background: none; border: 0 solid transparent; box-shadow: none; border-radius: 0;
  border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; margin-bottom: calc(10 * var(--u)); }
.item-modal-icon .dur { position: absolute; left: calc(8 * var(--u)); right: calc(8 * var(--u)); bottom: calc(-12 * var(--u)); height: calc(7 * var(--u));
  border-radius: 999px; background: var(--cream-dk); border: calc(2 * var(--u)) solid var(--line); overflow: hidden; }
.item-modal-icon .dur::after { content: ''; position: absolute; inset: 0 auto 0 0; width: calc(var(--p) * 100%); background: var(--sage); }
.item-modal-icon .dur.mid::after { background: var(--gold); }
/* user 2026-10-13: durability n / max under the modal bar (replaces details text) */
.item-modal-icon:has(.im-durn) { margin-bottom: calc(19 * var(--u)); }
.item-modal-icon .im-durn { position: absolute; left: 0; right: 0; top: calc(100% + 16 * var(--u)); text-align: center; font-size: max(11px, calc(12 * var(--u))); font-weight: 700; line-height: 1; pointer-events: none; }
.item-modal-icon .dur.low::after { background: var(--coral-dk); }
.item-modal-icon .qty { color: var(--cream-lt); }
/* K-270 sleep: bed button at the hotbar end (= .hk size, bed icon) + i bubble opening UP (.info-tip.up: tail at the bottom) */
.sleep-wrap { position: relative; display: inline-flex; align-items: center; gap: calc(6 * var(--u)); }
.sleep-btn.auto-hud .ic, .sleep-btn.auto-hud img { width: calc(30 * var(--u)); height: calc(30 * var(--u)); object-fit: contain; }
.sleep-wrap .info-i { position: absolute; top: calc(-10 * var(--u)); right: calc(-8 * var(--u)); margin: 0; width: calc(18 * var(--u)); height: calc(18 * var(--u)); font-size: calc(12 * var(--u)); z-index: 1; }
.sleep-btn { position: relative; width: calc(64 * var(--u)); height: calc(56 * var(--u)); padding: calc(4 * var(--u)) calc(2 * var(--u)) calc(2 * var(--u)); cursor: inherit;
  display: flex; flex-direction: column; align-items: center; justify-content: center; background: var(--cream-lt); border: var(--line-w) solid var(--line);
  border-radius: var(--radius-sm); box-shadow: var(--gloss), 0 calc(3 * var(--u)) 0 var(--line); }
.sleep-btn:active { transform: translateY(calc(3 * var(--u))); box-shadow: var(--gloss); }
.sleep-btn.on { background: #3d4a7a; color: var(--cream-lt); }
.sleep-btn img { width: calc(52 * var(--u)); height: calc(26 * var(--u)); object-fit: contain; }
.sleep-btn small { font-size: calc(10 * var(--u)); font-weight: 600; }
.sleep-btn kbd { position: absolute; top: calc(1 * var(--u)); left: calc(5 * var(--u)); font-size: calc(10 * var(--u)); font-weight: 600; color: var(--ink-dim); }
.bed-ph { display: grid; place-items: center; width: calc(40 * var(--u)); height: calc(22 * var(--u)); border-radius: calc(8 * var(--u)); border: calc(2 * var(--u)) solid var(--line);
  font-style: normal; font-weight: 700; font-size: calc(12 * var(--u)); background: #e9e4d6; color: var(--ink); }
.bed-ph.t2 { background: #c99a62; } .bed-ph.t3 { background: #6a7fa8; color: #fff; } .bed-ph.t4 { background: #b23a32; color: #fff; } .bed-ph.t5 { background: #e8dcc0; }
.bed-ph.t6 { background: #d77a8c; } .bed-ph.t7 { background: #eef3ff; } .bed-ph.t8 { background: #c93a3a; color: #ffe08a; }
.info-tip.up { transform-origin: var(--tail) 100%; }
.info-tip.up::after { top: auto; bottom: calc(-7 * var(--u)); border-width: 0 calc(2 * var(--u)) calc(2 * var(--u)) 0; }
.st-beds { display: flex; flex-wrap: wrap; align-items: center; gap: calc(4 * var(--u)); }   /* K-279 arena bed test buttons */
.st-beds .btn.sm { min-width: calc(30 * var(--u)); padding: 0 calc(6 * var(--u)); }
.item-modal .im-sell { display: flex; align-items: center; justify-content: center; gap: calc(4 * var(--u)); flex-wrap: wrap; color: var(--ink-dim); }   /* K-283 sell price line */
.item-modal .im-sell .ic { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
.item-modal .im-sell b { color: var(--ink); }
/* K-284 (user 2026-10-07): hotbar = 2 pages (A 9 slots Q..C / B 10 slots 1..0, GameCanvas page) + ▲▼ flip (.hb-page); smaller than K-273.
   Attack button touch only (desktop = Space). Sleep = own round HUD button (desktop bottom-left after chat + mail; phone right column above mail).
   Knobs: slot w/h, gap, --hotbar-h (toasts/buffbar/gather hint/panels anchor on it). */
:root { --hotbar-h: calc(56 * var(--u)); }
.hotbar { gap: calc(5 * var(--u)); padding: calc(7 * var(--u)); }
.hk { width: calc(46 * var(--u)); height: calc(42 * var(--u)); padding: calc(7 * var(--u)) calc(2 * var(--u)) calc(1 * var(--u)); }
.hk b { font-size: calc(9 * var(--u)); }
.hk small { font-size: calc(9 * var(--u)); }
.hb-page { display: flex; flex-direction: column; gap: calc(3 * var(--u)); }
.hb-page button { width: calc(22 * var(--u)); height: calc(19 * var(--u)); padding: 0; display: grid; place-items: center; cursor: inherit; font-size: calc(10 * var(--u)); line-height: 1;
  color: var(--ink); background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); border-radius: calc(6 * var(--u)); box-shadow: 0 calc(2 * var(--u)) 0 var(--line); }
.hb-page button:disabled { color: var(--gold); background: #2a2f38; box-shadow: none; transform: translateY(calc(2 * var(--u))); }
.hb-page button:focus-visible { outline: calc(2 * var(--u)) solid var(--blue-dk); outline-offset: calc(1 * var(--u)); }
@media (pointer: fine) { .hotbar .attack { display: none; } }
.sleep-wrap { position: absolute; z-index: 4; left: max(calc(64 * var(--u)), calc(env(safe-area-inset-left) + calc(52 * var(--u))));   /* user 2026-10-13: next to chat (old mail slot) */ bottom: calc(calc(18 * var(--u)) + env(safe-area-inset-bottom)); }
.sleep-btn { width: var(--btn-h); height: var(--btn-h); padding: 0; border-radius: 50%; display: grid; place-items: center; overflow: visible; }
.sleep-btn img { width: calc(36 * var(--u)); height: calc(24 * var(--u)); }
.sleep-btn .bed-ph { width: calc(28 * var(--u)); height: calc(18 * var(--u)); font-size: calc(10 * var(--u)); }
.sleep-btn kbd { top: auto; left: auto; right: calc(-4 * var(--u)); bottom: calc(-4 * var(--u)); padding: 0 calc(4 * var(--u)); border-radius: calc(6 * var(--u)); line-height: 1.4;
  background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); color: var(--ink); }
.sleep-wrap .info-i { top: calc(-8 * var(--u)); right: calc(-8 * var(--u)); }
@media (max-width: 620px) {
  /* phone: hotbar bottom-right = 4-col slot grid (3 rows) + ▲▼ column + attack column; pad bottom-left */
  .hotbar { grid-template-columns: repeat(4, calc(40 * var(--u))) calc(22 * var(--u)) calc(62 * var(--u)); grid-template-rows: repeat(3, calc(38 * var(--u)));
    gap: calc(4 * var(--u)); padding: calc(6 * var(--u)); }
  .hk { width: calc(40 * var(--u)); height: calc(38 * var(--u)); padding: calc(6 * var(--u)) calc(1 * var(--u)) 0; }
  .hk kbd { font-size: calc(9 * var(--u)); }
  .hb-page { grid-column: 5; grid-row: 1 / span 3; align-self: center; }
  .hotbar .attack { grid-column: 6; grid-row: 1 / span 3; width: calc(62 * var(--u)); height: calc(62 * var(--u)); }
  .sleep-wrap { left: auto; right: max(calc(10 * var(--u)), env(safe-area-inset-right)); bottom: calc(calc(250 * var(--u)) + env(safe-area-inset-bottom)); }
}
.hk.empty kbd { color: var(--line); font-weight: 700; top: calc(3 * var(--u)); left: calc(6 * var(--u)); }   /* K-284 key letter readable on the empty parchment slot */
.fish-pop.float { overflow: visible; max-height: none; inset: 0 auto 0 calc(24px + env(safe-area-inset-left)); margin: auto 0; }   /* K-288c close X on the corner (overflow clipped it); K-288d user: left-middle   /* K-288c close X sits on the top-right corner like every panel (overflow was clipping it; content fits 390x844) */
.fish-pop .empty { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }   /* K-288e user: ยังไม่ได้ปลา / รอปลากินเบ็ด centred */
/* K-292 fishing summary: fish caught + bait used = item-slot grids (qty badge top-right) */
.fish-pop .fs-h { margin: calc(6 * var(--u)) calc(12 * var(--u)) calc(4 * var(--u)); font-size: calc(15 * var(--u)); text-align: center; }
.fish-pop .fs-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(6 * var(--u)); margin: 0 calc(12 * var(--u)); }
.fish-pop .fs-grid .slot { width: calc(52 * var(--u)); height: calc(52 * var(--u)); }
.fish-pop .fp-sum { text-align: center; }   /* K-292 */
/* K-294 (user 2026-10-07 MOBA ref design/ui-ref/k294-mobile-wheel-ref.png): touch HUD (pointer: coarse; desktop/fine untouched).
   Skill wheel: .hotbar = 0-size anchor at the bottom-right safe corner; attack centre --wh-c in from right + bottom; the 10 slots of the shown
   page sit at polar spots --a/--r (GameCanvas inline from input.js WHEEL: k 0-3 inner arc r 72u, 4-9 outer arc r 128u, angles 165-290deg);
   .hb-swap = page 1/2 toggle (portrait above the wheel, short landscape left of it). Joystick .joy = floating stick zone bottom-left
   (input.js bindJoy). Chat/mail/sleep/fish: portrait right column above the swap; short landscape bottom row between stick + wheel, dock =
   top row left of the minimap. Knobs: --wh-* sizes, --sw-* swap spot, --joy-* zone/ring. */
.joy, .hb-swap { display: none; }
@media (pointer: coarse) {
  :root { --wh-c: calc(58 * var(--u)); --wh-atk: calc(78 * var(--u)); --wh-sk: calc(46 * var(--u)); --sw: calc(40 * var(--u)); --sw-x: 0px; --sw-y: calc(-178 * var(--u));
    --joy-w: min(52vw, calc(230 * var(--u))); --joy-h: calc(250 * var(--u)); --joy-d: calc(112 * var(--u)); --joy-k: calc(50 * var(--u)); --joy-rest: calc(84 * var(--u)); }
  .hotbar { left: auto; top: auto; right: env(safe-area-inset-right); bottom: env(safe-area-inset-bottom); transform: none; display: block; width: 0; height: 0;
    padding: 0; border: 0; border-image: none; filter: none; }
  .hotbar > .hk, .hotbar > .attack, .hotbar > .hb-swap { position: absolute; margin: 0; }
  .hotbar > .hk { width: var(--wh-sk); height: var(--wh-sk); padding: 0; border-radius: 50%; overflow: hidden;
    right: calc(var(--wh-c) - var(--wh-sk) / 2); bottom: calc(var(--wh-c) - var(--wh-sk) / 2);
    translate: calc(cos(var(--a)) * var(--r) * var(--u)) calc(sin(var(--a)) * var(--r) * var(--u));
    border: calc(3 * var(--u)) solid #c9a35a; border-image: none; background: radial-gradient(circle at 35% 30%, #4a5260, #23272f 70%);
    box-shadow: 0 calc(3 * var(--u)) calc(4 * var(--u)) rgba(20, 12, 6, .5); }
  .hotbar > .hk.empty { border: calc(2 * var(--u)) dashed rgba(251, 246, 234, .8); background: rgba(40, 30, 20, .35); box-shadow: none; }
  .hotbar > .hk.nomp { border-color: var(--blue-dk); }
  .hotbar > .hk .sk-ic { inset: 0; width: 100%; height: 100%; }
  .hotbar > .hk kbd { display: none; }
  .hotbar > .hk small { display: none; }
  .hotbar > .hk.combo small { display: block; left: 50%; bottom: 0; transform: translateX(-50%); white-space: nowrap; font-size: calc(8 * var(--u)); }
  .hotbar > .hk b { font-size: calc(8 * var(--u)); padding: 0 calc(3 * var(--u)); }
  .hotbar > .hk .charges { top: auto; right: auto; left: 50%; bottom: calc(1 * var(--u)); transform: translateX(-50%); color: #fff; text-shadow: 0 1px 0 #000, 0 0 calc(3 * var(--u)) rgba(0, 0, 0, .7); }   /* user 2026-10-16: dash stack count white */
  .hotbar > .hk .cd { border-radius: 50%; font-size: calc(14 * var(--u)); }
  .hotbar > .attack { width: var(--wh-atk); height: var(--wh-atk); right: calc(var(--wh-c) - var(--wh-atk) / 2); bottom: calc(var(--wh-c) - var(--wh-atk) / 2); }
  .hotbar > .attack .ic { width: calc(54 * var(--u)); height: calc(54 * var(--u)); }
  .hotbar > .attack small { bottom: calc(-6 * var(--u)); }
  .hotbar > .hb-page { display: none; }
  .hotbar > .hb-swap { display: grid; place-items: center; width: var(--sw); height: var(--sw); padding: 0; cursor: inherit; border-radius: 50%;
    right: calc(var(--wh-c) - var(--sw) / 2); bottom: calc(var(--wh-c) - var(--sw) / 2); translate: var(--sw-x) var(--sw-y);
    color: var(--ink); background: var(--cream-lt); border: var(--line-w) solid var(--line); box-shadow: var(--gloss), 0 calc(3 * var(--u)) 0 var(--line); touch-action: manipulation; }
  .hb-swap i { font-style: normal; font-size: calc(16 * var(--u)); line-height: 1; font-weight: 700; }
  .hb-swap b { position: absolute; right: calc(-6 * var(--u)); top: calc(-6 * var(--u)); min-width: calc(18 * var(--u)); height: calc(18 * var(--u)); display: grid; place-items: center;
    font-size: calc(11 * var(--u)); font-weight: 700; color: var(--gold); background: #2a2f38; border: calc(2 * var(--u)) solid var(--line); border-radius: 50%; }
  .hb-swap:active { transform: translateY(calc(3 * var(--u))); box-shadow: var(--gloss); }
  .hotbar > .fishbar { left: auto; transform: none; margin: 0; right: calc(var(--wh-c) - calc(21 * var(--u))); bottom: calc(430 * var(--u)); }
  /* joystick zone + ring + knob; base rest spot = --joy-rest from the zone's left/bottom, JS moves it to the finger */
  .joy { display: block; position: absolute; z-index: 4; left: env(safe-area-inset-left); bottom: env(safe-area-inset-bottom); width: var(--joy-w); height: var(--joy-h); touch-action: none; }
  .joy-base { position: absolute; left: var(--joy-rest); top: calc(100% - var(--joy-rest)); width: var(--joy-d); height: var(--joy-d); transform: translate(-50%, -50%); pointer-events: none;
    border-radius: 50%; background: radial-gradient(circle, rgba(251, 246, 234, .10) 55%, rgba(251, 246, 234, .28)); border: calc(3 * var(--u)) solid rgba(251, 246, 234, .7);
    box-shadow: 0 0 0 calc(2 * var(--u)) rgba(59, 42, 30, .35); opacity: .75; }
  .joy.on .joy-base { opacity: 1; }
  .joy-base i { position: absolute; left: 50%; top: 50%; width: var(--joy-k); height: var(--joy-k); margin: calc(var(--joy-k) / -2) 0 0 calc(var(--joy-k) / -2); border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, var(--cream-lt), var(--cream-dk)); border: var(--line-w) solid var(--line); box-shadow: 0 calc(3 * var(--u)) 0 rgba(59, 42, 30, .45); }
  /* chat / mail / sleep: right column above the swap (portrait default) */
  .chat-toggle, .sleep-wrap { left: auto; right: max(calc(10 * var(--u)), env(safe-area-inset-right)); }   /* K-298 user: hug the right edge (portrait) */
  .chat-toggle { bottom: calc(env(safe-area-inset-bottom) + calc(262 * var(--u))); }
  .sleep-wrap { bottom: calc(env(safe-area-inset-bottom) + calc(316 * var(--u))); }
}
@media (pointer: coarse) and (max-height: 520px) {
  /* short landscape: swap left of the wheel; chat/mail/sleep/fish = bottom row right of the stick zone; dock = top row left of the minimap */
  :root { --sw-x: calc(-196 * var(--u)); --sw-y: 0px; --joy-w: min(30vw, calc(280 * var(--u))); --joy-h: calc(230 * var(--u)); }
  .chat-toggle, .sleep-wrap { right: auto; bottom: calc(env(safe-area-inset-bottom) + calc(12 * var(--u))); }
  .chat-toggle { left: calc(env(safe-area-inset-left) + var(--joy-w) + calc(8 * var(--u))); }
  .sleep-wrap { left: calc(env(safe-area-inset-left) + var(--joy-w) + calc(60 * var(--u))); }
  .hotbar > .fishbar { right: calc(var(--wh-c) + calc(250 * var(--u))); bottom: calc(var(--wh-c) - calc(21 * var(--u))); }
  .dock { display: flex; flex-direction: row; top: max(calc(12 * var(--u)), env(safe-area-inset-top)); right: calc(max(calc(12 * var(--u)), env(safe-area-inset-right)) + var(--mm) + calc(56 * var(--u))); }
  .dock-more { top: calc(100% + 8 * var(--u)); bottom: auto; right: 0; }
  .bossbar, .skcancel { top: calc(calc(84 * var(--u)) + env(safe-area-inset-top)); }   /* below the dock row */
  .chat-popup { left: calc(env(safe-area-inset-left) + var(--joy-w)); bottom: calc(env(safe-area-inset-bottom) + calc(66 * var(--u))); }
}
/* K-297 (user 2026-10-07) touch: smaller minimap; pet HUD docked right of the character card (top-left), not bottom-right */
@media (pointer: coarse) {
  :root { --mm: calc(92 * var(--u)); }
  .pet-hud { top: max(calc(12 * var(--u)), env(safe-area-inset-top)); bottom: auto; right: auto;
    left: calc(max(calc(12 * var(--u)), env(safe-area-inset-left)) + var(--vitals-w, calc(240 * var(--u))) + calc(8 * var(--u))); }
  .ph-ring, .ph-hunger { width: calc(46 * var(--u)); } .ph-ring { height: calc(46 * var(--u)); }
}
/* K-299 (user 2026-10-07): ⋯ menu list opens top -> bottom (top-aligned, grows down; was bottom-aligned growing up) */
.dock-more { top: 0; bottom: auto; }
/* K-299 touch minimap: 92 was too small -> 116; tucked further into the top-right corner (ring margin 22 -> 12) */
@media (pointer: coarse) {
  :root { --mm: calc(116 * var(--u)); }
  .minimap { margin: calc(12 * var(--u)) calc(12 * var(--u)) 0 0; top: max(calc(4 * var(--u)), env(safe-area-inset-top)); right: max(calc(4 * var(--u)), env(safe-area-inset-right)); }
}
/* K-300b (user 2026-10-07) short landscape: sleep / mail / chat = vertical column RIGHT-middle (left of the minimap column, above the wheel);
   menu dock = vertical column LEFT-middle, its ⋯ list opens to the right. Portrait: swap button bottom, left of the wheel (like landscape). */
@media (pointer: coarse) and (max-height: 520px) {
  .chat-toggle, .sleep-wrap { left: auto; bottom: auto; right: max(calc(14 * var(--u)), env(safe-area-inset-right)); z-index: 6; }
  .chat-toggle { top: calc(var(--mm) + calc(40 * var(--u)) + env(safe-area-inset-top)); }
  .sleep-wrap { top: calc(var(--mm) + calc(40 * var(--u)) + var(--btn-h) + calc(6 * var(--u)) + env(safe-area-inset-top)); }
  .dock { flex-direction: column; top: calc(env(safe-area-inset-top) + calc(96 * var(--u))); transform: none; right: auto; left: max(calc(12 * var(--u)), env(safe-area-inset-left)); gap: calc(3 * var(--u)); padding: calc(5 * var(--u)); }
  .dock .mbtn { width: calc(34 * var(--u)); height: calc(34 * var(--u)); } .dock .mbtn .ic { width: calc(26 * var(--u)); height: calc(26 * var(--u)); }
  :root { --joy-h: calc(150 * var(--u)); }   /* stick zone below the dock column */
  .dock-more { top: 0; bottom: auto; right: auto; left: calc(100% + 8 * var(--u)); }
  .bossbar, .skcancel { top: calc(calc(16 * var(--u)) + env(safe-area-inset-top)); }
}
@media (pointer: coarse) and (min-height: 521px) {
  :root { --sw-x: calc(-232 * var(--u)); --sw-y: 0px; }
}
/* K-301 (user 2026-10-07): touch joystick ring turns red while deflected enough to RUN */
.joy.run .joy-base { border-color: #e0533f; box-shadow: 0 0 0 calc(2 * var(--u)) rgba(150, 30, 20, .5), 0 0 calc(14 * var(--u)) rgba(224, 83, 63, .55); }
.joy.run .joy-base i { background: #f08a78; }
/* K-301 collapsible menu dock (Panels Dock .dock-fold, state ageup.dockShut): desktop hidden; portrait = row bottom-centre above the
   stick/wheel band, toggle ^ v; short landscape = left column (K-300b), toggle < > */
.dock-fold { display: none; }
@media (pointer: coarse) {
  .dock-fold { display: grid; place-items: center; flex: none; width: calc(30 * var(--u)); height: calc(30 * var(--u)); padding: 0; cursor: inherit;
    border-radius: 50%; background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); box-shadow: var(--lift); }
  .dock-fold span { width: 0; height: 0; border: calc(7 * var(--u)) solid transparent; }
  .dock.shut > :not(.dock-fold) { display: none; }
  .dock.shut { background: none; border: 0; box-shadow: none; padding: 0; border-image: none; }
}
@media (pointer: coarse) and (min-height: 521px) {
  .dock { flex-direction: row; top: auto; right: auto; left: 50%; transform: translateX(-50%); bottom: calc(env(safe-area-inset-bottom) + calc(360 * var(--u)));
    gap: calc(3 * var(--u)); padding: calc(5 * var(--u)); max-height: none; }
  .dock .mbtn { width: calc(36 * var(--u)); height: calc(36 * var(--u)); } .dock .mbtn .ic { width: calc(28 * var(--u)); height: calc(28 * var(--u)); }
  .dock-fold span { border-top-color: var(--line); margin-top: calc(7 * var(--u)); }                 /* v = collapse (open state) */
  .dock.shut .dock-fold span { border-top-color: transparent; border-bottom-color: var(--line); margin: 0 0 calc(7 * var(--u)); }   /* ^ = expand */
  .dock-more { top: auto; bottom: calc(100% + 8 * var(--u)); right: auto; left: 50%; transform: translateX(-50%); }
}
@media (pointer: coarse) and (max-height: 520px) {
  .dock-fold span { border-right-color: var(--line); margin-right: calc(7 * var(--u)); }            /* < = collapse */
  .dock.shut .dock-fold span { border-right-color: transparent; border-left-color: var(--line); margin: 0 0 0 calc(7 * var(--u)); }  /* > = expand */
}
/* K-301b (user: orientations were swapped) PORTRAIT = dock column under the minimap (pre-K-301 place), fold ^ v at its top;
   SHORT LANDSCAPE = dock row bottom-centre between the stick and the wheel, fold < > at its left; ⋯ list opens upward there. */
@media (pointer: coarse) and (min-height: 521px) {
  .dock { flex-direction: column; left: auto; transform: none; bottom: auto; top: calc(var(--mm) + calc(78 * var(--u)));
    right: max(calc(12 * var(--u)), env(safe-area-inset-right)); }
  .dock-fold span { border-top-color: transparent; border-bottom-color: var(--line); margin: 0 0 calc(7 * var(--u)); }   /* ^ = collapse up */
  .dock.shut .dock-fold span { border-bottom-color: transparent; border-top-color: var(--line); margin: calc(7 * var(--u)) 0 0; }   /* v = expand */
  .dock-more { top: 0; bottom: auto; left: auto; right: calc(100% + 8 * var(--u)); transform: none; }
}
@media (pointer: coarse) and (max-height: 520px) {
  :root { --joy-h: calc(230 * var(--u)); }
  .dock { flex-direction: row; top: auto; left: 50%; right: auto; transform: translateX(-50%); bottom: calc(env(safe-area-inset-bottom) + calc(10 * var(--u))); }
  .dock-more { top: auto; bottom: calc(100% + 8 * var(--u)); left: 50%; right: auto; transform: translateX(-50%); }
}
/* K-301c (user) short landscape: dock = vertical column LEFT-middle under the character card, roomier container (padding/gap), fold < > on top */
@media (pointer: coarse) and (max-height: 520px) {
  :root { --joy-h: calc(120 * var(--u)); }
  .dock { flex-direction: column; align-items: center; left: max(calc(12 * var(--u)), env(safe-area-inset-left)); right: auto; bottom: auto; transform: none;
    top: calc(env(safe-area-inset-top) + calc(92 * var(--u))); gap: calc(5 * var(--u)); padding: calc(9 * var(--u)) calc(8 * var(--u)); }
  .dock .mbtn { width: calc(32 * var(--u)); height: calc(32 * var(--u)); } .dock .mbtn .ic { width: calc(24 * var(--u)); height: calc(24 * var(--u)); }
  .dock .mbtn kbd { display: none; }
  .dock-more { top: 0; bottom: auto; left: calc(100% + 8 * var(--u)); right: auto; transform: none; }
}
/* roomier touch dock container in portrait too */
@media (pointer: coarse) and (min-height: 521px) { .dock { gap: calc(6 * var(--u)); padding: calc(9 * var(--u)) calc(8 * var(--u)); align-items: center; } }
@media (pointer: coarse) and (max-height: 520px) { .dock { z-index: 8; } }   /* K-301c dock column above the tutorial / quest card */
.attack img.ic { object-fit: contain; }   /* K-302 weapon item icon */
/* K-302b (user "ขยาย container width ตอน responsive"): touch dock container wider than its buttons */
@media (pointer: coarse) { .dock { padding-left: calc(13 * var(--u)); padding-right: calc(13 * var(--u)); min-width: calc(var(--menu-btn) + 30 * var(--u)); } }
@media (pointer: coarse) and (max-height: 520px) { .dock { min-width: calc(32 * var(--u) + 30 * var(--u)); } }
/* K-302c (user): fold toggle = ^ v in BOTH orientations; when open it sits at the BOTTOM of the menu (^ = collapse), shut = only v */
@media (pointer: coarse) {
  .dock-fold { order: 99; }
  .dock-fold span { border: calc(7 * var(--u)) solid transparent; border-bottom-color: var(--line); margin: 0 0 calc(7 * var(--u)); }
  .dock.shut .dock-fold span { border-bottom-color: transparent; border-top-color: var(--line); margin: calc(7 * var(--u)) 0 0; }
}
/* K-302d fix: shut arrow was mixing an old landscape side colour (diagonal) -> reset the whole border, then colour only the top = v */
@media (pointer: coarse) {
  .dock .dock-fold span { border: calc(7 * var(--u)) solid transparent; border-bottom-color: var(--line); margin: 0 0 calc(7 * var(--u)); }
  .dock.shut .dock-fold span { border: calc(7 * var(--u)) solid transparent; border-top-color: var(--line); margin: calc(7 * var(--u)) 0 0; }
}
/* K-304 (user 2026-10-07) short landscape: bigger minimap; smaller + tighter sleep / mail / chat column under it */
@media (pointer: coarse) and (max-height: 520px) {
  :root { --mm: calc(140 * var(--u)); --rb: calc(34 * var(--u)); }
  .chat-toggle, .sleep-wrap .sleep-btn { width: var(--rb); height: var(--rb); min-height: 0; }
  .chat-toggle .ic { width: calc(20 * var(--u)); height: calc(20 * var(--u)); }
  .sleep-btn img { width: calc(26 * var(--u)); height: calc(18 * var(--u)); }
  .chat-toggle { top: calc(var(--mm) + calc(46 * var(--u)) + env(safe-area-inset-top)); }
  .sleep-wrap { top: calc(var(--mm) + calc(46 * var(--u)) + var(--rb) + calc(4 * var(--u)) + env(safe-area-inset-top)); }
}
/* K-296 loading mascot: 6-frame acorn walk strip (219x324 per frame) stepped by CSS + a soft hop bounce; knobs = size / durations */
.ld-acorn { display: block; width: calc(74 * var(--u)); height: calc(110 * var(--u)); background: url(/assets/brand/acorn-walk.webp?v=k296-1) 0 0 / 600% 100% no-repeat;
  animation: ld-acorn-walk .6s steps(6) infinite, ld-acorn-hop .3s ease-in-out infinite alternate; }
@keyframes ld-acorn-walk { to { background-position: 120% 0; } }
@keyframes ld-acorn-hop { from { transform: translateY(0); } to { transform: translateY(calc(-6 * var(--u))); } }
/* K-307 (user 2026-10-07): touch devices have no keyboard -> hide every hotkey hint (dock, ⋯ list, sleep N, buttons [H], panels) */
@media (pointer: coarse) { kbd { display: none !important; } }
/* K-308 pet eat: growth gain badge top-right of the pet portrait */
.pe-ring { position: relative; }
.pe-ring .pe-plus { position: absolute; top: calc(-4 * var(--u)); right: calc(-10 * var(--u)); z-index: 2; font-style: normal; font-weight: 700; font-size: calc(13 * var(--u));
  padding: 0 calc(6 * var(--u)); border-radius: 999px; background: var(--sage); color: var(--ink); border: calc(2 * var(--u)) solid var(--line); }
.pe-ring .pe-plus.craved { background: var(--gold); }
/* K-311 (user 2026-10-07) short landscape: NPC dialogue = bottom-centre between the stick and the wheel, compact */
@media (pointer: coarse) and (max-height: 520px) {
  .dialogue { bottom: calc(env(safe-area-inset-bottom) + calc(8 * var(--u))); width: min(56vw, calc(560 * var(--u))); min-height: 0; max-height: 46vh; overflow-y: auto; }
  .dlg-portrait { width: calc(64 * var(--u)); }
}
/* K-311b: dialogue bottom-centre for ANY short landscape screen (pointer media can misreport on some phones / desktop-mode browsers) */
@media (orientation: landscape) and (max-height: 600px) {
  .dialogue { bottom: calc(env(safe-area-inset-bottom) + calc(8 * var(--u))); width: min(56vw, calc(560 * var(--u))); min-height: 0; max-height: 46vh; overflow-y: auto; }
  .dlg-portrait { width: calc(64 * var(--u)); }
}
/* K-314 (user 2026-10-07) short landscape: interact hint (คุยกับ NPC / เก็บ / ใช้) bottom-centre; no bottom hotbar here (wheel right, stick left) */
@media (orientation: landscape) and (max-height: 600px) {
  .gather-hint { bottom: calc(env(safe-area-inset-bottom) + calc(12 * var(--u))); }
}

/* K-323 farm: plot seed bar = child of .hotbar centred just above it (like .fishbar); farm info button top-centre on the farm map */
.hotbar > .farmbar { position: absolute; left: 50%; bottom: 100%; transform: translateX(-50%); margin-bottom: calc(8 * var(--u)); pointer-events: auto;
  display: flex; align-items: center; gap: calc(6 * var(--u)); padding: calc(6 * var(--u)) calc(8 * var(--u)); white-space: nowrap; max-width: calc(100vw - 32px); overflow-x: auto;
  background: var(--cream); border: var(--line-w) solid var(--line); border-radius: var(--radius); box-shadow: var(--lift); }
.farmbar .fb-slot { padding: 0; border: 0; background: none; min-height: 0; cursor: pointer; }
.farmbar .fb-slot .slot { width: calc(52 * var(--u)); height: calc(52 * var(--u)); }
.farmbar button.fb-slot:hover .slot { outline: calc(2 * var(--u)) solid var(--brass, #c9a227); }
.farmbar .note { margin: 0 calc(4 * var(--u)); }
/* pond bar (user 2026-10-12): parents column (one slot per fish, grows up) + separate add box */
.farmbar .fb-group { display: flex; flex-direction: column; align-items: center; gap: calc(4 * var(--u)); padding: calc(4 * var(--u));
  border: var(--line-w) solid var(--line); border-radius: var(--radius); background: var(--cream-dk); align-self: flex-end; }
.farmbar .fb-parents { flex-direction: column-reverse; }
/* user 2026-10-14 pond: one row per parent (slot + own count / next), WorldPanels FarmSeedBar */
.farmbar .fb-prows { align-items: stretch; }
/* user 2026-10-14 pond: parent rows without the boxed bg, action buttons under them */
.farmbar .fb-pond { display: flex; flex-direction: column; gap: calc(6 * var(--u)); }
.farmbar .fb-ptop { display: flex; align-items: flex-end; gap: calc(6 * var(--u)); }
.farmbar .fb-pond .fb-prows { background: none; border: 0; padding: 0; }
.farmbar .fb-acts { display: flex; justify-content: center; gap: calc(8 * var(--u)); }
.farmbar .fb-prow { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.farmbar .fb-prow .note { white-space: nowrap; }
.farmbar .fb-group .fb-slot .slot { width: calc(44 * var(--u)); height: calc(44 * var(--u)); }
.farmbar .fb-cap { font-size: calc(11 * var(--u)); font-weight: 600; color: var(--ink-dim); }
.hotbar > .farmbar { overflow: visible; }
.farmbar .fb-x { position: absolute; top: calc(-10 * var(--u)); right: calc(-10 * var(--u)); width: calc(24 * var(--u)); height: calc(24 * var(--u)); min-height: 0; padding: 0;
  display: grid; place-items: center; border-radius: 50%; background: var(--cream-lt); border: var(--line-w) solid var(--line); box-shadow: var(--gloss); cursor: pointer; }
.farmbar .fb-x .ic { width: calc(14 * var(--u)); height: calc(14 * var(--u)); }
/* K-323 farm info = steel slot button like the fishing HUD (.fish-btn slot filled), floating top-centre, "Lv N" badge bottom-right */
.farm-info-btn.fish-btn { position: absolute; z-index: 4; top: calc(10 * var(--u) + env(safe-area-inset-top)); left: 50%; transform: translateX(-50%); pointer-events: auto; }
.farm-info-btn .fi-lv { position: absolute; right: calc(-8 * var(--u)); bottom: calc(-6 * var(--u)); font-style: normal; font-size: calc(10 * var(--u)); font-weight: 800; line-height: 1;
  padding: calc(2 * var(--u)) calc(4 * var(--u)); border-radius: calc(6 * var(--u)); background: #3b2a1f; color: #ffe08a; border: calc(1 * var(--u)) solid #c9a227; white-space: nowrap; }

/* ============ K-325 UI v4 controls (2026-10-08, kit approved kanban/shots/k325-buttons.png): steel pieces /assets/ui4/*.webp
   (lossless from design/ui-v4-buttons/cut/*.png @2x). 9-slice = border-image, slice = px in the @2x art (cut/slices.json),
   image-width = slice/2 * --u (UI v3 rule: corners/edges fixed, only the centre stretches). --pk = cap scale for short pills (sm .78).
   .btn = pill (default/ghost/sky); brass/mint/ok/active/key.max = pill_primary; rose/danger/pvpflag.on/key.clear = pill_danger;
   :hover = brightness, :active = *_pressed art, :disabled = *_disabled art. .seg .btn = tab / tab_active. .rbtn/.sleep-btn = round.
   input.sw = toggle sprite, checkbox = check, radio + .toggle i = radio. select = 3-slice background (dropdown_l/m/r + arrow; border-image
   fill would cover the arrow). Slider = Panels.jsx <Slider> (.slider: minus/plus ends, track, gold fill --v 0..1, invisible native range on top). ============ */
.btn {
  --pill: url(/assets/ui4/pill.webp); --pill-p: url(/assets/ui4/pill_pressed.webp); --pill-d: url(/assets/ui4/pill_disabled.webp); --pk: 1;
  min-height: var(--btn-h); padding: 0 calc(6 * var(--u)); background: none; box-shadow: none; border-radius: 0;
  border: 0 solid transparent; border-width: 0 calc(20 * var(--u) * var(--pk));
  border-image: var(--pill) 43 47 43 47 fill / calc(21.5 * var(--u) * var(--pk)) calc(23.5 * var(--u) * var(--pk)) / 0 stretch;
  color: var(--cream); text-shadow: 0 1px 0 #000, 0 0 calc(3 * var(--u)) rgba(0, 0, 0, .6);
}
.btn.brass, .btn.mint, .btn.ok, .btn.active {
  --pill: url(/assets/ui4/pill_primary.webp); --pill-p: url(/assets/ui4/pill_primary_pressed.webp); --pill-d: url(/assets/ui4/pill_primary_disabled.webp); color: #ffe9a8; }
.btn.rose, .btn.danger, .btn.pvpflag.on {
  --pill: url(/assets/ui4/pill_danger.webp); --pill-p: url(/assets/ui4/pill_danger_pressed.webp); --pill-d: url(/assets/ui4/pill_danger_disabled.webp); color: var(--cream); }
.btn:hover { filter: brightness(1.1); }
.btn:active:not(:disabled) { border-image-source: var(--pill-p); transform: translateY(calc(1 * var(--u))); }
.btn:disabled { border-image-source: var(--pill-d); filter: none; color: #d6d0c4; text-shadow: 0 1px 0 rgba(0, 0, 0, .55); }
.btn:focus-visible { outline: calc(3 * var(--u)) solid var(--gold); outline-offset: calc(1 * var(--u)); }
.btn.sm { --pk: .78; min-height: calc(34 * var(--u)); padding: 0 calc(4 * var(--u)); border-width: 0 calc(16 * var(--u)); box-shadow: none; }
.btn.big { min-height: calc(52 * var(--u)); }
.list .btn { border-width: 0 calc(18 * var(--u)); box-shadow: none; }
/* K-387 keypads (QtyPad/NumPad .qtypad) keep the pre-K-325 cream key look (user 2026-10-09: ui4 pills on number keys "ไม่สวย"): undo the pill border-image */
.qtypad .btn.key { border-image: none; background: var(--face); border: calc(2 * var(--u)) solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--gloss), 0 calc(2 * var(--u)) 0 var(--line); color: var(--line); text-shadow: none; padding: calc(2 * var(--u)); min-height: calc(38 * var(--u)); }
.qtypad .btn.key:active:not(:disabled) { box-shadow: var(--gloss), 0 0 0 var(--line); transform: translateY(calc(2 * var(--u))); }
.qtypad .btn.key:disabled { filter: grayscale(.7) opacity(.6); color: var(--line); }
.btn kbd { color: var(--gold); background: rgba(0, 0, 0, .35); border: calc(1 * var(--u)) solid rgba(243, 233, 210, .45); text-shadow: none; }
.list .btn .sub { color: #d9ccb0; }
.pvpflag.on { background: none; }
/* phones: sm pills keep a ~44px tap target (invisible vertical bleed) */
@media (pointer: coarse) { .btn.sm::before { content: ""; position: absolute; left: 0; right: 0; top: calc(-5 * var(--u)); bottom: calc(-5 * var(--u)); } }
/* tabs / segmented */
.seg .btn { --pill: url(/assets/ui4/tab.webp); --pill-p: url(/assets/ui4/tab.webp); --pill-d: url(/assets/ui4/tab.webp);
  min-height: calc(40 * var(--u)); border-width: 0 calc(16 * var(--u)); border-image-slice: 39 37 39 37 fill; border-image-width: calc(19.5 * var(--u) * var(--pk)) calc(18.5 * var(--u) * var(--pk));
  color: #c9c3b6; }
.seg .btn.sm { --pk: .85; min-height: calc(34 * var(--u)); }
.seg .btn.active { --pill: url(/assets/ui4/tab_active.webp); --pill-p: url(/assets/ui4/tab_active.webp); border-image-slice: 39 fill; color: #ffe9a8; }
.seg .btn:disabled { opacity: .55; }
/* round icon buttons */
.rbtn, .sleep-btn { border: 0; border-radius: 50%; box-shadow: none; color: #e9d9b0; background: url(/assets/ui4/round.webp) center / contain no-repeat; }
.rbtn:active, .sleep-btn:active { transform: none; box-shadow: none; background-image: url(/assets/ui4/round_pressed.webp); }
.sleep-btn.on { background: url(/assets/ui4/round_pressed.webp) center / contain no-repeat; filter: drop-shadow(0 0 calc(6 * var(--u)) rgba(140, 160, 255, .8)); }
.rbtn .ic { width: calc(24 * var(--u)); height: calc(24 * var(--u)); }
/* touch HUD discs (K-294 .hb-swap, K-301 .dock-fold): same socket; --line scoped = cream arrow on steel */
.hotbar > .hb-swap, .dock-fold { --line: #e9d9b0; color: #e9d9b0; border: 0; box-shadow: none; background: url(/assets/ui4/round.webp) center / contain no-repeat; }
.hotbar > .hb-swap:active, .dock-fold:active { transform: none; box-shadow: none; background-image: url(/assets/ui4/round_pressed.webp); }
/* toggle / check / radio sprites */
input.sw { width: calc(59.5 * var(--u)); height: calc(28 * var(--u)); border: 0; border-radius: 0; box-shadow: none;
  background: url(/assets/ui4/toggle_off.webp) center / 100% 100% no-repeat; }
input.sw::after { display: none; }
input.sw:checked { background: url(/assets/ui4/toggle_on.webp) center / 100% 100% no-repeat; }   /* full shorthand: old K-266 :checked background reset size */
input[type=checkbox]:not(.sw), input[type=radio] { appearance: none; -webkit-appearance: none; flex: none; width: calc(26 * var(--u)); height: calc(26 * var(--u));
  min-height: 0; padding: 0; margin: 0; border: 0; border-radius: 0; box-shadow: none; cursor: inherit; background: url(/assets/ui4/check_off.webp) center / contain no-repeat; }
input[type=checkbox]:not(.sw):checked { background-image: url(/assets/ui4/check_on.webp); }
input[type=radio] { background-image: url(/assets/ui4/radio_off.webp); }
input[type=radio]:checked { background-image: url(/assets/ui4/radio_on.webp); }
input.sw:disabled, input[type=checkbox]:disabled, input[type=radio]:disabled { opacity: .5; }
input.sw:focus-visible, input[type=checkbox]:focus-visible, input[type=radio]:focus-visible { outline: calc(3 * var(--u)) solid var(--gold); outline-offset: calc(2 * var(--u)); border-radius: calc(6 * var(--u)); }
.toggle i { width: calc(26 * var(--u)); height: calc(26 * var(--u)); border: 0; box-shadow: none; background: url(/assets/ui4/radio_off.webp) center / contain no-repeat; }
.toggle.on i { background: url(/assets/ui4/radio_on.webp) center / contain no-repeat; box-shadow: none; }   /* full shorthand: the old .toggle.on i radial shorthand (higher specificity) left size auto = cropped 52px art (user 2026-10-13) */
/* dropdown: caps 22u (= 44px @2x / 2) fixed, middle stretches, arrow 17.5x14u */
select, .set-row select, .ach-pick select, input.dd, .set-row .dd, .ach-pick .dd {
  appearance: none; -webkit-appearance: none; height: calc(40 * var(--u)); min-height: calc(40 * var(--u)); padding: 0 calc(46 * var(--u)) 0 calc(26 * var(--u));   /* clear the cap rivets */
  border: 0; border-radius: 0; box-shadow: none; color: var(--cream); text-shadow: 0 1px 0 #000; cursor: inherit;
  background: url(/assets/ui4/dropdown_arrow.webp) right calc(16 * var(--u)) center / calc(17.5 * var(--u)) calc(14 * var(--u)) no-repeat,
    url(/assets/ui4/dropdown_l.webp) left center / calc(22 * var(--u)) 100% no-repeat,
    url(/assets/ui4/dropdown_r.webp) right center / calc(22 * var(--u)) 100% no-repeat,
    url(/assets/ui4/dropdown_m.webp) center / calc(100% - 44 * var(--u)) 100% no-repeat;
}
select option { background: #26303c; color: var(--cream); }
select:focus-visible, input.dd:focus-visible { outline: calc(3 * var(--u)) solid var(--gold); outline-offset: calc(1 * var(--u)); }
select:disabled, input.dd:disabled { opacity: .55; }
/* slider (Panels.jsx Slider) */
.slider { display: flex; align-items: center; flex: 1 1 calc(220 * var(--u)); min-width: calc(120 * var(--u)); max-width: calc(260 * var(--u)); }
.slider .sl-end { position: relative; z-index: 1; flex: none; width: calc(30 * var(--u)); height: calc(30 * var(--u)); min-height: 0; padding: 0; border: 0; cursor: inherit;
  background: url(/assets/ui4/slider_minus.webp) center / contain no-repeat; }
.slider .sl-end.plus { background-image: url(/assets/ui4/slider_plus.webp); }
.slider .sl-end:active:not(:disabled) { transform: translateY(calc(1 * var(--u))); }
.slider .sl-end:disabled { opacity: .5; }
.slider .sl-end::before { content: ""; position: absolute; inset: calc(-7 * var(--u)) calc(-4 * var(--u)); }   /* tap target ~44u */
.slider .sl-track { position: relative; flex: 1; height: calc(20 * var(--u)); margin: 0 calc(-6 * var(--u)); border: 0 solid transparent;
  border-image: url(/assets/ui4/slider_track.webp) 19 32 19 33 fill / calc(9.5 * var(--u)) calc(16 * var(--u)) calc(9.5 * var(--u)) calc(16.5 * var(--u)) stretch; }
.slider .sl-fill { position: absolute; left: calc(5 * var(--u)); top: calc(3 * var(--u)); height: calc(14 * var(--u)); width: calc(var(--v, 0) * (100% - 10 * var(--u)));
  border: 0 solid transparent; border-image: url(/assets/ui4/slider_fill.webp) 13 28 13 28 fill / calc(6.5 * var(--u)) calc(14 * var(--u)) stretch; }
.slider .sl-val { position: absolute; inset: 0; z-index: 1; display: grid; place-items: center; pointer-events: none; font-size: calc(12 * var(--u)); font-weight: 600; line-height: 1;
  color: var(--cream); text-shadow: 0 1px 0 #000, 0 0 calc(2 * var(--u)) #000; font-variant-numeric: tabular-nums; }
.slider input[type=range] { position: absolute; z-index: 2; inset: calc(-8 * var(--u)) 0; width: 100%; height: calc(100% + 16 * var(--u)); margin: 0; padding: 0; min-height: 0; opacity: 0; cursor: inherit; }
.slider .sl-track:has(input:focus-visible) { outline: calc(2 * var(--u)) solid var(--gold); outline-offset: calc(3 * var(--u)); }
.slider.off { opacity: .55; }
.cd-qty .slider { max-width: none; }
.set-row .slider { flex: 0 1 calc(230 * var(--u)); }   /* same width every row, right-aligned */
/* K-325 Settings (Panels.jsx SettingsPanel): top tabs (.seg.set-tabs), sections = ui3 inset, rows dashed, logout bottom-right */
.set-tabs { flex-wrap: nowrap; gap: calc(4 * var(--u)); }
.set-tabs .btn { min-width: 0; padding: 0; }
.settings-panel .set-sec { background: none; border-radius: 0; box-shadow: none; border: calc(4 * var(--u)) solid transparent; padding: calc(6 * var(--u)) calc(12 * var(--u)); margin: 0;
  border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch; }
.settings-panel .set-row { border-top-color: #d8c39b; }
.settings-panel .set-foot { justify-content: flex-end; margin-top: auto; }
/* K-482 legal links (Settings foot + cash-shop top-up) -> static game/legal/* in a new tab */
.legal-links { text-align: right; } .legal-links a { color: #8a4b12; }
.settings-panel .legal-links { margin-top: auto; } .settings-panel .legal-links + .set-foot { margin-top: calc(4 * var(--u)); }
/* K-326 Mastery (Panels.jsx MasteryList): .set-tabs per kind; list scrolls under fixed tabs; rows = ui3 inset cards, 2 cols when panel >= 600px.
   Bar = ui4 slider_track + slider_fill full width, clip-path to --v (0..1) so the fill caps never squash at low xp. */
.mastery-panel .body { overflow: hidden; }
.mastery-tabs { flex: none; }
.mastery-tabs .btn { white-space: nowrap; }
@container (max-width: 400px) { .mastery-tabs .btn { font-size: calc(12.5 * var(--u)); border-width: 0 calc(11 * var(--u)); } }   /* phone portrait: เก็บเกี่ยว/งานฝีมือ on one line */
.mastery-list { flex: 1; min-height: 0; overflow-y: auto; display: grid; grid-template-columns: 1fr; align-content: start; gap: calc(6 * var(--u)); padding-right: calc(2 * var(--u)); }
@container (min-width: 600px) { .mastery-list { grid-template-columns: 1fr 1fr; } }
.mastery-row { display: grid; grid-template-columns: calc(46 * var(--u)) minmax(0, 1fr) auto; grid-template-areas: "ic name tier" "ic bar bar"; align-items: center;
  column-gap: calc(8 * var(--u)); row-gap: calc(2 * var(--u)); padding: calc(4 * var(--u)) calc(8 * var(--u)); border: calc(4 * var(--u)) solid transparent;
  border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch; }
.mastery-row .ms-slot { grid-area: ic; width: calc(46 * var(--u)); height: calc(46 * var(--u)); padding: calc(6 * var(--u)); display: grid; place-items: center;
  border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.mastery-row .ms-slot .ic { width: 100%; height: 100%; object-fit: contain; }
.mastery-row .name { grid-area: name; min-width: 0; font-size: calc(15 * var(--u)); font-weight: 600; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mastery-row .tier { grid-area: tier; width: calc(34 * var(--u)); height: calc(34 * var(--u)); margin: calc(-4 * var(--u)) 0; display: grid; place-items: center; font-size: calc(13 * var(--u)); font-weight: 700; line-height: 1;
  color: var(--gold); text-shadow: 0 1px 0 #000; background: url(/assets/ui3/tier_badge.png) center / contain no-repeat; }
.mastery-row .mbar { grid-area: bar; position: relative; height: calc(20 * var(--u)); border: 0 solid transparent;
  border-image: url(/assets/ui4/slider_track.webp) 19 32 19 33 fill / calc(9.5 * var(--u)) calc(16 * var(--u)) calc(9.5 * var(--u)) calc(16.5 * var(--u)) stretch; }
.mastery-row .mbar i { position: absolute; left: calc(5 * var(--u)); right: calc(5 * var(--u)); top: calc(3 * var(--u)); height: calc(14 * var(--u)); border: 0 solid transparent;
  border-image: url(/assets/ui4/slider_fill.webp) 13 28 13 28 fill / calc(6.5 * var(--u)) calc(14 * var(--u)) stretch; clip-path: inset(0 calc((1 - var(--v, 0)) * 100%) 0 0 round calc(7 * var(--u))); }
.mastery-row .mbar b { position: absolute; inset: 0; display: grid; place-items: center; font-size: calc(11.5 * var(--u)); font-weight: 600; line-height: 1;
  color: var(--cream); text-shadow: 0 1px 0 #000, 0 0 calc(2 * var(--u)) #000; }
.mastery-row.max .tier { filter: drop-shadow(0 0 calc(4 * var(--u)) rgba(255, 214, 120, .9)); }
.mastery-row.max .mbar b { color: #ffe9a8; }
/* K-327 battle pass (user 2026-10-08 "ติ๊กถูกไม่สวย, ช่องว่างข้างล่างเยอะ"): panel height = content (cap = old fixed height, body scrolls past it);
   premium owned = non-interactive pill_primary span (.btn.brass.bp-badge) + ui4 check_on sprite, no unicode tick. */
.panel.bpass { height: auto; bottom: auto !important;   /* .panel @media(max-height:520px) etc set bottom:4px -> with top:50% that would clamp height to half screen */
   max-height: min(calc(100vh - calc(60 * var(--u))), calc(820 * var(--u))) !important; }
.panel.bpass .body { height: auto; }
@media (max-width: 620px) { .panel.bpass { height: auto; max-height: calc(100vh - calc(24 * var(--u))) !important; } }
.bp-badge { cursor: default; pointer-events: none; font-weight: 600; }
.bp-badge .bp-ok { flex: none; width: calc(22 * var(--u)); height: calc(22 * var(--u)); background: url(/assets/ui4/check_on.webp) center / contain no-repeat; }
/* K-335 quest tabs (WorldPanel เนื้อเรื่อง|รายวัน|รายสัปดาห์|รายเดือน + BoardPanel periods): ui4 .seg.set-tabs (K-326 style) + red count badge;
   list scrolls under fixed tabs; board row = ui3 inset card: name / ui4 slider bar (--v 0..1) / reward slots (ui3 steel slot) / claim state.
   Dock badge = .mbtn .badge (coral count). Dialogue hand-in = .dlg-turnin mint buttons. */
.quest-panel .body { overflow: hidden; display: flex; flex-direction: column; }
.quest-tabs { flex: none; margin-bottom: calc(6 * var(--u)); }
.quest-tabs .btn { position: relative; white-space: nowrap; overflow: visible; }
@container (max-width: 400px) { .quest-tabs .btn { font-size: calc(12.5 * var(--u)); border-width: 0 calc(11 * var(--u)); } }
.quest-tabs .badge, .dock .mbtn .badge { position: absolute; right: calc(-4 * var(--u)); top: calc(-6 * var(--u)); min-width: calc(18 * var(--u)); height: calc(18 * var(--u)); padding: 0 calc(4 * var(--u));
  border-radius: calc(9 * var(--u)); background: var(--coral); color: #fff; font-size: calc(10.5 * var(--u)); font-weight: 700; line-height: 1; display: grid; place-items: center;
  border: calc(2 * var(--u)) solid var(--line); z-index: 1; pointer-events: none; }
.dock .mbtn { position: relative; }
.dock .mbtn .badge.dot { min-width: 0; width: calc(14 * var(--u)); height: calc(14 * var(--u)); padding: 0; right: calc(-2 * var(--u)); top: calc(-2 * var(--u)); }   /* user 2026-10-13: ⋯ red dot = a ⋯ row has a badge */
.dm-badge { flex: none; min-width: calc(20 * var(--u)); height: calc(20 * var(--u)); padding: 0 calc(5 * var(--u)); border-radius: calc(10 * var(--u)); background: var(--coral); color: #fff;
  font-size: calc(11 * var(--u)); font-weight: 700; line-height: 1; display: grid; place-items: center; }   /* ⋯ row count (mail unread) */
.qb-list { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: calc(6 * var(--u)); padding-right: calc(2 * var(--u)); }
.qb-reset { margin: 0; font-size: calc(12.5 * var(--u)); color: var(--ink-dim); text-align: right; }
.qb-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name rw" "bar rw" "act act"; align-items: center;
  column-gap: calc(8 * var(--u)); row-gap: calc(3 * var(--u)); padding: calc(6 * var(--u)) calc(10 * var(--u)); border: calc(4 * var(--u)) solid transparent;
  border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch; }
.qb-row .name { grid-area: name; min-width: 0; font-size: calc(15 * var(--u)); font-weight: 600; line-height: 1.25; }
.qb-row .qb-old { font-weight: 400; color: var(--ink-dim); }
.qb-row .mbar { grid-area: bar; position: relative; height: calc(20 * var(--u)); border: 0 solid transparent;
  border-image: url(/assets/ui4/slider_track.webp) 19 32 19 33 fill / calc(9.5 * var(--u)) calc(16 * var(--u)) calc(9.5 * var(--u)) calc(16.5 * var(--u)) stretch; }
.qb-row .mbar i { position: absolute; left: calc(5 * var(--u)); right: calc(5 * var(--u)); top: calc(3 * var(--u)); height: calc(14 * var(--u)); border: 0 solid transparent;
  border-image: url(/assets/ui4/slider_fill.webp) 13 28 13 28 fill / calc(6.5 * var(--u)) calc(14 * var(--u)) stretch; clip-path: inset(0 calc((1 - var(--v, 0)) * 100%) 0 0 round calc(7 * var(--u))); }
.qb-row .mbar b { position: absolute; inset: 0; display: grid; place-items: center; font-size: calc(11.5 * var(--u)); font-weight: 600; line-height: 1;
  color: var(--cream); text-shadow: 0 1px 0 #000, 0 0 calc(2 * var(--u)) #000; }
.qb-row .qb-rw { grid-area: rw; display: flex; gap: calc(4 * var(--u)); }
.qb-row .rw-slot { position: relative; width: calc(46 * var(--u)); height: calc(46 * var(--u)); padding: calc(8 * var(--u)); display: grid; place-items: center;
  border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.qb-row .rw-slot .ic { width: 100%; height: 100%; object-fit: contain; }
.qb-row .rw-slot b { position: absolute; right: calc(3 * var(--u)); bottom: calc(1 * var(--u)); font-size: calc(11 * var(--u)); color: #fff; text-shadow: 0 1px 0 #000, 0 0 calc(2 * var(--u)) #000; }
.qb-row .qb-act { grid-area: act; justify-self: end; }
.qb-row .qb-act:empty { display: none; }
.qb-row .qb-act .note { font-size: calc(12.5 * var(--u)); font-weight: 600; color: #8a4b12; }
.qb-row.got { opacity: .72; }
.dlg-turnin { display: flex; flex-wrap: wrap; gap: calc(6 * var(--u)); margin-top: calc(6 * var(--u)); }
.qb-ev { display: flex; flex-direction: column; gap: calc(6 * var(--u)); }
.qb-ev + .qb-ev { margin-top: calc(8 * var(--u)); }
.qb-ev-name { margin: 0; font-size: calc(16 * var(--u)); font-weight: 700; color: #8a4b12; }
@media (max-width: 620px) { .quest-tabs { gap: calc(2 * var(--u)); } .quest-tabs .btn { font-size: calc(11.5 * var(--u)); border-width: 0 calc(8 * var(--u)); } }   /* 5 tabs fit at 390px */
/* K-336 login (App.jsx Login): ui4 tabs (.seg.set-tabs) + form; eye toggle inside the password field (44u tap); "หรือ" rule; OAuth = plain ui4 pills */
.login .set-tabs .btn { flex: 1; }
.pw-field { position: relative; display: flex; }
.pw-field input { flex: 1; padding-right: calc(48 * var(--u)); }
.pw-eye { position: absolute; right: calc(2 * var(--u)); top: 50%; transform: translateY(-50%); width: calc(44 * var(--u)); height: calc(44 * var(--u)); min-height: 0;
  padding: 0; display: grid; place-items: center; background: none; border: 0; box-shadow: none; color: var(--ink-dim); }
.pw-eye:active { transform: translateY(-50%); box-shadow: none; }
.pw-eye .ic { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
.login-or { display: flex; align-items: center; gap: calc(8 * var(--u)); color: var(--ink-dim); font-size: .9em; }
.login-or::before, .login-or::after { content: ""; flex: 1; border-top: calc(1 * var(--u)) solid currentColor; opacity: .45; }
.login a.btn { display: flex; align-items: center; justify-content: center; text-decoration: none; }

/* K-338 provider sign-in buttons: brand look, not the steel kit (Google white + G, LINE #06C755 + white logo) */
.sso { display: flex; align-items: center; justify-content: center; gap: calc(10 * var(--u)); min-height: calc(46 * var(--u)); padding: 0 calc(16 * var(--u)); margin-top: calc(8 * var(--u));
  border-radius: calc(10 * var(--u)); font-weight: 700; font-size: calc(15 * var(--u)); text-decoration: none; box-shadow: 0 calc(2 * var(--u)) 0 rgba(0, 0, 0, .25); }
.sso:hover { filter: brightness(1.04); } .sso:active { transform: translateY(calc(2 * var(--u))); box-shadow: none; }
.sso-google { background: #fff; color: #1f1f1f; border: 1px solid #747775; }
.sso-line { background: #06C755; color: #fff; border: 1px solid #05a647; }
.sso-ic { width: calc(24 * var(--u)); height: calc(24 * var(--u)); flex: none; }

/* K-339 no page scroll (user 2026-10-08): document never scrolls on any screen/device; only containers (.sheet, .panel .body, lists) scroll.
   QA tools/qa/k339-noscroll.mjs. Pre-game --u gets an extra height cap (/800 knob) so the register sheet fits 16:9 / 16:10 desktop; :root:has()
   = every --u token recomputes (a --u override on .title-screen would not: tokens resolve at :root). Landscape = logo left, sheet right. */
html, body, #root { height: 100%; overflow: hidden; overscroll-behavior: none; }
:root:has(.title-screen) { --u: clamp(.85px, min(max(min(100vw / 1280, 100dvh / 720), min(100vw / 720, 100dvh / 1280)), 100dvh / 800), 2px); }   /* theme.css --u + height cap */
.title-screen { height: 100vh; height: 100dvh; min-height: 0; overflow: hidden; justify-content: safe center; }
.title-screen .logo { flex: 0 100 auto; min-height: calc(64 * var(--u)); min-width: 0; height: min(calc(300 * var(--u)), 34vh); width: auto; max-width: 60vw; object-fit: contain; margin-top: 0; }
.title-screen .sheet { flex: 0 1 auto; min-height: 0; max-height: 100%; overflow-y: auto; overscroll-behavior: contain; margin-top: 0; }
.create-col { display: flex; flex-direction: column; gap: calc(12 * var(--u)); min-width: 0; }
/* Title screens stacked on every viewport (user 2026-10-08, undoes K-339 landscape logo | sheet): logo on top, sheet below; the logo
   shrinks by height first (flex-shrink 100, vh caps) so nothing page-scrolls. */
@media (orientation: landscape) and (min-height: 521px) { .title-screen .logo { height: min(calc(300 * var(--u)), 30vh); } }   /* stacked title: logo gives height to the sheet */
@media (orientation: landscape) and (max-height: 520px) {   /* phone landscape: small logo; login = form | SSO columns; create = no logo */
  .title-screen { gap: calc(6 * var(--u)); padding-top: max(calc(8 * var(--u)), env(safe-area-inset-top)); padding-bottom: max(calc(8 * var(--u)), env(safe-area-inset-bottom)); }
  .title-screen .logo { height: 16vh; min-height: 0; }
  .title-screen:has(.create) .logo { display: none; }
  .sheet.login:has(.login-sso) { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .85fr); column-gap: calc(20 * var(--u)); align-content: start; width: min(calc(640 * var(--u)), 100%); }
  .sheet.login > .set-tabs { grid-column: 1 / -1; }
  .login-sso { align-self: center; }
}

/* K-341 creation wizard + Stepper (HairPicker.jsx Stepper: creation + barber; replaces <select>). Wizard = .sheet.create.wizard (K-339 columns):
   .wiz-steps numbered dots (done = sage, on = blue) + .wiz-bar (--v fill) + .wiz-body (one step) + .wiz-nav (ย้อนกลับ | ถัดไป). */
.stepper .st-label { font-size: .9em; font-weight: 500; color: var(--ink-dim); }
.stepper .face-step { border-radius: 999px; outline-offset: calc(2 * var(--u)); }
.stepper .face-step:focus-visible { outline: calc(3 * var(--u)) solid var(--blue); }
.stepper .face-step > .btn { min-width: calc(44 * var(--u)); min-height: calc(40 * var(--u)); padding: 0; font-size: calc(22 * var(--u)); line-height: 1; }
.st-val { display: flex; align-items: center; justify-content: center; gap: calc(8 * var(--u)); min-width: 0; min-height: calc(40 * var(--u)); padding: 0 calc(10 * var(--u));
  background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); border-radius: 999px; font-weight: 600; }
.st-val span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-val small { color: var(--ink-dim); font-weight: 400; font-size: .78em; flex: none; }
.st-sw { display: inline-block; flex: none; width: calc(20 * var(--u)); height: calc(20 * var(--u)); border-radius: 50%; border: calc(2 * var(--u)) solid var(--line); vertical-align: middle; }
.sheet.create.wizard { width: min(calc(760 * var(--u)), 100%); gap: calc(10 * var(--u)); }
.wiz-top { display: grid; gap: calc(8 * var(--u)); }
.wiz-top h2 { margin: 0; text-align: center; font-size: var(--title-size); }
.wiz-main { display: flex; flex-direction: column; align-items: center; gap: calc(12 * var(--u)); min-height: 0; }
.wiz-main .create-col { gap: calc(10 * var(--u)); width: 100%; }
.wiz-title { margin: 0; font-size: calc(18 * var(--u)); }
@media (orientation: landscape) {
  .wiz-main { flex-direction: row; align-items: flex-start; }
  .wiz-main .create-portrait { flex: none; }
  .wiz-main .create-col { flex: 1 1 0; }
}
@media (orientation: landscape) and (max-height: 520px) {   /* phone landscape: compact wizard so step + nav fit (no inner scroll) */
  .wizard .wiz-top h2, .wiz-steps li span, .wiz-title { display: none; }
  .sheet.create.wizard { gap: calc(6 * var(--u)); padding-top: calc(12 * var(--u)); padding-bottom: calc(12 * var(--u)); }
  .wiz-main .create-portrait { width: calc(140 * var(--u)); height: calc(170 * var(--u)); }
  .wizard .stepper { flex-direction: row; align-items: center; gap: calc(8 * var(--u)); }
  .wizard .stepper .st-label { flex: 0 0 calc(72 * var(--u)); }
  .wizard .stepper .face-step { flex: 1; }
  .wiz-body { min-height: 0; gap: calc(6 * var(--u)); }
  .wiz-sum { grid-template-columns: 1fr 1fr; }
}
.wiz-steps { list-style: none; margin: 0; padding: 0; display: flex; justify-content: space-between; gap: calc(2 * var(--u)); }
.wiz-steps li { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: calc(2 * var(--u)); font-size: calc(11 * var(--u)); color: var(--ink-dim); }
.wiz-steps li span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wiz-steps button { width: calc(28 * var(--u)); height: calc(28 * var(--u)); padding: 0; border-radius: 50%; font: inherit; font-size: calc(13 * var(--u)); font-weight: 600;
  color: var(--ink); background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--line); cursor: default; }
.wiz-steps li.done button { background: var(--sage); color: #fff; cursor: pointer; }
.wiz-steps li.on button { background: var(--blue); color: #fff; box-shadow: 0 0 0 calc(3 * var(--u)) rgba(255, 255, 255, .7); }
.wiz-steps li.on { color: var(--ink); font-weight: 600; }
.wiz-bar { height: calc(8 * var(--u)); border-radius: 999px; background: var(--cream-dk); border: calc(2 * var(--u)) solid var(--line); overflow: hidden; }
.wiz-bar i { display: block; height: 100%; width: var(--v); background: var(--sage); transition: width .2s; }
.wiz-body { display: grid; gap: calc(10 * var(--u)); align-content: start; min-height: calc(120 * var(--u)); text-align: left; }
.name-check { margin: 0; min-height: 1.4em; color: var(--ink-dim); }
.name-check.ok { color: var(--sage-dk, #4f7a4a); font-weight: 600; } .name-check.bad { color: var(--coral-dk, #b4472f); }
.wiz-sum { display: grid; gap: calc(4 * var(--u)); margin: 0; }
.wiz-sum div { display: flex; justify-content: space-between; gap: calc(10 * var(--u)); padding: calc(4 * var(--u)) calc(10 * var(--u)); background: var(--cream-lt); border-radius: var(--radius-sm); }
.wiz-sum dt { color: var(--ink-dim); } .wiz-sum dd { margin: 0; font-weight: 600; text-align: right; }
.wiz-nav { display: grid; grid-template-columns: 1fr 1.4fr; gap: calc(10 * var(--u)); }

/* K-344 login/title BG = sunset scene (design/login-bg-k344, user pick แบบ B). Portrait screens use the 9:16 version. */
@media (orientation: portrait) {
  .title-screen { background-image: url(/assets/ui2/login_bg_k344_port.webp?v=k344b); }
}

/* K-345 login: no scrollbars at all on pre-game screens (page never scrolls, K-339; panel content scales to fit) + glow motes */
.title-screen, .title-screen .sheet { scrollbar-width: none; }
.title-screen::-webkit-scrollbar, .title-screen .sheet::-webkit-scrollbar { display: none; }
.title-screen { position: relative; overflow: hidden; isolation: isolate; }   /* motes z -1 = above the BG, under every child */
.title-motes { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.title-motes i { position: absolute; border-radius: 50%; mix-blend-mode: screen; opacity: 0;
  animation-name: mote-float, mote-twinkle; animation-timing-function: ease-in-out; animation-iteration-count: infinite; }
.title-motes i.m0 { background: radial-gradient(circle, #fff7d6 0%, #ffd36b 45%, rgba(255, 190, 80, 0) 70%); }
.title-motes i.m1 { background: radial-gradient(circle, #fff 0%, #ffe9a8 40%, rgba(255, 233, 168, 0) 70%); }
.title-motes i.m2 { background: radial-gradient(circle, #fff3fb 0%, #ffb6d9 45%, rgba(255, 182, 217, 0) 70%); }
@keyframes mote-float { 0% { transform: translate(0, 0); } 50% { transform: translate(calc(14 * var(--u)), calc(-26 * var(--u))); } 100% { transform: translate(0, 0); } }
@keyframes mote-twinkle { 0%, 100% { opacity: .15; } 50% { opacity: .95; } }
@media (prefers-reduced-motion: reduce) { .title-motes i { animation: none; opacity: .5; } }

/* K-347 admin warp */
.admin-warp-q { width: 100%; margin-bottom: calc(8 * var(--u)); }
.admin-warp-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(180 * var(--u)), 1fr)); gap: calc(6 * var(--u)); max-height: 60vh; overflow-y: auto; }
.admin-warp-list .btn { width: 100%; justify-content: space-between; }
.admin-warp-list small { opacity: .7; font-size: calc(10 * var(--u)); }

/* K-346 quest nav: tracker card under the minimap (right), target pin, off-screen edge arrow (NavTracker.jsx; pin/edge moved by rAF transform) */
.nav-track { position: absolute; z-index: 4; right: calc(max(calc(12 * var(--u)), env(safe-area-inset-right)) + var(--menu-btn, calc(44 * var(--u))) + 30 * var(--u)); top: calc(var(--mm) + 78 * var(--u) + env(safe-area-inset-top));   /* left of the dock column */
  width: min(calc(250 * var(--u)), 46vw); padding: calc(7 * var(--u)) calc(10 * var(--u)); border-radius: calc(10 * var(--u)); color: #fff6df;
  background: rgba(36, 24, 14, .78); border: calc(2 * var(--u)) solid rgba(255, 211, 77, .55); box-shadow: 0 calc(3 * var(--u)) calc(8 * var(--u)) rgba(0, 0, 0, .35);
  font-size: calc(14 * var(--u)); line-height: 1.3; pointer-events: auto; overflow: hidden; }
.nav-track header { display: flex; align-items: center; gap: calc(6 * var(--u)); }
.nav-track .nt-list { list-style: none; margin: calc(6 * var(--u)) 0 0; padding: calc(6 * var(--u)) 0 0; border-top: 1px solid rgba(255, 255, 255, .15); max-height: calc(160 * var(--u)); overflow-y: auto; }   /* HUD quest list, single-select ติดตาม */
.nav-track .nt-list li { display: flex; align-items: center; gap: calc(6 * var(--u)); padding: calc(2 * var(--u)) 0; }
.nav-track .nt-list li span { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #e8d9a8; }
.nav-track .nt-list li.on span { color: #ffd34d; font-weight: 700; }
.nav-track .nt-list .nt-pin.on { outline: calc(2 * var(--u)) solid #ffd34d; }
.nav-track header img, .nav-track header svg { width: calc(20 * var(--u)); height: calc(20 * var(--u)); flex: none; }
.nav-track header b { flex: 1; min-width: 0; color: #ffd34d; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-track .nt-x { flex: none; width: calc(26 * var(--u)); height: calc(26 * var(--u)); border: 0; border-radius: 50%; background: rgba(255, 255, 255, .12); color: inherit; font-size: calc(18 * var(--u)); line-height: 1; cursor: inherit; }
.nav-track p { margin: calc(3 * var(--u)) 0 0; }
.nav-track .nt-step { font-weight: 700; }
.nav-track .nt-to b { color: #7fe3ff; }
.nav-track .nt-route { opacity: .8; font-size: calc(12.5 * var(--u)); }
.nav-track .nt-go { margin-top: calc(6 * var(--u)); width: 100%; }
@media (pointer: coarse) { .nav-track .nt-go { min-height: 44px; } .nav-track .nt-x { width: 36px; height: 36px; } }
.nav-pin, .nav-edge { position: absolute; z-index: 3; left: 0; top: 0; pointer-events: none; will-change: transform; }
.nav-pin i { position: absolute; left: calc(-11 * var(--u)); top: calc(-30 * var(--u)); width: calc(22 * var(--u)); height: calc(30 * var(--u));
  background: #ffd34d; clip-path: polygon(0 0, 100% 0, 100% 55%, 50% 100%, 0 55%); filter: drop-shadow(0 0 calc(3 * var(--u)) #3b2a1f); animation: nav-bob 1s ease-in-out infinite alternate; }
.nav-pin.via i, .nav-edge.via i { background: #7fe3ff; }
@keyframes nav-bob { to { translate: 0 calc(-8 * var(--u)); } }
.nav-edge i { position: absolute; left: calc(-16 * var(--u)); top: calc(-14 * var(--u)); width: calc(32 * var(--u)); height: calc(28 * var(--u)); background: #ffd34d;
  clip-path: polygon(0 0, 100% 50%, 0 100%, 25% 50%); filter: drop-shadow(0 0 calc(2 * var(--u)) #3b2a1f); }
.nav-edge b { position: absolute; left: 50%; top: calc(16 * var(--u)); translate: -50% 0; white-space: nowrap; padding: 0 calc(6 * var(--u)); border-radius: calc(8 * var(--u));
  background: rgba(36, 24, 14, .8); color: #fff6df; font-size: calc(13 * var(--u)); }
.qb-list .nt-pin.on, .qbook .nt-pin.on { filter: brightness(1.15); outline: calc(2 * var(--u)) solid #ffd34d; }

.tut-coach .tut-nav { display: none; margin: calc(2 * var(--u)) 0 calc(4 * var(--u)); width: 100%; }
@media (max-width: 620px), (pointer: coarse) and (max-height: 520px) {   /* K-346 phone: tracker replaces the coach slot; with a coach = button inside it */
  .nav-track { left: max(calc(12 * var(--u)), env(safe-area-inset-left)); right: auto; top: calc(108 * var(--u) + env(safe-area-inset-top)); width: min(62vw, calc(330 * var(--u))); }
  .game:has(.tut-coach) .nav-track { display: none; }
  .tut-coach .tut-nav { display: block; min-height: 44px; }
}

/* K-355 (user 2026-10-09): scrollbar = the title/content divider ornament (ui3/divider.png rotated -> divider_v.png 38x198): thumb =
   9-slice of the gold bar (arrow tips fixed 40 px of the source, middle stretches), track = faint engraved line. Chromium/Electron/Safari. */
::-webkit-scrollbar { width: calc(14 * var(--u)); height: calc(14 * var(--u)); background: transparent; }
::-webkit-scrollbar-track { background: linear-gradient(90deg, transparent 42%, rgba(91, 64, 38, .28) 42%, rgba(91, 64, 38, .28) 58%, transparent 58%); margin: calc(6 * var(--u)) 0; }
::-webkit-scrollbar-thumb { min-height: calc(40 * var(--u)); background: transparent; border-style: solid; border-color: transparent; border-width: calc(14 * var(--u)) 0;
  border-image: url(/assets/ui3/divider_v.png) 40 0 40 0 fill / calc(14 * var(--u)) 0 stretch; filter: drop-shadow(0 1px 1px rgba(40, 26, 14, .4)); }
/* horizontal bar (user 2026-10-12: thumb stood up + stretched on every sideways list): unrotated divider.png 198x38, tips fixed left/right */
::-webkit-scrollbar-track:horizontal { background: linear-gradient(180deg, transparent 42%, rgba(91, 64, 38, .28) 42%, rgba(91, 64, 38, .28) 58%, transparent 58%); margin: 0 calc(6 * var(--u)); }
::-webkit-scrollbar-thumb:horizontal { min-height: 0; min-width: calc(40 * var(--u)); border-width: 0 calc(14 * var(--u));
  border-image: url(/assets/ui3/divider.png) 0 40 0 40 fill / 0 calc(14 * var(--u)) stretch; }
::-webkit-scrollbar-thumb:hover { filter: brightness(1.12) drop-shadow(0 1px 1px rgba(40, 26, 14, .4)); }
::-webkit-scrollbar-corner { background: transparent; }

/* K-357 (user 2026-10-09 "เลือกแล้ว ... เป็นกรอบทอง"): selected slot = the frame itself turns gold, no outline ring. Art ui3/slot_gold.png =
   recolour of slot.png, same shape/slice (design/ui-v3/slot_gold.py). Every slot selection routes here: .slot.sel (bag/bank/shop/gear/cosmetics,
   SlotGrid), .slot.active (ItemSlot/ItemList: craft/enhance/socket/repair, fish bait, "ไม่ใช้" none-slot), .skin-cell.on .slot. Keyboard focus =
   .slot:focus-visible ring (FORMS top block), never removed here. */
.slot.sel, .slot.active, .skin-cell.on .slot { border-image-source: url(/assets/ui3/slot_gold.png); background: none; }
.slot.sel:not(.filled), .slot.active:not(.filled) { color: var(--cream-lt); }

/* K-358 Dropdown (Panels.jsx): trigger input.dd = ui4 dropdown art (K-325 select rule above); popup = steel slot 9-slice well, cream rows,
   hovered/keyboard row (.hi) = gold wash, current value (.sel) = gold text + bar. Inner list scrolls (K-355 bar). z above .info-tip (70). */
input.dd { max-width: 100%; cursor: inherit; caret-color: transparent; user-select: none; -webkit-user-select: none; text-overflow: ellipsis; }
input.dd.open { filter: brightness(1.1); }
.dd-pop { position: fixed; z-index: 80; max-width: calc(100vw - 16px); filter: drop-shadow(0 calc(4 * var(--u)) calc(6 * var(--u)) rgba(20, 12, 4, .55)); }
.dd-list { margin: 0; padding: calc(4 * var(--u)); list-style: none; max-height: calc(260 * var(--u)); overflow-y: auto; font-size: calc(14 * var(--u));
  color: var(--cream); text-shadow: 0 1px 0 #000;
  border: var(--slot-edge) solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.dd-list li { display: flex; align-items: center; min-height: calc(34 * var(--u)); padding: 0 calc(12 * var(--u)) 0 calc(14 * var(--u)); white-space: nowrap;
  border-radius: calc(6 * var(--u)); cursor: inherit; position: relative; }
.dd-list li.hi { background: linear-gradient(90deg, rgba(232, 184, 76, .5), rgba(232, 184, 76, .18)); color: #fff4cf; }
.dd-list li.sel { color: #ffd968; font-weight: 600; }
.dd-list li.sel::before { content: ""; position: absolute; left: calc(4 * var(--u)); top: 22%; bottom: 22%; width: calc(4 * var(--u)); border-radius: 2px;
  background: linear-gradient(#ffe7a0, var(--gold)); }

/* K-358b (user 2026-10-09 "input ... theme ของเกม"): every text-like field (text/password/search/number/email, textarea, chat, login, stall,
   mail...) = ui3 inset parchment 9-slice (fixed corners: image-width 12u, layout border 6u), ink text, dim placeholder, gold focus ring.
   Height = --btn-h from the FORMS base rule (padding/size stay there so per-component padding/width overrides still win). */
input:not([type=checkbox], [type=radio], [type=range], [type=color], [type=button], [type=submit], [type=file], .sw, .dd), textarea {
  color: var(--ink); background: none; border-radius: 0; box-shadow: none;
  border: calc(6 * var(--u)) solid transparent; border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / calc(12 * var(--u)) / 0 stretch; }
input::placeholder, textarea::placeholder { color: var(--ink-dim); opacity: .75; }
input:not([type=checkbox], [type=radio], [type=range], [type=color], .sw, .dd):focus-visible, textarea:focus-visible {
  outline: calc(2 * var(--u)) solid var(--gold); outline-offset: calc(1 * var(--u)); box-shadow: 0 0 calc(8 * var(--u)) rgba(255, 214, 120, .55); }
input:disabled, textarea:disabled { opacity: .6; }

/* K-360 (user 2026-10-09): SlotCard lists (NPC shop buy/buyback, market listings + catalog, premium shop, trade) = craft-row look: no white
   card, slot left, name line, meta/sub line, price (Acorn icon) left + buttons right on ONE line, thin divider. CSS order only, no JSX change. */
.mk:has(> .slot-card) { gap: 0; }
.mk .card.slot-card { grid-template-columns: calc(60 * var(--u)) minmax(0, 1fr); gap: calc(12 * var(--u)); padding: calc(8 * var(--u)) calc(4 * var(--u));
  background: none; border: 0; border-radius: 0; box-shadow: none; border-bottom: calc(2 * var(--u)) solid rgba(139, 107, 78, .25); }
.mk .card.slot-card:hover { background: rgba(255, 255, 255, .22); }
.mk .card.slot-card > .slot { width: calc(60 * var(--u)); align-self: center; }
.slot-card .sc-body { gap: calc(4 * var(--u)) calc(8 * var(--u)); }
.slot-card .sc-body > .nm { order: -2; flex: 1 1 100%; font-size: calc(15 * var(--u)); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.slot-card .sc-body > .meta, .slot-card .sc-body > .sub { order: -1; }
.slot-card .sc-body > .price { margin-right: auto; }
.ev-info { margin: 0 0 calc(8 * var(--u)); padding: calc(8 * var(--u)) calc(10 * var(--u)); border-radius: calc(8 * var(--u)); background: #3b2a4a; color: #f3e6ff; font-size: calc(13 * var(--u)); }   /* K-476 event rules banner */
.ev-info p { margin: calc(4 * var(--u)) 0 0; line-height: 1.45; }
.slot-card .sc-body > .chip.ev { order: -1; background: #6b4a8a; color: #fff; font-size: calc(12 * var(--u)); }   /* K-476 event exchange tag */

/* K-361 (user 2026-10-09): quest lists (QuestBook story/event, board daily/weekly/monthly .qb-row, journal) = no big white/inset box per row,
   thin divider only (same family as K-360). Journal current row = gold wash (K-357 gold = selected). */
.qb-list, .qb-sec > .qb-fold > .qb-in { gap: 0; }
.qb-q, .qb-q.done, .qb-q .ui-quest-row, .ui-split .ui-quest-row, .qb-row { background: none; border: 0; border-image: none; border-radius: 0; box-shadow: none; }
.qb-q, .qb-row, .ui-split .ui-quest-row { border-bottom: calc(2 * var(--u)) solid rgba(139, 107, 78, .25); }
.qb-q { padding: calc(2 * var(--u)) 0; }
.qb-row { padding: calc(8 * var(--u)) calc(4 * var(--u)); }
.qb-q .ui-quest-row { padding-top: calc(6 * var(--u)); padding-bottom: calc(6 * var(--u)); }
.ui-quest-row:hover { background: rgba(255, 255, 255, .22); }
.ui-quest-row:active { transform: none; }
.ui-split .ui-quest-row.sel { background: linear-gradient(90deg, rgba(232, 184, 76, .45), rgba(232, 184, 76, .12)); }

/* K-363 (user 2026-10-09) hotbar. Skill art (assets/skill-icons, 128px) has its OWN steel frame + plate (~20px/128 rim = 15.6%): in a slot
   that read as a second frame/bg. Hotbar shows only the inner plate (clip-path inset 15.6% + scale 1/(1-2*.156) = 1.45, same idea as .bb
   scale 1.18), sized to the slot's INNER edge: desktop square --hk-in from the steel rim (slot.png rim ~24px of slice 33 -> edge*24/33);
   touch disc = padding box (inside the gold ring). Art never recoloured. Page flip ▲▼ = ui4 round discs (pressed art = current page). */
.hotbar { --hk-in: calc(var(--slot-edge) * 24 / 33); }   /* knob: inner edge of the steel rim */
.hotbar > .hk .sk-ic { inset: var(--hk-in); margin: auto; width: auto; height: calc(100% - 2 * var(--hk-in)); aspect-ratio: 1;
  clip-path: inset(15.6%); transform: scale(1.45); }
.hb-page button { width: calc(24 * var(--u)); height: calc(24 * var(--u)); border: 0; border-radius: 50%; box-shadow: none; font-size: calc(9 * var(--u));
  color: #e9d9b0; text-shadow: 0 1px 0 #000; background: url(/assets/ui4/round.webp) center / contain no-repeat; }
.hb-page button:hover:not(:disabled) { filter: brightness(1.12); }
.hb-page button:disabled { color: var(--gold); background: url(/assets/ui4/round_pressed.webp) center / contain no-repeat; transform: none; }
.hb-page button:focus-visible { outline-color: var(--gold); border-radius: 50%; }
@media (pointer: coarse) {
  .hotbar > .hk .sk-ic { inset: 0; width: 100%; height: 100%; }
}
/* K-358 fix: phone settings section was wider than .body (nowrap labels + controls = min-content) -> focusing a control scrolled the body sideways.
   Grid track capped to the body, labels shrink with ellipsis. */
.settings-panel .set-sec { grid-template-columns: minmax(0, 1fr); }   /* grid auto track = min-content (305 > 252 on 390px) */
.settings-panel .set-row > span { flex: 0 1 auto; }
.field.inline .dd { width: auto; min-width: calc(140 * var(--u)); max-width: 62%; }   /* K-358: size attr = longest label; 110u left 38u text after the cap rivets */
/* K-360c (user 2026-10-09 "ตลาด... หน้าซื้อของ ผิด layout"): market buy filter row (.row > .field.inline flex:1 + Acorn chip) overflowed the panel:
   flex item min-width:auto = input.dd intrinsic width (size attr = longest def name; the 62% cap is cyclic in intrinsic sizing) -> dropdown ran under
   the inset frame (arrow cut), chip forced to its own line. Explicit min-width lets the field fit the row so the 62% cap resolves. */
.field.inline { min-width: min(calc(220 * var(--u)), 100%); }   /* knob: narrower row -> chip wraps below instead of squeezing the dd */
.field.inline .dd { min-width: min(calc(140 * var(--u)), 62%); }

/* K-360b (user 2026-10-09 "Mobile ลดขนาดของปุ่มลงตาม Aspect ratio"): phone SlotCard row (slot, gaps, pill buttons) scales with the short screen
   side via a local --u (theme --u floors at .85px) so price + ×1 + ×10 stay on one line (390px: 18000 + both fit). Name/price/meta text keep
   the root sizes (--body-size = root-computed). Tap area = .btn.sm::before bleed in fixed px so it does not shrink. */
@media (max-width: 620px), (max-height: 520px) {
  .mk .card.slot-card { --u: clamp(.6px, min(100vw, 100dvh) / 620, .85px); }   /* knob: 620 = short side at full size */
  .slot-card .sc-body > .nm { font-size: var(--body-size); }
  .slot-card .sc-body > :is(.meta, .sub) { font-size: calc(var(--body-size) * .8); }
  .slot-card .sc-body > .btn { font-size: calc(13.5 * var(--u)); }
  .slot-card .sc-body > .btn::before { content: ""; position: absolute; left: -4px; right: -4px; top: -8px; bottom: -8px; }
}
/* K-363c (user 2026-10-09 "skill-slot ... ติด bg ขาว"): empty hotbar slot painted --cream-dk (line ~299 .hk.empty beats .hk background:none)
   as a square behind the rounded slot_empty art -> white corners. Slot art only. Touch wheel keeps its own dark disc (pointer: coarse). */
@media (pointer: fine) { .hk.empty { background: none; } }
/* K-365 (user 2026-10-09 "ภารกิจที่สำเร็จ ทำขีดฆ่าตัว text เลย"): finished quest steps + finished quests in lists = line-through, dimmed ink.
   Steps (.prog .o.done: quest book + journal detail), quest book .qb-q.fin, board/pass .qb-row.done/.got, journal done tab .ui-quest-row.fin,
   guild quests .card.gq.done. Tutorial coach / nav tracker show only the current step (never a done one). */
.prog .o.done > span:first-child, .qb-q.fin .ui-quest-row .nm, .qb-row:is(.done, .got) .name, .ui-quest-row.fin .nm, .gq.done .nm {
  text-decoration: line-through; text-decoration-thickness: calc(2 * var(--u)); text-decoration-color: rgba(91, 64, 38, .7); color: var(--ink-dim); }
/* K-366 (user 2026-10-09): every scroller = K-355 divider scrollbar. Chromium drops ::-webkit-scrollbar when scrollbar-width/-color is set,
   so those props live only in the Firefox @supports block (line ~552). QA audit: tools/qa/k360-363-shot.mjs logs `sb` (must be []). */
@supports not selector(::-webkit-scrollbar) { .ach-cats { scrollbar-width: thin; } }
/* K-367 (user 2026-10-09): U panel tabs ตัวละคร | สมุดสกิล (.seg.char-tabs = ui4 tab art); book body wrapper transparent to the .body flex column;
   slot strip = one hotbar page + ▲▼ (.hb-page, same ui4 round art as the HUD). */
.char-tabs { flex: none; }
.skillbook { display: contents; }
.sb-slots-row { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.sb-slots-row > .sb-slots { flex: 1; min-width: 0; }
.sb-slots-row > .hb-page { flex: none; }
/* K-368 (user 2026-10-09 "UI ตัดผม ... ตัวละครไม่ถูกเลื่อนลงตาม section แล้วลดขนาดตัวละครลงหน่อย"): barber .body never scrolls; preview fixed
   (top, or left column on short screens) + smaller (130x166u, knob); only .hair-picker scrolls (K-355 bar). */
.panel.barber .body { overflow: hidden; }
.panel.barber .ui-charlay { flex: none; }
.panel.barber .ui-portrait { width: calc(130 * var(--u)); height: calc(166 * var(--u)); }   /* knob: preview size */
.panel.barber .rig-preview { width: calc(130 * var(--u)); height: calc(166 * var(--u)); }
.panel.barber .hair-picker { flex: 1; min-height: 0; overflow-y: auto; align-content: start; padding-right: calc(4 * var(--u)); }
@media (max-height: 520px) {
  .panel.barber .body { flex-direction: row; align-items: stretch; }
  .panel.barber .ui-charlay { align-self: center; }
}
/* K-376 (user 2026-10-09, ref kanban/shots/k376-ref-cashshop.jpg): ร้านโอ๊กทอง CashShopPanels.jsx. Big centred sheet (bpass sizing), body never
   scrolls: grid (.cs-grid) + package list scroll inside (K-355 bar). Left = grid + bottom category strip; right .cs-side = try-on RigPreview +
   12-slot cart + sum + buy. Card = cream tile, steel .slot icon, ribbon (.cs-rib ev = event coral, own = sage), in-cart = gold frame (K-357 .slot.sel)
   + gold rim. Phone (<=620px wide): column, preview hidden, side = bottom drawer (.cs-drawer-bar toggles .open). Short (<=520px tall): side
   narrower, preview hidden. Sizes = knobs. */
.panel.cashshop { width: min(calc(100vw - calc(40 * var(--u))), calc(1180 * var(--u))) !important; max-width: none !important;
  height: min(calc(100dvh - calc(40 * var(--u))), calc(760 * var(--u))); max-height: none !important; bottom: auto !important;
  left: 50% !important; right: auto !important; top: 50% !important; transform: translate(-50%, -50%) !important; z-index: 8; }
.panel.cashshop .body { overflow: clip;   /* clip: card focus/scrollIntoView must not scroll the body (hidden still scrolls programmatically) */
  gap: calc(8 * var(--u)); }
.cs-top { flex: none; display: flex; align-items: center; justify-content: flex-end; gap: calc(8 * var(--u)); }
.cs-top .btn { white-space: nowrap; }
.cs-bal { display: inline-flex; align-items: center; gap: calc(6 * var(--u)); padding: calc(3 * var(--u)) calc(14 * var(--u)) calc(3 * var(--u)) calc(6 * var(--u));
  background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--brown); border-radius: calc(999 * var(--u)); font-weight: 600; }
.cs-bal .ic { width: calc(26 * var(--u)); height: calc(26 * var(--u)); }
.cs-bal b { font-size: calc(18 * var(--u)); color: var(--gold-dk); }
.cs-bal small { color: var(--ink-dim); font-size: calc(12 * var(--u)); }
.cs-main { flex: 1; min-height: 0; display: flex; gap: calc(10 * var(--u)); }
.cs-left { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: calc(8 * var(--u)); }
.cs-left > .empty, .cs-topup { flex: 1; min-height: 0; }
.cs-grid { flex: 1; min-height: 0; overflow-y: auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(122 * var(--u)), 1fr));
  gap: calc(8 * var(--u)); align-content: start; padding: calc(6 * var(--u)) calc(4 * var(--u)) calc(4 * var(--u)); }
.cs-card { position: relative; display: flex; flex-direction: column; align-items: center; gap: calc(4 * var(--u)); padding: calc(10 * var(--u)) calc(6 * var(--u)) calc(8 * var(--u));
  background: linear-gradient(var(--cream-lt), var(--cream)); border: calc(2 * var(--u)) solid var(--brown); border-radius: var(--radius-sm);
  box-shadow: 0 calc(3 * var(--u)) 0 rgba(59, 42, 30, .35); color: var(--ink); font: inherit; cursor: pointer; text-align: center; transition: transform .12s, filter .12s; }
button.cs-card:hover, button.cs-card:focus-visible { transform: translateY(calc(-2 * var(--u))); filter: brightness(1.05); }
button.cs-card:active { transform: translateY(calc(1 * var(--u))); }
.cs-card.in { border-color: var(--gold-dk); box-shadow: 0 0 0 calc(2 * var(--u)) var(--gold), 0 calc(3 * var(--u)) 0 rgba(59, 42, 30, .35); }
.cs-card .slot { width: calc(68 * var(--u)); height: calc(68 * var(--u)); flex: none; }
.cs-card .nm { font-size: calc(13 * var(--u)); line-height: 1.25; min-height: 2.5em; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cs-card .pr { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); font-weight: 600; color: var(--gold-dk); font-size: calc(15 * var(--u)); }
.cs-card .pr .ic, .cs-sum .ic, .cs-drawer-bar b .ic { width: calc(20 * var(--u)); height: calc(20 * var(--u)); }
.cs-rib { position: absolute; z-index: 1; top: calc(6 * var(--u)); left: calc(-4 * var(--u)); max-width: 80%; padding: calc(1 * var(--u)) calc(8 * var(--u));
  background: var(--coral); color: var(--cream-lt); font-size: calc(11 * var(--u)); font-weight: 600; border: calc(2 * var(--u)) solid var(--line);
  border-radius: 0 calc(8 * var(--u)) calc(8 * var(--u)) 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 0 rgba(0,0,0,.35); }
.cs-rib.own { left: auto; right: calc(-4 * var(--u)); top: calc(30 * var(--u)); background: var(--sage-dk); border-radius: calc(8 * var(--u)) 0 0 calc(8 * var(--u)); }
.cs-card.paused { filter: grayscale(1); opacity: .6; cursor: not-allowed; }   /* K-480 CBT: listed greyed, not sold */
.cs-rib.off { left: auto; right: calc(-4 * var(--u)); background: var(--ink-soft, #6b5f52); border-radius: calc(8 * var(--u)) 0 0 calc(8 * var(--u)); }
.cs-cats { flex: none; display: flex; flex-wrap: wrap; gap: calc(6 * var(--u)); padding: calc(8 * var(--u)) calc(2 * var(--u)) calc(2 * var(--u));
  border-top: calc(2 * var(--u)) solid rgba(139, 107, 78, .35); }
.cs-cats .btn { flex: none; white-space: nowrap; }
.cs-side { flex: none; width: calc(320 * var(--u)); display: flex; flex-direction: column; gap: calc(8 * var(--u)); min-height: 0; }
.cs-drawer-bar { display: none; }
.cs-preview { flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: calc(6 * var(--u));
  padding: calc(8 * var(--u)); border: calc(2 * var(--u)) solid var(--brown); border-radius: var(--radius-sm);
  background: radial-gradient(ellipse 60% 14% at 50% 82%, rgba(59, 42, 30, .18), transparent 70%), linear-gradient(#cfe3ea, #e9f0d8 62%, #d7c79f 63%, #c9b78c); }
.cs-tried { flex: none; width: 100%; display: flex; align-items: center; justify-content: space-between; gap: calc(6 * var(--u)); }
.cs-tried .note { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: rgba(255, 250, 238, .8); border-radius: calc(8 * var(--u)); padding: calc(2 * var(--u)) calc(8 * var(--u)); }
.cs-cart { flex: none; display: flex; flex-direction: column; gap: calc(8 * var(--u)); padding: calc(10 * var(--u)); background: var(--cream-lt);
  border: calc(2 * var(--u)) solid var(--brown); border-radius: var(--radius-sm); }
.cs-slots { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: calc(5 * var(--u)); }
.cs-slots .slot { width: auto; height: auto; aspect-ratio: 1; min-height: 0; overflow: visible; }   /* base min-height var(--slot) forced overflow on narrow carts; visible = × not clipped */
.cs-x { position: absolute; top: calc(-6 * var(--u)); right: calc(-6 * var(--u)); width: calc(20 * var(--u)); height: calc(20 * var(--u)); padding: 0; display: grid; place-items: center;
  background: var(--coral); border: calc(2 * var(--u)) solid var(--line); border-radius: 50%; color: var(--cream-lt); cursor: pointer; z-index: 1; }
.cs-x::before { content: ""; position: absolute; inset: calc(-8 * var(--u)); }   /* tap bleed */
.cs-x .ic { width: calc(12 * var(--u)); height: calc(12 * var(--u)); }
.cs-sum { display: flex; align-items: baseline; justify-content: space-between; gap: calc(6 * var(--u)); flex-wrap: wrap; }
.cs-sum b { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); font-size: calc(20 * var(--u)); color: var(--gold-dk); }
.note.short { color: var(--coral-dk); font-weight: 600; }
.cs-buy { display: flex; gap: calc(6 * var(--u)); justify-content: flex-end; }
.cs-buy .btn:last-child { flex: 1; }
.cs-topup { display: flex; flex-direction: column; gap: calc(8 * var(--u)); }
.cs-off { padding: calc(6 * var(--u)) calc(10 * var(--u)); background: var(--cream-dk); border-radius: calc(8 * var(--u)); text-align: center; font-weight: 600; }
.cs-packs { grid-template-columns: repeat(auto-fill, minmax(calc(150 * var(--u)), 1fr)); }
.cs-pack { cursor: default; padding-top: calc(16 * var(--u)); }
.cs-pack.b-best, .cs-pack.b-value { border-color: var(--gold-dk); box-shadow: 0 0 0 calc(2 * var(--u)) var(--gold), 0 calc(3 * var(--u)) 0 rgba(59, 42, 30, .35); }
.cs-pack.b-best .cs-rib, .cs-pack.b-value .cs-rib { background: var(--gold-dk); }
.cs-pk-ic .ic { width: calc(54 * var(--u)); height: calc(54 * var(--u)); }
.cs-pts { font-size: calc(22 * var(--u)); color: var(--gold-dk); }
.cs-pts small { font-size: calc(12 * var(--u)); color: var(--ink-dim); }
.cs-bonus { font-size: calc(13 * var(--u)); font-weight: 600; color: var(--sage-dk); background: rgba(126, 160, 110, .18); border-radius: calc(999 * var(--u)); padding: 0 calc(10 * var(--u)); }
.cs-pack .btn { width: 100%; margin-top: auto; }
@media (max-height: 520px) {
  .panel.cashshop { height: calc(100dvh - 8px); }
  .cs-side { width: calc(260 * var(--u)); }
  .cs-cats { flex-wrap: nowrap; overflow-x: auto; }
  .cs-preview { display: none; }
  .cs-cart { flex: 1; min-height: 0; overflow-y: auto; }
}
@media (max-width: 620px) {
  .panel.cashshop { width: calc(100vw - calc(12 * var(--u))) !important; height: calc(100dvh - calc(16 * var(--u))); }
  .cs-main { flex-direction: column; gap: calc(6 * var(--u)); }
  .cs-grid { grid-template-columns: repeat(auto-fill, minmax(calc(100 * var(--u)), 1fr)); gap: calc(6 * var(--u)); }
  .cs-card .slot { width: calc(56 * var(--u)); height: calc(56 * var(--u)); }
  .cs-side { width: auto; gap: calc(6 * var(--u)); }
  .cs-cats { flex-wrap: nowrap; overflow-x: auto; }
  .cs-preview { display: none; }
  .cs-drawer-bar { display: flex; align-items: center; gap: calc(8 * var(--u)); width: 100%; min-height: 44px; padding: calc(4 * var(--u)) calc(12 * var(--u));
    background: var(--cream-lt); border: calc(2 * var(--u)) solid var(--brown); border-radius: var(--radius-sm); color: var(--ink); font: inherit; font-weight: 600; cursor: pointer; }
  .cs-drawer-bar > span:not(.cs-caret) { flex: 1; text-align: left; }
  .cs-drawer-bar b { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); color: var(--gold-dk); }
  .cs-caret { width: 0; height: 0; border: calc(7 * var(--u)) solid transparent; border-bottom-color: var(--brown); margin-top: calc(-7 * var(--u)); }
  .cs-side.open .cs-caret { border-bottom-color: transparent; border-top-color: var(--brown); margin: calc(7 * var(--u)) 0 0; }
  .cs-side:not(.open) .cs-cart { display: none; }
  .cs-top { justify-content: space-between; }
}
/* K-378 (user 2026-10-09): mount skin in the cash shop preview = small follower beside the character (RigPreview look.pet) + ลองขี่ toggle
   (.cs-ride, top-right of the preview stage; only while a mount skin is kept selected). Phone portrait: preview hidden (K-376) -> no toggle. */
.cs-preview { position: relative; }
.cs-ride { position: absolute; top: calc(8 * var(--u)); right: calc(8 * var(--u)); z-index: 1; }
@media (max-width: 620px) {   /* K-378 phone portrait: open cart drawer also shows a short preview (follower / ลองขี่ visible on phone) */
  .cs-side.open .cs-preview { display: flex; flex: none; height: calc(190 * var(--u)); padding: calc(4 * var(--u)); }
}
/* K-381 cash shop test-walk: drag inside the preview stage = stick (no page pan / text select); hint chip top-left. */
.cs-preview { touch-action: none; user-select: none; }
.cs-walk-hint { position: absolute; top: calc(8 * var(--u)); left: calc(8 * var(--u)); z-index: 1; font-size: calc(11 * var(--u)); color: var(--ink-dim); background: rgba(255, 250, 238, .8); border-radius: calc(8 * var(--u)); padding: calc(1 * var(--u)) calc(8 * var(--u)); pointer-events: none; }
/* K-385 (user 2026-10-09 "BG ทำเป็นห้องลองชุดสวยๆ หน่อย แบบ BG คลีนๆ"): cash shop preview stage = CSS fitting room (no image, approved sheet
   kanban/shots/k385-bg.png). .cs-stage layers top->bottom: brass rod, curtain drapes L/R (--cs-cur colours, soft fold shading), wood floor
   (bottom --cs-floor band: baseboard shadow + plank seams + warm gradient), wall glow, faint diamond lattice, cream wall. Canvas fills the stage
   (CashShopPanels sizes it to the box; foot line = middle of the floor band). Colours/sizes = knobs. */
.cs-stage { --cs-cur: #d08a8a; --cs-cur-lt: #e6abab; --cs-cur-dk: #a65f62; --cs-wall: #f8f0e1; --cs-wall-ln: rgba(170, 135, 95, .12); --cs-floor: 24%;
  --cs-drape: calc(26 * var(--u));
  position: relative; flex: 1; min-height: 0; align-self: stretch; overflow: hidden; border-radius: calc(8 * var(--u));
  box-shadow: inset 0 0 calc(18 * var(--u)) rgba(120, 85, 50, .18);
  background:
    linear-gradient(#e2bf78, #a8803c) top / 100% calc(7 * var(--u)) no-repeat,
    repeating-linear-gradient(90deg, var(--cs-cur-dk) 0, var(--cs-cur) calc(3 * var(--u)), var(--cs-cur-lt) calc(6.5 * var(--u)), var(--cs-cur) calc(10 * var(--u)), var(--cs-cur-dk) calc(13 * var(--u))) left top / var(--cs-drape) 100% no-repeat,
    repeating-linear-gradient(90deg, var(--cs-cur-dk) 0, var(--cs-cur) calc(3 * var(--u)), var(--cs-cur-lt) calc(6.5 * var(--u)), var(--cs-cur) calc(10 * var(--u)), var(--cs-cur-dk) calc(13 * var(--u))) right top / var(--cs-drape) 100% no-repeat,
    linear-gradient(rgba(90, 60, 30, .28), rgba(90, 60, 30, 0)) 0 calc(100% - var(--cs-floor)) / 100% calc(6 * var(--u)) no-repeat,
    linear-gradient(90deg, rgba(90, 60, 30, .14) 1px, transparent 1px) 0 100% / calc(54 * var(--u)) var(--cs-floor) repeat-x,
    linear-gradient(#e6c9a0, #cda674) 0 100% / 100% var(--cs-floor) no-repeat,
    radial-gradient(ellipse 60% 50% at 50% 40%, rgba(255, 255, 255, .75), transparent 72%),
    repeating-linear-gradient(45deg, var(--cs-wall-ln) 0 1px, transparent 1px calc(22 * var(--u))),
    repeating-linear-gradient(-45deg, var(--cs-wall-ln) 0 1px, transparent 1px calc(22 * var(--u))),
    var(--cs-wall); }
.cs-stage > canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.cs-preview { background: var(--cream-lt); }   /* K-385 the room lives in .cs-stage; old sky/ground gradient dropped */

/* K-396 gear stat breakdown (Panels.jsx GearStats / GearDiff, ref kanban/shots/k396-ref-yulgang.png in parchment colours):
   total ink + (bonus) sage-dk · ตีบวก line gold-dk · เพชร lines blue-dk · diff up sage-dk / down coral-dk · .gear-flash = 3 s post-enhance pulse */
.gear-stats, .gear-diff { list-style: none; margin: 0; padding: calc(6 * var(--u)) calc(10 * var(--u)); display: grid; gap: calc(3 * var(--u)); text-align: left;
  font-size: calc(14 * var(--u)); background: var(--cream-dk); border-radius: calc(10 * var(--u)); color: var(--ink); }
.gear-stats li, .gear-diff li { display: flex; align-items: baseline; gap: calc(6 * var(--u)); flex-wrap: wrap; }
.gear-stats li > span, .gear-diff li > span { min-width: calc(64 * var(--u)); color: var(--ink-dim); }
.gear-stats .gs-total b { font-weight: 600; }
.gear-stats .gs-bonus, .gear-diff li.up em { font-style: normal; font-weight: 600; color: var(--sage-dk); }
.gear-diff li.down em { font-style: normal; font-weight: 600; color: var(--coral-dk); }
.gear-stats .gs-enh, .gear-stats .gs-gem { font-size: calc(13 * var(--u)); border-top: calc(1 * var(--u)) dashed var(--ink-dim); padding-top: calc(3 * var(--u)); }
.gear-stats .gs-gem + .gs-gem { border-top: 0; padding-top: 0; }
.gear-stats .gs-enh, .gear-stats .gs-enh > span { color: var(--gold-dk); font-weight: 600; }
.gear-stats .gs-gem, .gear-stats .gs-gem > span { color: var(--blue-dk); font-weight: 600; }
.gear-stats em { font-style: normal; }
.gear-stats.compact { padding: calc(2 * var(--u)) calc(6 * var(--u)); font-size: calc(12 * var(--u)); display: flex; flex-wrap: wrap; gap: calc(2 * var(--u)) calc(10 * var(--u)); }
.gear-stats.compact li > span { min-width: 0; }
.gear-diff i { font-style: normal; color: var(--ink-dim); }
.gear-diff b { font-weight: 600; }
.gs-broken { color: var(--coral-dk); font-weight: 600; }
.gs-sub { display: block; font-size: calc(11 * var(--u)); color: var(--ink-dim); font-weight: 500; }
.gs-sub .e { color: var(--gold-dk); } .gs-sub .g { color: var(--blue-dk); }
.gear-flash { border: calc(2 * var(--u)) solid var(--sage-dk); border-radius: calc(12 * var(--u)); padding: calc(6 * var(--u)); margin-bottom: calc(6 * var(--u)); animation: gear-flash 1s ease-out 2; }
.gear-flash.downgrade { border-color: var(--coral-dk); }
.gear-flash h4 { margin: 0 0 calc(4 * var(--u)); color: var(--sage-dk); }
.gear-flash.downgrade h4 { color: var(--coral-dk); }
.gear-flash .gear-diff li.up b:last-of-type, .gear-flash .gear-diff li.down b:last-of-type { animation: gear-pop .6s ease-out 3; }
@keyframes gear-flash { 0% { background: var(--gold); } 100% { background: transparent; } }
@keyframes gear-pop { 50% { transform: scale(1.25); } }
.gear-flash .gear-diff b { display: inline-block; }
@media (prefers-reduced-motion: reduce) { .gear-flash, .gear-flash .gear-diff b { animation: none; } }

/* K-404 chat (ChatPanels.jsx ChatBox), user rounds: translucent dark box, thin dark border, small radius, NO parchment; compact (K-404b: text
   11.5u, box 380u wide, height --chat-h 266u = -30 %; K-404c: all of it x --chat-k .8 via --cu, text floor 10px). Top row = v fold (= close, hit area ::after) + active channel name. Channel tabs = K-125
   steel side-tab rail OUTSIDE the box's right edge (icons, active lit + arrow, .chat-dot unread), sized down (--side-tab 28u). Bottom = standard
   K-358 Dropdown (ui4 art, shrunk) + dark input + small send. Log flexes + scrolls inside. Knobs: --chat-h, --chat-bg, --side-tab, widths. */
.chat-popup { --chat-k: .8; --cu: calc(var(--u) * var(--chat-k));   /* K-404c knob: whole-chat scale (box, rail, controls, text) */
  --chat-h: calc(266 * var(--cu)); --chat-bg: rgba(10, 9, 8, .6); --chat-ink: #ece6da; --side-tab: calc(28 * var(--cu)); --chat-gap: calc(4 * var(--cu));
  --chat-rail: calc(var(--side-tab) + calc(14 * var(--cu)));
  position: absolute; color: var(--chat-ink); background: var(--chat-bg); border: 1px solid rgba(0, 0, 0, .7); border-radius: calc(6 * var(--cu));
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .06) inset, 0 calc(4 * var(--cu)) calc(12 * var(--cu)) rgba(0, 0, 0, .35);
  padding: calc(5 * var(--cu)); gap: calc(4 * var(--cu));
  width: min(calc(380 * var(--cu)), calc(100vw - var(--chat-rail) - calc(24 * var(--cu)) - env(safe-area-inset-left) - env(safe-area-inset-right)));
  height: max(var(--chat-h), calc(7 * var(--side-tab) + 6 * var(--chat-gap) + calc(12 * var(--cu)))); }
.chat-top { display: flex; align-items: center; gap: calc(6 * var(--cu)); flex: none; }
.chat-fold { position: relative; flex: none; display: grid; place-items: center; width: calc(22 * var(--cu)); height: calc(20 * var(--cu)); padding: 0; cursor: inherit; color: #cfc6b6;
  background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .15); border-radius: calc(4 * var(--cu)); }
.chat-fold:hover { background: rgba(255, 255, 255, .16); }
.chat-fold::after { content: ""; position: absolute; inset: calc(-10 * var(--cu)); }   /* touch hit area ~42u */
.chat-fold .ic, .chat-fold svg.ic.glyph { width: calc(14 * var(--cu)); height: calc(14 * var(--cu)); color: currentColor; stroke-width: 2.6; }
.chat-title { font-size: max(10px, calc(11.5 * var(--cu))); font-weight: 600; color: #d8cfbf; text-shadow: 0 1px 1px #000; }
.chat-rail { top: calc(4 * var(--cu)); left: calc(100% + calc(8 * var(--cu))); }   /* knob: gap box -> rail */
.chat-rail .side-tab-group { gap: var(--chat-gap); }
.chat-rail .side-tab { padding: calc(5 * var(--cu)); }
.chat-rail .side-tab.active { transform: translateX(calc(-2 * var(--cu))); }
.chat-rail .side-tab.active::before { left: calc(-11 * var(--cu)); border-width: calc(5 * var(--cu)); border-right-width: calc(6 * var(--cu)); }
.chat-dot { position: absolute; right: calc(-3 * var(--cu)); top: calc(-3 * var(--cu)); width: calc(9 * var(--cu)); height: calc(9 * var(--cu)); border-radius: 50%;
  background: #ff6b5e; border: calc(1.5 * var(--cu)) solid #14110e; pointer-events: none; }
.chat-toggle .chat-dot { width: calc(11 * var(--u)); height: calc(11 * var(--u)); }
.chat-popup .chatlog { flex: 1 1 0; min-height: 0; max-height: none; padding: calc(1 * var(--cu)) calc(3 * var(--cu)); font-size: max(10px, calc(11.5 * var(--cu))); line-height: 1.28;
  background: none; border: 0; border-radius: 0; color: var(--chat-ink); text-shadow: 0 1px 1px #000; }
.chat-popup .chatlog:empty::before { color: #a59c8c; }
.chat-popup .chatlog li { line-height: 1.28; }
.chat-popup .chatlog li.notice { color: #b3a993; }
.chat-popup .chatlog b, .chat-popup .chat-name { color: #9fd0ff; }
.chat-popup .ch-world .chat-tag, .chat-popup .chat-to.ch-world { color: #ffb066; }
.chat-popup .ch-party .chat-tag, .chat-popup .chat-to.ch-party { color: #8cc2ff; }
.chat-popup .ch-guild .chat-tag, .chat-popup .chat-to.ch-guild { color: #94e394; }
.chat-popup .ch-whisper .chat-tag, .chat-popup .ch-whisper .chat-dir, .chat-popup .chat-to.ch-whisper { color: #ff9ad8; }
.chat-popup li.ch-whisper { background: rgba(255, 120, 200, .08); }
.chat-popup .ch-system .chat-tag { color: #ffd36a; }
.chatbox { align-items: center; flex-wrap: wrap; gap: calc(4 * var(--cu)); flex: none; }
.chat-popup .chatbox input:not(.dd) { flex: 1; height: calc(24 * var(--cu)); min-height: 0; padding: 0 calc(7 * var(--cu)); font-size: max(10px, calc(11.5 * var(--cu))); color: #fff;
  background: rgba(0, 0, 0, .35); border: 1px solid rgba(255, 255, 255, .14); border-image: none; border-radius: calc(4 * var(--cu)); }
.chat-popup .chatbox input:not(.dd)::placeholder { color: #a59c8c; opacity: 1; }
.chat-popup input.dd.chat-say { --dd-h: calc(26 * var(--cu)); flex: none; width: auto; field-sizing: content; min-width: 0; height: var(--dd-h); min-height: 0;   /* K-358 art, shrunk; width = label (field-sizing, size attr fallback) */
  padding: 0 calc(var(--dd-h) * .55 + 12 * var(--cu)) 0 calc(var(--dd-h) * .55);   /* caps = art 44x80 (.55 x h) */
  font-size: max(10px, calc(11.5 * var(--cu)));
  background: url(/assets/ui4/dropdown_arrow.webp) right calc(var(--dd-h) * .3) center / calc(var(--dd-h) * .38) auto no-repeat,
    url(/assets/ui4/dropdown_l.webp) left center / auto 100% no-repeat,
    url(/assets/ui4/dropdown_r.webp) right center / auto 100% no-repeat,
    url(/assets/ui4/dropdown_m.webp) center / calc(100% - var(--dd-h) * 1.1 + 2px) 100% no-repeat; }
.chat-popup .chatbox > .btn { height: calc(24 * var(--cu)); min-height: 0; padding: 0 calc(10 * var(--cu)); font-size: max(10px, calc(11.5 * var(--cu))); color: #fff; text-shadow: none;
  border: 1px solid rgba(255, 255, 255, .2); border-image: none; border-radius: calc(4 * var(--cu)); background: rgba(255, 255, 255, .14); box-shadow: none; }
.chat-popup .chat-to { color: #ff9ad8; font-size: max(10px, calc(11 * var(--cu))); }
@media (pointer: coarse) and (orientation: portrait) {   /* phone portrait: clear of the right button column (K-438: portrait, was min-height 521 = also hit touch tablets in landscape) */
  .chat-popup { left: max(calc(10 * var(--u)), env(safe-area-inset-left)); width: calc(100vw - var(--chat-rail) - calc(86 * var(--u)) - calc(20 * var(--u)) - env(safe-area-inset-left) - env(safe-area-inset-right)); }
}
@media (pointer: coarse) and (max-height: 520px) {   /* phone landscape: right of the stick zone, bottom; tutorial coach steps aside while chat is open (would cover it) */
  .chat-popup { bottom: calc(env(safe-area-inset-bottom) + calc(8 * var(--cu))); }
  .game:has(#game-chat) .tut-coach { visibility: hidden; }
}

@media (pointer: coarse) {   /* K-404c touch: >= ~40px hit areas around the shrunk controls; field heights floor 28px */
  .chat-rail .side-tab::after, .chat-popup .chatbox > .btn::after { content: ""; position: absolute; inset: -6px -9px; }
  .chat-popup .chatbox > .btn { position: relative; }
  .chat-popup .chatbox input:not(.dd), .chat-popup input.dd.chat-say, .chat-popup .chatbox > .btn { height: max(28px, calc(24 * var(--cu))); }
  .chat-popup input.dd.chat-say { --dd-h: max(28px, calc(24 * var(--cu))); }
}
/* K-405 HUD ping (.ping-hud, net.js PING/pingEma): small pill, colour dot + "N ms". K-452: lives first in the card's social row (SocialBar
   children, above the name) in all layouts. data-lvl good/ok/bad (GameCanvas PING_LVL knobs). */
.ping-hud { display: inline-flex; flex: none; align-items: center; gap: calc(4 * var(--u)); height: calc(20 * var(--u)); padding: 0 calc(6 * var(--u)); pointer-events: none;
  font-size: max(10px, calc(10 * var(--u))); font-weight: 600; color: #f3ede0; text-shadow: 0 1px 1px #000; background: rgba(10, 9, 8, .55); border-radius: 999px; white-space: nowrap; }
.ping-hud i { width: calc(8 * var(--u)); height: calc(8 * var(--u)); border-radius: 50%; background: #8a8378; }
.ping-hud[data-lvl=good] i { background: #5fd36a; } .ping-hud[data-lvl=ok] i { background: #f2c94c; } .ping-hud[data-lvl=bad] i { background: #ff5b4f; }

/* ============ K-413/415/417 (2026-10-10, K-406 audit fixes) ============
   K-413 PairPanels phone (<=620w: stall / bank / NPC shop): pair = viewport height (backdrop pad 16u x2), two panes split it (left 1.15 : bag 1),
   each pane clips, .pp-body scrolls inside -> no pane off-screen (K-339). Was: height auto -> pair taller than 844 -> grid-centred top off-screen.
   Empty listing row: phone .st-row > .slot grid-area ic + areas none = slot pushed to an implicit column, hint text in the 40u column (1 word/line). */
@media (max-width: 620px) {
  .pp-wrap .pe-pair { height: calc(100dvh - calc(32 * var(--u))); max-height: none; overflow: hidden; gap: calc(8 * var(--u)); }
  .pp-wrap .pe-left, .pp-wrap .pe-right { flex: 1 1 0; min-height: 0; max-height: none; display: flex; flex-direction: column; overflow: hidden; }
  .pp-wrap .pe-left { flex-grow: 1.15; }   /* knob: shop vs bag height share */
  .pp-wrap .pp-body { overflow: hidden auto; }
  .pp-body .bag-scroll { flex: 1 1 auto; min-height: calc(90 * var(--u)); max-height: none; }
  .pp-body .st-list { flex: 1 1 auto; min-height: calc(96 * var(--u)); max-height: none; }   /* list shrinks to ~2 rows (scrolls) so chat stays in view */
  .st-log, .st-viewers { height: calc(72 * var(--u)); }   /* knob: phone chat log height */
  .st-row.empty-row > .slot { grid-area: auto; }
}
.st-row.empty-row .note { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* K-415 quest + quest-board tabs (PassPanels QuestTabs .quest-tabs): label never clipped. Width = content share (flex auto, not equal 1fr), tab caps
   10u (was 16u, text ran under the cap art), 13u font. Panel content < 400px (phone): wrap to 2 rows (3 + 2), caps 8u. */
.quest-tabs .btn { flex: 1 1 auto; padding: 0 calc(2 * var(--u)); border-width: 0 calc(10 * var(--u)); font-size: calc(13 * var(--u)); }
@container (max-width: 400px) {
  .quest-tabs { flex-wrap: wrap; gap: calc(4 * var(--u)); }
  .quest-tabs .btn { flex: 1 1 28%; min-height: calc(34 * var(--u)); font-size: calc(12.5 * var(--u)); border-width: 0 calc(8 * var(--u)); }
}

/* K-417 phone overflow nits. World boss table: band never splits; panel < 480px = stacked rows (band | name / map / time). */
.wb-table td:first-child { white-space: nowrap; }
@container (max-width: 480px) {
  .wb-table thead { display: none; }
  .wb-table tr { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: calc(10 * var(--u)); padding: calc(4 * var(--u)) 0; border-bottom: calc(1 * var(--u)) solid rgba(139, 107, 78, .3); }
  .wb-table td { display: block; padding: 0; border: 0; }
  .wb-table td:first-child { grid-row: 1 / span 3; align-self: center; font-weight: 600; }
  .wb-table td.tnum { white-space: normal; }
  /* skill book slot strip: 10 slots = 5 + 5 (was 3-3-3-1) */
  .sb-slots { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .sb-slots .sb-slot { width: auto; min-width: 0; }
}
/* cash shop top row: balance never wraps, row wraps instead of cutting the test +1000 pill */
.cs-bal, .cs-bal small { white-space: nowrap; }
@media (max-width: 620px) { .cs-top { flex-wrap: wrap; justify-content: flex-end; row-gap: calc(4 * var(--u)); } .cs-bal { margin-right: auto; } }
/* horizontally scrolling chip rows (ach categories, cash shop categories on phone): right-edge fade = "more ->" hint, gone at scroll end */
@supports (animation-timeline: scroll()) {
  .ach-cats, .cs-cats { animation: k417-fade linear both; animation-timeline: scroll(self inline); }
  @keyframes k417-fade { from, 96% { -webkit-mask-image: linear-gradient(90deg, #000 82%, transparent); mask-image: linear-gradient(90deg, #000 82%, transparent); }
    to { -webkit-mask-image: none; mask-image: none; } }
}

/* ============ K-412/416 (2026-10-10, K-406 audit): last v2 white cards -> UI v3/v4 kit ============
   Rows = K-361 divider look (no card, 2u divider, white wash hover, gold wash = selected). Slots = ui3 steel 9-slice (slot_empty = vacant/locked,
   slot = owned, slot_gold = selected/complete, K-357). Category chips = ui4 tab art. Bars = ui4 slider_track + slider_fill clipped to --v (K-326).
   Value boxes (barber Stepper, stall chat log) = ui3 inset (K-359). JSX: ach/book/trainer bars -> .mbar, fame rows .rank-row, .bk-slot/.mp-slot wraps. */
:is(.ach-body, .book-head, .tr-head, .sb-pts) .mbar { position: relative; display: block; height: calc(20 * var(--u)); border: 0 solid transparent;
  border-image: url(/assets/ui4/slider_track.webp) 19 32 19 33 fill / calc(9.5 * var(--u)) calc(16 * var(--u)) calc(9.5 * var(--u)) calc(16.5 * var(--u)) stretch; }
:is(.ach-body, .book-head, .tr-head, .sb-pts) .mbar i { position: absolute; left: calc(5 * var(--u)); right: calc(5 * var(--u)); top: calc(3 * var(--u)); height: calc(14 * var(--u)); border: 0 solid transparent;
  border-image: url(/assets/ui4/slider_fill.webp) 13 28 13 28 fill / calc(6.5 * var(--u)) calc(14 * var(--u)) stretch; clip-path: inset(0 calc((1 - var(--v, 0)) * 100%) 0 0 round calc(7 * var(--u))); }
:is(.ach-body, .book-head, .tr-head, .sb-pts) .mbar b { position: absolute; inset: 0; display: grid; place-items: center; font-size: calc(11.5 * var(--u)); font-weight: 600; line-height: 1;
  color: var(--cream); text-shadow: 0 1px 0 #000, 0 0 calc(2 * var(--u)) #000; }
.book-head .mbar { height: calc(24 * var(--u)); }
.book-head .mbar i { top: calc(4 * var(--u)); height: calc(16 * var(--u)); }
:is(.tr-head, .sb-pts) .tr-prog { width: calc(120 * var(--u)); border-radius: 0; background: none; overflow: visible; }

/* rows: achievements, fame/ach board, trainer, skill book, stable */
.ach-list, .sb-group ul, .mk:has(> .rank-row), .mount-combine { gap: 0; }
.ach-row, .mk .card.rank-row, .tr-row, .sb-row, .mount-combine .card {
  background: none; border: 0; border-radius: 0; box-shadow: none; border-bottom: calc(2 * var(--u)) solid rgba(139, 107, 78, .25); }
.ach-row, .tr-row, .sb-row, .mk .card.rank-row, .mount-combine .card { padding: calc(8 * var(--u)) calc(4 * var(--u)); }
:is(.ach-row, .mk .card.rank-row, .tr-row, .sb-row:not(.locked, .unlearned), .mount-combine .card):hover { background: rgba(255, 255, 255, .22); }
.sb-group li:last-child, .ach-row:last-child, .rank-row:last-child, .mount-combine .card:last-child { border-bottom: 0; }
.sb-row.on { box-shadow: inset calc(4 * var(--u)) 0 0 var(--sage); }   /* on hotbar = sage edge */
.sb-row.picked { box-shadow: none; background: linear-gradient(90deg, rgba(232, 184, 76, .45), rgba(232, 184, 76, .12)); }   /* picked = K-357 gold */
.mount-combine .card.ready { box-shadow: none; background: linear-gradient(90deg, rgba(232, 184, 76, .4), rgba(232, 184, 76, .1)); }
.rank-row > b:first-child { min-width: calc(40 * var(--u)); color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.rank-row:nth-child(-n + 3) > b:first-child { color: #a8761c; font-size: 1.1em; }

/* achievement badge = steel slot (vacant = slot_empty, reached = slot, gold/complete = slot_gold); tier pips stay */
.ach-badge { width: calc(56 * var(--u)); height: calc(56 * var(--u)); padding: calc(9 * var(--u)); border-radius: 0; background: none; box-shadow: none;
  border: 0 solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.ach-badge .ic { width: 100%; height: 100%; object-fit: contain; }
.ach-badge.none { border-image-source: url(/assets/ui3/slot_empty.png); }
.ach-badge.gold { border-image-source: url(/assets/ui3/slot_gold.png); background: none; }
/* category chips = ui4 tabs (icon + label in a row) */
.ach-cats { gap: calc(4 * var(--u)); }
.ach-cats button { --pk: .85; flex-direction: row; gap: calc(4 * var(--u)); min-width: 0; min-height: calc(36 * var(--u)); padding: 0 calc(2 * var(--u)); white-space: nowrap;
  font-size: calc(12.5 * var(--u)); color: #c9c3b6; text-shadow: 0 1px 0 #000; background: none; border-radius: 0; border: 0 solid transparent; border-width: 0 calc(14 * var(--u));
  border-image: url(/assets/ui4/tab.webp) 39 37 39 37 fill / calc(19.5 * var(--u) * var(--pk)) calc(18.5 * var(--u) * var(--pk)) / 0 stretch; }
.ach-cats button:hover { filter: brightness(1.1); }
.ach-cats button.on { background: none; color: #ffe9a8; border-image-source: url(/assets/ui4/tab_active.webp); }
.ach-cats .ic { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
.ach-sw.on { outline-color: var(--gold); }

/* collection book cells: icon in a steel slot, name under (locked = slot_empty + black silhouette, selected = slot_gold) */
.book-cell { background: none; border: 0; border-radius: calc(6 * var(--u)); padding: calc(2 * var(--u)); gap: calc(3 * var(--u)); }
.book-cell .bk-slot { display: block; width: calc(56 * var(--u)); height: calc(56 * var(--u)); padding: calc(9 * var(--u)); box-sizing: border-box;
  border: 0 solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.book-cell .bk-slot > * { display: block; width: 100%; height: 100%; object-fit: contain; }   /* block parent: % height in an auto grid track = intrinsic -> overflow */
.book-cell.locked .bk-slot { border-image-source: url(/assets/ui3/slot_empty.png); }
.book-cell.on { background: none; }
.book-cell.on .bk-slot { border-image-source: url(/assets/ui3/slot_gold.png); }
.book-cell:hover .bk-slot { filter: brightness(1.08); }
.book-cell:focus-visible { outline: calc(2 * var(--u)) solid var(--gold); }

/* stable parts = steel slots (missing = slot_empty, art greyed) */
.mpart .mp-slot { display: block; width: calc(48 * var(--u)); height: calc(48 * var(--u)); padding: calc(8 * var(--u)); box-sizing: border-box;
  border: 0 solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.mpart .mp-slot .ic { display: block; width: 100%; height: 100%; object-fit: contain; border: 0; border-radius: 0; background: none; }
.mpart.missing .mp-slot { border-image-source: url(/assets/ui3/slot_empty.png); }
.mpart b { z-index: 1; }
.mount-combine .card .mparts { flex: 1 1 auto; }

/* skill book hotbar strip: steel slots, empty = slot_empty (no "ว่าง" pill text; kbd only), drop target while picking = gold */
.sb-slot { width: calc(56 * var(--u)); min-height: 0; aspect-ratio: 1; padding: calc(8 * var(--u)); background: none; border-radius: 0; color: var(--cream-lt);
  border: 0 solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; }
.sb-slot.empty { background: none; border-image-source: url(/assets/ui3/slot_empty.png); color: var(--ink-dim); }
.sb-slot.empty > b { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }   /* "ว่าง" = screen reader only */
.sb-slot.target { border-image-source: url(/assets/ui3/slot_gold.png); }
.sb-slot kbd { z-index: 1; top: calc(3 * var(--u)); left: calc(6 * var(--u)); padding: 0 calc(3 * var(--u)); border-radius: calc(4 * var(--u)); line-height: 1.3; }
.sb-slot:not(.empty) kbd { color: var(--cream-lt); background: rgba(30, 20, 12, .72); }
.sb-slot .sk-ic { width: 100%; height: 100%; }
.sb-slot .ui-close.sm { z-index: 2; }

/* barber / creation Stepper value + stall shop chat log = ui3 inset (K-359 field look) */
.st-val, .st-log { background: none; border-radius: 0; border: calc(6 * var(--u)) solid transparent;
  border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / calc(12 * var(--u)) / 0 stretch; }
.st-log { padding: calc(4 * var(--u)) calc(6 * var(--u)); }

/* K-416 NumField (readOnly input + NumPad below) / QtyStepper (= .st-qty from K-237) */
.num-field { display: grid; gap: calc(6 * var(--u)); }
.num-field input { cursor: inherit; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; caret-color: transparent; }
.num-field.open input { outline: calc(2 * var(--u)) solid var(--gold); outline-offset: calc(1 * var(--u)); }
.num-field .qtypad { width: min(100%, calc(320 * var(--u))); justify-self: end; }
.auto-panel .st-qty { margin-bottom: calc(4 * var(--u)); }
.st-qty-row input:disabled { opacity: .6; }

/* K-423 (user 2026-10-10 "ย้ายอุปกรณ์สวมใส่ไปไว้หน้า U") U paper-doll, Panels.jsx CharacterPanel .char-doll: .pdoll = gear col | rig | gear col,
   .pdoll-tools = 6 tool slots bottom row, ค่าพลัง 2x2 under. --dl-slot = slot size knob (48u), shrinks so 6 tools fit (100cqi = .panel width).
   Rig = .85 x column height (knob). Short screens (<=520h): doll left, tools row + stats right. .bag-gear/.bag-tools rules above = dead (bag gear tab removed). */
.char-doll { --dl-slot: min(calc(48 * var(--u)), calc((100cqi - 110 * var(--u)) / 6)); }
.char-doll .body { gap: calc(6 * var(--u)); }
.pdoll { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: calc(6 * var(--u)); padding: 0 calc(4 * var(--u)); }
.pdoll-col { display: flex; flex-direction: column; gap: calc(5 * var(--u)); }
.pdoll .slot, .pdoll-tools .slot { width: var(--dl-slot); min-height: 0; aspect-ratio: 1; }
.pdoll .gear-placeholder, .pdoll-tools .gear-placeholder { width: 62%; height: 62%; }
.pdoll .slot.filled.dim .ic { opacity: .45; filter: grayscale(.6); }   /* 2H weapon mirrored in the shield slot */
.pdoll-rig { display: grid; place-items: end center; min-width: 0; }
.pdoll-rig .rig-preview { height: calc((4 * var(--dl-slot) + 15 * var(--u)) * .85); width: auto; max-width: 100%; aspect-ratio: 220 / 280; object-fit: contain; margin: 0; }
.pdoll-tools { display: flex; justify-content: center; gap: calc(6 * var(--u)); padding-top: calc(8 * var(--u)); border-top: calc(2 * var(--u)) solid rgba(139, 107, 78, .35); }
.char-doll .character-power { padding: calc(6 * var(--u)) calc(10 * var(--u)); }
.char-doll .character-power .kv { grid-template-columns: repeat(5, minmax(0, 1fr)); grid-template-rows: auto auto; grid-auto-flow: column; gap: 0 calc(6 * var(--u)); font-size: calc(13 * var(--u)); text-align: center; }   /* 5 stat columns (hp atk matk crit def): dt over dd */
.character-power .kv .dim { opacity: .55; }   /* user 2026-10-15 unused attack type dimmed */
.char-doll .character-power .kv dt { font-size: calc(11 * var(--u)); line-height: 1.2; }
.char-doll .character-power .kv dd { text-align: center; font-size: calc(15 * var(--u)); }
.char-doll .character-power .gs-sub { font-size: calc(10 * var(--u)); }
.char-doll .character-power .gs-sub b { white-space: nowrap; }   /* Thai: never split ตีบวก/เพชร mid-word */

.pdoll-pick .slot-grid { justify-content: center; }
@media (max-height: 520px) {
  .char-doll { --dl-slot: calc(38 * var(--u)); }
  .char-doll .character-power .kv dd { font-size: calc(13 * var(--u)); }
  .char-doll .character-power { padding: calc(3 * var(--u)) calc(8 * var(--u)); }
  .char-doll .body { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto 1fr; align-content: start; gap: calc(4 * var(--u)) calc(10 * var(--u)); }
  .char-doll .char-tabs { grid-column: 1 / -1; }
  .char-doll .pdoll { grid-row: 2 / 4; align-self: start; }
  .char-doll .pdoll-tools { justify-content: start; flex-wrap: wrap; border-top: 0; padding-top: 0; }
  .char-doll .character-power .kv { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto auto auto; }
}
/* K-426 social panel (user: party tab too short, side-tab rail ran past the panel bottom): min height fits the 5-tab rail (top + 5 tabs + 4 gaps + margin).
   .side-tabs top 24u / gap 14u (phone top 78u / gap 10u); knob = the min-height values. */
.panel.social-panel { min-height: min(calc(24 * var(--u) + 5 * var(--side-tab) + 4 * calc(14 * var(--u)) + calc(40 * var(--u))), 100%); }
@media (max-width: 620px) { .panel.social-panel { min-height: min(calc(78 * var(--u) + 5 * var(--side-tab) + 4 * calc(10 * var(--u)) + calc(30 * var(--u))), 100%); } }

/* K-424 (user 2026-10-10 "เควสสอนเล่นกดนำทางได้ + ใส่ของมีเหลืองๆ แนะนำ"): coach นำทาง on every screen (NavTracker portals .tut-nav = tutorial route,
   hidden when the step has no target); desktop keeps the tracker card too. .tut-hl = tutorial highlight (engine/tut-highlight.mjs selectors,
   TutorialCoach toggles): gold pulse ring, same palette as .tut-glow; .tut-open = closed panel's dock button + 'เปิดที่นี่' pill on its left. */
.tut-coach .tut-nav { display: block; }
.tut-hl { position: relative; outline: calc(3 * var(--u)) solid #f2c84b !important; outline-offset: calc(1 * var(--u)); border-radius: calc(8 * var(--u));
  animation: tut-glow 1.1s ease-in-out infinite; z-index: 1; }
.btn.tut-hl { border-radius: calc(999 * var(--u)); }
.tut-open::after { content: "เปิดที่นี่"; position: absolute; right: calc(100% + 30 * var(--u)); top: 50%; translate: 0 -50%; white-space: nowrap; pointer-events: none;
  padding: calc(2 * var(--u)) calc(8 * var(--u)); border-radius: calc(999 * var(--u)); background: #f2c84b; color: #3b2a1f; font-size: calc(12 * var(--u)); font-weight: 600;
  box-shadow: 0 calc(2 * var(--u)) 0 rgba(59, 42, 31, .35); animation: tut-bob-x .8s ease-in-out infinite; }
@media (max-width: 620px) { .tut-open::after { font-size: calc(11 * var(--u)); } }
/* K-428 tab title row may carry a right node (bag: Acorn + load), space-between */
.tab-title.has-right { display: flex; align-items: center; justify-content: space-between; gap: calc(8 * var(--u)); }
.tab-title .tt-l { display: inline-flex; align-items: center; gap: calc(6 * var(--u)); }
.bag-wallet-inline { display: inline-flex; align-items: center; gap: calc(10 * var(--u)); font-size: calc(15 * var(--u)); font-weight: 500; }
.bag-wallet-inline .coins { display: inline-flex; gap: calc(8 * var(--u)); }
.bag-wallet-inline .ic { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
.bag-wallet-inline .coins > span { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); font-variant-numeric: tabular-nums; }
.bag-capacity .bag-load { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); margin-right: calc(8 * var(--u)); }
.bag-load .load { display: inline-flex; align-items: center; gap: calc(6 * var(--u)); font-weight: 600; color: var(--ink-dim); }
.bag-load .weight { display: inline-block; width: calc(22 * var(--u)); height: calc(24 * var(--u)); background: url(/assets/ui3/weight.png) center / contain no-repeat; }
.bag-load .load.over { color: var(--locked); }

/* K-427 (bug: 844x390 item detail cut ถอด/ใส่ below the screen; K-423 shot): Panels.jsx ItemModal = .im-head (icon + name, fixed) | .im-body (details,
   K-396 stats, gems, sell, mastery, qty pad; scrolls, K-366 bar) | .actions (fixed). Cap = dynamic viewport minus safe areas minus backdrop pad.
   Short landscape (<=520h): grid head + actions left col, body right col full height. 200u/620u = column/width knobs. .pdoll-pick (no .im-body) keeps whole-box scroll. */
.item-modal-backdrop { padding-block: max(calc(16 * var(--u)), env(safe-area-inset-top)) max(calc(16 * var(--u)), env(safe-area-inset-bottom)); }
.item-modal, .confirm-modal { max-height: calc(100dvh - 2 * max(calc(16 * var(--u)), env(safe-area-inset-top), env(safe-area-inset-bottom))); }
.item-modal:has(> .im-body) { overflow: hidden; }
.im-head, .im-body { display: flex; flex-direction: column; gap: calc(8 * var(--u)); }
.im-head { flex: none; }
.im-body { flex: 0 1 auto; min-height: 0; overflow-y: auto; }
.item-modal > .actions { flex: none; }
@media (max-height: 520px) and (orientation: landscape) {
  .item-modal:has(> .im-body) { width: min(calc(620 * var(--u)), 100%); display: grid; grid-template-columns: minmax(0, calc(200 * var(--u))) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto; gap: calc(8 * var(--u)) calc(14 * var(--u)); padding: calc(12 * var(--u)); }
  .item-modal .im-head { grid-area: 1 / 1; align-self: center; }
  .item-modal .im-head .item-modal-icon { width: calc(80 * var(--u)); height: calc(80 * var(--u)); }
  .item-modal .im-head .item-modal-icon .ic { width: calc(64 * var(--u)); height: calc(64 * var(--u)); }
  .item-modal .im-body { grid-area: 1 / 2 / 3 / 3; align-self: start; max-height: 100%; }
  .item-modal .im-body > :first-child { margin-inline: calc(40 * var(--u)); }   /* clear the absolute close button (38u) */
  .item-modal:has(> .im-body) > .actions { grid-area: 2 / 1; flex-wrap: wrap; margin-top: 0; }
}

/* K-429 other-player profile = K-423 paper-doll read-only (TradePanels ProfilePanel .char-doll.prof-doll: reuses every .pdoll/.character-power rule above).
   .prof-head = name + title chip + fame line; read-only vacant slot = span.slot (no hover); short screens: head + actions span both grid columns. */
.prof-doll { --dl-slot: min(calc(46 * var(--u)), calc((100cqi - 110 * var(--u)) / 6)); }   /* knob: 2u under U (actions row) */
.prof-head { display: flex; flex-wrap: wrap; align-items: center; gap: calc(4 * var(--u)) calc(8 * var(--u)); }
.prof-head h3 { margin: 0; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prof-head .note { flex: 0 1 auto; margin: 0; font-size: calc(12 * var(--u)); display: inline-flex; align-items: center; gap: calc(3 * var(--u)); }
.prof-head .note .ic { width: calc(16 * var(--u)); height: calc(16 * var(--u)); }
.prof-doll .prof-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(6 * var(--u)); margin: 0; }
.prof-doll .prof-actions { flex-wrap: nowrap; }
.prof-doll .prof-actions .btn { flex: 1 1 0; min-width: 0; padding-left: calc(6 * var(--u)); padding-right: calc(6 * var(--u)); white-space: nowrap; }
.prof-doll .prof-actions .btn .ic { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
@container (max-width: 520px) { .prof-doll .prof-actions { flex-wrap: wrap; } .prof-doll .prof-actions .btn { flex: 1 1 calc(50% - 6 * var(--u)); } }   /* phone: 2 per row */
@media (max-height: 520px) {
  .prof-doll { --dl-slot: calc(38 * var(--u)); }   /* = K-423 short-screen knob (rule above outranks it by order) */
  .prof-doll .prof-head { grid-column: 1 / -1; }
  .prof-doll .body { grid-template-rows: auto auto 1fr; }
  .prof-doll .pdoll { grid-row: 2 / 4; }
  .prof-doll .prof-actions { grid-column: 2; grid-row: 3; align-self: start; }   /* right column under stats (full-width row overlapped the doll) */
  .prof-head .note { flex: 0 1 auto; }
}

/* K-430 admin announcement marquee (AnnounceBar.jsx): long thin strip top-centre between .vitals and .ping-hud/minimap, K-404 chat look
   (translucent dark, thin border, small radius) + megaphone. Text track = container (cqw): span translateX(100cqw -> -100%), GPU transform only.
   kind accent = left border + icon colour. pointer-events none except ×. Knobs: --an-w width, top offset, accent colours. */
.announce { --an-w: min(calc(560 * var(--u)), calc(100vw - 2 * (var(--mm) * 1.24 + 64 * var(--u))));
  position: absolute; z-index: 6; left: 50%; top: calc(max(calc(12 * var(--u)), env(safe-area-inset-top)) + calc(6 * var(--u))); transform: translateX(-50%);
  width: var(--an-w); height: calc(30 * var(--u)); display: flex; align-items: center; gap: calc(6 * var(--u)); padding: 0 calc(4 * var(--u)) 0 calc(8 * var(--u));
  pointer-events: none; color: #f3ede0; background: rgba(10, 9, 8, .62); border: 1px solid rgba(0, 0, 0, .7); border-left: calc(3 * var(--u)) solid var(--an-c, #e8d9a8);
  border-radius: calc(6 * var(--u)); box-shadow: 0 0 0 1px rgba(255, 255, 255, .06) inset, 0 calc(3 * var(--u)) calc(10 * var(--u)) rgba(0, 0, 0, .35); }
.announce.k-event { --an-c: #f2c94c; } .announce.k-warning { --an-c: #ff6b5e; }
.announce > .ic { flex: none; width: calc(18 * var(--u)); height: calc(18 * var(--u)); color: var(--an-c, #e8d9a8); }
.announce-track { flex: 1; min-width: 0; height: 100%; overflow: hidden; container-type: inline-size; display: flex; align-items: center;
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent); }
.announce-track span { flex: none; white-space: nowrap; font-size: calc(14 * var(--u)); font-weight: 600; text-shadow: 0 1px 1px #000; will-change: transform;
  animation-name: an-scroll; animation-timing-function: linear; }
@keyframes an-scroll { from { transform: translateX(100cqw); } to { transform: translateX(-100%); } }
.announce-x { flex: none; pointer-events: auto; position: relative; width: calc(22 * var(--u)); height: calc(22 * var(--u)); padding: 0; display: grid; place-items: center;
  font-size: calc(16 * var(--u)); line-height: 1; color: #cfc6b6; background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .15); border-radius: calc(4 * var(--u)); cursor: pointer; }
.announce-x:hover { background: rgba(255, 255, 255, .18); }
.announce-x::after { content: ""; position: absolute; inset: calc(-8 * var(--u)); }   /* touch hit area */
@media (max-width: 720px) {   /* phones portrait: top row = vitals + minimap -> strip spans below them */
  .announce { left: max(8px, env(safe-area-inset-left)); transform: none;   /* right end clears the .dock menu column (knob: 16u + 14px) */
    --an-w: calc(100vw - max(8px, env(safe-area-inset-left)) - max(calc(12 * var(--u)), env(safe-area-inset-right)) - var(--menu-btn) - calc(16 * var(--u)) - 14px); top: calc(env(safe-area-inset-top) + var(--mm) * 1.24 + calc(40 * var(--u))); height: 28px; }
  .announce-track span { font-size: 13px; } .announce > .ic { width: 16px; height: 16px; } .announce-x { width: 22px; height: 22px; font-size: 16px; }
}
/* K-435 restart countdown chip (RestartNotice.jsx) under the K-430 marquee, same dark look; refresh modal = ConfirmModal classes, z above all. */
.restart-chip { position: absolute; z-index: 6; left: 50%; transform: translateX(-50%); top: calc(max(calc(12 * var(--u)), env(safe-area-inset-top)) + calc(42 * var(--u)));
  pointer-events: none; padding: calc(2 * var(--u)) calc(10 * var(--u)); font-size: calc(12 * var(--u)); font-weight: 600; color: #f3ede0; text-shadow: 0 1px 1px #000;
  background: rgba(10, 9, 8, .62); border: 1px solid rgba(0, 0, 0, .7); border-left: calc(3 * var(--u)) solid #ff6b5e; border-radius: 999px; white-space: nowrap; }
.restart-chip b { color: #ffb4a8; font-variant-numeric: tabular-nums; }
.restart-modal { z-index: 90; }
.restart-body { margin: calc(12 * var(--u)) calc(14 * var(--u)); text-align: center; line-height: 1.5; font-size: calc(14 * var(--u)); }
@media (max-width: 720px) { .restart-chip { left: max(8px, env(safe-area-inset-left)); transform: none; top: calc(env(safe-area-inset-top) + var(--mm) * 1.24 + calc(40 * var(--u)) + 34px); font-size: 12px; } }

/* K-433 SHORT LANDSCAPE HUD, any pointer (user checks phones + a resized desktop browser; fine pointer had the dock right + round buttons
   bottom-left): dock = 2-column grid under the character card (left; 2 cols so it ends well above the joystick), sleep / mail / chat = one
   row under the minimap (right-aligned, order sleep mail chat), ping = top row left of the minimap ring (outside it), minimap = touch metrics
   for both pointers. Coach + quest tracker sit right of the dock; open chat hides the coach (would overlap). Knobs: --rb, --k433-dock-w. */
@media (orientation: landscape) and (max-height: 520px), (orientation: landscape) and (pointer: coarse) {   /* K-438: + every touch landscape (tablets 1024x600..1180x820) */
  :root { --mm: calc(140 * var(--u)); --rb: calc(34 * var(--u)); --k433-dock-w: calc(96 * var(--u)); }
  .minimap { margin: calc(12 * var(--u)) calc(12 * var(--u)) 0 0; top: max(calc(4 * var(--u)), env(safe-area-inset-top)); right: max(calc(4 * var(--u)), env(safe-area-inset-right)); }
  .dock { display: grid; grid-template-columns: repeat(2, calc(32 * var(--u))); gap: calc(5 * var(--u)); justify-items: center; align-content: start;
    left: max(calc(12 * var(--u)), env(safe-area-inset-left)); right: auto; bottom: auto; transform: none; top: calc(env(safe-area-inset-top) + calc(80 * var(--u)));
    padding: calc(8 * var(--u)); min-width: 0; max-height: none; }
  .dock .mbtn { width: calc(32 * var(--u)); height: calc(32 * var(--u)); } .dock .mbtn .ic { width: calc(24 * var(--u)); height: calc(24 * var(--u)); }
  .dock .mbtn kbd { display: none; }
  .dock .dock-fold { grid-column: 1 / -1; }
  .dock-more { top: 0; bottom: auto; left: calc(100% + 8 * var(--u)); right: auto; transform: none; }
  .chat-toggle, .sleep-wrap { position: absolute; left: auto; bottom: auto; z-index: 6; top: calc(var(--mm) + calc(42 * var(--u)) + env(safe-area-inset-top)); }
  .chat-toggle, .sleep-wrap .sleep-btn { width: var(--rb); height: var(--rb); min-height: 0; }
  .chat-toggle .ic { width: calc(20 * var(--u)); height: calc(20 * var(--u)); }
  .chat-toggle { right: max(calc(14 * var(--u)), env(safe-area-inset-right)); }
  .sleep-wrap { right: calc(max(calc(14 * var(--u)), env(safe-area-inset-right)) + var(--rb) + calc(8 * var(--u))); }
  .tut-coach, .nav-track { left: calc(max(calc(12 * var(--u)), env(safe-area-inset-left)) + var(--k433-dock-w)); top: calc(80 * var(--u) + env(safe-area-inset-top)); }
  .game:has(#game-chat) .tut-coach { visibility: hidden; }
}
@media (orientation: landscape) and (max-height: 520px) and (pointer: fine) {   /* no stick: chat right of the dock, above the desktop hotbar */
  .chat-popup { left: calc(max(calc(12 * var(--u)), env(safe-area-inset-left)) + var(--k433-dock-w)); bottom: calc(var(--hotbar-h) + calc(18 * var(--u)) + env(safe-area-inset-bottom)); }
}

/* K-434 social + install row (SocialBar.jsx). K-452 (user): rendered in the card's .bars but positioned OUTSIDE the frame, just above its top
   edge (bottom: 100%), aligned with the name column (left = --soc-x ~ bars padding-left, knob); portrait frame top clear, nothing drawn
   inside the status frame. Order: ping pill, 20u round dark brand icons (brand colour on hover), install pill. The card moves down by --soc-h. */
.vitals .bars { position: relative; }
.soc-bar { position: absolute; z-index: 5; bottom: calc(100% + calc(3 * var(--u))); left: var(--soc-x, calc(24 * var(--u)));
  display: flex; align-items: center; gap: calc(4 * var(--u)); height: calc(20 * var(--u)); width: max-content; }
.vitals { margin-top: var(--soc-h); }
:root { --soc-h: calc(16 * var(--u)); }   /* knob: room above the card (row 20u + 3u gap minus the portrait ring's own overhang above the bars) */
.soc-ic, .soc-dl { display: inline-flex; align-items: center; justify-content: center; height: calc(20 * var(--u)); color: #f3ede0; cursor: inherit;
  background: rgba(20, 16, 12, .62); border: 1px solid rgba(255, 255, 255, .22); box-shadow: 0 1px 2px rgba(0, 0, 0, .4); text-decoration: none; }
.soc-ic { width: calc(20 * var(--u)); border-radius: 50%; }
.soc-ic svg { width: calc(12 * var(--u)); height: calc(12 * var(--u)); }
.soc-discord:hover { color: #8c9bff; } .soc-facebook:hover { color: #6aa4ff; } .soc-tiktok:hover { color: #6ff3ee; } .soc-instagram:hover { color: #ff7ab8; }
.soc-dl { gap: calc(2 * var(--u)); padding: 0 calc(7 * var(--u)) 0 calc(4 * var(--u)); border-radius: 999px; font: inherit; font-size: max(10px, calc(10 * var(--u))); font-weight: 600; }
.soc-dl .ic { width: calc(11 * var(--u)); height: calc(11 * var(--u)); stroke-width: 3; }
.soc-ic:hover, .soc-dl:hover { background: rgba(40, 32, 24, .8); }
@media (pointer: coarse) { .soc-ic, .soc-dl { position: relative; } .soc-ic::after, .soc-dl::after { content: ""; position: absolute; inset: -9px -3px; } }   /* touch hit ~38px tall, no overlap sideways */
.soc-howto { width: min(calc(360 * var(--u)), 92vw); padding: calc(18 * var(--u)) calc(20 * var(--u)); }
.soc-howto h3 { margin: 0 0 calc(8 * var(--u)); font-size: calc(17 * var(--u)); }
.soc-howto ol { margin: 0; padding-left: calc(20 * var(--u)); display: grid; gap: calc(6 * var(--u)); font-size: calc(14 * var(--u)); line-height: 1.4; }
.soc-hint-ic { display: inline-block; width: calc(20 * var(--u)); height: calc(20 * var(--u)); vertical-align: -0.3em; color: #2c66a8; }
@media (max-width: 620px) { .soc-dl .ic { display: none; } .soc-dl { padding: 0 calc(7 * var(--u)); } }   /* K-434 portrait: row clears the ping label */

/* K-432 U tabs ตัวละคร | สมุดสกิล | สกิน: one row on every width (3 tabs wrapped on phone) */
.char-tabs { flex-wrap: nowrap; }
.char-tabs .btn { flex: 1 1 0; min-width: 0; white-space: nowrap; }

/* K-438 HUD fit at ANY viewport (user: smaller OK, overlap never). Layout families: P = portrait (any pointer), L = landscape + (touch OR
   <= 520px tall) = K-433 arrangement, D = desktop landscape (unchanged look). Regression tool: tools/qa/hud-overlap.mjs (20-viewport matrix).
   - scale: short landscape shrinks --u below the .85 floor (knob 470 px design height, .62 floor); narrow portrait (<=380) scales only the skill wheel .86.
   - ping: K-452 moved it into the card's social row (was top-right above the minimap ring + --ping-h shift).
   - left column (L + P) stacks under the measured top-left cluster (GameCanvas --hudl-b / --hudl-w): [P: announce] -> dock (2-col grid) |
     coach / quest tracker right of it (L touch: also right of the stick; P: also below the minimap). */
@media (orientation: landscape) and (max-height: 430px) { :root { --u: clamp(.62px, calc(100dvh / 470), .85px); } }
@media (orientation: portrait) and (max-width: 380px) and (pointer: coarse) { .hotbar { scale: .86; transform-origin: 100% 100%; } }   /* narrow phones: skill wheel clears the stick (panels keep --u = readable text) */
@media (orientation: landscape) and (max-height: 520px), (orientation: landscape) and (pointer: coarse) {
  .announce { left: calc(var(--hudl-w, 220px) + calc(10 * var(--u))); right: calc(max(calc(4 * var(--u)), env(safe-area-inset-right)) + calc(12 * var(--u)) + var(--mm) * 1.12 + calc(10 * var(--u)));
    width: auto; transform: none; top: calc(max(calc(12 * var(--u)), env(safe-area-inset-top)) + calc(6 * var(--u))); }
  .dock { top: calc(var(--hudl-b, 80px) + calc(8 * var(--u))); margin-top: 0; }
  .tut-coach, .nav-track { margin-top: 0; top: calc(var(--hudl-b, 80px) + calc(8 * var(--u)));
    left: calc(max(calc(12 * var(--u)), env(safe-area-inset-left)) + var(--tut-x)); }
}
@media (orientation: landscape) and (pointer: coarse) {   /* L touch: chat right of the stick, clear of the skill wheel (knob 260u) */
  .chat-popup { left: calc(env(safe-area-inset-left) + var(--joy-rest) + var(--joy-d) / 2 + calc(16 * var(--u))); bottom: calc(env(safe-area-inset-bottom) + calc(8 * var(--u)));
    width: min(calc(380 * var(--cu)), calc(100vw - var(--joy-rest) - var(--joy-d) / 2 - calc(16 * var(--u)) - calc(260 * var(--u)) - var(--chat-rail) - env(safe-area-inset-left) - env(safe-area-inset-right))); }
}
@media (orientation: portrait) {
  .game:has(.announce) { --ann-slot: calc(28px + calc(8 * var(--u))); }
  .announce { left: max(calc(12 * var(--u)), env(safe-area-inset-left)); right: calc(max(calc(4 * var(--u)), env(safe-area-inset-right)) + calc(12 * var(--u)) + var(--mm) * 1.12 + calc(10 * var(--u)));
    width: auto; transform: none; top: calc(var(--hudl-b, 80px) + calc(6 * var(--u))); height: 28px; }
  .dock { display: grid; grid-template-columns: repeat(2, calc(32 * var(--u))); gap: calc(5 * var(--u)); justify-items: center; align-content: start; flex-direction: column;
    left: max(calc(12 * var(--u)), env(safe-area-inset-left)); right: auto; bottom: auto; transform: none; translate: none; margin-top: 0;
    top: calc(var(--hudl-b, 80px) + var(--ann-slot, 0px) + calc(8 * var(--u))); padding: calc(8 * var(--u)); min-width: 0; max-height: none; }
  .dock .mbtn { width: calc(32 * var(--u)); height: calc(32 * var(--u)); } .dock .mbtn .ic { width: calc(24 * var(--u)); height: calc(24 * var(--u)); }
  .dock .mbtn kbd { display: none; }
  .dock .dock-fold { grid-column: 1 / -1; }
  .dock-more { top: 0; bottom: auto; left: calc(100% + 8 * var(--u)); right: auto; transform: none; }
  .tut-coach, .nav-track { margin-top: 0; translate: none; left: calc(max(calc(12 * var(--u)), env(safe-area-inset-left)) + var(--tut-x)); right: auto;
    width: min(calc(330 * var(--u)), calc(100vw - var(--k433-dock-w, calc(96 * var(--u))) - calc(24 * var(--u)) - env(safe-area-inset-left) - env(safe-area-inset-right)));
    top: max(calc(var(--hudl-b, 80px) + var(--ann-slot, 0px) + calc(8 * var(--u))), calc(env(safe-area-inset-top) + calc(16 * var(--u)) + var(--mm) + calc(40 * var(--u)))); }
}
/* K-438 coach: fold button (TutorialCoach slim = header row only, localStorage ageup.tutSlim) + phone scale-down (visual scale, origin top-left;
   rects follow) — user: card was oversized on phones. Knob: --tut-k. */
.tut-coach header { flex-wrap: nowrap; }
.tut-fold { flex: none; display: grid; place-items: center; width: calc(26 * var(--u)); height: calc(26 * var(--u)); padding: 0; cursor: inherit; position: relative;
  background: rgba(59, 42, 30, .12); border: 1px solid rgba(59, 42, 30, .35); border-radius: calc(6 * var(--u)); color: var(--line); }
.tut-fold::after { content: ""; position: absolute; inset: calc(-8 * var(--u)); }
.tut-fold .ic { width: calc(16 * var(--u)); height: calc(16 * var(--u)); stroke-width: 3; }
.tut-coach.slim > :not(header) { display: none; }
@media (orientation: portrait) and (max-width: 620px), (orientation: landscape) and (max-height: 520px) {
  .tut-coach, .nav-track { scale: var(--tut-k); transform-origin: 0 0; }
}

/* K-439 multi-touch (defensive): a 2nd finger on the touch HUD never starts a browser pan/zoom (= pointercancel on the stick/skill fingers). */
@media (pointer: coarse) { .hotbar, .hotbar button { touch-action: none; } }
@media (pointer: coarse) and (orientation: portrait) {   /* K-438 P touch: chat above the stick zone + skill wheel (tablets: was bottom 76u over both); width cap */
  .chat-popup { bottom: calc(env(safe-area-inset-bottom) + max(calc(246 * var(--u)), var(--joy-h, 0px) + calc(8 * var(--u))));
    width: min(calc(560 * var(--cu)), calc(100vw - var(--chat-rail) - calc(86 * var(--u)) - calc(20 * var(--u)) - env(safe-area-inset-left) - env(safe-area-inset-right))); }
}
@media (pointer: coarse) and (orientation: portrait) {   /* K-438 short portrait (360x640): open chat stops below the left dock (knob 176u = dock column height + gap) */
  .chat-popup { max-height: calc(100dvh - max(calc(246 * var(--u)), var(--joy-h, 0px) + calc(8 * var(--u))) - var(--hudl-b, 80px) - var(--ann-slot, 0px) - calc(176 * var(--u)) - env(safe-area-inset-bottom)); }
}
/* K-438 audit: smallest panel text floored at 9px (was 10u = 7.7-8.5px on phones / short landscape) */
.book-cell small, .char-doll .character-power .gs-sub { font-size: max(9px, calc(10 * var(--u))); }
/* K-443 (user: coach smaller + hug the menu): phone coach / quest tracker scale --tut-k .7 (was .8); left = dock grid width (2 x 32u + gap 5u +
   padding 16u + 2 borders) + --tut-gap 7u (was --k433-dock-w 96u and, on touch landscape, right of the stick). Knobs. */
:root { --tut-k: .7; --tut-gap: calc(7 * var(--u)); --tut-x: calc(2 * 32 * var(--u) + 5 * var(--u) + 16 * var(--u) + 2 * var(--line-w) + var(--tut-gap)); }

/* K-445 map overlay (MapOverlay.jsx, panel 'map', opened by a minimap tap): centred big parchment like .cashshop; stage = ui3 inset holding the
   local canvas or the world svg (touch-action none: drag/pinch handled in JS); zoom column top-right; tap card bottom-left. */
.minimap canvas { pointer-events: auto; cursor: pointer; }
.panel.mapview { width: 100vw !important; max-width: none !important;   /* K-516 user 2026-10-12: map = full screen (was 1100x720 box) */
  height: 100dvh; max-height: none !important; bottom: auto !important;
  left: 50% !important; right: auto !important; top: 50% !important; transform: translate(-50%, -50%) !important; z-index: 8; }
.panel.mapview .body { overflow: hidden; display: flex; flex-direction: column; gap: calc(8 * var(--u)); min-height: 0; flex: 1; }
.mv-top { flex: none; display: flex; align-items: center; gap: calc(10 * var(--u)); flex-wrap: wrap; }
.mv-tabs { flex-wrap: nowrap; }
.mv-name { display: inline-flex; align-items: center; gap: calc(8 * var(--u)); font-weight: 600; color: var(--ink); min-width: 0; }
.mv-name .zonetag { height: calc(24 * var(--u)); font-size: calc(12 * var(--u)); }
.mv-daily { font-size: calc(13 * var(--u)); color: var(--ink-dim); font-weight: 500; }   /* K-572 daily craft bonus */
.mv-main { position: relative; flex: 1; min-height: 0; }
.mv-stage { position: absolute; inset: 0; overflow: hidden; touch-action: none; user-select: none; cursor: grab; border-radius: calc(10 * var(--u));
  background: #2f3a2a; box-shadow: inset 0 0 0 calc(3 * var(--u)) var(--line); }
.mv-stage:active { cursor: grabbing; }
.mv-stage canvas, .mv-stage svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.mv-stage.mv-wait { display: grid; place-items: center; color: #fff6df; }
.mv-world { background: #e9dcbc; }
.mv-e line { stroke: #6b4a2c; stroke-width: 3; stroke-linecap: round; }
.mv-e.boat line { stroke: #3d8fc4; stroke-dasharray: 8 7; stroke-width: 2.5; }
.mv-e.hall line { opacity: .28; }
.mv-e.hot line { stroke: #e0a020; stroke-width: 5; opacity: 1; }
.mv-e text { font: 600 12px Mitr, sans-serif; fill: #1f5f8a; text-anchor: middle; paint-order: stroke; stroke: #e9dcbc; stroke-width: 4px; }
.mv-n { cursor: pointer; }
.mv-n rect { stroke: var(--line); stroke-width: 2.5; }
.mv-n text { font: 600 13px Mitr, sans-serif; fill: #2a1d12; text-anchor: middle; }
.mv-n text.sub { font-size: 11px; font-weight: 500; }
.mv-n text.lt { fill: #fff6df; }
.mv-n text.you { font-size: 12px; fill: #8a5a00; paint-order: stroke; stroke: #fff3c8; stroke-width: 4px; }
.mv-n.here rect { stroke: #ffc21a; stroke-width: 5; }
.mv-n.sel rect { stroke: #e0a020; stroke-width: 4; filter: drop-shadow(0 0 4px rgba(255, 200, 40, .9)); }
.mv-zoom { position: absolute; z-index: 2; top: calc(8 * var(--u)); right: calc(8 * var(--u)); display: flex; flex-direction: column; gap: calc(6 * var(--u)); }
.mv-zoom .btn { min-width: calc(44 * var(--u)); justify-content: center; }
.mv-card { position: absolute; z-index: 2; left: calc(8 * var(--u)); bottom: calc(8 * var(--u)); width: min(calc(280 * var(--u)), calc(100% - 16 * var(--u)));
  max-height: calc(100% - 16 * var(--u)); overflow-y: auto; padding: calc(8 * var(--u)) calc(12 * var(--u)); border-radius: calc(10 * var(--u)); color: #fff6df;
  background: rgba(36, 24, 14, .86); border: calc(2 * var(--u)) solid rgba(255, 211, 77, .55); font-size: calc(13 * var(--u)); line-height: 1.35; }
.mv-card.wide { width: min(calc(360 * var(--u)), calc(100% - 16 * var(--u))); }
.mv-card header { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.mv-card header b { flex: 1; min-width: 0; color: #ffd34d; font-size: calc(15 * var(--u)); }
.mv-card p { margin: calc(4 * var(--u)) 0; }
.mv-card .mv-meta { display: flex; flex-wrap: wrap; align-items: center; gap: calc(6 * var(--u)); color: #e8d9b8; }
.mv-card .zonetag { height: calc(22 * var(--u)); font-size: calc(11 * var(--u)); }
.mv-card .mv-link { display: inline-block; margin: 0 calc(6 * var(--u)) calc(2 * var(--u)) 0; padding: 0 calc(6 * var(--u)); border-radius: calc(6 * var(--u)); background: rgba(255, 255, 255, .1); }
.mv-card .mv-you { color: #ffd34d; font-style: normal; font-size: calc(12 * var(--u)); }
.mv-card .mv-x { float: right; }
.mv-card .btn { margin-top: calc(4 * var(--u)); }
@media (max-width: 620px), (max-height: 520px) {
  .panel.mapview { width: 100vw !important; height: 100dvh; }
  .mv-zoom .btn { min-width: 40px; min-height: 36px; }
}
.mv-card .nt-x { flex: none; width: calc(28 * var(--u)); min-width: 28px; height: calc(28 * var(--u)); min-height: 28px; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .12); color: inherit; font-size: calc(18 * var(--u)); line-height: 1; }
.panel.mapview { position: fixed; }   /* K-445 viewport-centred (in .stage the containing block is narrower on phones) */
.mv-tabs .btn { white-space: nowrap; }
.game:has(.panel.mapview) :is(.nav-edge, .nav-pin, .tut-arrow) { display: none; }   /* quest pin/arrow + tutorial arrow would float over the overlay */
@media (max-height: 520px) and (orientation: landscape) {   /* short landscape: tabs column left, map gets the full body height */
  .panel.mapview .body { flex-direction: row; }
  .mv-top { flex-direction: column; align-items: stretch; flex-wrap: nowrap; width: calc(120 * var(--u)); }
  .mv-tabs { flex-direction: column; }
  .mv-name { flex-direction: column; align-items: flex-start; font-size: calc(13 * var(--u)); white-space: normal; }
  .mv-zoom { gap: 4px; } .mv-zoom .btn { min-height: 30px; height: 30px; }
}
/* K-446 Settings Feedback tab (Panels.jsx FeedbackTab): icon in tab, full-width textarea, counter left + ส่ง right */
.set-tabs .btn.ic-tab { flex: 0 0 auto; padding: 0 calc(12 * var(--u)); display: inline-flex; align-items: center; justify-content: center; gap: calc(3 * var(--u)); }   /* sized to icon + label, other tabs share the rest */
.set-tabs .btn.ic-tab > svg { width: calc(16 * var(--u)); height: calc(16 * var(--u)); flex: none; }
.fb-sec .fb-text { width: 100%; box-sizing: border-box; min-height: calc(120 * var(--u)); margin-top: calc(6 * var(--u)); }
.fb-sec .fb-foot { display: flex; align-items: center; justify-content: space-between; gap: calc(8 * var(--u)); margin-top: calc(6 * var(--u)); }
.fb-sec .fb-count { color: var(--ink-dim); }
@media (max-height: 520px) and (orientation: landscape) { .mv-card.wide { width: min(calc(300 * var(--u)), 48%); font-size: calc(12 * var(--u)); } }
@media (max-width: 380px) {   /* K-452 narrow phones: row clears the minimap -> install pill = icon only, tighter gaps */
  .soc-bar { gap: calc(3 * var(--u)); }
  .soc-dl { font-size: 0; gap: 0; padding: 0 calc(5 * var(--u)); } .soc-dl .ic { display: inline-block; width: calc(12 * var(--u)); height: calc(12 * var(--u)); }
}
@media (max-width: 520px) { .set-tabs .btn.ic-tab { padding: 0 calc(8 * var(--u)); } .set-tabs .btn.ic-tab .tab-l { display: none; } .set-tabs .btn.ic-tab > svg { width: calc(22 * var(--u)); height: calc(22 * var(--u)); } }   /* K-446 phone: icon-only Feedback tab (5 tabs fit; aria-label keeps the name) */
/* K-455 (user: row too big, hug the frame): status row ~22 % smaller + left edge on the status frame's left border (--soc-x 0). Knobs. */
:root { --soc-x: 0px; }
.soc-bar { gap: calc(3 * var(--u)); height: calc(16 * var(--u)); }
.soc-ic { width: calc(16 * var(--u)); height: calc(16 * var(--u)); }
.soc-ic svg { width: calc(9.5 * var(--u)); height: calc(9.5 * var(--u)); }
.soc-dl { height: calc(16 * var(--u)); font-size: max(8px, calc(8 * var(--u))); padding: 0 calc(6 * var(--u)) 0 calc(3 * var(--u)); }
.soc-dl .ic { width: calc(9 * var(--u)); height: calc(9 * var(--u)); }
.ping-hud { height: calc(16 * var(--u)); padding: 0 calc(5 * var(--u)); gap: calc(3 * var(--u)); font-size: max(8px, calc(8 * var(--u))); }
.ping-hud i { width: calc(6 * var(--u)); height: calc(6 * var(--u)); }
@media (max-width: 380px) { .soc-dl { font-size: 0; padding: 0 calc(4 * var(--u)); } }   /* K-452 icon-only install pill, re-stated after the K-455 sizes */

/* K-454 leaderboard (TradePanels.jsx LeaderboardPanel): body = head + scrolling list + pinned my row; medals = K-411 ui2/ach/medal_*.png */
.lb-panel .body { overflow: hidden; }
.lb-head { display: flex; gap: calc(8 * var(--u)); align-items: center; flex-wrap: wrap; }
.lb-head .dd { flex: 1 1 calc(180 * var(--u)); min-width: 0; }
.lb-period { flex: 0 0 auto; } .lb-period .btn { white-space: nowrap; }
.lb-list { flex: 1; min-height: 0; overflow-y: auto; }
.lb-row { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.lb-row .nm { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: calc(6 * var(--u)); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.lb-row .nm small { overflow: hidden; text-overflow: ellipsis; }
.lb-name { background: none; border: 0; padding: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.lb-name:hover { text-decoration: underline; }
.lb-medal { flex: 0 0 auto; width: calc(28 * var(--u)); height: calc(28 * var(--u)); margin: 0 calc(6 * var(--u)); background: url(/assets/ui2/ach/medal_gold.png) center / contain no-repeat; }
.lb-medal.m2 { background-image: url(/assets/ui2/ach/medal_silver.png); } .lb-medal.m3 { background-image: url(/assets/ui2/ach/medal_bronze.png); }
.lb-row > b:first-child { min-width: calc(40 * var(--u)); text-align: center; }
.lb-mine { flex: 0 0 auto; border-top: calc(2 * var(--u)) solid rgba(139, 107, 78, .45); }
.mk .card.rank-row.lb-me { background: linear-gradient(90deg, rgba(232, 184, 76, .4), rgba(232, 184, 76, .1)); border-bottom: 0; }
/* K-457 (user: portrait panel = as tall as its content, not the whole screen): phone portrait .panel height auto, TOP-anchored under the
   safe area (consistent rule: every short panel starts at the top, grows down), capped at the viewport (100dvh - 8u top - 8u bottom - safe);
   taller content scrolls inside .body (flex 1 / min-height 0, K-366 scrollbar). Side-tab rail min-height (Panels.jsx K-125c JS, K-426
   .social-panel) still applies = rail fits. Panels with their own height (npc-panel, bpass, cashshop) keep it. */
@media (max-width: 620px) and (orientation: portrait) {
  .panel { bottom: auto; height: auto; max-height: calc(100dvh - calc(16 * var(--u)) - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
}
/* K-455b (user): order social -> install -> ping (CSS order); install icon fits its pill; row clears the portrait ring (--soc-x 20u = right of
   the ring's overlap onto the bars) and the whole card + row sit 4u higher (--soc-h 16u -> 12u, row stays glued to the frame top). Knobs. */
:root { --soc-x: calc(20 * var(--u)); --soc-h: calc(12 * var(--u)); }
.soc-bar .ping-hud { order: 99; }
.soc-dl .ic { width: calc(8 * var(--u)); height: calc(8 * var(--u)); stroke-width: 2.6; flex: none; }
.soc-dl { overflow: hidden; }

/* K-458 (user: K-455 sizes too small to tap on phones) back to the K-452 sizes; K-455b order/offset kept. Touch: invisible hit area ~36u.
   --soc-h 12u -> 16u (row 16u -> 20u). Knobs. */
:root { --soc-h: calc(16 * var(--u)); }
.soc-bar { gap: calc(4 * var(--u)); height: calc(20 * var(--u)); }
.soc-ic { width: calc(20 * var(--u)); height: calc(20 * var(--u)); position: relative; }
.soc-ic svg { width: calc(12 * var(--u)); height: calc(12 * var(--u)); }
.soc-dl { height: calc(20 * var(--u)); font-size: max(9px, calc(10 * var(--u))); padding: 0 calc(7 * var(--u)) 0 calc(4 * var(--u)); position: relative; overflow: visible; }
.soc-dl .ic { width: calc(11 * var(--u)); height: calc(11 * var(--u)); }
.ping-hud { height: calc(20 * var(--u)); padding: 0 calc(6 * var(--u)); gap: calc(4 * var(--u)); font-size: max(9px, calc(10 * var(--u))); }
.ping-hud i { width: calc(7 * var(--u)); height: calc(7 * var(--u)); }
@media (pointer: coarse) { .soc-ic::after, .soc-dl::after { content: ''; position: absolute; inset: calc(-8 * var(--u)) calc(-3 * var(--u)); } }
@media (max-width: 380px) { .soc-dl { font-size: 0; padding: 0 calc(5 * var(--u)); } }   /* icon-only install pill on narrow phones (re-stated) */

/* K-459 (user: social + install smaller; install label = just "ติดตั้ง"; download icon must not overflow its pill, same size as the others).
   Bug: svg.ic.glyph (0,2,1, 22u) outranked .soc-dl .ic (0,2,0), so the download glyph drew 22u inside a 20u pill. Fix = .soc-dl svg.ic.glyph.
   Row 20u -> 18u; social glyph + download glyph both 10u (one size). Touch hit area unchanged (::after, K-458). Knobs. */
:root { --soc-h: calc(14 * var(--u)); }
.soc-bar { gap: calc(4 * var(--u)); height: calc(18 * var(--u)); }
.soc-ic { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
.soc-ic svg { width: calc(10 * var(--u)); height: calc(10 * var(--u)); }
.soc-dl { height: calc(18 * var(--u)); gap: calc(3 * var(--u)); font-size: max(9px, calc(9 * var(--u))); padding: 0 calc(7 * var(--u)) 0 calc(5 * var(--u)); }
.soc-dl svg.ic.glyph { width: calc(10 * var(--u)); height: calc(10 * var(--u)); stroke-width: 2.6; flex: none; }
.ping-hud { height: calc(18 * var(--u)); font-size: max(9px, calc(9 * var(--u))); }
@media (max-width: 380px) { .soc-dl { font-size: 0; gap: 0; padding: 0; width: calc(18 * var(--u)); } }   /* narrow phones: install = round 18u icon like the social icons */

/* fix (user 2026-10-11 "Social ติดตั้ง กดไม่ได้สักปุ่ม"): .vitals is pointer-events:none (taps fall through to the map) and the K-452 row lives
   inside it -> every soc button inherited none. Row + its buttons opt back in; ping pill stays none (display only). */
.soc-bar { pointer-events: auto; }
.soc-bar .ping-hud { pointer-events: none; }

/* K-468 (user 2026-10-11: two dividers under "ของในกระเป๋า"): bag tab-title border-bottom + .bag-capacity border-top stacked. Title rule kept,
   capacity rule dropped when it directly follows the title (storage view has no title -> its rule stays). */
.bag-panel .tab-title + .bag-capacity { border-top: 0; }

/* K-471 FPS pill (GameCanvas, vfxPrefs.fps, Settings > การแสดงผล): same pill as ping, right after it; no status dot. */
.soc-bar .fps-hud { order: 100; }

/* K-465 3D world map (ui/WorldMap3D.jsx): canvas fills the stage; DOM labels projected per frame (pointer-events none, taps reach the canvas). */
.wm3d { overflow: hidden; touch-action: none; }   /* position = .mv-stage absolute inset 0 */
.wm3d canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.wm-labels { position: absolute; inset: 0; pointer-events: none; }
.wm-l { position: absolute; left: 0; top: 0; display: flex; flex-direction: column; align-items: center; white-space: nowrap; font: 600 max(10px, calc(11 * var(--u))) Mitr, sans-serif;
  color: #fff7e2; text-shadow: 0 0 3px #2a1d12, 0 1px 2px #2a1d12, 0 0 1px #2a1d12; line-height: 1.15; }
.wm-l i { font-style: normal; font-size: .8em; opacity: .9; }
.wm-l.here b { color: #ffd34d; }
.wm3d + .mv-zoom { z-index: 2; }

/* K-486 HoverTip (ui/HoverTip.jsx): dark parchment-edged bubble, max ~1.5 lines per paragraph; skill: .ht-h title row, .ht-d flavour, .ht-n numbers,
   .ht-g learn gate (.lock rose); item: .ht-s source lines. */
.htip { position: fixed; z-index: 400; max-width: min(calc(420 * var(--u)), calc(100vw - 16px)); padding: calc(7 * var(--u)) calc(10 * var(--u)); border-radius: calc(8 * var(--u));
  background: rgba(30, 22, 16, .94); border: 1px solid #b08a5a; box-shadow: 0 4px 14px rgba(0, 0, 0, .45); color: #f6ecd6; pointer-events: none;
  font: 500 max(11px, calc(12 * var(--u))) Mitr, sans-serif; line-height: 1.35; }
.htip p { margin: calc(3 * var(--u)) 0 0; }
.htip .ht-h { display: flex; gap: calc(8 * var(--u)); align-items: baseline; justify-content: space-between; }
.htip .ht-h b { color: #ffd98a; font-size: 1.05em; } .htip .ht-h span { color: #cdb894; font-size: .85em; white-space: nowrap; }
.htip .ht-d { color: #fff3dc; } .htip .ht-n { color: #bfe3ff; font-size: .9em; } .htip .ht-g { color: #a9e6a0; font-size: .9em; } .htip .ht-g.lock { color: #ff9c86; }
.htip .ht-s { color: #f2e2c2; font-size: .92em; } .htip .ht-s::before { content: '• '; color: #ffcf6a; }

/* K-477 commission board tab (CommissionPanel.jsx) */
.cm { display: grid; gap: calc(8 * var(--u)); }
.quest-panel .cm { flex: 1; min-height: 0; overflow-y: auto; align-content: start; padding-right: calc(2 * var(--u)); }   /* user 2026-10-14: orders/commission tabs did not scroll (.quest-panel .body overflow hidden; only .qb-list scrolled) */
.cm-list { display: grid; gap: calc(6 * var(--u)); }
.cm-row { display: grid; grid-template-columns: calc(44 * var(--u)) 1fr auto; grid-template-areas: "ic nm pr" "act act act"; gap: calc(4 * var(--u)) calc(8 * var(--u)); align-items: center;
  padding: calc(6 * var(--u)) calc(8 * var(--u)); border: 0 solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; color: var(--cream-lt); }
.cm-ic { grid-area: ic; width: calc(40 * var(--u)); height: calc(40 * var(--u)); display: grid; place-items: center; }
.cm-ic img, .cm-ic svg { max-width: 100%; max-height: 100%; }
.cm-nm { grid-area: nm; display: grid; } .cm-nm small, .cm-act small, .cm-pr small { opacity: .8; font-size: calc(12 * var(--u)); }
.cm-pr { grid-area: pr; display: flex; align-items: center; gap: calc(3 * var(--u)); font-weight: 700; }
.cm-pr .ic { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
.cm-act { grid-area: act; display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: calc(6 * var(--u)); }
.cm-post { display: grid; gap: calc(6 * var(--u)); }
.cm-row .chip { color: #3b2a1a; }

/* K-490 (user 2026-10-12 "Quest ui กับ Tutorial ui container เดียวกัน Bg สีดำ แยกบนล่าง ชิดซ้ายกลาง" + "พับได้ มีปุ่ม > ตรงกลางซ้าย"): .questdock =
   [.qd-body: TutorialCoach (top) + NavTracker (bottom)] + .qd-fold strip (‹). Fixed left, vertically centred, dark glass; children lose their own
   position/parchment/box. Folded = only the › tab at the left edge middle (localStorage ageup.qdFold). Phones: K-438 scale (--tut-k), no dock offset
   (dock sits top-left, the dock is not at mid height). Old "coach hides the tracker on phones" rule overridden. Knobs. */
.questdock { position: absolute; z-index: 5; left: max(calc(12 * var(--u)), env(safe-area-inset-left)); top: 50%; translate: 0 -50%;
  display: flex; align-items: stretch; border-radius: calc(12 * var(--u)); overflow: hidden; pointer-events: auto;
  background: rgba(10, 8, 6, .74); border: 1px solid rgba(255, 211, 77, .28); box-shadow: 0 calc(4 * var(--u)) calc(14 * var(--u)) rgba(0, 0, 0, .4); }
.questdock:not(:has(.tut-coach, .nav-track)) { display: none; }
.qd-body { width: min(calc(300 * var(--u)), calc(100vw - 64px)); display: flex; flex-direction: column; }
.qd-fold { flex: none; width: calc(22 * var(--u)); border: 0; border-left: 1px solid rgba(255, 211, 77, .22); background: rgba(255, 255, 255, .06); color: #ffd34d;
  font: 700 calc(20 * var(--u)) / 1 Mitr, sans-serif; cursor: inherit; padding: 0; }
.qd-fold:hover { background: rgba(255, 211, 77, .16); }
.questdock.folded { left: max(0px, env(safe-area-inset-left)); border-radius: 0 calc(10 * var(--u)) calc(10 * var(--u)) 0; border-left: 0; }
.questdock.folded .qd-body { display: none; }
.questdock.folded .qd-fold { width: calc(26 * var(--u)); height: calc(56 * var(--u)); border-left: 0; font-size: calc(24 * var(--u)); }
@media (pointer: coarse) { .qd-fold { width: 30px; } .questdock.folded .qd-fold { width: 34px; height: 64px; } }
.questdock .tut-coach, .questdock .nav-track { position: static; inset: auto; translate: none; scale: none; margin: 0; width: auto; filter: none; animation: none;
  border: 0; border-image: none; border-radius: 0; background: none; box-shadow: none; color: #fff6df; padding: calc(9 * var(--u)) calc(12 * var(--u)); pointer-events: auto; }
.questdock .tut-coach + .nav-track { border-top: 1px solid rgba(255, 211, 77, .3); }
.questdock .tut-coach header b { color: #ffd34d; } .questdock .tut-coach header small { color: #e8dcc0; opacity: .85; }
.questdock .tut-coach .tut-hint { color: #f3e8d0; }
.questdock .tut-fold { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .25); color: #fff6df; }
.game:has(.tut-coach) .questdock .nav-track { display: block; }
@media (orientation: portrait) and (max-width: 620px), (orientation: landscape) and (max-height: 520px) {
  .questdock { scale: var(--tut-k, 1); transform-origin: 0 50%; } .qd-body { width: min(58vw, calc(300 * var(--u))); }
}
.wm-l em { font-style: normal; font-size: .82em; color: #ff8a6a; font-weight: 700; }   /* live world boss line (WorldMap3D) */
/* K-494 channel badge (minimap) + picker rows */
.zonetag.chtag { background: #5a4630; cursor: pointer; font: inherit; font-weight: 700; font-size: calc(13 * var(--u)); }
.zonetag.chtag.one { opacity: .8; }
.ch-list { display: flex; flex-direction: column; gap: calc(8 * var(--u)); min-width: calc(360 * var(--u)); }   /* user 2026-10-12: one horizontal row per channel: name | wide density bar | n/cap | action */
.ch-row { display: grid; grid-template-columns: calc(84 * var(--u)) 1fr calc(84 * var(--u)); align-items: center; gap: calc(10 * var(--u));
  padding: calc(6 * var(--u)) calc(8 * var(--u)); border: var(--line-w) solid var(--line); border-radius: calc(8 * var(--u)); background: #fff3; }
.ch-row.here { background: #f3d58a66; border-color: #f2c230; box-shadow: 0 0 0 calc(2 * var(--u)) #ffd84a, 0 0 calc(10 * var(--u)) #ffd84a99; }   /* current channel = yellow frame */
.ch-row em { font-style: normal; text-align: right; font-variant-numeric: tabular-nums; }
.ch-bar { height: calc(12 * var(--u)); border-radius: 99px; background: #0002; overflow: hidden; }
.ch-bar i { display: block; height: 100%; background: #5fae5a; }
.ch-bar i.busy { background: #e0b43a; } .ch-bar i.full { background: #d0574a; }
.ch-here { text-align: center; font-weight: 700; color: #6b4a1e; }
.note.warn { color: #a3402f; }
.minimap .mm-label .chtag { top: calc(10 * var(--u)); left: calc(-4 * var(--u)); transform: none; height: calc(24 * var(--u)); padding: 0 calc(8 * var(--u)); font-size: calc(12 * var(--u)); }   /* K-494 top-left corner outside the ring */
/* K-494 pre-game Channel chips (App.jsx Lobby) */
.lobby-ch { display: flex; flex-direction: column; align-items: stretch; gap: calc(6 * var(--u)); margin: calc(6 * var(--u)) 0 calc(12 * var(--u)); min-width: calc(280 * var(--u)); }   /* one row per channel */
.lobby-ch .muted { width: 100%; text-align: center; }
.ch-chip { display: grid; grid-template-columns: calc(44 * var(--u)) 1fr; align-items: center; gap: calc(10 * var(--u)); width: 100%; line-height: 1.15; text-align: left; }
.ch-chip .ch-bar { width: 100%; height: calc(10 * var(--u)); }
.ch-chip em { text-align: right; }
.ch-chip em { font-style: normal; font-size: .85em; opacity: .8; font-variant-numeric: tabular-nums; }
.ch-chip .ch-all { font-size: .75em; opacity: .75; white-space: nowrap; }   /* whole-channel online (all maps) */
.ch-chip.on { outline: calc(3 * var(--u)) solid #ffd84a; outline-offset: calc(2 * var(--u)); box-shadow: 0 0 calc(10 * var(--u)) #ffd84aaa; }   /* user 2026-10-12: selected = yellow frame */
.ch-chip.full { opacity: .5; }

/* K-494 (user 2026-10-12 "กรอบเหล็ก, เลือก = กรอบเหล็กเหลืองเหมือนเลือกไอเทม"): channel rows (lobby .ch-chip + in-game .ch-row) = steel 9-slice slot frame
   (ui3/slot.png, dark fill, cream text); selected / current = slot_gold.png (same as .slot.sel). Overrides the btn + yellow outline looks above. */
.lobby-ch .ch-chip, .ch-list .ch-row { border: 0 solid transparent; border-radius: 0; box-shadow: none; outline: 0; background: none; color: var(--cream-lt);
  border-image: url(/assets/ui3/slot.png) var(--slot-slice) fill / var(--slot-edge) / 0 stretch; padding: calc(8 * var(--u)) calc(14 * var(--u)); }
.lobby-ch .ch-chip.on, .ch-list .ch-row.here { border-image-source: url(/assets/ui3/slot_gold.png); outline: 0; box-shadow: none; background: none; }
.ch-list .ch-row .ch-here { color: #ffd84a; }
.lobby-ch .ch-chip .ch-bar, .ch-list .ch-row .ch-bar { background: #0006; }
.lobby-div { display: block; width: min(calc(240 * var(--u)), 80%); height: calc(30 * var(--u)); margin: calc(2 * var(--u)) auto; background: url(/assets/ui3/divider.png) center / contain no-repeat; }   /* K-494 lobby: name | channels | buttons */

/* potion -> hotbar slot picker (GameCanvas slotPick modal): two rows of key cells, current occupant icon, selected = gold */
.slot-pick { display: flex; flex-wrap: wrap; gap: calc(6 * var(--u)); justify-content: center; margin: calc(6 * var(--u)) 0; }
.slot-pick-cell { position: relative; width: calc(48 * var(--u)); height: calc(48 * var(--u)); min-height: 0; padding: calc(4 * var(--u)); display: grid; place-items: center;
  border: var(--line-w) solid var(--line); border-radius: var(--radius); background: var(--cream-dk); }
.slot-pick-cell.on { outline: calc(3 * var(--u)) solid var(--gold); background: #fff3c4; }
.slot-pick-cell kbd { position: absolute; top: calc(1 * var(--u)); left: calc(3 * var(--u)); font-size: calc(10 * var(--u)); }
.slot-pick-cell :is(img, svg, .sk-ic, .item-ic) { width: 80%; height: 80%; }

/* lobby channel status (App.jsx): ราบรื่น / หนาแน่น / เต็ม */
/* user 2026-10-13: no pill bg, status = text colour only */
:is(.ch-chip, .ch-row) .ch-st { justify-self: end; font-style: normal; font-weight: 700; opacity: 1; font-size: .85em; }
.ch-st.ok { color: #6fd46f; } .ch-st.busy { color: #f2c23a; } .ch-st.full { color: #ff6a52; }

/* K-543 welcome popup (WelcomePopup.jsx): poster fits the screen, buttons under it */
.welcome-pop .popup { max-width: min(92vw, calc(560 * var(--u))); padding: calc(10 * var(--u)); display: flex; flex-direction: column; align-items: center; gap: calc(8 * var(--u)); position: relative; }
.welcome-pop .welcome-img { display: block; max-width: 100%; max-height: calc(100dvh - 110px); object-fit: contain; border-radius: calc(8 * var(--u)); }
.welcome-pop .ui-close { position: absolute; top: calc(-14 * var(--u)); right: calc(-14 * var(--u)); z-index: 2; }
.welcome-pop .actions { display: flex; flex-direction: row; flex-wrap: nowrap; gap: calc(10 * var(--u)); justify-content: center; }
.welcome-pop .actions .btn { width: auto; min-width: 0; margin: 0; white-space: nowrap; padding-inline: calc(14 * var(--u)); }

/* user 2026-10-12 party HUD: own box under the name card (.vitals child, absolute); touch = round icon + red count, list on tap */
.vitals .partyhud { position: absolute; left: 0; top: calc(100% + 6 * var(--u)); z-index: 2; pointer-events: auto; }
.partyhud .ph-ic { display: none; }
.partyhud .partybar { margin: 0; min-width: calc(190 * var(--u)); padding: calc(6 * var(--u)) calc(10 * var(--u)); }
.partyhud .ph-title { display: flex; align-items: center; gap: calc(4 * var(--u)); font-size: calc(12 * var(--u)); font-weight: 700; color: var(--ink-dim); }
.partyhud .ph-title svg { width: calc(14 * var(--u)); height: calc(14 * var(--u)); }
@media (pointer: coarse) {
  .partyhud .ph-ic { display: grid; place-items: center; position: relative; width: calc(40 * var(--u)); height: calc(40 * var(--u)); min-height: 0; padding: 0; border-radius: 50%;
    background: var(--cream); border: var(--line-w) solid var(--line); box-shadow: var(--lift); }
  .partyhud .ph-ic svg { width: 60%; height: 60%; }
  .partyhud .ph-ic b { position: absolute; top: calc(-4 * var(--u)); right: calc(-4 * var(--u)); min-width: calc(18 * var(--u)); height: calc(18 * var(--u)); padding: 0 calc(4 * var(--u));
    border-radius: 999px; background: #d63a2f; color: #fff; font-size: calc(11 * var(--u)); line-height: calc(18 * var(--u)); text-align: center; border: 2px solid #fff; }
  .vitals .partyhud { top: calc(4 * var(--u)); left: calc(100% + 8 * var(--u)); }   /* touch: right of the name card (below = under the dock column) */
  .partyhud .partybar { display: none; position: absolute; top: calc(44 * var(--u)); left: 0; }
  .partyhud.open .partybar { display: flex; }
}
/* user 2026-10-12: welcome popup covers the whole game (dim backdrop over every HUD / panel / tutorial) */
.zone-confirm.welcome-pop { position: fixed; inset: 0; z-index: 400; display: grid; place-items: center; background: rgba(12, 8, 4, .62); }

/* user 2026-10-12 caravan buy box: refusal line left, buy button bottom-right */
.caravan .cv-foot { display: flex; align-items: center; justify-content: flex-end; gap: calc(10 * var(--u)); margin-top: calc(8 * var(--u)); }
.caravan .cv-foot .note { margin: 0 auto 0 0; }
/* user 2026-10-12 trade = bank style: left 4x4 grids (them / mine) + Acorn + actions, right = bag (TradePanels.jsx) */
.trade-left .trade-grid { grid-template-columns: repeat(4, var(--slot)); width: max-content; margin: 0 auto calc(4 * var(--u)); }
.trade-left .trade-grid .slot-btn { padding: 0; border: 0; background: none; min-height: 0; }
.trade-left h3 { margin: calc(4 * var(--u)) 0; }
.trade-left .trade-soft { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); margin-left: calc(6 * var(--u)); font-weight: 700; }

/* welcome v2 (user 2026-10-12 bigger): frameless poster, height-limited, close X on its corner, buttons under it */
.welcome-pop .welcome-box { display: flex; flex-direction: column; align-items: center; gap: calc(10 * var(--u)); max-width: 96vw; padding-bottom: max(calc(24 * var(--u)), env(safe-area-inset-bottom)); }
.welcome-pop .welcome-imgwrap { position: relative; }
.welcome-pop .welcome-box .welcome-img { display: block; max-width: 96vw; max-height: calc(100dvh - 140px);   /* user 2026-10-14 buttons hugged the bottom edge: was -90px */ height: auto; border-radius: calc(12 * var(--u)); box-shadow: 0 8px 40px rgba(0, 0, 0, .6); }
.welcome-pop .welcome-imgwrap .ui-close { position: absolute; top: calc(-12 * var(--u)); right: calc(-12 * var(--u)); }
/* user 2026-10-12: channel chip inner padding (lobby + in-game rows) */
.lobby-ch .ch-chip { padding: calc(8 * var(--u)) calc(14 * var(--u)); min-height: calc(42 * var(--u)); }
.ch-row { padding: calc(6 * var(--u)) calc(12 * var(--u)); }
/* user 2026-10-12: combat chip (BuffStrip fight) bigger + red blink; tap/click = focus tooltip (.bf:focus::after) */
.bf.fight, .bf.fight .bf-ring { width: calc(32 * var(--u)); }
.bf.fight .bf-ring { height: calc(32 * var(--u)); background: #e2504a; animation: fight-blink .8s ease-in-out infinite; cursor: pointer; }
.bf.fight .bf-ring > * { background: #6a1a1a; }
.bf.fight .bf-ring .ic { color: #ffd0c8; }
@keyframes fight-blink { 50% { background: #ff2a1a; box-shadow: 0 0 calc(10 * var(--u)) calc(3 * var(--u)) rgba(255, 40, 20, .85); } }
@media (prefers-reduced-motion: reduce) { .bf.fight .bf-ring { animation: none; } }
.nav-track .nt-x svg { width: calc(16 * var(--u)); height: calc(16 * var(--u)); }   /* fold chevron */
/* user 2026-10-12: bank ฝาก/ถอน modal: gap above the ok/cancel row */
.confirm-modal .st-modal { margin-bottom: calc(18 * var(--u)); }
.cw-card.picked:disabled { opacity: 1; }   /* picked + used up = still bright (gold frame) */
.cw-actions .btn { white-space: nowrap; }
/* user 2026-10-13: craft recipe with a town bonus above the base (recipes.bonus) -> green ^^ top-left */
.slot .rnd { position: absolute; left: calc(2 * var(--u)); top: calc(2 * var(--u)); z-index: 2; width: calc(14 * var(--u)); height: calc(16 * var(--u)); pointer-events: none; }
.slot .rnd svg { width: 100%; height: 100%; display: block; overflow: visible; }
.slot .rnd path { fill: none; stroke: #5fe05a; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; paint-order: stroke; filter: drop-shadow(0 0 1px #0b2a0a) drop-shadow(0 1px 0 #0b2a0a); }
/* user 2026-10-13: craft "ใช้ focus" radio got squeezed/cropped by the long label (flex shrink) */
.toggle i { flex: none; }
.toggle { text-align: left; }

/* ---- K-586 Albion market (MarketPanel.jsx): item groups, item view (chart + order book), my listings/orders ---- */
.mk2 .mk-groups, .mk2 .mk-mine, .mk2 .mk-book ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: calc(6 * var(--u)); }
.mk2 .mk-g { width: 100%; display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: calc(10 * var(--u)); text-align: left;
  padding: calc(6 * var(--u)) calc(10 * var(--u)); border-radius: calc(10 * var(--u)); background: var(--cream-lt); border: 1px solid rgba(0,0,0,.12); cursor: pointer; font: inherit; color: var(--ink); }
.mk2 .mk-g:hover { filter: brightness(1.05); }
.mk2 .mk-g small, .mk2 .mk-mine small { color: var(--ink-dim); }
.mk2 .mk-mine li { display: grid; grid-template-columns: auto 1fr auto; grid-template-areas: "s n b" "s p b" "s m b"; align-items: center; column-gap: calc(10 * var(--u));
  padding: calc(6 * var(--u)) calc(10 * var(--u)); border-radius: calc(10 * var(--u)); background: var(--cream-lt); }
.mk2 .mk-mine li > :first-child { grid-area: s; } .mk2 .mk-mine li > b { grid-area: n; } .mk2 .mk-mine li > .tnum { grid-area: p; }
.mk2 .mk-mine li > small { grid-area: m; } .mk2 .mk-mine li > button { grid-area: b; }
.mk2 .mk-vh { display: flex; align-items: center; gap: calc(10 * var(--u)); flex-wrap: wrap; margin-bottom: calc(8 * var(--u)); }
.mk2 .mk-vh b { flex: 1; font-size: calc(17 * var(--u)); }
.mk-chart { margin: 0 0 calc(10 * var(--u)); padding: calc(8 * var(--u)); border-radius: calc(10 * var(--u)); background: #22302a; color: #e8e1cf; }
.mk-chart svg { width: 100%; height: auto; display: block; }
.mk-chart .ln { stroke: #f2c14e; stroke-width: 2; stroke-linejoin: round; }
.mk-chart .pt { fill: #f2c14e; } .mk-chart .wh { stroke: rgba(242,193,78,.45); stroke-width: 1.5; }
.mk-chart .vol { fill: rgba(120,190,150,.45); } .mk-chart .ax { fill: #b9b19c; font-size: 8px; }
.mk-chart figcaption { display: flex; justify-content: space-between; font-size: calc(12 * var(--u)); color: #b9b19c; } .mk-chart figcaption b { color: #f2c14e; }
.mk-chart.empty { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: calc(90 * var(--u)); }
.mk2 .mk-book { display: grid; grid-template-columns: 1fr 1fr; gap: calc(10 * var(--u)); }
.mk2 .mk-book h3 { margin: 0 0 calc(4 * var(--u)); font-size: calc(14 * var(--u)); }
.mk2 .mk-bk { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: calc(6 * var(--u)); padding: calc(4 * var(--u)) calc(8 * var(--u));
  border-radius: calc(8 * var(--u)); background: var(--cream-lt); }
.mk2 .mk-bk small { grid-column: 1 / 2; color: var(--ink-dim); } .mk2 .mk-bk.own { outline: 2px solid rgba(201,138,28,.5); }
.mk2 .mk-bk .pp { font-weight: 700; display: inline-flex; align-items: center; gap: 2px; }
.mk-hint { color: #2f7a4f; font-weight: 600; }
@media (max-width: 640px) { .mk2 .mk-book { grid-template-columns: 1fr; } }
.mk2 .mk-vh .slot, .mk2 .mk-g .slot, .mk2 .mk-mine .slot { width: calc(44 * var(--u)); height: calc(44 * var(--u)); flex: none; }   /* K-586 small item cells */
/* K-586 item view layout (user 2026-10-13): one gap everywhere, actions bottom-right with top margin, range buttons no-wrap */
.mk2 { --mk-gap: calc(12 * var(--u)); }
.mk2 .mk-view { display: flex; flex-direction: column; gap: var(--mk-gap); }
.mk2 .mk-view > * { margin: 0; }
.mk2 .mk-vh { gap: var(--mk-gap); margin: 0; }
.mk2 .mk-vh .set-tabs { display: flex; gap: calc(6 * var(--u)); flex: none; }
.mk2 .mk-vh .set-tabs .btn { white-space: nowrap; width: auto; min-width: 0; flex: none; padding-inline: calc(12 * var(--u)); }
.mk2 .mk-book { gap: var(--mk-gap); }
.mk2 .mk-book section { display: flex; flex-direction: column; gap: calc(6 * var(--u)); }
.mk2 .mk-book h3 { margin: 0; }
.mk2 .mk-bk .a .btn { white-space: nowrap; }
.mk2 .mk-view > .actions { display: flex; justify-content: flex-end; gap: var(--mk-gap); margin-top: calc(8 * var(--u)); }
/* K-590 chart hover / tap tooltip */
.mk-chart { position: relative; }
.mk-chart svg { touch-action: pan-y; cursor: crosshair; outline-offset: 2px; }
.mk-chart .hit { fill: transparent; }
.mk-chart .guide { stroke: rgba(232,225,207,.55); stroke-width: 1; stroke-dasharray: 3 3; pointer-events: none; }
.mk-chart .vol.on { fill: rgba(120,190,150,.9); }
.mk-tip { position: absolute; top: calc(8 * var(--u)); transform: translateX(10px); pointer-events: none; z-index: 2; display: flex; flex-direction: column; gap: 2px;
  padding: calc(6 * var(--u)) calc(10 * var(--u)); border-radius: calc(8 * var(--u)); background: rgba(14,20,17,.94); border: 1px solid rgba(242,193,78,.5);
  color: #e8e1cf; white-space: nowrap; font-size: calc(12 * var(--u)); box-shadow: 0 2px 8px rgba(0,0,0,.35); }
.mk-tip.left { transform: translateX(calc(-100% - 10px)); }
.mk-tip b { color: #f2c14e; font-size: calc(15 * var(--u)); display: inline-flex; align-items: center; gap: 3px; }
.mk-tip small { color: #b9b19c; }
/* K-586 (user 2026-10-13): steel 9-slice frame on EACH ขาย / รับซื้อ row (rim only, cream inside; same rim art as .panel .body) */
.mk2 .mk-bk { border: var(--slot-edge) solid transparent; border-image: url(/assets/ui3/slot.png) var(--slot-slice) / var(--slot-edge) / 0 stretch;
  border-radius: 0; background-clip: padding-box; padding: calc(4 * var(--u)) calc(6 * var(--u)); }
/* K-586 book = tabs + one full-width list (user 2026-10-13): row "N/ชิ้น (+enh) ··· มี|รับ ×qty [btn]" */
.mk2 .mk-book { display: flex; flex-direction: column; gap: var(--mk-gap); }
.mk2 .mk-book .set-tabs { display: flex; gap: calc(6 * var(--u)); }
.mk2 .mk-book .set-tabs .btn { white-space: nowrap; flex: none; width: auto; min-width: 0; padding-inline: calc(12 * var(--u)); }
.mk2 .mk-bk { grid-template-columns: 1fr auto auto; gap: var(--mk-gap); }
.mk2 .mk-bk .pp small { font-weight: 400; color: var(--ink-dim); margin-left: 2px; }
.mk2 .mk-bk .pp em { font-style: normal; color: #b0701c; margin-left: calc(6 * var(--u)); }
.mk2 .mk-bk .q { color: var(--ink-dim); }
/* K-591 Frame foot: action row OUTSIDE the scrolling steel .body, bottom-right, never scrolls away (Panels.jsx Frame foot prop) */
.panel-acorn { position: absolute; right: calc(-6 * var(--u)); bottom: calc(-46 * var(--u)); z-index: 6; pointer-events: none; }   /* user 2026-10-16: Acorn over the bottom scroll roller (Frame/PairPanels acorn) */
.pe-pair { position: relative; }
.pe-pair > .panel-acorn { bottom: calc(14 * var(--u)); right: calc(-10 * var(--u)); z-index: 30; }
.panel .panel-foot { flex: none; display: flex; justify-content: flex-end; align-items: center; gap: calc(12 * var(--u)); padding: calc(10 * var(--u)) calc(12 * var(--u)) calc(4 * var(--u)); }
.mk2 .mk-view > .actions { display: none; }

/* ============ K-592 modal aspect fit (user 2026-10-13: mobile landscape sell modal fell off screen; "aspect ratio, not a 2nd layout").
   Every modal child of .item-modal-backdrop re-scales its own --u so its design height (--fit-h, in u) fits the viewport height:
   --u = min(page --u, (100dvh - margin) / --fit-h). Content keeps its proportions (same layout, smaller). Safety net: max-height + scroll
   (the later `.popup { overflow: visible }` had cancelled .confirm-modal's scroll). --fit-h = calibration knobs per modal kind. ============ */
:root { --u-page: var(--u); }
.item-modal-backdrop > * { --fit-h: 720; --u: max(.42px, min(var(--u-page), calc((100dvh - 24px) / var(--fit-h))));
  max-height: calc(100dvh - 16px); overflow-y: auto; overscroll-behavior: contain; }
.item-modal-backdrop > .popup:has(.qtypad) { --fit-h: 880; }        /* sell / buy-order / stall list: qty row + price keypad */
.item-modal-backdrop > .popup:has(.st-qty):not(:has(.qtypad)) { --fit-h: 600; }   /* buy now / quick sell: qty row only */
.item-modal-backdrop > .craft-detail { --fit-h: 640; }
.item-modal-backdrop > .pe-pair, .item-modal-backdrop > .pe-panel { --fit-h: 760; }
/* K-592 market money summary (MarketPanel SumRows): label left, value right, total row bold + rule above */
.mk-sum { margin: 0; display: flex; flex-direction: column; gap: calc(4 * var(--u)); font-size: calc(14 * var(--u)); }
.mk-sum > div { display: flex; justify-content: space-between; align-items: baseline; gap: calc(12 * var(--u)); }
.mk-sum dt { color: var(--ink-dim); } .mk-sum dd { margin: 0; white-space: nowrap; font-weight: 600; color: var(--ink); display: inline-flex; align-items: center; gap: 3px; }
.mk-sum > .tot { border-top: 1px dashed rgba(0,0,0,.25); padding-top: calc(6 * var(--u)); margin-top: calc(2 * var(--u)); }
.mk-sum > .tot dt { color: var(--ink); font-weight: 700; } .mk-sum > .tot dd { font-size: calc(17 * var(--u)); font-weight: 800; }
.mk-bal { text-align: right; margin: 0; }
/* K-592 short landscape (phones on their side): keypad modals go 2-column (left: item / qty / summary, right: price field + keypad) so the
   aspect fit above needs far less shrink (--fit-h 600 instead of ~860). Same classes in StallPanel + MarketPanel (.st-modal/.st-field/.qtypad). */
@media (orientation: landscape) and (max-height: 520px) {
  .item-modal-backdrop > .popup:has(.qtypad) { --fit-h: 600; width: min(calc(640 * var(--u)), calc(100vw - 24px)); }
  .popup .st-modal:has(.qtypad) { display: grid; grid-template-columns: 1fr 1fr; grid-auto-flow: row dense; column-gap: calc(16 * var(--u)); align-content: start; }
  .popup .st-modal:has(.qtypad) > * { grid-column: 1; }
  .popup .st-modal:has(.qtypad) > .st-field { grid-column: 2; grid-row: 1; }
  .popup .st-modal:has(.qtypad) > .qtypad { grid-column: 2; grid-row: 2 / span 8; align-self: start; }
}
@media (orientation: landscape) and (max-height: 520px) {   /* K-592: ok / cancel side by side on short screens (stacked = 2 extra rows) */
  .item-modal-backdrop > .popup > .actions { flex-direction: row; flex-wrap: nowrap; justify-content: center; gap: calc(12 * var(--u)); }
  .item-modal-backdrop > .popup:has(.qtypad) { --fit-h: 560; }
}
@media (orientation: landscape) and (max-height: 520px) {   /* K-592 balance columns: quick-sell link under the keypad; measured fit */
  .popup .st-modal:has(.qtypad) > .btn.ghost { grid-column: 2; grid-row: 10; }
  .item-modal-backdrop > .popup:has(.qtypad) { --fit-h: 640; }
}
@media (orientation: landscape) and (max-height: 520px) {   /* K-592 tighter grid: keypad spans rows 2-4 (beside hint/qty/summary), quick-sell row 5 */
  .popup .st-modal:has(.qtypad) > .qtypad { grid-row: 2 / span 3; }
  .popup .st-modal:has(.qtypad) > .btn.ghost { grid-row: 5; }
  .item-modal-backdrop > .popup:has(.qtypad) { --fit-h: 600; }
}
@media (orientation: landscape) and (max-height: 520px) {   /* K-592 final grid: keypad beside hint+qty (rows 2-3), quick-sell beside the summary (row 4) */
  .popup .st-modal:has(.qtypad) > .qtypad { grid-row: 2 / span 2; }
  .popup .st-modal:has(.qtypad) > .btn.ghost { grid-row: 4; align-self: end; }
  .item-modal-backdrop > .popup:has(.qtypad) { --fit-h: 660; }
}
/* K-594 stall: listed item ghost in its old bag cell (gold rim, dim art), lock note, title buttons */
.slot.ghost { opacity: .75; cursor: default; }
.st-lock { margin: 0 0 calc(6 * var(--u)); color: #b0701c; }
.pe-panel .ui-title h2 .btn.sm { margin-left: calc(8 * var(--u)); vertical-align: middle; }
/* K-594 one side hidden (stall: bag or shop closed alone): keep the remaining panel at half-pair width, centred */
.pp-wrap .pe-pair > .pe-panel:only-child { flex: 0 1 calc(494 * var(--u)); max-width: 100%; }
/* K-596 hidden PairPanels side: invisible placeholder keeps the visible panel in place (no re-centring) */
.pe-panel.pe-gone { visibility: hidden; pointer-events: none; }
.pp-wrap .pe-pair > .pe-panel:only-child { flex: initial; }
/* K-597 stall PairPanels: no dark scrim (world stays visible); still catches outside clicks */
.item-modal-backdrop.no-scrim { background: none; }
/* K-597 (user: "ทำให้หมุนจอได้"): no-scrim backdrop lets pointer / wheel through to the game canvas (orbit camera drag, zoom); panels stay interactive */
.item-modal-backdrop.no-scrim { pointer-events: none; }
.item-modal-backdrop.no-scrim .pe-panel:not(.pe-gone) { pointer-events: auto; }

/* K-605 login language picker: fixed screen top-right (out of the sheet flow: logo/sheet size unchanged) */
.login-lang { position: fixed; top: calc(12 * var(--u)); right: calc(12 * var(--u)); z-index: 5; }
/* K-605 i18n: longer labels (en) -> tabs size to content (share leftover), never overlap; last resort ellipsis */
.settings-panel .set-tabs .btn { flex: 1 1 0; padding: 0; border-width: 0 calc(9 * var(--u)); font-size: calc(13 * var(--u)); white-space: nowrap; overflow: hidden; }
.settings-panel .set-tabs .btn.ic-tab { flex: 1.55 1 0; padding: 0; }
/* user 2026-10-13 CraftPanel: my mastery per craft line of the station (MasteryRow), capped height */
.st-mastery { flex: none; max-height: calc(118 * var(--u)); }
/* K-624 toast icon (sword / boss head) + item feed: mid-left, a bit below centre (S.INVENTORY diff, GameCanvas FEED_MS) */
.toast.ico { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.toast.ico > img, .toast.ico > svg, .toast.ico > span:first-child, .toast.ico > i:first-child { width: calc(26 * var(--u)); height: calc(26 * var(--u)); object-fit: contain; flex: none; }
.ifeed { position: absolute; z-index: 7; left: calc(12 * var(--u) + env(safe-area-inset-left)); bottom: calc(110 * var(--u) + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: calc(3 * var(--u)); pointer-events: none; }
.ifeed > div { display: flex; align-items: center; gap: calc(6 * var(--u)); padding: calc(2 * var(--u)) calc(10 * var(--u)) calc(2 * var(--u)) calc(4 * var(--u)); font-size: calc(13 * var(--u));
  color: #fff; text-shadow: 0 1px 2px #000a; background: linear-gradient(90deg, #0008, #0000); border-radius: calc(6 * var(--u)); animation: ifeed-in .18s ease-out; max-width: calc(260 * var(--u)); }
.ifeed > div > :first-child { width: calc(24 * var(--u)); height: calc(24 * var(--u)); flex: none; }
.ifeed > div > b { color: #9be08a; }
.ifeed > div.dn > b { color: #ff9b8a; }
.ifeed > div > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@keyframes ifeed-in { from { opacity: 0; transform: translateX(calc(-12 * var(--u))); } }
.fish-pop .fp-autosw { flex: 1; text-align: left; }   /* user 2026-10-14 auto fishing = state checkbox (was ambiguous เปิด/ปิด button) */
/* user 2026-10-14 item modal: compare with the worn piece (Panels GearCompare) - icon + deltas only */
.gear-cmp { display: flex; align-items: center; gap: calc(8 * var(--u)); padding: calc(4 * var(--u)) calc(8 * var(--u)); border: var(--line-w) dashed var(--line); border-radius: var(--radius-sm); margin: calc(4 * var(--u)) 0; }
.gear-cmp .slot.sm { width: calc(36 * var(--u)); height: calc(36 * var(--u)); flex: none; }
.gear-cmp ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: calc(2 * var(--u)) calc(10 * var(--u)); font-weight: 700; font-size: calc(13 * var(--u)); }
.gear-cmp li.up { color: var(--sage-dk); } .gear-cmp li.down { color: var(--coral-dk); }
/* user 2026-10-14 trade: footer actions OUTSIDE the panels (PairPanels footer), pair shrinks by the footer so nothing scrolls */
.pp-wrap:has(.pp-foot) { grid-template-rows: auto auto; align-content: center; row-gap: calc(8 * var(--u)); }
.pp-wrap:has(.pp-foot) .pe-pair { height: min(calc(100dvh - calc(100 * var(--u))), calc(620 * var(--u))); }
.pp-foot { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(8 * var(--u)); margin: 0; }
.pp-foot .btn { width: auto; min-width: calc(96 * var(--u)); margin: 0; }
.trade-left { justify-content: flex-start; }
/* trade small screens (phone portrait/landscape): both offer grids side by side + smaller cells -> left pane fits without scrolling */
@media (max-width: 620px), (max-height: 700px) {
  .trade-left .tr-sides { display: flex; gap: calc(10 * var(--u)); justify-content: center; }
  .trade-left .tr-side { min-width: 0; }
  .trade-left { --slot: calc(34 * var(--u)); gap: calc(4 * var(--u)); padding: calc(6 * var(--u)) calc(8 * var(--u)); }
  .trade-left .trade-grid { gap: calc(3 * var(--u)); }
  .trade-left h3 { font-size: calc(13 * var(--u)); margin: 0; }
  .trade-left .trade-soft { margin: 0; }
}
@media (max-width: 620px) { .pp-wrap .pe-left:has(.trade-left) { flex-grow: 1.45; } }   /* trade: offer pane taller than the bag pane (bag scrolls, offers never) */
@media (max-width: 620px) { .trade-left { --slot: calc(31 * var(--u)); } .trade-left .tr-sides { gap: calc(6 * var(--u)); } }
.bag .slot { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }   /* phone press-and-hold = item tooltip (HoverTip hold), not the OS callout */
/* ============ K-645 stone buttons (user 2026-10-15: Codex art, no steel rim) = /assets/ui5/stone_{pill,pill_p,round,badge}_{grey,green,red}.webp
   (design/ui-stone-buttons/sheet.png -> cut/). Replaces every cream/white button face: keypad keys, sleep/auto HUD, plain chips, tooltip badges.
   Pill = 3-slice border-image (slice 0 70 = round caps, centre stretches); cap width = height x .5 (art 379x142). ============ */
:root { --stp: url(/assets/ui5/stone_pill_grey.webp); --stp-g: url(/assets/ui5/stone_pill_green.webp); --stp-r: url(/assets/ui5/stone_pill_red.webp);
  --stpp: url(/assets/ui5/stone_pill_p_grey.webp); --stpp-g: url(/assets/ui5/stone_pill_p_green.webp); --stpp-r: url(/assets/ui5/stone_pill_p_red.webp); }
.qtypad .btn.key { --sp: var(--stp); --spp: var(--stpp); background: none; box-shadow: none; border-radius: 0; border: 0 solid transparent; border-width: 0 calc(18 * var(--u));
  border-image: var(--sp) 0 70 fill / 0 calc(18 * var(--u)) / 0 stretch; color: var(--cream-lt); text-shadow: 0 1px 0 #000, 0 0 calc(3 * var(--u)) rgba(0, 0, 0, .6); padding: 0; }
.qtypad .btn.key.max { --sp: var(--stp-g); --spp: var(--stpp-g); }
.qtypad .btn.key.clear { --sp: var(--stp-r); --spp: var(--stpp-r); }
.qtypad .btn.key:active:not(:disabled) { border-image-source: var(--spp); box-shadow: none; transform: translateY(calc(1 * var(--u))); }
.qtypad .btn.key:disabled { filter: grayscale(.8) brightness(.85); color: #cfc8bb; }
/* HUD sleep + auto (next to chat): round stone */
.sleep-btn { width: calc(56 * var(--u)); height: calc(56 * var(--u)); border: 0; border-radius: 50%; box-shadow: none; background: url(/assets/ui5/stone_round_grey.webp) center / 100% 100% no-repeat; }
.sleep-btn.on { background-image: url(/assets/ui5/stone_round_green.webp); }
.sleep-btn:active { transform: translateY(calc(2 * var(--u))); box-shadow: none; }
.sleep-btn img { width: calc(40 * var(--u)); height: calc(22 * var(--u)); }
/* chips: plain = grey stone, mint = green, rose/warn = red (other tints keep their face) */
.chip:not(.sky):not(.brass):not(.ev):not(.h-weak):not(.h-hungry):not(.h-dying), .chip.mint, .chip.rose, .chip.warn {
  background: none; border: 0 solid transparent; border-width: 0 calc(12 * var(--u)); border-radius: 0; padding: calc(3 * var(--u)) calc(2 * var(--u));
  border-image: var(--stp) 0 70 fill / 0 calc(12 * var(--u)) / 0 stretch; color: var(--cream-lt); text-shadow: 0 1px 0 #000; }
.chip.mint { border-image-source: var(--stp-g); }
.chip.rose, .chip.warn { border-image-source: var(--stp-r); }
/* tooltip header badges (itemTip .ht-badges): kind = stone pill, tier = round stone */
.ht-badges { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); flex: none; }
.ht-badges .sb { font-style: normal; font-size: calc(11 * var(--u)); font-weight: 700; color: var(--cream-lt); text-shadow: 0 1px 0 #000; line-height: 1;
  border: 0 solid transparent; border-width: 0 calc(10 * var(--u)); border-image: var(--stp) 0 70 fill / 0 calc(10 * var(--u)) / 0 stretch; padding: calc(5 * var(--u)) 0; }
.ht-badges .sb.round { border: 0; border-image: none; width: calc(26 * var(--u)); height: calc(26 * var(--u)); padding: 0; display: grid; place-items: center;
  background: url(/assets/ui5/stone_badge_green.webp) center / 100% 100% no-repeat; }
/* K-646 item modal: worn | this piece compare grid (Panels GearCompare) */
.gear-cmp2 { display: grid; gap: calc(3 * var(--u)); padding: calc(6 * var(--u)) calc(8 * var(--u)); margin: calc(4 * var(--u)) 0; border: var(--line-w) dashed var(--line); border-radius: var(--radius-sm); font-size: calc(13 * var(--u)); }
.gear-cmp2 .gc-row { display: grid; grid-template-columns: minmax(calc(60 * var(--u)), auto) 1fr 1fr; align-items: center; gap: calc(8 * var(--u)); text-align: center; }
.gear-cmp2 .gc-row > span { text-align: left; color: var(--ink-dim); }
.gear-cmp2 .gc-row b.up { color: var(--sage-dk); } .gear-cmp2 .gc-row b.down { color: var(--coral-dk); }
.gear-cmp2 .gc-row em { font-style: normal; font-size: .85em; }
.gear-cmp2 .gc-head { align-items: start; padding-bottom: calc(4 * var(--u)); border-bottom: 1px solid rgba(59, 42, 26, .25); }
.gear-cmp2 .gc-side { display: grid; justify-items: center; gap: calc(2 * var(--u)); }
.gear-cmp2 .gc-side small { color: var(--ink-dim); }
.gear-cmp2 .gc-side b { font-size: calc(12 * var(--u)); line-height: 1.2; }
.gear-cmp2 .slot.sm { width: calc(40 * var(--u)); height: calc(40 * var(--u)); }
.item-modal .gc-sock { margin: 0; text-align: center; }
/* user 2026-10-15: long typed amounts never wrap (ทิ้ง 1000000 / strip value) */
.item-modal .actions .btn, .item-modal .ui-strip b, .qtypad .btn.key { white-space: nowrap; }
.item-modal .actions .btn { max-width: none; }
/* user 2026-10-15 item modal kind/tier tag top-right (left of the close X) */
.item-modal .im-tag { position: absolute; z-index: 2; top: calc(52 * var(--u)); right: calc(10 * var(--u)); flex-direction: column; align-items: flex-end; }   /* under the close X: never over the centred icon */
/* SocketTip: sockets in the item tooltip */
.htip .ht-sock { margin-top: calc(4 * var(--u)); }
.htip .ht-sock ul { list-style: none; margin: calc(2 * var(--u)) 0; padding: 0; display: grid; gap: calc(2 * var(--u)); }
.htip .ht-sock li { display: flex; align-items: center; gap: calc(6 * var(--u)); font-size: .95em; }
.htip .ht-sock li.empty { opacity: .65; }
.htip .ht-sock .slot { width: calc(22 * var(--u)); height: calc(22 * var(--u)); flex: none; }
.htip .ht-req { font-weight: 700; } .htip .ht-req.lock { color: #ff8a7a; }
.htip .ht-sock .slot { width: calc(22 * var(--u)); height: calc(22 * var(--u)); min-width: 0; min-height: 0; aspect-ratio: 1; padding: 0; border-width: calc(1 * var(--u)); }   /* user 2026-10-15: global .slot min-height made empty sockets tall */
.htip .ht-sock li { line-height: 1.2; }
.htip .ht-req { font-weight: 700; } .htip .ht-req.lock { color: #ff8a7a; }
/* user 2026-10-15: hover sockets = same size as the right-click card (.im-gems 34u) */
.htip .ht-sock .slot { width: calc(34 * var(--u)); height: calc(34 * var(--u)); border-width: initial; }
.htip .ht-sock .slot .ic { width: 80%; height: 80%; }
.htip .ht-sock li { gap: calc(8 * var(--u)); font-size: calc(14 * var(--u)); }
.htip .ht-sock ul { gap: calc(4 * var(--u)); }
/* user 2026-10-15: modal tags under the icon (row), smaller name + description */
.item-modal .im-tag { position: static; display: flex; flex-direction: row; justify-content: center; margin: calc(4 * var(--u)) auto 0; }
.item-modal .im-head h3 { font-size: calc(17 * var(--u)); margin: calc(4 * var(--u)) 0 0; }
.item-modal .im-desc { font-size: calc(12.5 * var(--u)); line-height: 1.4; }
.src-link { color: var(--blue-dk, #2d5d8a); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; font-weight: 600; }   /* item-card source names = นำทาง links */
/* K-648 output slot wrapped in a HoverTip span: keep the row / detail slot size (was .craft-row > .slot only -> capes blew up) */
.craft-row > span > .slot { width: calc(68 * var(--u)); min-height: 0; aspect-ratio: 1; }
.cd-head > span > .slot { width: calc(96 * var(--u)); min-height: 0; aspect-ratio: 1; flex: none; }
.farmbar .fb-slot { display: inline-flex; flex-direction: column; align-items: center; gap: calc(2 * var(--u)); } .farmbar .fb-nm { font-size: calc(10.5 * var(--u)); width: calc(64 * var(--u)); line-height: 1.15; text-align: center; white-space: normal; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; color: var(--ink); }   /* 2 lines, no ellipsis cut (user 2026-10-16) */   /* seed name under the slot */
/* user 2026-10-15 sell/qty modals: stone keys were too wide (18u caps) -> overflow; slimmer caps, keys may shrink, keypad modals wider */
.qtypad .btn.key { border-width: 0 calc(11 * var(--u)); border-image-width: 0 calc(11 * var(--u)); min-width: 0; }
.qtypad-keys, .qtypad-side { min-width: 0; }
.popup.confirm-modal:has(.qtypad) { width: min(calc(400 * var(--u)), calc(100vw - calc(16 * var(--u)))); }
.popup.confirm-modal:has(.qtypad) .ui-title h2 { white-space: nowrap; font-size: min(1em, calc(22 * var(--u))); }
.st-row .st-slot { padding: 0; border: 0; background: none; min-height: 0; cursor: pointer; flex: none; }
/* keypad modals wider (user 2026-10-15 x2) */
.popup.confirm-modal:has(.qtypad) { width: min(calc(460 * var(--u)), calc(100vw - calc(16 * var(--u)))); }
@media (max-width: 620px) { .st-row > .st-slot { grid-area: ic; } }   /* HoverTip wrapper keeps the phone row grid area of the slot */
/* user 2026-10-15: item modal bottom buttons side by side (were stacked) */
.item-modal > .actions, .item-modal .actions { display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: center; gap: calc(10 * var(--u)); }
.item-modal .actions .btn { flex: 0 1 auto; min-width: 0; width: auto; }
.st-mastery { display: grid; grid-template-columns: 1fr; } .st-mastery .mastery-row { width: 100%; box-sizing: border-box; }   /* user 2026-10-15 craft page: mastery card full width */

.bp-member { display: flex; align-items: center; justify-content: space-between; gap: calc(10 * var(--u)); flex-wrap: wrap; } .bp-member > div { display: flex; flex-direction: column; gap: calc(2 * var(--u)); } .bp-refund { display: block; }   /* user 2026-10-15 Premium membership card (PassPanels PremiumCard) */
/* user 2026-10-15 HUD Premium tag under the status bars (PassPanels PremiumTag): grey = not member, gold = active; modal = PremiumModal */
.vitals .avatar .prem-tag { position: absolute; left: 50%; bottom: calc(-12 * var(--u)); transform: translateX(-50%); z-index: 2; min-height: 0; min-width: 0; height: calc(22 * var(--u)); padding: 0 calc(10 * var(--u)); font-size: calc(11 * var(--u)); white-space: nowrap; pointer-events: auto;
  border-image: none; border-width: 0; color: #fff; text-shadow: 0 1px 0 #000, 0 0 calc(3 * var(--u)) rgba(0, 0, 0, .7); isolation: isolate; }   /* user 2026-10-15: centred under the face over the ring bottom (top tried, user kept bottom), short, white text */
.vitals .avatar .prem-tag::after { content: ""; position: absolute; inset: 0; z-index: -1; border: 0 solid transparent; border-width: 0 calc(11 * var(--u)); border-image: var(--pill) 43 47 43 47 fill / calc(11 * var(--u)) calc(12 * var(--u)) / 0 stretch; filter: var(--prem-f); pointer-events: none; }   /* pill art on a layer: tint never touches the text */
.vitals .avatar .prem-tag.ghost { --prem-f: grayscale(1) brightness(1.45); }   /* not member = grey (ยกเลิก button look) */
.vitals .avatar .prem-tag.on { --prem-f: sepia(1) saturate(4) hue-rotate(-8deg) brightness(1.35); }   /* active = gold */
@media (max-height: 500px) { .vitals .avatar .prem-tag { height: calc(16 * var(--u)); font-size: calc(9 * var(--u)); padding: 0 calc(7 * var(--u)); bottom: calc(-9 * var(--u)); } .vitals .avatar .prem-tag::after { border-width: 0 calc(8 * var(--u)); border-image-width: calc(8 * var(--u)) calc(9 * var(--u)); } }   /* phone landscape: dock right under the card */
.prem-modal { display: flex; flex-direction: column; gap: calc(6 * var(--u)); max-width: 100%; } .prem-modal, .prem-modal * { white-space: normal; overflow-wrap: anywhere; }
.prem-state { margin: 0; font-weight: 600; } .prem-state.on { color: #9a6a10; }
.prem-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: calc(4 * var(--u)); }
.prem-list li { display: flex; align-items: center; gap: calc(6 * var(--u)); } .prem-list li > :first-child { width: calc(22 * var(--u)); height: calc(22 * var(--u)); flex: none; object-fit: contain; }

.popup.confirm-modal:has(.prem-modal) { width: min(calc(560 * var(--u)), calc(100vw - calc(16 * var(--u)))); }   /* user 2026-10-15 Premium benefit window wider */
.prem-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(calc(220 * var(--u)), 1fr)); gap: calc(4 * var(--u)) calc(14 * var(--u)); }

/* user 2026-10-16 minimap tags (zone "ปลอดภัย"/T + CH + castle owner) = stone pill like the HUD Premium badge (ui4 pill on ::after, tinted per zone; text stays white) */
:is(.minimap .mm-label .zonetag, .zonetag.ch-corner) { isolation: isolate; background: none; border: 0; border-radius: 0; box-shadow: none; color: #fff; text-shadow: 0 1px 0 #000, 0 0 calc(3 * var(--u)) rgba(0, 0, 0, .7); padding: 0 calc(12 * var(--u)); }
:is(.minimap .mm-label .zonetag, .zonetag.ch-corner)::after { content: ""; position: absolute; inset: 0; z-index: -1; border: 0 solid transparent; border-width: 0 calc(11 * var(--u)); border-image: url(/assets/ui4/pill.webp) 43 47 43 47 fill / calc(11 * var(--u)) calc(12 * var(--u)) / 0 stretch; filter: var(--tag-f, none); pointer-events: none; }
.minimap .mm-label .zonetag.z-blue { --tag-f: sepia(1) saturate(3.2) hue-rotate(170deg) brightness(1.25); }
.minimap .mm-label .zonetag.z-yellow { --tag-f: sepia(1) saturate(4) hue-rotate(-8deg) brightness(1.35); }
.minimap .mm-label .zonetag.z-red { --tag-f: sepia(1) saturate(5) hue-rotate(-38deg) brightness(1.1); }
.minimap .mm-label .zonetag.z-black { --tag-f: grayscale(1) brightness(.75); }
.minimap .mm-label .zonetag.z-dungeon { --tag-f: sepia(1) saturate(3) hue-rotate(225deg) brightness(1.1); }
.minimap .mm-label .zonetag.gw-own { --tag-f: sepia(1) saturate(2.5) hue-rotate(-15deg) brightness(.95); }
.zonetag.ch-corner { position: absolute; z-index: 5; top: max(calc(12 * var(--u)), env(safe-area-inset-top)); right: max(calc(14 * var(--u)), env(safe-area-inset-right)); height: calc(24 * var(--u)); font-size: calc(12 * var(--u)); padding: 0 calc(10 * var(--u)); --tag-f: none; }   /* user 2026-10-16: CH = top-right screen corner, plain steel (ยกเลิก look) */

/* user 2026-10-16 BP level numbers = keypad stone pills (K-645 ui5): grey = not reached, green = reached, next = gold digits */
.bp-n { background: none; border-radius: 0; border: 0 solid transparent; border-width: 0 calc(12 * var(--u)); border-image: var(--stp) 0 70 fill / 0 calc(12 * var(--u)) / 0 stretch; color: var(--cream-lt); text-shadow: 0 1px 0 #000, 0 0 calc(3 * var(--u)) rgba(0, 0, 0, .6); }
.bp-col.reached .bp-n { background: none; border-image-source: var(--stp-g); }
.bp-col.next .bp-n { background: none; color: #ffe27a; }
.bp-legend .bp-n { border-image: none; }

/* user 2026-10-16 Stripe embedded checkout frame (CashShopPanels StripeFrame) */
.popup.stripe-frame { width: min(calc(560 * var(--u)), calc(100vw - calc(16 * var(--u)))); max-height: calc(100dvh - calc(24 * var(--u))); overflow-y: auto; }
.stripe-frame .stripe-box { min-height: calc(320 * var(--u)); background: #fff; border-radius: calc(8 * var(--u)); padding: calc(4 * var(--u)); }

/* user 2026-10-16 farmbar (pond collect / seed + grain pick) = same riveted parchment card as the hotbar (ui3 inset 9-slice) */
.hotbar > .farmbar { background: none; border-radius: 0; box-shadow: none; border: 0 solid transparent; border-image: url(/assets/ui3/inset.png) var(--inset-slice) fill / var(--inset-edge) / 0 stretch; filter: drop-shadow(0 calc(3 * var(--u)) calc(3 * var(--u)) rgba(40, 26, 14, .35)); padding: calc(10 * var(--u)) calc(14 * var(--u)); }
/* user 2026-10-16 farmbar: steel close (ui3 close.png like panels) + title top-left above the bar */
.farmbar .fb-x.ui-close { top: calc(-16 * var(--u)); right: calc(-16 * var(--u)); width: calc(38 * var(--u)); height: calc(38 * var(--u)); border: 0; border-radius: 0; box-shadow: none; background: url(/assets/ui3/close.png) center / contain no-repeat; }
.farmbar .fb-x.ui-close svg { display: none; }
.farmbar .fb-title { position: absolute; left: calc(6 * var(--u)); bottom: 100%; margin-bottom: calc(2 * var(--u)); font-weight: 700; font-size: calc(14 * var(--u)); color: var(--cream-lt, #fff7e6); text-shadow: 0 1px 0 #000, 0 0 calc(4 * var(--u)) rgba(0, 0, 0, .8); white-space: nowrap; pointer-events: none; }
/* user 2026-10-16 (relayed): skill learn/upgrade cost icons (skill point, Acorn, materials) on the ui5 stone badge like the numpad keys; short = red stone */
.skilltrain .cr-in .slot { background: url(/assets/ui5/stone_badge_grey.webp) center / 100% 100% no-repeat; border: 0; border-image: none; border-radius: 50%; box-shadow: none; }
.skilltrain .cr-in .slot::before, .skilltrain .cr-in .slot::after { display: none; }
.skilltrain .cr-in.short .slot { background-image: url(/assets/ui5/stone_badge_red.webp); }
.skilltrain .cr-in .slot > :is(img, svg, .ic) { width: 62%; height: 62%; }
/* user 2026-10-16: skill learn/upgrade header chips (แต้มสกิล, Acorn) + skill book points chip = ui5 stone pill like the numpad keys (K-645), white text */
:is(.tr-head, .sb-pts) > .chip, .chip.panel-acorn { --sp: var(--stp); background: none; box-shadow: none; border-radius: 0; border: 0 solid transparent; border-width: 0 calc(16 * var(--u)); border-image: var(--sp) 0 70 fill / 0 calc(16 * var(--u)) / 0 stretch; color: var(--cream-lt); text-shadow: 0 1px 0 #000, 0 0 calc(3 * var(--u)) rgba(0, 0, 0, .6); min-height: calc(30 * var(--u)); padding: 0 calc(2 * var(--u)); display: inline-flex; align-items: center; gap: calc(4 * var(--u)); }
:is(.tr-head, .sb-pts) > .chip > :is(svg, img, .ic), .chip.panel-acorn > :is(svg, img, .ic) { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
/* user 2026-10-16 skill learn/upgrade head: แต้มสกิล left + Acorn top-right on row 1, skill-point EXP bar full width on row 2, line dropdown row 3 */
.tr-head { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: calc(6 * var(--u)); }
.tr-head > .chip.sky { grid-column: 1; grid-row: 1; justify-self: start; }
.tr-head > .chip.brass { grid-column: 3; grid-row: 1; justify-self: end; }
.tr-head > .tr-prog { grid-column: 1 / -1; grid-row: 2; width: auto; }
.tr-head > .dd { grid-column: 1 / -1; grid-row: 3; justify-self: end; margin-left: 0; field-sizing: content; min-width: 0; }   /* width = selected label (user 2026-10-16) */

/* user 2026-10-16 "เอา focus outline เหลืองออก ทั้งหมด": no focus rings anywhere (overrides every :focus/:focus-visible outline above, incl. the slider ring). Text inputs keep their field look. */
*:focus, *:focus-visible { outline: none !important; }
input:focus-visible, textarea:focus-visible { box-shadow: none !important; }   /* the yellow glow ring of text fields too */
.slider .sl-track:has(input:focus-visible) { outline: none !important; }
/* user 2026-10-16: search clear "x" = the steel round close (ui3 close.png, like panel close), sized to the field */
input[type=search]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; width: calc(20 * var(--u)); height: calc(20 * var(--u)); margin-left: calc(4 * var(--u)); background: url(/assets/ui3/close.png) center / contain no-repeat; cursor: pointer; opacity: 1; }
/* user 2026-10-16 card wheel: ล้าง / ย้อน absolute bottom-right inside the wheel box */
.cardwheel .cw-top { position: relative; }
.cardwheel .cw-undo { position: absolute; left: calc(12 * var(--u)); right: calc(12 * var(--u)); bottom: calc(12 * var(--u)); display: flex; justify-content: space-between; pointer-events: none; }   /* ล้าง bottom-left, ย้อน bottom-right */
.cardwheel .cw-undo > .btn { pointer-events: auto; }
.cw-wheel .cw-icon > :is(img, .ic) { width: 100%; height: 100%; display: block; object-fit: contain; }   /* foreignObject reward icon */
.cardwheel .cw-top > .cw-count { position: absolute; left: calc(12 * var(--u)); top: calc(8 * var(--u)); z-index: 1; }
/* user 2026-10-16 skill book: แต้มสกิล chip top-left, EXP bar full width below */
.sb-pts { display: grid; grid-template-columns: 1fr; justify-items: start; gap: calc(6 * var(--u)); }
.sb-pts > .tr-prog { justify-self: stretch; width: auto; }
.enh-need.short .slot { box-shadow: 0 0 0 calc(2 * var(--u)) #b33; opacity: .7; }   /* enhance tab: stone needed, none in bag */
