/* ---- THE SHOP WINDOW (VEND) -----------------------------------------------------------------
   A player's own stall, and everybody else's. Four faces in one window — set up, manage, browse,
   ledger — and the bag half of the first two is the INVENTORY'S OWN GRID (`.rpg-cell`, same size,
   same icons), because an item must look the same wherever a player meets it. That is the same rule
   the strongbox follows, and the reason this borrows its column shapes rather than inventing new
   ones: two windows a player moves items between must not read as two different games. */
.rpg-panel--vend { width: min(960px, 96vw); overflow: hidden; }
.rpg-panel--vend.is-open { display: flex; flex-direction: column; }
.rpg-panel--vend > * { flex: none; }
.rpg-panel--vend > .rpg-vend-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

/* 8:5 like the strongbox — the bag is eight tiles across and the shelf is a list, so an even split
   would squeeze the tiles smaller than they are in the bag itself. */
.rpg-vend-cols { display: grid; grid-template-columns: 8fr 6fr; gap: var(--sp-4); align-items: stretch; }
.rpg-vend-side { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.rpg-vend-bag { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: var(--sp-2); align-content: start; min-width: 0; min-height: 0;
  max-height: 46vh; overflow-y: auto; padding: var(--sp-2); }

.rpg-vend-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: var(--sp-3); }
.rpg-vend-field > span { font-family: var(--font-banner); font-size: 11px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-mute); }

/* THE SHELF. A LIST rather than a grid, and deliberately: every line carries a price the player
   types into, and a price field inside a 44px tile is unusable. The listings a shopper reads are the
   same list, which is what keeps the manage view and the browse view recognisably one window. */
.rpg-vend-lines { list-style: none; margin: 0 0 var(--sp-3); padding: 0;
  display: flex; flex-direction: column; gap: 6px;
  background: var(--glass-deep); border: 1px solid var(--glass-stroke);
  border-radius: var(--r-2); padding: var(--sp-2); min-height: 120px; }
.rpg-vend-lines--wide { min-height: 160px; }
.rpg-vend-line { display: flex; align-items: center; gap: var(--sp-2);
  padding: 5px 6px; border-radius: var(--r-1); background: rgba(7,9,26,.4);
  border: 1px solid var(--glass-stroke); }
.rpg-vend-line-icon { width: 30px; height: 30px; flex: none; display: grid; place-items: center; }
.rpg-vend-line-icon img { width: 28px; height: 28px; }
.rpg-vend-line-name { flex: 1 1 auto; min-width: 0; font-family: var(--font-quill);
  color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rpg-vend-line-name em { display: block; font-style: normal; font-size: 11px; color: var(--ink-mute); }
.rpg-vend-line-price { flex: none; font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--gold-hi); }
.rpg-vend-line-when { flex: none; font-family: var(--font-mono); font-size: 11px;
  font-variant-numeric: tabular-nums; color: var(--ink-mute); }
.rpg-vend-empty { padding: var(--sp-3); text-align: center; font-family: var(--font-quill);
  color: var(--ink-mute); background: none; border: 0; }

/* Number fields sized to the digits they hold, so a price and a quantity do not both stretch to
   fill the row and leave the Buy button hunting for its place. */
.rpg-vend-price, .rpg-vend-qty { flex: none; width: 92px; padding: 4px 6px;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--ink); background: rgba(7,9,26,.6);
  border: 1px solid var(--glass-stroke); border-radius: var(--r-1); }
.rpg-vend-qty { width: 62px; }
.rpg-vend-price:focus, .rpg-vend-qty:focus { outline: none; border-color: var(--gold); }
/* No browser spinner arrows on the price and count boxes — a stepper on a 10,000,000-gold field is
   noise, and the arrows do not match the panel. */
.rpg-vend-price, .rpg-vend-qty { appearance: textfield; -moz-appearance: textfield; }
.rpg-vend-price::-webkit-inner-spin-button, .rpg-vend-price::-webkit-outer-spin-button,
.rpg-vend-qty::-webkit-inner-spin-button, .rpg-vend-qty::-webkit-outer-spin-button {
  -webkit-appearance: none; appearance: none; margin: 0; }
