/* ---- Bag: category tabs and footer ------------------------------------------------------------
   A tab strip is an INDEX into a page of the Ledger, so it is set as one: small caps, wide tracked,
   and the active tab marked by a lit gold underline rather than by a filled block. Gold is a line
   and point material (VIL Colour) — a filled gold tab would be the one thing the rule forbids. */
.rpg-tabs { display: flex; flex-wrap: wrap; gap: 2px; margin: 0 0 10px;
  border-bottom: 1px solid rgba(198,160,104,.22); }
.rpg-tab { position: relative; padding: 6px 11px 8px; border: 0; background: none; cursor: pointer;
  font-family: var(--font-banner); font-size: 10px; font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink-mute); transition: color .15s; }
.rpg-tab:hover { color: var(--ink-soft); }
.rpg-tab.is-active { color: var(--gold-hi); }
/* The lit segment under the active tab, brighter at its centre — the plate's own treatment. */
.rpg-tab.is-active::after { content: ''; position: absolute; left: 6px; right: 6px; bottom: -1px;
  height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  box-shadow: 0 0 8px -1px var(--gold-glow); }

/* Out of the current tab. DIMMED, NOT REMOVED: the slot keeps its place and its index, so the bag
   never reflows under a drag and nothing can be dropped into the wrong cell. It also means a player
   can still see that the thing they are looking for is in there, just filed elsewhere. */
.rpg-cell.is-filtered { opacity: .18; filter: grayscale(1) brightness(.7); }

.rpg-bag-foot { display: flex; align-items: center; justify-content: space-between;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid rgba(198,160,104,.22); }
.rpg-purse { display: flex; align-items: center; gap: 6px; font-family: var(--font-mono);
  font-size: 14px; color: var(--ink); }
.rpg-purse i { font-style: normal; color: var(--gold); text-shadow: 0 0 8px var(--gold-glow); }
.rpg-cap { font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums;
  color: var(--ink-mute); }

/* ---- The item card ----------------------------------------------------------------------------
   A leaf of the illustrated catalogue: a thing you READ, which is why it is a panel beside the bag
   rather than a label chasing the pointer. Primary tier — it carries the full flourish set. */
/* Anchored off the INVENTORY panel's edge: the window is min(1056px, 94vw) wide, so the card
   starts at half of that plus a 12px gutter — it moved out with the 20% resize. */
.rpg-itemcard { position: absolute; left: calc(50% + min(540px, 48vw)); top: 50%;
  transform: translateY(-50%); width: 260px; padding: 16px 18px 14px;
  pointer-events: none; display: none; z-index: 41; }
.rpg-itemcard.is-open { display: block; }
/* The tier hue for the card. `ItemDetailCard` writes data-rarity and every accent below reads
   `--r-c`, but nothing ever SET it — so the chip and name sat on their fallbacks for every tier.
   Hues come from items.css, the palette of record. Common keeps the fallback ink deliberately. */
.rpg-itemcard[data-rarity="uncommon"]  { --r-c: var(--r-uncommon-c); }
.rpg-itemcard[data-rarity="rare"]      { --r-c: var(--r-rare-c); }
.rpg-itemcard[data-rarity="epic"]      { --r-c: var(--r-epic-c); }
.rpg-itemcard[data-rarity="legendary"] { --r-c: var(--r-legendary-c); }
/* The rarity chip. A FILLED block is right here and nowhere else on the card: it is the one badge
   whose whole job is to be read before anything else, and it is not gold (VIL keeps gold to lines
   and points) — it takes the tier colour items.css already owns. */
