/* Slash filters: the funnel on the search bar, the two-stage menu under it, and the chips
   that land on the sort row beside Select. Theme tokens only — this file has to survive the
   dark / light / sakura switch the same way app.css does. */

.search-wrap { position: relative; }

#invChipFunnel {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; border-radius: 8px; cursor: pointer;
  display: grid; place-items: center; font-size: 15px; line-height: 1;
  background: transparent; border: 1px solid transparent; color: var(--muted);
}
#invChipFunnel:hover { color: var(--txt); border-color: var(--line2); background: var(--panel2); }
#invChipFunnel.on { color: var(--txt); border-color: var(--accent); background: var(--panel2); }
/* The input has to stop short of the funnel or long text runs underneath it. */
.search-wrap #searchInput { padding-right: 42px; }

#invChipMenu {
  display: none; position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 40;
  background: var(--panel); border: 1px solid var(--line2); border-radius: 11px;
  box-shadow: 0 12px 30px #0006; overflow: hidden; max-height: 320px; overflow-y: auto;
}
#invChipMenu.on { display: block; }
#invChipMenu .head {
  padding: 7px 11px; font-size: 11.5px; font-weight: 700; letter-spacing: .3px;
  color: var(--muted); border-bottom: 1px solid var(--line);
}
#invChipMenu .vlist { max-height: 260px; overflow-y: auto; }
#invChipMenu .row {
  display: flex; align-items: center; gap: 10px; padding: 8px 11px;
  cursor: pointer; font-size: 13px; color: var(--txt);
}
#invChipMenu .row.hi { background: var(--panel2); }
/* A rejected value is an error, not a fainter hint (Ian 2026-09-17: "take it as red"). */
#invChipMenu .row.dead { cursor: default; }
#invChipMenu .row.dead .k, #invChipMenu .row.dead .d { color: var(--red); }
#invChipMenu .row .k { font-weight: 700; white-space: nowrap; }
#invChipMenu .row .d { color: var(--muted); font-size: 12px; }
#invChipMenu .row .mt { color: var(--accent); }

/* Confirmed filters ride INSIDE the search bar, left of the caret, as
   files/01-inventory-catalog.html section 5 draws them.

   To be inside it, the bar has to BE a box. In app.css the border and background sit on the
   input and .search-wrap is only a positioning container, so anything added beside the input
   landed outside the visible bar. The chrome moves to the wrapper and the input goes
   transparent inside it. Scoped to #view-inventory so the customers panel search
   (.ct-top .search-wrap) keeps its own smaller treatment untouched.

   --panel rather than the per-theme input backgrounds in app.css: that token is what every
   theme redefines, so light and sakura follow without three more overrides. */
/* Half the row at rest, three quarters while you are typing in it, back to half when the caret
   leaves. Spec §2 says full width; 75% is Ian's call, because 100% shoves the four buttons
   beside it off the row entirely. At 75% they are covered while you type and back the moment
   you stop, which he is happy with. :focus-within does the whole job with no JS: the slash
   menu and the chips both live inside the wrapper, so picking a filter never counts as
   leaving it. flex-basis rather than width, because the toolbar is a flex row and the buttons
   beside it want the space back. min-width keeps it usable on a narrow window, where 50% of
   the row is not enough to type into. */
#view-inventory .search-wrap { flex: 0 1 50%; min-width: 220px; transition: flex-basis .16s ease; }
#view-inventory .search-wrap:focus-within { flex-basis: 75%; }

#view-inventory .search-wrap {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: var(--panel); border: 1px solid var(--line2); border-radius: 12px;
  padding: 6px 42px 6px 42px; transition: .15s;
}
#view-inventory .search-wrap:focus-within { border-color: var(--accent2); box-shadow: var(--glow-blue); }
#view-inventory .search-wrap input {
  flex: 1 1 90px; min-width: 90px; width: auto;
  background: transparent; border: 0; border-radius: 0; box-shadow: none;
  padding: 7px 0; font-size: 15px;
}
#view-inventory .search-wrap input:focus { outline: none; box-shadow: none; border-color: transparent; }

.search-wrap #invChips { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.search-wrap #invChips.hidden { display: none; }
.ichip {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 8px;
  border: 1px solid var(--line2); border-radius: 7px; background: var(--panel2);
  font-size: 12px; font-weight: 600; color: var(--txt); white-space: nowrap; line-height: 1.6;
}
.ichip .k { color: var(--accent2); font-weight: 700; }
.ichip button {
  border: 0; background: transparent; color: var(--muted); cursor: pointer;
  font-size: 11px; line-height: 1; padding: 3px; border-radius: 5px;
}
.ichip button:hover { color: var(--txt); background: var(--panel); }