.rpg-vend-confirm { align-self: center; font-size: 12px; color: #f0b0a6; }

.rpg-vend-total { margin: 0 0 var(--sp-3); font-family: var(--font-quill); color: var(--ink-soft); }
.rpg-vend-owner { margin: 0 0 var(--sp-3); font-family: var(--font-quill); color: var(--ink-soft); }
.rpg-vend-hint { margin: var(--sp-2) 0 0; font-family: var(--font-quill); font-size: 12px;
  color: var(--ink-mute); }
.rpg-vend-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* ONE BUTTON RECIPE, three weights. `.rpg-btn` outside the action bar carries only the cursor rule,
   so this window states its own rather than inheriting a treatment meant for a 46px icon cell. */
.rpg-vend-btn { padding: 7px 14px; border-radius: var(--r-1); cursor: pointer; white-space: nowrap;
  font-family: var(--font-banner); font-size: 12px; font-weight: 600; letter-spacing: .06em;
  color: var(--ink-soft); background: rgba(7,9,26,.55); border: 1px solid var(--glass-stroke); }
.rpg-vend-btn:hover:not(:disabled) { border-color: var(--glass-stroke-hi); color: var(--ink); }
.rpg-vend-btn:disabled { opacity: .45; cursor: default; }
.rpg-vend-btn.is-primary { color: var(--gold-hi); border-color: var(--gold);
  background: linear-gradient(180deg, rgba(92,74,42,.85), rgba(52,40,22,.85)); }
.rpg-vend-btn.is-danger { color: #f0b0a6; border-color: rgba(190,86,70,.7);
  background: linear-gradient(180deg, rgba(84,34,28,.7), rgba(48,20,16,.7)); }

/* THE PRICING DIALOG — inside the window, not a browser prompt. It replaced two `window.prompt`s,
   which are a different application appearing over the game: unstyled, unable to show the item, and
   unable to state the one limit that bites (a listing holds at most 99 of a stack). */
.rpg-vend-stage { margin: 0 0 var(--sp-3); padding: var(--sp-3); border-radius: var(--r-2);
  background: rgba(7,9,26,.62); border: 1px solid var(--gold);
  display: flex; flex-direction: column; gap: var(--sp-2); }
.rpg-vend-stage-head { display: flex; align-items: center; gap: var(--sp-2); }
.rpg-vend-stage-field { display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-2); }
.rpg-vend-stage-field > span { font-family: var(--font-banner); font-size: 11px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-mute); }

/* WHERE A DRAGGED STACK WILL LAND. Same treatment as the strongbox's grids, so the two windows a
   player moves items between light up the same way. */
.rpg-vend-lines.is-drop { outline: 2px dashed var(--gold); outline-offset: 3px;
  background: rgba(201,164,110,.07); }
.rpg-vend-bag .rpg-cell[draggable="true"] { cursor: grab; }

/* THE SHOPPER'S VIEW OF A STALL — the shelf on the left, the basket on the right, the same
   arrangement the NPC shop uses. Buying from a player and buying from Garrick are the same act, and
   two layouts for one act is two things to learn. */
.rpg-vend-cols--shop { grid-template-columns: 7fr 5fr; }
.rpg-vend-checkout { min-width: 0; }

/* ALL TEN ROWS, ALWAYS. A shop selling one thing and a shop selling ten produce the same window
   height, so the Buy button does not move under the pointer as stock sells. The row height is
   stated once here and the vacant rows are the same box with nothing in it. */
.rpg-vend-lines--fixed { min-height: 0; }
.rpg-vend-lines--fixed .rpg-vend-line { min-height: 42px; }
.rpg-vend-line.is-vacant { background: rgba(7,9,26,.22); border-style: dashed; }
.rpg-vend-lines--basket { min-height: 210px; }

/* The +/- stepper in the basket. Same 18px squares as the NPC shop's cart, so the two carts are
   plainly the same control. */
.rpg-vend-qty-step { display: flex; align-items: center; gap: 5px; flex: none; }
.rpg-vend-qty-step button { width: 18px; height: 18px; line-height: 1; padding: 0;
  border-radius: 4px; cursor: pointer; color: var(--ink-soft);
  background: rgba(7,9,26,.6); border: 1px solid var(--glass-stroke); }
.rpg-vend-qty-step button:hover { border-color: var(--gold); color: var(--ink); }
.rpg-vend-qty-step .q { font-family: var(--font-mono); font-size: 12px; min-width: 14px;
  text-align: center; font-variant-numeric: tabular-nums; }
.rpg-vend-total strong.is-short { color: var(--ember); }

/* THE STALL COLOUR SWATCHES. The one place in the interface where the literal colour IS the
   information, so the hex arrives inline as `--swatch` rather than as a class per palette entry —
   a second copy of the palette in CSS is a second thing to keep in step with `VEND_STALL_COLOURS`. */
.rpg-vend-swatches { display: flex; gap: 6px; flex-wrap: wrap; }
.rpg-vend-swatch { width: 28px; height: 28px; padding: 0; border-radius: var(--r-1);
  cursor: pointer; background: var(--swatch); border: 2px solid var(--glass-stroke); }