.rpg-itemcard-chip { display: inline-block; padding: 2px 8px; border-radius: 3px;
  font-family: var(--font-banner); font-size: 10px; font-weight: 700; letter-spacing: .16em;
  color: var(--r-c, var(--ink)); border: 1px solid var(--r-c, var(--glass-stroke));
  background: color-mix(in srgb, var(--r-c, #6a5fae) 22%, transparent); }
.rpg-itemcard-name { margin: 9px 0 2px; font-family: var(--font-display); font-size: 20px;
  line-height: 1.15; color: var(--r-c, var(--ink)); }
.rpg-itemcard-type { font-size: 12px; color: var(--ink-mute); margin-bottom: 12px; }
/* The plate gives the illustration real room — it is the only picture on the card and the fastest
   way to recognise the item. Set into the page like a slot, for the same reason. */
/* The same light plate as the bag and equipment slots — one item ground across the window. */
.rpg-itemcard-art { height: 116px; display: grid; place-items: center; font-size: 54px;
  border-radius: var(--r-2); margin-bottom: 12px;
  background: #e6e4ed; border: 1px solid var(--glass-stroke);
  box-shadow: inset 0 2px 5px rgba(20,14,50,.22); }
.rpg-itemcard-art img { width: 88px; height: 88px; object-fit: contain; filter: var(--icon-filter); }
.rpg-itemcard-row { display: flex; justify-content: space-between; align-items: baseline;
  padding: 4px 0; font-size: 13px; color: var(--ink-soft);
  border-bottom: 1px solid rgba(154,134,232,.10); }
.rpg-itemcard-row b { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--ink); }
.rpg-itemcard-row.is-locked b { color: var(--ember); }
.rpg-itemcard-flavor { margin: 11px 0 0; font-family: var(--font-quill); font-style: italic;
  font-size: 13px; line-height: 1.45; color: var(--ink-quill); }
/* The split-gesture hint, shown only on a stack of more than one. Quieter than flavour text —
   it is chrome speaking, not the item. */
.rpg-itemcard-hint { display: none; margin: 9px 0 0; font-size: 11px; line-height: 1.4;
  color: var(--ink-mute); }
.rpg-itemcard-foot { display: flex; justify-content: space-between; align-items: center;
  margin-top: 13px; padding-top: 10px; border-top: 1px solid rgba(198,160,104,.22); }
.rpg-itemcard-sell { font-size: 12px; color: var(--ink-mute); }
.rpg-itemcard-price { font-family: var(--font-mono); font-size: 14px; color: var(--ink);
  display: flex; align-items: center; gap: 5px; }
.rpg-itemcard-price i { font-style: normal; color: var(--gold); text-shadow: 0 0 8px var(--gold-glow); }

/* ---- Character sheet: the headline trio -------------------------------------------------------
   Attack, Defense and Max HP answer "can I take this fight"; everything below answers "why". They
   were previously three rows of seven, set at the same size as Flee, which stated no hierarchy at
   all. Each sits in its own cut cell so the trio reads as one instrument. */
.rpg-headline { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 18px; }
.rpg-headline-fig { display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px 8px 10px; border-radius: var(--r-2);
  background: linear-gradient(180deg, #120e2a, #1c1540);
  box-shadow: inset 0 2px 6px rgba(0,0,0,.7), inset 0 -1px 0 rgba(198,160,104,.18); }
.rpg-headline-fig i { font-style: normal; font-size: 15px; color: var(--gold);
  text-shadow: 0 0 8px var(--gold-glow); line-height: 1; }
.rpg-headline-fig b { font-family: var(--font-mono); font-size: 26px; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--ink); line-height: 1.1; }
.rpg-headline-fig span { font-family: var(--font-banner); font-size: 10px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-mute); }

/* ---- The workbench ----------------------------------------------------------------------------
   Two columns, the same split as the satchel: what you can choose from on the left, what you have
   chosen on the right. The bench slots reuse `.rpg-slot` and the bag stacks reuse `.rpg-cell`, so
   an item looks the same wherever the player meets it — a material that changed appearance between
   the bag and the bench would read as a different material. */
/* THREE COLUMNS: what you have, what you can make, and the one you picked. The ingredients used to
   sit in the middle column under the bench, which put a wall of cells between the search box and the
   recipe list — the two things a player alternates between. As its own rail it is a standing
   inventory of the bench, glanceable without pushing anything else down the page. */
/* The rail's width is a variable because the mats grid's HEIGHT is derived from it — see below. */
/* RECIPES FIRST, then the ingredients rail, then the picked recipe (owner-requested swap).
   The book is what the player came here to read, so it now opens on the left edge where reading
   starts, and the rail of materials sits between the book and the detail it feeds. */
.rpg-craft { --ing-col: 232px;
  display: grid; grid-template-columns: minmax(0, 1fr) 300px var(--ing-col); gap: var(--sp-5);
  /* STRETCH, not `start`. With `start` every column was sized by its own content, so the recipe
     list's `1fr` track had nothing to be a fraction OF — the book simply grew, took the panel with
     it, and its styled scrollbar (below) could never appear because it never overflowed. Fourteen
     recipes made a window taller than the screen. */
  align-items: stretch;
  /* A FIXED HEIGHT, so the window stops resizing as you click down the recipe list. The item card
     grows with the item — a sword has four stat rows and flavour, a material has none — and with
     the card in a column of its own the whole panel was inheriting that height and jumping on
     every selection.
     The number is MEASURED in the browser across all ten recipes rather than guessed: the tallest
     card the book can produce is the Wizard Cloak's at 442px (against 304 for Stone Arrows), so 560
     clears it by more than a hundred — headroom for several more stat rows before the jump could
     come back, and it is the height the owner asked for besides. The recipe list is a `1fr` track
     in its own column, so every pixel of it goes to the book.
     Pinning the CONTAINER rather than the card is what actually stops the jump: it holds the two
     side columns still as well.
     NOW A FIXED HEIGHT AND A SHORTER ONE (owner's call): 470px, down from a 560 floor the recipe
     list then blew straight through. `height` rather than `min-height` because a floor is not a
     ceiling — it stopped the panel shrinking and did nothing at all about it growing. 470 still
     clears the tallest card the book can produce (the Wizard Cloak's, measured at 442px), and the
     book itself now scrolls inside its column instead of stretching the window. */
  height: 470px; }
/* The SWAP IS VISUAL ONLY — `order`, not a reshuffle of the markup. The DOM is what a screen
   reader narrates and what Tab walks, and there the ingredients rail legitimately comes first: it
   is a short read-only readout, and making a keyboard user tab through the whole recipe list to
   reach the search box would be paying for a column swap with the one order that has to stay
   sensible. Grid's `order` moves the boxes and leaves that order alone. */
.rpg-craft-ing { display: grid; gap: var(--sp-2); min-width: 0; order: 3; align-content: start; }
.rpg-craft-left { display: grid; gap: var(--sp-2); min-width: 0; order: 1;
  /* heading, search, then the list taking the rest — see `.rpg-craft-list`. */
  grid-template-rows: auto auto 1fr; align-content: stretch;
  /* A grid item is floored at its content height unless told otherwise, and that floor is what
     kept the list from ever being smaller than its recipes. */
  min-height: 0; }
/* THE MIDDLE COLUMN IS THE CARD. Its own height no longer moves anything: the grid above is pinned
   to the tallest card, and a shorter one simply leaves space under it. */
/* It scrolls on its own if a card ever does outgrow the pinned height, rather than pushing the
   window back open — the same gilded rail the book gets. */
.rpg-craft-detail { order: 2; min-height: 0; overflow-y: auto; padding-right: 2px; }
/* The right column's lower half: what the picked recipe needs, how long it takes, and the button.
   Separated from the rail above it by a rule, because "what I am carrying" and "what this needs"
   are two different readings of the same kind of thing and would otherwise run together. */
.rpg-craft-make { display: grid; gap: var(--sp-2); margin-top: var(--sp-3);
  padding-top: var(--sp-3); border-top: 1px solid var(--glass-stroke); }
.rpg-craft-make:empty { display: none; }
.rpg-craft-search { width: 100%; padding: 8px 11px; border-radius: var(--r-2);
  border: 1px solid var(--glass-stroke); background: var(--glass-deep); color: var(--ink);
  font: 14px var(--font-body); outline: none; }
.rpg-craft-search:focus { border-color: var(--gold); }
/* FOUR ACROSS, FOUR DEEP, then scroll. The height is pinned to exactly four rows so the rail does
   not grow and shrink as materials are gathered and spent — a column that changes height on every
   craft drags the recipe list up and down beside it. `auto-rows` keeps the cells square once the
   grid is scrolling and the tracks stop being sized by content. */
/* THREE PER ROW, not four (owner's call): the rail's column is a fixed 208px, so four cells left
   each icon around 46px — small enough that a wood billet and a stone read as the same brown
   square. Three gives them roughly 64px each, which is the size the icons were rendered for. */
.rpg-craft-mats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: min-content; gap: var(--sp-2);
  /* FOUR ROWS EXACTLY, still. The old note derived this from a 4x4 grid being as tall as it is
     wide; at three across the same height shows four rows of larger cells with the fifth cut, which
     is the same "there is more below" signal and the same reason not to hand-type a pixel height.
     The width is still the honest unit to express it in — it tracks the column. */
  max-height: var(--ing-col); overflow-y: auto; align-content: start;
  padding-right: 2px; }