/* Phone: chips wrap onto their own line inside the box rather than squeezing the caret out. */
@media (max-width: 767px) {
  #view-inventory .search-wrap { padding: 5px 40px 5px 38px; }
  .search-wrap #invChips { flex-basis: 100%; flex-wrap: wrap; order: 2; }
  #view-inventory .search-wrap input { order: 1; }
}

/* Phone. The bar is already tight at 390px, so chips wrap onto their own line and the
   explanatory note goes away rather than pushing the sort controls off the row. */
@media (max-width: 767px) {
  #invChips { flex-basis: 100%; order: 9; }
  .ichip-note { display: none; }
  #invChipMenu { max-height: 60vh; }
  #invChipMenu .vlist { max-height: calc(60vh - 40px); }
}

/* ---- THE ONE CONTROL ROW ----
   invControlRow() moves the My Inventory title and .inv-controls into #_sortBar, leaving
   #invHeader in the document as an empty anchor. It hides by rule rather than by inline style
   because runSearch() sets invHeader.style.display='' whenever the search box empties, which
   would flash an empty bordered row between the render and the next arrangement pass. */
#invHeader { display: none !important; }

#_sortBar { flex-wrap: wrap; }
#_invTitle { margin: 0; white-space: nowrap; }
#_invFilterBtn { white-space: nowrap; }

/* Phone. .inv-controls carries its own two breakpoints in app.css keyed to ids inside it, and
   those still apply — it is the same element, just reparented. All that is needed here is to
   let it take its own line instead of fighting the sort select for width. */
@media (max-width: 767px) {
  #_sortBar { row-gap: 8px; }
  #_invControls { margin-left: 0 !important; flex-basis: 100%; }
  #_invTitle { flex-basis: 100%; }
}

/* ---- THE CARD TILE ----
   Ledger Glass is the redesign's tile (see cardBlockMode). Two things the prototype does that
   the shipped block does not:

   1. The three stat boxes become ONE bubble, label and number on a line. Three bordered boxes
      under every tile is most of why the grid reads as busy.
   2. The art is height-capped. Uncapped, a 63x88 card at a quarter of a 1440px window is
      ~450px tall and a single row fills the laptop — you scroll a screen per four cards. The
      cap is min(280px, 32vh) so it also shrinks on a short window rather than a narrow one. */
/* Three separate stat boxes, as files/01-inventory-catalog.html section 4 draws them:
   [ Cost C$1,500 ] [ 2d ] [ ▲ C$700 ]. This replaces the single pill the prototype used; Ian
   picked the mockup. Specificity, not !important: team.css declares the same three selectors
   and loads later in the head, so .lg-card .lg-cap .lg-stats at (0,3,0) beats its (0,1,0). */