.rpg-vend-swatch:hover { border-color: var(--glass-stroke-hi); }
.rpg-vend-swatch.is-active { border-color: var(--gold-hi);
  box-shadow: 0 0 0 2px rgba(201,164,110,.35); }

/* ── THE TREE STRIP, and the three kinds of node ──────────────────────────────────────────────
   A SECOND ROW OF TABS, quieter than the Class/Character pair above it, because it answers a
   narrower question: those two say which KIND of thing you are looking at, these say which tree of
   that kind. Pills rather than underlined tabs, so the two rows never read as one strip of four
   peers with "Character skills" sitting beside "Beast Master". */
.rpg-tree-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.rpg-tree-tab { padding: 3px 12px; cursor: pointer; border-radius: var(--r-pill);
  border: 1px solid var(--glass-stroke); background: none; color: var(--ink-mute);
  font-family: var(--font-banner); font-size: 10px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; transition: color .15s, border-color .15s, background .15s; }
.rpg-tree-tab:hover { color: var(--ink-soft); border-color: var(--gold); }
.rpg-tree-tab.is-active { color: var(--gold-hi); border-color: var(--gold);
  background: var(--glass-deep); box-shadow: 0 0 10px var(--gold-glow); }

/* THREE KINDS OF NODE, TOLD APART BY SHAPE, not by colour alone. A passive is the plain disc the
   tree has always drawn. A SUMMON is a hexagon-ish cut corner — it is the only node that puts a
   creature in the world, and it heads every column. A SPELL is a diamond: something you cast,
   which is what the hotbar draws. Shape rather than hue because these three sit in one grid at a
   glance, and a player reading the tree in the corner of their eye should not have to compare two
   similar borders — nor should the distinction vanish for a colour-blind player.
   The rank pill stays circular and square-on; only the disc itself is cut. */
.rpg-node--summon { border-radius: 22% 50% 22% 50%; }
.rpg-node--spell { border-radius: 12%; transform: rotate(45deg); }
.rpg-node--spell > svg, .rpg-node--spell .rank { transform: rotate(-45deg); }
/* A BEAST-SCOPED PASSIVE reads cooler than the character's own: its numbers never reach your
   sheet, and a tree where the bonus's owner is invisible is exactly the confusion that was once a
   real bug in derive.ts. Paired with the tooltip line, which is where it is stated in words. */
.rpg-node--beast { border-color: var(--beast-node, #7fd0c8); color: var(--beast-node, #7fd0c8); }
.rpg-node--beast.has-ranks { box-shadow: 0 0 12px rgba(127,208,200,.45); }

/* Town concept: blued steel, parchment lettering and restrained brass fittings.
   Static fills only: no new compositing filters or animated ornament. */
.rpg-ui, .hud-hotbar, .hud-quests {
  --chrome: #20262e;
  --glass-stroke: #626873;
  --gold: #bca47b;
  --gold-hi: #e9d9b5;
  --gold-glow: rgba(194,169,123,.2);
}
.rpg-status {
  background: linear-gradient(150deg, rgba(48,56,67,.96), rgba(20,25,32,.94));
  border: 1px solid #a18e70;
  box-shadow: inset 0 1px 0 #68717b, inset 0 0 0 3px #242b34, 0 5px 14px #0006;
}
.rpg-portrait { background: radial-gradient(circle at 50% 35%, #596779, #202934); }
.rpg-portrait-ring { border-color: #c0ab82; box-shadow: inset 0 0 0 2px #253443, 0 0 0 2px #526575; }
.hud-hotbar.v-page {
  border-radius: 9px;
  box-shadow: 0 0 0 1px #b19b76, 0 0 0 3px #252b33,
    inset 0 1px 0 #84909b, inset 0 -2px 0 #0d1219, 0 7px 18px #0008;
}
.hud-quests.v-page { background: linear-gradient(150deg, rgba(42,48,56,.93), rgba(19,24,30,.9)); }
.hud-quests-title { padding-bottom: 7px; border-bottom: 1px solid #aa947750; }
.hud-minimap-ring { border-color: #a99a80; box-shadow: 0 0 0 2px #252e39, inset 0 0 16px #0007; }
.hud-minimap-n { background: #27313d; }
.rpg-actionbar .rpg-btn-glyph {
  background: linear-gradient(150deg, #424d59, #202731 70%);
  border-color: #9a896d;
  box-shadow: inset 0 1px 0 #89909a80, inset 0 0 0 3px #202731;
}
.rpg-chat { background: linear-gradient(155deg, rgba(39,47,57,.93), rgba(17,22,29,.92)); }