/* The empty line has to span the grid or it lays out as one cell of text. */
.rpg-craft-mats .rpg-craft-empty { grid-column: 1 / -1; }
/* NOT clickable any more. The bench slots and the click-to-stage gesture are gone, so the rail is a
   readout of what you are carrying, and a pointer cursor on it would promise an action that no
   longer exists. `default` rather than omitting the rule, because `.rpg-cell` sets `pointer`. */
.rpg-craft-mat { cursor: default; }
.rpg-craft-mat:hover { transform: none; border-color: var(--glass-stroke); }
/* ---- the picked recipe's ingredients, lit on the rail ------------------------------------------
   Only while something is picked (`is-picking`), because with no recipe selected there is nothing
   to be "not required" and greying the whole rail would read as a disabled bench. Pushing the rest
   back is what makes the lit cells findable — lighting alone leaves eight gold-ish squares and no
   figure/ground, which is the failure mode of every "highlight" that only adds. */
.rpg-craft-mats.is-picking .rpg-craft-mat { opacity: .3; filter: grayscale(.8); }
.rpg-craft-mats.is-picking .rpg-craft-mat.is-req { opacity: 1; filter: none; }
/* HAVE: the gold that means "live" everywhere else in this UI. */
.rpg-craft-mat.is-req { border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold) inset, 0 0 12px var(--gold-glow, rgba(201,164,110,.4)); }
/* LACK: ember, the same colour the detail column's shortfall count already uses, so the two halves
   of the answer are not painted in two different languages. */