.lg-card .lg-cap .lg-stats {
  display: flex; align-items: stretch; gap: 5px; margin-top: 7px;
  border: 0; border-top: 0; padding-top: 0; background: none;
}
.lg-card .lg-cap .lg-stats .lg-stat {
  flex: 1 1 0; min-width: 0; display: flex; align-items: baseline; justify-content: center;
  gap: 4px; padding: 3px 6px; text-align: center;
  border: 1px solid rgba(255, 255, 255, .13); border-radius: 7px;
  background: rgba(255, 255, 255, .04);
  font: 600 9px ui-monospace, Menlo, monospace; letter-spacing: .06em; text-transform: uppercase;
  color: #8b93a7; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lg-card .lg-cap .lg-stats .lg-stat + .lg-stat { border-left: 1px solid rgba(255, 255, 255, .13); padding-left: 6px; }
.lg-card .lg-cap .lg-stats .lg-stat b { font-size: 11px; color: #c8cfdc; letter-spacing: 0; text-transform: none; }
/* "Margin box on normal cards auto-colors: green up, red down." */
.lg-card .lg-cap .lg-stats .lg-stat.up b { color: var(--green); }
.lg-card .lg-cap .lg-stats .lg-stat.down b { color: var(--red); }

/* No height cap (Ian 2026-09-11): a min(280px, 32vh) max-height sat here and cropped the card
   in the 4- and 6-wide grids. The frame is a true 63:88 card ratio (app.css, .grid.cols4/6),
   so the block now grows down until the whole card shows; the track width is untouched. */
.lg-card .lg-ph, .lg-card .imgwrap { overflow: hidden; }
.lg-card .lg-ph img, .lg-card .imgwrap img { object-fit: cover; }

/* ---- THE FILTER ROW ----
   The row under the search bar. It held the slash-command hints; it now holds the button that
   opens the same menu, which is what Ian asked for and what stays useful past week one. */
#invFilterRow {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 2px 0 8px;
}
#invFilterRow:empty { display: none; }
#_invFilterBtn { white-space: nowrap; }

/* ---- CONTROLS THE REDESIGN DOES NOT DRAW (Ian, 2026-09-09) ----
   Hidden rather than deleted, and hidden from CSS rather than by editing games.js. All three
   are injected at runtime by games.js on a lifecycle that re-adds them whenever the add-on
   flag changes or the window resizes, so removing the node is a fight the stylesheet wins
   permanently and a patch would keep losing. The ids stay in the document, which is what the
   Inventory help tour and games.js's own scope handling need. */
#btnPcGames { display: none !important; }          /* 🎮 Video games — reached from the search bar */
#invKindSeg { display: none !important; }          /* All / Pokémon / 🎮 Games kind segment */
#searchScope [data-scope="games"] { display: none !important; }

/* Set · number on their own line under the name, as the prototype's .st row draws them. Ian
   decluttered the set off the tile on 2026-07-25; the redesign puts it back, because two cards
   that share a number across two sets are otherwise indistinguishable on the grid. */
.lg-card .lg-cap .lg-set {
  font-size: 11px; font-weight: 600; color: #aab2c5; margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Viewer mode: spec §8's light dark tint over the card art, so a buyer holding the screen sees
   the numbers as the subject and the art as backdrop. Art only — the caption sits above it. */
body.viewer-on .lg-card .lg-ph::after,
body.viewer-on .pcard .imgwrap::after {
  content: ''; position: absolute; inset: 0; background: rgba(10, 12, 18, .35);
  pointer-events: none; border-radius: inherit;
}
body.viewer-on .lg-card .lg-ph, body.viewer-on .pcard .imgwrap { position: relative; }

/* ---- 👁 VIEWER IN THE HEADER ----
   Sits right of the tabs, shown only on Inventory. See 07-invViewerButton.js for why it left
   the control row: app.css hides #_sortBar entirely in viewer mode, and the control row now
   lives in that bar, so the button that turns viewer mode OFF was hiding with it. */
header #btnViewer.hdr-viewer { margin-left: 8px; flex: 0 0 auto; white-space: nowrap; }
header #btnViewer.hdr-viewer.hidden { display: none !important; }
@media (max-width: 767px) {
  header #btnViewer.hdr-viewer { margin-left: 6px; padding: 0 10px; font-size: 12px; }
}

/* ---- HEADER: the in-stock count takes the sale chip's place (Ian, 2026-09-10) ----
   #activeSaleChip is hidden, not deleted: Ian's call was "have it work in the background", and
   the state behind it is what multi-sale uses to know which sale an add is filling.
   #invPill already exists in the header and already carries the count with no emoji, so it is
   un-hidden rather than replaced. app.css hides it with !important, hence the same here at a
   higher specificity. #invStockLine, the toolbar's emoji copy, goes: one count is enough. */
header #activeSaleChip { display: none !important; }
header #invPill { display: inline-block !important; }
#invStockLine { display: none !important; }

/* ---- PREPARE FOR OFFLINE SHOW: small, yellow, far right of the Filters row ---- */
#invFilterRow #btnPrepareOffline.prep-right {
  margin-left: auto;
  font-size: 80%; padding: 6px 12px; line-height: 1.2;
  background: transparent; border: 1px solid var(--accent); color: var(--accent);
  white-space: nowrap;
}
#invFilterRow #btnPrepareOffline.prep-right:hover {
  background: rgba(255, 203, 5, .10); border-color: var(--accent);
}

/* Phone: the funnel is the only way into the filters and measured 30px on a 390px screen. */
@media (max-width: 767px) {
  #invChipFunnel { width: 44px; height: 44px; right: 2px; }
  /* This screen's wrapper reserves the room, not the input: its own input rule zeroes side padding. */
  #view-inventory .search-wrap { padding-right: 50px; }
}

/* The stock reminder on a database tile or picker row: its own small line under the name. */
.stock-line { display: block; flex-basis: 100%; width: 100%; font-size: 10.5px; line-height: 1.3; margin: 1px 0; }