.rpg-craft-mat.is-req.is-short { border-color: var(--ember);
  box-shadow: 0 0 0 1px var(--ember) inset, 0 0 12px rgba(255,122,82,.35); }
/* NONE AT ALL: a hollow socket. Dashed is the "nothing here yet" affordance the empty gear slots
   already use, and the artwork is knocked back to a watermark so the cell reads as a space the
   material is missing from rather than as a stack you own. */
.rpg-craft-mat.is-missing { border-style: dashed; background: rgba(255,122,82,.06); }
.rpg-craft-mat.is-missing .rpg-tile { opacity: .34; filter: grayscale(1); }
/* have/needed. Centred along the foot of the cell — it REPLACES the stack count while it is up
   (see `renderMats`), so there is nothing in the other corner to dodge, and a centred badge on a
   square cell is what stops "2/3" reading as a fragment of the artwork. */
.rpg-craft-need { position: absolute; left: 50%; transform: translateX(-50%); bottom: 3px; z-index: 2; pointer-events: none;
  padding: 0 3px; border-radius: var(--r-1); background: rgba(8,6,20,.82);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 10px;
  line-height: 1.5; color: var(--gold-hi); }
.rpg-craft-mat.is-short .rpg-craft-need { color: var(--ember); }
/* FILLS THE COLUMN. `max-height: 38vh` cut the book off well short of the panel's own height, so
   the recipe list scrolled inside a window that had empty space below it. The column is a grid
   whose last row is this list (see `.rpg-craft-left`), so `1fr` hands it whatever is left after the
   heading and the search box, and `min-height: 0` is what lets a grid item actually shrink to its
   track instead of being sized by its content. */
.rpg-craft-list { display: flex; flex-direction: column; gap: 6px;
  /* ALWAYS `scroll`, not `auto` (owner's call: "a designed scroll bar on the recipes column"). The
     gilded channel below is part of the panel's furniture, and with `auto` it appears and vanishes
     as recipes are learned or the search filters the book — the column's width changing under the
     list every time you type. Reserved once, it never moves. */
  min-height: 0; overflow-y: scroll; }
/* FIREFOX (and anything else without the WebKit pseudo-elements) gets the two standard properties
   it actually implements. Styling only `::-webkit-*` would have left every non-Chromium player
   looking at a stock grey OS scrollbar bolted to a gilded panel, which is the exact seam this file
   exists to hide. `thin`, never `none`: an invisible scrollbar is a bar that cannot be grabbed, and
   the recipe book is long enough to need dragging.
   GUARDED BY @supports, and that guard is load-bearing rather than tidy. Chromium implements BOTH,
   and `scrollbar-color` WINS — set unconditionally it silently threw away every rule below and drew
   the OS scrollbar in gold instead, complete with a pair of stepper triangles at the ends. The two
   engines therefore get one styling each, and neither gets both. */
@supports not selector(::-webkit-scrollbar) {
  .rpg-craft-list, .rpg-craft-mats, .rpg-craft-detail, .rpg-bestiary-grid,
  .rpg-shop-wares, .rpg-shop-cart, .rpg-forge-picker { scrollbar-width: thin;
    scrollbar-color: var(--gold-deep, var(--gold-mid)) rgba(10, 8, 26, .55); }
}
/* THE GILDED RAIL. 10px, not the chat log's 6 — the chat scrolls itself and is read, where this one
   is DRAGGED, and a 6px target is a miss at the speed a player flicks through a recipe book.
   The track is the same well the search field sits in so the bar reads as cut into the panel, and
   the thumb is the panel's gold: the one colour in this UI that already means "this is live". */
.rpg-craft-list::-webkit-scrollbar, .rpg-bestiary-grid::-webkit-scrollbar { width: 10px; }
.rpg-craft-detail::-webkit-scrollbar { width: 8px; }
.rpg-craft-list::-webkit-scrollbar-track,
.rpg-craft-detail::-webkit-scrollbar-track,
.rpg-bestiary-grid::-webkit-scrollbar-track { background: rgba(10, 8, 26, .55);
  border-radius: var(--r-pill); }
/* The transparent border + `background-clip: content-box` is what insets the thumb inside its
   track without a second element: the border is drawn from the padding box outward and the
   background stops short of it, so the gold sits as a 6px pill in a 10px channel. */
.rpg-craft-list::-webkit-scrollbar-thumb,
.rpg-craft-detail::-webkit-scrollbar-thumb,
.rpg-bestiary-grid::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--gold-base), var(--gold-mid)) content-box;
  border: 2px solid transparent; border-radius: var(--r-pill); }
.rpg-craft-list::-webkit-scrollbar-thumb:hover,
.rpg-bestiary-grid::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, var(--gold-hi-base), var(--gold-base)) content-box; }
/* Chrome draws a pair of stepper buttons at the ends unless they are explicitly zeroed, and they
   inherit nothing from the rules above — two grey squares capping a gold rail. */
.rpg-craft-list::-webkit-scrollbar-button,
.rpg-craft-detail::-webkit-scrollbar-button,
.rpg-bestiary-grid::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
/* The materials rail scrolls too (five rows of mats and up), so it gets the same rail rather than
   a stock one sitting six inches from the styled one. Narrower, because it is never the thing
   being dragged — it is a readout. */
.rpg-craft-mats::-webkit-scrollbar { width: 8px; }
.rpg-craft-mats::-webkit-scrollbar-track { background: rgba(10, 8, 26, .55);
  border-radius: var(--r-pill); }
.rpg-craft-mats::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--gold-base), var(--gold-mid)) content-box;
  border: 2px solid transparent; border-radius: var(--r-pill); }
.rpg-craft-mats::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
/* THE SHOP'S RAILS: the wares grid (dragged, so the 10px rail) and the cart (a readout, 8px) — and the
   forge's picker with them. They were the last stock OS scrollbars on a gilded window (owner,
   2026-09-09: the weapon shop's scrollbar), drawn grey against the panel's gold. */
.rpg-shop-wares::-webkit-scrollbar { width: 10px; }
.rpg-shop-cart::-webkit-scrollbar, .rpg-forge-picker::-webkit-scrollbar { width: 8px; }
.rpg-shop-wares::-webkit-scrollbar-track, .rpg-shop-cart::-webkit-scrollbar-track,
.rpg-forge-picker::-webkit-scrollbar-track { background: rgba(10, 8, 26, .55); border-radius: var(--r-pill); }
.rpg-shop-wares::-webkit-scrollbar-thumb, .rpg-shop-cart::-webkit-scrollbar-thumb,
.rpg-forge-picker::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--gold-base), var(--gold-mid)) content-box;
  border: 2px solid transparent; border-radius: var(--r-pill); }
.rpg-shop-wares::-webkit-scrollbar-thumb:hover, .rpg-shop-cart::-webkit-scrollbar-thumb:hover,
.rpg-forge-picker::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, var(--gold-hi-base), var(--gold-base)) content-box; }
.rpg-shop-wares::-webkit-scrollbar-button, .rpg-shop-cart::-webkit-scrollbar-button,
.rpg-forge-picker::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
/* THE CLOCK, drawn rather than typed. An emoji here inherits whatever the player's system has and
   lands at a different size and baseline on every platform; a bordered circle with two hands is the
   same everywhere and takes the surrounding text colour. */
.rpg-craft-clock { display: inline-block; position: relative; width: 12px; height: 12px;
  margin-right: 6px; vertical-align: -1px;
  border: 1.5px solid currentColor; border-radius: 50%; opacity: .85; }
.rpg-craft-clock::before, .rpg-craft-clock::after { content: ''; position: absolute;
  background: currentColor; border-radius: 1px; }
/* Hour hand to the top, minute hand to the right — a clock reading two o'clock, which reads as a
   clock at 12px where a symmetrical pair reads as a plus sign. */
.rpg-craft-clock::before { left: 50%; top: 2px; width: 1.5px; height: 3.5px; transform: translateX(-50%); }
.rpg-craft-clock::after { left: 50%; top: 50%; width: 3.5px; height: 1.5px; transform: translateY(-50%); }
.rpg-recipe { display: flex; align-items: center; gap: 10px; padding: 7px 10px; cursor: pointer;
  border-radius: var(--r-2); border: 1px solid var(--glass-stroke); background: var(--glass-deep); }
.rpg-recipe:hover { border-color: var(--gold); }
.rpg-recipe.is-active { border-color: var(--gold); box-shadow: 0 0 10px var(--gold-glow); }
/* DIMMED, NOT HIDDEN: "what do I need for that?" is the question this window answers, and a recipe
   you cannot afford yet is exactly the one being asked about. */
.rpg-recipe.is-dim { opacity: .48; }
.rpg-recipe-glyph { width: 26px; height: 26px; display: grid; place-items: center; font-size: 18px; }
.rpg-recipe-glyph .rpg-icon { width: 26px; height: 26px; }
.rpg-recipe-name { flex: 1 1 auto; font-family: var(--font-display); font-size: 15px; color: var(--ink); }
.rpg-recipe-out { font-family: var(--font-mono); font-size: 12px; color: var(--ink-mute); }
/* NO PLATE OF ITS OWN. This column used to be a bordered, dark-gradient box because it held the
   output heading, the costs and the button — a group that needed framing. It now holds ONE thing,
   the item card, and the card is already a framed page in its own right: a box around a box read as
   a black gradient bleeding out from behind the card. The column is bare and the card is the
   surface. */
.rpg-craft-detail { padding: 0; }
.rpg-craft-out { display: flex; align-items: center; gap: 9px; margin: 0 0 var(--sp-3);
  font-family: var(--font-display); font-size: 18px; color: var(--gold-hi); }
.rpg-craft-out .rpg-tile { position: static; width: 30px; height: 30px; inset: auto; }
.rpg-craft-out .rpg-icon { width: 30px; height: 30px; }
.rpg-craft-costs { display: flex; flex-direction: column; gap: 5px; }
.rpg-craft-cost { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-soft); }
.rpg-craft-cost .rpg-tile { position: static; width: 22px; height: 22px; inset: auto; font-size: 15px; }
.rpg-craft-cost .rpg-icon { width: 22px; height: 22px; }
.rpg-craft-cost-name { flex: 1 1 auto; }
.rpg-craft-cost-qty { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--ink); }
.rpg-craft-cost.is-short .rpg-craft-cost-qty { color: var(--ember); }
.rpg-craft-time { margin: var(--sp-3) 0; font-family: var(--font-quill); font-style: italic;
  font-size: 13px; color: var(--ink-quill); }
.rpg-craft-note { margin: var(--sp-3) 0; font-family: var(--font-quill); font-style: italic;
  font-size: 12px; color: var(--ink-quill); }
/* THE BATCH STEPPER. Sits between the ingredient list and the button, which is deliberate: the two
   numbers it moves — what this costs and how long it takes — are both directly above and below it,
   so raising the count is watched rather than discovered. */
.rpg-craft-batch { display: flex; align-items: center; gap: 8px; margin: var(--sp-3, 10px) 0 2px; }
.rpg-craft-step { width: 26px; height: 26px; padding: 0; line-height: 1; flex: none;
  border-radius: var(--r-1, 5px); border: 1px solid var(--glass-stroke, rgba(255,255,255,.10));
  background: var(--glass, rgba(255,255,255,.03)); color: var(--gold-hi);
  font: 600 16px var(--font-body); cursor: pointer; transition: border-color .13s; }
.rpg-craft-step:hover:not(:disabled) { border-color: var(--gold); }
.rpg-craft-step:disabled { opacity: .3; cursor: default; }
/* Tabular figures and a fixed width, so stepping 9 -> 10 does not shove the buttons sideways. */
.rpg-craft-batch-n { min-width: 2.2ch; text-align: center; font-family: var(--font-mono);
  font-variant-numeric: tabular-nums; font-size: 15px; color: var(--ink); }
/* What the BAG can feed, not what the bench allows — the honest ceiling, and the answer to "why
   will it not go higher". */
.rpg-craft-batch-max { font: italic 11px var(--font-quill); color: var(--ink-quill); }

.rpg-craft-go, .rpg-craft-cancel { width: 100%; padding: 9px 0; cursor: pointer;
  border-radius: var(--r-2); border: 1px solid var(--gold); background: rgba(201,164,110,.16);
  color: var(--gold-hi); font-family: var(--font-banner); font-size: 12px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; }
.rpg-craft-go:hover, .rpg-craft-cancel:hover { background: rgba(201,164,110,.28); }
.rpg-craft-go[disabled] { opacity: .4; cursor: not-allowed; }
.rpg-craft-cancel { border-color: var(--ember); color: var(--ember);
  background: rgba(255,122,82,.12); }
.rpg-craft-cancel:hover { background: rgba(255,122,82,.22); }
/* The bar is drawn from the SERVER's two numbers and clamps at full; see CraftPanel. */
.rpg-craft-bar { position: relative; height: 16px; border-radius: var(--r-pill); overflow: hidden;
  border: 1px solid var(--glass-stroke); background: rgba(10,8,26,.8); }
.rpg-craft-bar .fill { position: absolute; inset: 0; width: 0%; border-radius: var(--r-pill);
  background: linear-gradient(180deg, #e9c07a, #b7823c); transition: width .1s linear; }
 /* The label spans the whole bar, so it sits over the filled part for part of the craft and over
    the empty part for the rest. Light ink with a dark halo is legible on both; dark ink was legible
    on the gold and invisible on the well. */
.rpg-craft-bar .label { position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 11px; color: #fff3da;
  text-shadow: 0 1px 2px rgba(0,0,0,.85); }

/* THE FORGE — Hadric's anvil. LAYOUT ported EXACTLY from the old game's `smithy.ts` (owner
   explicitly liked it and asked for the same region arrangement): a SINGLE COLUMN, stage on top
   — Equipment + Catalyst input boxes, then a four-across Upgrade/Success/Duration/Cost stat row,
   then one big Forge button/the hammer-fall progress bar — and the "Choose an item" picker
   (Equipped/Unequipped tabs over an item grid) full-width BELOW it, matching the reference's
   `.shop-stage-body { display:flex; flex-direction:column }` stacking (forge-panel, then
   forge-picker) rather than a sidebar layout. Reuses `.rpg-recipe`/`.rpg-tabs`/`.rpg-craft-bar`/
   `.rpg-craft-cancel`/`.rpg-craft-out`/`.rpg-tile` wholesale (same picker rows, same tab strip,
   same progress bar and cancel button as the workbench); the box grid and the result modal are
   new to this panel. */
.rpg-forge { display: flex; flex-direction: column; gap: var(--sp-4); position: relative;
  margin-top: var(--sp-4); }
.rpg-forge-detail { display: grid; gap: var(--sp-3); align-content: start; min-width: 0; }
.rpg-forge-picker-panel { display: grid; gap: var(--sp-2); min-width: 0;
  border-top: 1px solid rgba(198,160,104,.18); padding-top: var(--sp-3); }
.rpg-forge-tabs { margin: 0 0 6px; }
.rpg-forge-picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 4px; max-height: 32vh; overflow-y: auto; padding-right: 2px; }
.rpg-forge-empty { color: var(--ink-dim, #a89bd0); font-size: 13px; padding: var(--sp-4) 0; }

/* The stat/input box grid — two boxes on top (Equipment/Catalyst), four across the info row
   (Upgrade/Success/Duration/Cost). Same card chrome for every box; only the eyebrow + content
   differ, matching the old view's `.forge-box` family. */
.rpg-forge-row { display: grid; gap: var(--sp-2); }
.rpg-forge-row--top { grid-template-columns: 1fr 1fr; }
.rpg-forge-row--info { grid-template-columns: repeat(4, 1fr); }
.rpg-forge-box { position: relative; display: grid; gap: 4px; align-content: start;
  padding: var(--sp-3) var(--sp-3) var(--sp-2); border-radius: var(--r-2);
  border: 1px solid var(--glass-stroke, rgba(201,164,110,.18));
  background: rgba(20,16,40,.42); min-width: 0; }
.rpg-forge-box--input.is-filled { border-color: var(--gold); }
.rpg-forge-box--input.is-locked { border-style: dashed; opacity: .7; }
.rpg-forge-box--input.is-empty { justify-items: center; text-align: center; color: var(--ink-mute); }
.rpg-forge-box-eyebrow { font-family: var(--font-banner); font-size: 10px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-mute, #9384b8); }
.rpg-forge-box-glyph { font-size: 22px; line-height: 1; opacity: .5; margin: 4px 0; }
.rpg-forge-box-art { width: 26px; height: 26px; }
.rpg-forge-box-art .rpg-icon, .rpg-forge-box-art img { width: 26px; height: 26px; }
.rpg-forge-box-line { font-size: 12px; color: var(--ink-soft); }
.rpg-forge-box-line strong { color: var(--ink); }
.rpg-forge-box-stock { font-family: var(--font-mono); font-size: 11px; color: var(--ink-dim, #cabcf0); }
.rpg-forge-box-stock.is-short { color: var(--ember); }
.rpg-forge-box-card { display: contents; }
.rpg-forge-box--info { text-align: left; }
.rpg-forge-box--info.is-cap { opacity: .55; }
.rpg-forge-box--info.is-safe { border-color: #8fe0a0; }
.rpg-forge-box--info.is-risky { border-color: var(--ember); }
.rpg-forge-box-big { font-family: var(--font-banner); font-size: 15px; font-weight: 600;
  color: var(--gold-hi); letter-spacing: .02em; }
.rpg-forge-box-big i { font-style: normal; margin-right: 3px; opacity: .8; }
.rpg-forge-box-arrow { color: var(--ink-mute); margin: 0 2px; }
.rpg-forge-box-delta { display: block; font-family: var(--font-mono); font-size: 11px;
  color: var(--ink-dim, #cabcf0); }

/* The big Forge button — one action, full width, unmissable. */
.rpg-forge-row--action { margin-top: 2px; }
.rpg-forge-go { width: 100%; padding: 12px 0; cursor: pointer; border-radius: var(--r-2);
  border: 1px solid var(--gold); background: rgba(201,164,110,.16); color: var(--gold-hi);
  font-family: var(--font-banner); font-size: 13px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; display: flex; align-items: center; justify-content: center; gap: 8px; }
.rpg-forge-go-glyph { font-size: 16px; }
.rpg-forge-go:hover { background: rgba(201,164,110,.28); }
.rpg-forge-go.is-short { opacity: .55; border-color: var(--ember); color: var(--ember); }
/* Mid-attempt: the picker inputs are gone (see `renderProgress`), just the hammer-fall bar. */
.rpg-forge-row--forging { display: grid; gap: var(--sp-2); }
/* z-index 42, ONE above `.rpg-itemcard`'s own 41 (rpg-ui.css ~1375) — the equipment box embeds
   that card inline (`.is-inline` only resets its position/size, not its tooltip z-index), so the
   result modal needs to outrank it explicitly or the success/destroyed flash renders BEHIND the
   card instead of over the whole stage. */
.rpg-forge-result { position: absolute; inset: 0; z-index: 42; display: grid; place-items: center; }
.rpg-forge-result:empty { display: none; }
/* DRAMATIC BUT CHEAP (owner's brief) — no new art, just a full-bleed colour flash and bold text. */
.rpg-forge-result-modal { display: grid; justify-items: center; gap: var(--sp-2);
  padding: var(--sp-6) var(--sp-8); border-radius: var(--r-3); text-align: center;
  animation: rpg-forge-flash .4s ease-out; }
.rpg-forge-result-modal.is-success { background: radial-gradient(circle, rgba(143,224,160,.22), rgba(20,16,40,.94));
  border: 1px solid #8fe0a0; box-shadow: 0 0 60px rgba(143,224,160,.35); }
.rpg-forge-result-modal.is-destroyed { background: radial-gradient(circle, rgba(255,60,40,.30), rgba(20,16,40,.96));
  border: 1px solid #ff3c28; box-shadow: 0 0 80px rgba(255,60,40,.5); }
.rpg-forge-result-modal h3 { font-family: var(--font-banner); font-size: 22px; letter-spacing: .1em;
  text-transform: uppercase; margin: 0; }
.rpg-forge-result-modal.is-success h3 { color: #8fe0a0; }
.rpg-forge-result-modal.is-destroyed h3 { color: #ff3c28; text-shadow: 0 0 18px rgba(255,60,40,.8); }
.rpg-forge-result-modal p { margin: 0; font-size: 13px; color: #fff3da; }
.rpg-forge-result-glyph { font-size: 40px; line-height: 1; }
.rpg-forge-shatter { animation: rpg-forge-shake .5s ease-in-out; filter: drop-shadow(0 0 12px rgba(255,60,40,.8)); }
.rpg-forge-result-dismiss { margin-top: var(--sp-2); padding: 7px 22px; cursor: pointer;
  border-radius: var(--r-pill); border: 1px solid var(--gold); background: rgba(201,164,110,.16);
  color: var(--gold-hi); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; }
.rpg-forge-result-dismiss:hover { background: rgba(201,164,110,.28); }
@keyframes rpg-forge-flash { from { opacity: 0; transform: scale(.92); } to { opacity: 1; transform: scale(1); } }
@keyframes rpg-forge-shake { 0%,100% { transform: translateX(0); } 20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); } 60% { transform: translateX(-4px); } 80% { transform: translateX(4px); } }
.rpg-craft-locked, .rpg-craft-empty { margin: var(--sp-3) 2px; font-family: var(--font-quill);
  font-style: italic; font-size: 13px; color: var(--ink-mute); }

/* WHERE DOES THIS GO? The equipped slot an item under the pointer — hovered, or being dragged —
   would fill. Gold like the hover border, but LIT rather than merely outlined: an empty gear slot
   is a dashed grey square, and against forty of them a border colour alone does not carry across
   the width of the window to wherever the player is actually looking.
   Turned solid for the moment it is lit, because the dashes are the "nothing here yet" affordance
   and this cell is, for now, spoken for. */
.rpg-slot.is-target { border-style: solid; border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold) inset, 0 0 12px var(--gold-glow, rgba(201,164,110,.4));
  background-color: #fdf6e3; }
/* The label comes back while the slot is lit, even on an occupied one: the cue is answering
   "which slot is that?", and an unlabelled highlight makes the player work it out from position. */
.rpg-slot.is-target .rpg-slot-tag { opacity: 1; }

