/* ============================================================================
   INVENTORY — the manager's section (public/manager-inventory.js).

   Everything is scoped to .inv-page, the node the module mounts next to #cards,
   so nothing here can reach another page of the app. Every colour, radius, tap
   size and type step comes from system.css; nothing is retyped.

   This file used to style a standalone page — nine category chips, a category
   editor, a five-photo strip, a pinch-crop stage, a bottom nav of its own, a stats
   grid and an import gallery. All of that went with the page. What is left is a
   list, two sheets, and the one piece of geometry that decides whether the screen
   is usable at all: the typing row does not move.
   ========================================================================== */

.inv-page{
  --ink:var(--sys-ink);--gray:var(--sys-muted);--hair:var(--sys-line);--card:var(--sys-panel);
  --blue:var(--sys-accent);--blue-bg:var(--sys-accent-soft);--red:var(--sys-red-ink);--red-bg:var(--sys-red-soft);
  --amber:var(--sys-orange);--amber-bg:var(--sys-orange-soft);--green:var(--sys-green);--green-bg:var(--sys-green-soft);
  --spring:cubic-bezier(.34,1.35,.5,1);
  font-family:var(--sys-font);color:var(--ink);
  font-variant-numeric:tabular-nums;-webkit-font-smoothing:antialiased;
  display:block;
}
.inv-page *{box-sizing:border-box}

/* The ONE search field, written once and never re-rendered — only #invBody is
   replaced. Rebuilding a focused input underneath iOS's keyboard is what made the
   old standalone page feel broken. 16px, or iOS zooms the page in on focus and
   never zooms back out. */
.inv-page .inv-search{width:100%;min-height:46px;padding:0 14px;font:inherit;font-family:inherit;font-size:16px;
  border:0;border-radius:var(--sys-r-control);background:var(--card);color:var(--ink);
  box-shadow:var(--sys-shadow-card);margin-bottom:12px}
.inv-page .inv-search::placeholder{color:var(--sys-placeholder)}
.inv-page .inv-search:focus{outline:2px solid var(--blue);outline-offset:-2px}

/* THREE NUMBERS, NOT THREE WORDS.
   The row that stood here read "At jobs · Storage · No photo" — you had to guess
   what tapping one would do, and then it did nothing, because the filter behind it
   was never written ("no entiendo este menú, es horrible"). A number says what you
   get before you touch it; the one in force wears the ring. */
/* The three number-cards that stood here until 2026-09-24 are gone: two of them
   were place filters and the third was a chore, wearing one row. The rail above
   (.inv-seg) is the filter; the chore is .inv-chore; the shelf is a pinned card. */
/* A place: Storage, or one job. The whole card is the target, and its shapes are
   the Houses card's — that is the card he already reads every day. */
.inv-page .inv-place{display:block;width:100%;text-align:left;font:inherit;font-family:inherit;color:inherit;cursor:pointer;
  border:0;border-radius:var(--sys-r-card);background:var(--card);box-shadow:var(--sys-shadow-card);
  padding:14px;margin-bottom:10px}
.inv-page .inv-place:active{transform:scale(.995)}
.inv-page .inv-plhead{display:flex;align-items:center;gap:8px}
/* The shouted street tag that used to sit above every address is gone (2026-09-25):
   it repeated the title, and on the Storage card it printed STORAGE over "Storage". */
.inv-page .inv-pill{padding:3px 9px;border-radius:var(--sys-r-pill);font-size:var(--sys-t-caption);font-weight:var(--sys-w-semibold)}
.inv-page .inv-pill.green{background:var(--green-bg);color:var(--green)}
.inv-page .inv-pill.amber{background:var(--amber-bg);color:var(--amber)}
.inv-page .inv-pill.blue{background:var(--blue-bg);color:var(--blue)}
.inv-page .inv-pill.grey{background:var(--sys-fill);color:var(--gray)}
.inv-page .inv-plname{display:block;font-size:19px;font-weight:var(--sys-w-bold);letter-spacing:-.01em;margin-top:8px}
.inv-page .inv-plchev{margin-left:auto;font-size:17px;color:var(--sys-faint)}

/* WHAT IS IN IT, not how many. The strip of covers is the point of the card: you
   read the room at a glance instead of reading a number and imagining it. A job
   holding nothing shows one dashed slot, and that slot IS the invitation. */
.inv-page .inv-strip{display:flex;align-items:center;gap:6px;margin-top:10px}
.inv-page .inv-tile{width:48px;height:48px;flex:none;border-radius:10px;overflow:hidden;background:var(--sys-fill-2);
  display:grid;place-items:center;font-size:13px;font-weight:var(--sys-w-bold);color:var(--gray)}
.inv-page .inv-tile img{width:100%;height:100%;object-fit:cover;display:block}
.inv-page .inv-tile.add{background:transparent;box-shadow:0 0 0 1px var(--hair) inset;color:var(--blue);font-size:19px;font-weight:var(--sys-w-medium)}
.inv-page .inv-tile.more{background:var(--sys-fill);color:var(--gray)}
.inv-page .inv-tile.letter{background:var(--sys-fill);color:var(--sys-muted);font-size:17px}
.inv-page .inv-invite{font-size:14px;font-weight:var(--sys-w-semibold);color:var(--blue);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* THE ROOM, IN PICTURES. One tile per piece — inside a house, and again for the
   pieces still missing a photo. The square is the camera, the name is the piece. */
.inv-page .inv-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:2px 0 4px}
.inv-page .inv-cell{position:relative;min-width:0}
.inv-page .inv-cell.marked .inv-shot{box-shadow:0 0 0 2px var(--blue)}
.inv-page .inv-shot{position:relative;display:grid;place-items:center;width:100%;aspect-ratio:1;padding:0;
  border:0;border-radius:14px;overflow:hidden;background:var(--sys-fill-2);color:var(--blue);
  font:inherit;font-family:inherit;font-size:26px;cursor:pointer}
.inv-page .inv-shot img{width:100%;height:100%;object-fit:cover;display:block}
.inv-page .inv-shot.add{background:var(--card);box-shadow:0 0 0 1px var(--hair) inset}
/* No photo, and no way to add one from here: the initial, as on the list cards (UI-157). */
.inv-page .inv-shot.letter{background:var(--sys-fill);color:var(--sys-muted);font-weight:var(--sys-w-semibold)}
.inv-page .inv-shot.letter .inv-qbadge{background:var(--sys-fill-2);color:var(--gray)}
.inv-page .inv-shot:active{opacity:.7}
.inv-page .inv-qbadge{position:absolute;left:7px;top:7px;padding:2px 8px;border-radius:var(--sys-r-pill);
  background:rgba(0,0,0,.55);color:#fff;font-size:var(--sys-t-caption);font-weight:var(--sys-w-bold)}
.inv-page .inv-shot.add .inv-qbadge{background:var(--sys-fill);color:var(--gray)}
/* The × that takes a line back. Its TARGET is the house rule's full tap square;
   what you see is a 28px disc inside it, so the corner of a photo is not eaten by
   a button. Shrinking the target to the disc is the bug this spelling avoids. */
.inv-page .inv-x.cell{position:absolute;right:-6px;top:-6px;width:var(--sys-tap);height:var(--sys-tap);
  border-radius:50%;color:var(--sys-muted);font-size:16px;line-height:var(--sys-tap);text-align:center;
  background:radial-gradient(circle at center,rgba(255,255,255,.96) 0 14px,transparent 14px)}
.inv-page .inv-x.cell:active{background:radial-gradient(circle at center,var(--sys-fill) 0 14px,transparent 14px)}
.inv-page .inv-cellname{display:block;width:100%;margin-top:6px;padding:0;border:0;background:none;text-align:left;
  font:inherit;font-family:inherit;font-size:13px;font-weight:var(--sys-w-semibold);color:inherit;cursor:pointer;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.inv-page .inv-cellsub{min-height:16px;font-size:var(--sys-t-caption);color:var(--gray);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.inv-page .inv-cellsub .blue{color:var(--blue)}
.inv-page .inv-cell .inv-mark{width:100%;min-width:0;margin-top:6px}

/* A piece: thumbnail, name with its count, and where it is. */
.inv-page .inv-row{display:flex;align-items:center;gap:11px;width:100%;background:var(--card);
  border:0;color:inherit;border-radius:14px;padding:9px 11px;margin-bottom:7px;
  cursor:pointer;text-align:left;font:inherit;font-family:inherit}
.inv-page .inv-row:active{transform:scale(.995)}
.inv-page .rw{flex:1;min-width:0}
.inv-page .rn{display:block;font-size:15px;font-weight:var(--sys-w-semibold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.inv-page .rm{display:block;font-size:var(--sys-t-caption);color:var(--gray);margin-top:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.inv-page .rq{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:var(--sys-r-pill);
  background:var(--sys-fill);font-size:var(--sys-t-micro);font-weight:var(--sys-w-bold);vertical-align:1px}
.inv-page .inv-here{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:var(--sys-r-pill);
  background:var(--blue-bg);color:var(--blue);font-size:var(--sys-t-micro);font-weight:var(--sys-w-bold);vertical-align:1px}
.inv-page .chev{flex:none;color:var(--sys-faint);font-size:17px}

/* The picture. A piece with none wears its first letter — never an emoji that says
   "box" for a sofa, and never a blank square that reads as broken. */
.inv-page .pic{width:44px;height:44px;flex:none;border-radius:10px;overflow:hidden;background:var(--sys-fill-2);
  display:grid;place-items:center;font-size:17px;font-weight:var(--sys-w-bold);color:var(--sys-faint)}
.inv-page .pic img{width:100%;height:100%;object-fit:cover;display:block}
/* The letter square, spelled out rather than inherited: inside the manager shell the
   fill token sits on a white card and the placeholder read as an empty box. */
.inv-page .pic.inv-blank{background:var(--sys-fill);color:var(--sys-muted);padding:0;box-shadow:none;border:0}
/* NOT UPPERCASED ANY MORE. This class labels a group, and it was also being given
   whole sentences and Mario's OWN category names — so a category he typed
   "Consoles" arrived on screen as CONSOLES, and an instruction shouted. A label is
   small, grey and spaced; it does not need to raise its voice to be a label. */
.inv-page .inv-lab{font-size:var(--sys-t-caption);font-weight:var(--sys-w-semibold);letter-spacing:0;
  color:var(--gray);margin:16px 2px 7px}

/* -------------------------------- controls -------------------------------- */
.inv-page .inv-btn{display:block;width:100%;min-height:48px;margin-top:10px;border:0;border-radius:var(--sys-r-pill);
  background:var(--blue);color:#fff;font:inherit;font-family:inherit;font-size:16px;font-weight:var(--sys-w-semibold);cursor:pointer}
.inv-page .inv-btn:active{transform:scale(.99)}
.inv-page .inv-btn[disabled]{opacity:.45;cursor:default}
.inv-page .inv-btn.ghost{background:var(--card);color:var(--blue);box-shadow:0 0 0 1px var(--hair) inset}
.inv-page .inv-btn.danger{background:transparent;color:var(--red);box-shadow:0 0 0 1px var(--red-bg) inset}
.inv-page .inv-x{width:var(--sys-tap);height:var(--sys-tap);flex:none;border:0;background:none;font:inherit;font-family:inherit;
  font-size:20px;line-height:1;color:var(--gray);cursor:pointer;border-radius:10px}
.inv-page .inv-x:active{background:var(--sys-press-a)}
.inv-page .inv-mark{flex:none;min-width:70px;min-height:38px;border:0;border-radius:var(--sys-r-pill);
  background:var(--sys-fill);color:var(--gray);font:inherit;font-family:inherit;font-size:13px;font-weight:var(--sys-w-semibold);cursor:pointer}
.inv-page .inv-mark.on{background:var(--blue);color:#fff}
.inv-page .inv-qty{display:flex;align-items:center;gap:2px;flex:none;padding:3px;background:var(--sys-fill);border-radius:var(--sys-r-control)}
.inv-page .inv-qbtn{width:var(--sys-tap);height:var(--sys-tap);border:0;background:none;font-family:inherit;
  font-size:20px;line-height:1;color:var(--blue);cursor:pointer;border-radius:9px}
.inv-page .inv-qbtn:active{background:var(--sys-press-a)}
.inv-page .inv-qn{min-width:26px;text-align:center;font-size:var(--sys-t-lead);font-weight:var(--sys-w-bold)}

/* --------------------------------- states --------------------------------- */
.inv-page .inv-empty{background:var(--card);border-radius:var(--sys-r-card);padding:26px 18px;text-align:center;margin:8px 0}
.inv-page .inv-empty .t{font-size:17px;font-weight:var(--sys-w-semibold)}
.inv-page .inv-empty .d{font-size:var(--sys-t-caption);color:var(--gray);margin-top:4px}
.inv-page .inv-err{color:var(--red);font-size:var(--sys-t-caption);margin-top:8px}
/* The same slot says the good news too, and it must not say it in the colour of
   a refusal: "On the pull sheet for 778 Kalamath St." in red reads as a failure. */
.inv-page .inv-err.ok{color:var(--green)}
.inv-page .inv-state{display:grid;place-items:center;min-height:30dvh}
.inv-page .inv-pulse{width:26px;height:26px;border-radius:50%;background:var(--hair);animation:invpulse 1s var(--sys-ease) infinite alternate}
@keyframes invpulse{from{opacity:.35;transform:scale(.85)}to{opacity:1;transform:scale(1)}}

/* --------------------------------- the sheets ----------------------------- */
.inv-page .inv-scrim{position:fixed;inset:0;background:var(--sys-scrim);z-index:var(--sys-z-scrim);
  opacity:0;pointer-events:none;transition:opacity .25s}
.inv-page .inv-scrim.on{opacity:1;pointer-events:auto}
.inv-page .inv-sheet{position:fixed;box-sizing:border-box;bottom:var(--sys-dock-bottom);left:var(--sys-center-x);
  transform:translate(-50%,105%);width:min(560px,var(--sys-usable-w));background:var(--card);
  border-radius:var(--sys-r-sheet) var(--sys-r-sheet) 0 0;box-shadow:var(--sys-shadow-sheet);
  z-index:var(--sys-z-sheet);padding:10px 18px calc(20px + var(--sys-safe-b));
  transition:transform .35s var(--spring);overflow-y:auto;-webkit-overflow-scrolling:touch;
  max-height:calc(var(--sys-kb-view-h) - 8dvh - var(--sys-safe-t))}
.inv-page .inv-sheet.on{transform:translate(-50%,0)}
html.kb-open .inv-page .inv-sheet{padding-bottom:20px}
.inv-page .inv-grab{width:38px;height:4px;border-radius:2px;background:var(--hair);margin:0 auto 12px;flex:none}

/* ======================= THE HOUSE'S OWN PAGE =============================

   IT IS A PAGE, NOT A SHEET. A sheet left the list of jobs sliding behind it
   ("mueve las casas de atrás") and put the address halfway down the screen. This
   covers the phone: the list under it is hidden, the section header is hidden with
   it, and the screen carries its own Back.

   THE ONE RULE OF THE SCREEN, unchanged from the sheet it replaces: the typing row
   never moves. Anything that appears above the field would push it away from the
   keyboard — and the suggestion list changes on every letter. So the screen is a
   FIXED-height flex column anchored to the bottom, the row is its LAST child, and
   the lines and the suggestions scroll between the header and the row. */
/* Pinned to BOTH edges of the window rather than given a dvh height: 100dvh is the
   viewport Safari has with its bars hidden, so a page that tall hangs below the one
   you can see and the header walks off the top the moment a field takes focus. Top
   and bottom, and the column is exactly the window — and with the keyboard up,
   --sys-dock-bottom is its height, so the bottom rises to meet it. */
.inv-page .inv-scrn{position:fixed;box-sizing:border-box;display:none;flex-direction:column;
  left:var(--sys-center-x);transform:translateX(-50%);width:min(560px,var(--sys-usable-w));
  top:0;bottom:var(--sys-dock-bottom);
  background:var(--sys-page);z-index:var(--sys-z-fullscreen);
  padding:calc(10px + var(--sys-safe-t)) 18px var(--sys-safe-b);overflow:hidden}
.inv-page .inv-scrn.on{display:flex}
/* In the native shell the window already clears the clock, so the page must not pay
   the top inset twice. html.ni-top, never html.native-app: the shell's own inset
   changes with the scroll state and only this class tracks it (public/native-inset.js). */
html.ni-top .inv-page .inv-scrn{padding-top:10px}
html.kb-open .inv-page .inv-scrn{padding-top:10px}
/* The typing row is a white bar to the screen's edges. On the page's grey ground a
   grey field and a grey stepper have no edges at all — on the sheet they sat on
   white and that is the contrast they were drawn for.
   The screen pays the home-indicator inset (above); the bar's own white is allowed
   back over it by the same amount and re-pays it as padding, so the colour reaches
   the edge of the glass while nothing readable or tappable does. */
.inv-page .inv-scrn .inv-flrow{margin:8px -18px calc(-1 * var(--sys-safe-b));
  padding:10px 18px calc(10px + var(--sys-safe-b));
  background:var(--card);border-top:1px solid var(--hair)}
html.kb-open .inv-page .inv-scrn .inv-flrow{padding-bottom:10px}
/* The list is hidden, not dimmed: nothing behind the page can move. */
.inv-page.screen-on .inv-list{display:none}
/* …and the piece's sheet still opens ON TOP of the page it was opened from. */
.inv-page.screen-on .inv-sheet{z-index:calc(var(--sys-z-fullscreen) + 2)}
.inv-page.screen-on .inv-scrim{z-index:calc(var(--sys-z-fullscreen) + 1)}

.inv-page .inv-scrnhd{flex:none;display:flex;align-items:flex-start;gap:10px;margin-bottom:10px}
.inv-page .inv-scrnback{width:var(--sys-tap);height:var(--sys-tap);flex:none;border:0;border-radius:50%;
  background:var(--card);box-shadow:var(--sys-shadow-card);color:var(--blue);
  font:inherit;font-family:inherit;font-size:19px;line-height:1;cursor:pointer}
.inv-page .inv-scrnback:active{background:var(--sys-press-a)}
.inv-page .inv-scrnttl{flex:1;min-width:0;padding-top:1px}
.inv-page .inv-scrnttl .t{font-size:var(--sys-t-title);font-weight:var(--sys-w-bold);letter-spacing:-.01em;
  line-height:1.15;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.inv-page .inv-scrnttl .d{font-size:var(--sys-t-caption);color:var(--gray);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.inv-page .inv-flscroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;margin:0 -4px;padding:0 4px}
.inv-page .inv-flrow{flex:none;display:flex;align-items:center;gap:8px;padding-top:10px;
  border-top:1px solid var(--hair);margin-top:8px}
.inv-page .inv-flrow.two{gap:10px}
.inv-page .inv-flrow.two .inv-btn{margin-top:0}
/* 16px: below it iOS zooms the page in on focus and never zooms back out. */
.inv-page .inv-flname{flex:1;min-width:0;min-height:46px;padding:0 12px;font:inherit;font-family:inherit;font-size:16px;
  border:0;border-radius:var(--sys-r-control);background:var(--sys-fill);color:var(--ink)}
.inv-page .inv-flname::placeholder{color:var(--sys-placeholder)}
.inv-page .inv-flname:focus{outline:2px solid var(--blue);outline-offset:-2px}
.inv-page .inv-cam{width:46px;height:46px;flex:none;padding:0;border:0;border-radius:var(--sys-r-control);
  background:var(--sys-fill);color:var(--blue);font:inherit;font-family:inherit;font-size:20px;cursor:pointer;
  display:grid;place-items:center;overflow:hidden}
.inv-page .inv-cam .pic{width:46px;height:46px;border-radius:var(--sys-r-control)}
.inv-page .inv-cam:active{background:var(--sys-press-a)}
.inv-page .inv-add{flex:none;min-width:62px;min-height:46px;padding:0 14px;border:0;border-radius:var(--sys-r-pill);
  background:var(--blue);color:#fff;font:inherit;font-family:inherit;font-size:15px;font-weight:var(--sys-w-semibold);cursor:pointer}
.inv-page .inv-add[disabled]{opacity:.45}
/* The chosen piece: the accent ring says "this line is going INTO that", which is
   the one thing on this screen he must not misread. */
.inv-page .inv-pick{display:flex;align-items:center;gap:11px;background:var(--blue-bg);
  box-shadow:0 0 0 1.5px var(--blue) inset;border-radius:14px;padding:9px 11px;margin:8px 0 0}

/* --------------------------------- one piece ------------------------------ */
.inv-page .inv-kcover{position:relative;width:100%;aspect-ratio:4/3;border-radius:var(--sys-r-card);
  overflow:hidden;background:var(--sys-fill-2);display:grid;place-items:center;cursor:pointer;margin-bottom:12px}
.inv-page .inv-kcover .pic{width:100%;height:100%;border-radius:0;font-size:40px}
.inv-page .inv-kcam{position:absolute;left:0;right:0;bottom:0;padding:8px 12px;text-align:center;
  font-size:13px;font-weight:var(--sys-w-semibold);color:#fff;background:linear-gradient(transparent,rgba(0,0,0,.55))}
.inv-page .inv-kname{width:100%;min-height:48px;padding:0 14px;font:inherit;font-family:inherit;font-size:17px;
  font-weight:var(--sys-w-semibold);border:0;border-radius:var(--sys-r-control);background:var(--sys-fill);color:var(--ink)}
.inv-page .inv-kwhere{font-size:var(--sys-t-caption);color:var(--gray);margin:8px 2px 0;line-height:var(--sys-line-body)}
.inv-page .inv-krow{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:14px}
.inv-page .inv-klab{font-size:var(--sys-t-caption);color:var(--gray)}

/* A place that is not a door: "in transit" and "sold with the home" have no intake
   behind them, so the card is told, not tapped. */
.inv-page .inv-place.static{cursor:default}
.inv-page .inv-place.static:active{transform:none}

/* ======================= ＋ : THE TWO ANSWERS =============================

   The page holds still; adding happens in a sheet over it. These sheets are the
   only place a keyboard appears, and they keep the geometry the page used to have:
   a FIXED-height flex column whose LAST child is the row you type into, so a
   suggestion, a category or an error can never push the field off the keyboard. */
.inv-page .inv-sheet.inv-fl{display:flex;flex-direction:column;
  height:calc(var(--sys-kb-view-h) - 8dvh - var(--sys-safe-t));
  max-height:none;overflow:hidden}
.inv-page .inv-flhead{flex:none;margin-bottom:8px}
.inv-page .inv-flttl{font-size:var(--sys-t-title);font-weight:var(--sys-w-bold);letter-spacing:-.01em}
.inv-page .inv-flhint{font-size:var(--sys-t-caption);color:var(--gray);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* The button that opens them: one target, the width of the phone, with no keyboard
   behind it until he asks. */
.inv-page .inv-big{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;
  min-height:52px;border:0;border-radius:var(--sys-r-pill);background:var(--blue);color:#fff;
  font:inherit;font-family:inherit;font-size:16px;font-weight:var(--sys-w-semibold);cursor:pointer}
.inv-page .inv-big:active{transform:scale(.99)}
.inv-page .inv-big[disabled]{opacity:.45;cursor:default}
.inv-page .inv-bigplus{font-size:19px;line-height:1}

/* The chooser: two answers, each one a card that says what it will ask for. */
.inv-page .inv-shttl{font-size:var(--sys-t-title);font-weight:var(--sys-w-bold);letter-spacing:-.01em;margin-bottom:10px}
.inv-page .inv-choice{display:flex;align-items:center;gap:12px;width:100%;padding:14px;margin-bottom:8px;
  border:0;border-radius:var(--sys-r-card);background:var(--card);box-shadow:0 0 0 1px var(--hair) inset;
  text-align:left;font:inherit;font-family:inherit;color:inherit;cursor:pointer}
.inv-page .inv-choice:active{background:var(--sys-press-a)}
.inv-page .inv-choice .ic{width:38px;height:38px;flex:none;border-radius:12px;background:var(--blue-bg);
  color:var(--blue);display:grid;place-items:center;font-size:19px}
.inv-page .inv-choice .tx{flex:1;min-width:0}
.inv-page .inv-choice .t{display:block;font-size:var(--sys-t-lead);font-weight:var(--sys-w-semibold)}
.inv-page .inv-choice .d{display:block;font-size:var(--sys-t-caption);color:var(--gray);margin-top:2px}

/* Categories: his own list, as chips, with the one he is on wearing the ink. The
   ＋ is only there for a manager, because only a manager may write the list. */
.inv-page .inv-chips{display:flex;flex-wrap:wrap;gap:7px}
/* A chip is a control he taps with a thumb in a warehouse: the house floor is
   var(--sys-tap), and a category is no exception. */
.inv-page .inv-chip{min-height:var(--sys-tap);padding:0 16px;border:0;border-radius:var(--sys-r-pill);
  background:var(--sys-fill);color:var(--ink);font:inherit;font-family:inherit;font-size:14px;
  font-weight:var(--sys-w-medium);cursor:pointer}
.inv-page .inv-chip.on{background:var(--blue);color:#fff;font-weight:var(--sys-w-semibold)}
.inv-page .inv-chip.new{background:transparent;color:var(--blue);box-shadow:0 0 0 1px var(--hair) inset}
.inv-page .inv-catnew{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.inv-page .inv-catin{flex:1;min-width:0;min-height:44px;padding:0 12px;font:inherit;font-family:inherit;font-size:16px;
  border:0;border-radius:var(--sys-r-control);background:var(--sys-fill);color:var(--ink)}
.inv-page .inv-catin:focus{outline:2px solid var(--blue);outline-offset:-2px}
.inv-page .inv-catgo{flex:none;min-height:44px;padding:0 16px;border:0;border-radius:var(--sys-r-pill);
  background:var(--blue);color:#fff;font:inherit;font-family:inherit;font-size:15px;font-weight:var(--sys-w-semibold);cursor:pointer}
.inv-page .inv-catx{width:var(--sys-tap);height:var(--sys-tap);flex:none;border:0;background:none;
  font:inherit;font-family:inherit;font-size:20px;color:var(--gray);cursor:pointer;border-radius:10px}

/* The optional photo, at the top of the new-piece sheet. */
.inv-page .inv-nsphoto{display:flex;align-items:center;gap:12px;margin-bottom:4px}
.inv-page .inv-nsphoto .inv-shot{width:96px;height:96px;flex:none;aspect-ratio:auto}
.inv-page .inv-nshint{font-size:var(--sys-t-caption);color:var(--gray)}

/* Where the units he is adding come from — the shelf, or bought — over the row,
   the full width of the sheet, because it is the line that decides (UI-156). */
.inv-page .inv-hvplan{flex:none;padding-top:10px;font-size:var(--sys-t-body);font-weight:var(--sys-w-semibold);color:var(--sys-ink)}
.inv-page .inv-hvplan:empty{display:none}
/* The piece he picked, sitting in the typing row where the field would be. */
.inv-page .inv-picked{flex:1;min-width:0;display:flex;align-items:center;gap:9px}
.inv-page .inv-picked .rn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:var(--sys-t-lead);font-weight:var(--sys-w-semibold)}

/* Your categories: a row per name, its count, a tap to rename and an × that asks
   where the pieces go. The server decides all three; this only asks. */
.inv-page .inv-catrow{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.inv-page .inv-catrow.gone{background:var(--red-bg);border-radius:14px;padding:10px 12px}
.inv-page .inv-catname{flex:1;min-width:0;min-height:var(--sys-tap);padding:0 12px;border:0;border-radius:14px;
  background:var(--card);box-shadow:0 0 0 1px var(--hair) inset;text-align:left;
  font:inherit;font-family:inherit;color:inherit;cursor:pointer}
.inv-page .inv-catrow .inv-btn{margin-top:0}

/* The one control in this section that destroys something: the quietest type on the
   screen, at the very bottom, under everything it would delete. */
.inv-page .inv-wipe{display:block;width:100%;min-height:var(--sys-tap);margin:18px 0 4px;border:0;
  background:none;color:var(--red);font:inherit;font-family:inherit;font-size:var(--sys-t-caption);
  font-weight:var(--sys-w-medium);cursor:pointer}
.inv-page .inv-wipe:active{opacity:.6}

/* ======================= FRAME THE PIECE ==============================
   A photo of a dining room is not a photo of the chairs. The square IS the photo:
   what he frames here is what is stored. It sits above every sheet, because it is
   the one screen you cannot be looking past. */
.inv-page .inv-croplayer{position:fixed;inset:0;display:none;flex-direction:column;
  background:var(--sys-page);z-index:calc(var(--sys-z-fullscreen) + 3);
  padding:calc(10px + var(--sys-safe-t)) 16px calc(12px + var(--sys-safe-b))}
.inv-page .inv-croplayer.on{display:flex}
html.ni-top .inv-page .inv-croplayer{padding-top:10px}
.inv-page .inv-crophd{flex:none;display:flex;align-items:center;gap:12px;margin-bottom:10px}
.inv-page .inv-crophd .inv-btn{margin-top:0;width:auto;padding:0 16px;min-height:var(--sys-tap)}
.inv-page .inv-cropttl{flex:1;min-width:0;text-align:center;padding-right:76px;
  font-size:var(--sys-t-title);font-weight:var(--sys-w-bold);letter-spacing:-.01em}
/* The frame: as big as the screen allows, always square, never taller than the room
   it has — a crop surface you have to scroll to is a crop surface nobody uses. */
.inv-page .inv-cropwrap{flex:1;min-height:0;display:grid;place-items:center}
.inv-page .inv-cropbox{position:relative;width:100%;aspect-ratio:1;max-height:100%;max-width:100%;overflow:hidden;border-radius:var(--sys-r-card);background:#000;
  touch-action:none;-webkit-user-select:none;user-select:none}
.inv-page .inv-cropbox img{position:absolute;max-width:none;display:block;-webkit-user-drag:none}
.inv-page .inv-crophint{flex:none;text-align:center;font-size:var(--sys-t-caption);color:var(--gray);margin:10px 0 0}
.inv-page .inv-croprow{flex:none;display:flex;align-items:center;gap:10px;margin-top:10px}
.inv-page .inv-croprow .inv-btn{margin-top:0;flex:1}
/* Standing in a room, the stepper counts the room; this is the other number, kept
   quiet and kept on screen so raising one is never mistaken for raising the other. */
.inv-page .inv-kown{font-size:var(--sys-t-caption);color:var(--gray);margin:6px 2px 0;text-align:right}

/* ==================== THIS HOUSE, IN THE HOUSE =========================
   The same section, rendered inside the house drawer's own tab. The panel carries
   `inv-page` so every rule above reaches it — nothing here escapes it. */
.inv-page.inv-house{padding:2px 0 4px}
.inv-page .inv-hhead{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  font-size:var(--sys-t-lead);font-weight:var(--sys-w-semibold);margin:2px 2px 4px}
/* The page can be short of the total — the server caps a read at 200 rows — and a
   count that quietly leaves rows out is the bug this repo keeps naming. */
.inv-page .inv-hshort{font-size:var(--sys-t-caption);font-weight:var(--sys-w-medium);color:var(--gray)}
.inv-page .inv-cellname.as-text{cursor:default}
.inv-page.inv-house .inv-shot{cursor:default}
/* The house's panel sits straight on the page, and --sys-fill IS the page colour
   (#F5F5F7): an initial tile there had no box at all, its letter floating a hundred
   pixels over its name (review of UI-157). Here it wears the card fill and the
   hairline the list cards and the old ＋ tile used. */
.inv-page.inv-house .inv-shot.letter{background:var(--card);box-shadow:0 0 0 1px var(--hair) inset}
.inv-page.inv-house .inv-shot.letter .inv-qbadge{background:var(--sys-fill);color:var(--gray)}
/* Destage: the answer that is not "it came back" wears the colour of a thing that
   needs a conversation, not the colour of a thing that is done. */
.inv-page .inv-mark.on.odd{background:var(--amber-bg);color:var(--amber)}

/* ============ THE SECTION AS A SCREEN OF ITS OWN =====================
   The crew app has no hub for it to sit in, so it opens as a full screen with its
   own header and Back — the same list, the same pages, the same sheets. */
.inv-page.inv-solo{position:fixed;inset:0 var(--sys-safe-r) 0 var(--sys-safe-l);z-index:var(--sys-z-fullscreen);overflow-y:auto;
  -webkit-overflow-scrolling:touch;background:var(--sys-page);
  padding:calc(10px + var(--sys-safe-t)) 16px calc(24px + var(--sys-safe-b))}
html.ni-top .inv-page.inv-solo{padding-top:10px}
.inv-page.inv-solo #invSoloHd{margin-bottom:12px}
/* The manager's section sits in his app's 480px column; this screen covers the
   whole window, and on an iPad its cards ran 992px wide with the date floating in
   the middle of each (UI-165). The same column here: 448 is 480 less the gutters. */
.inv-page.inv-solo > #invSoloHd,
.inv-page.inv-solo > .inv-list{max-width:448px;margin-left:auto;margin-right:auto}

/* ------------------------------------------------------------------ *
   2026-09-24 — what the three big numbers cannot say, and the pieces
   filed under a category that is no longer on his list.
 * ------------------------------------------------------------------ */
/* The quietest line on the screen, under the places, not above them: it is a
   thing to notice on the way past, never the first thing read. */
.inv-page .inv-stats{margin:18px 2px 4px;font-size:var(--sys-t-caption);color:var(--gray);
  line-height:1.5;text-align:center}
/* The orphan filter, once he is inside it: which name he is looking at and the
   one control that gets him out. */
.inv-page .inv-catbar{display:flex;align-items:center;justify-content:space-between;gap:10px;
  min-height:44px;padding:0 4px 10px;font-size:var(--sys-t-caption);color:var(--gray)}
.inv-page .inv-catclear{min-height:44px;padding:0 4px;border:0;background:transparent;color:var(--blue);
  font:inherit;font-family:inherit;font-size:var(--sys-t-caption);font-weight:var(--sys-w-semibold);cursor:pointer}

/* ------------------------------------------------------------------ *
   WHERE IT HAS BEEN. The event log is the data model of this module and
   the sheet used to throw the whole timeline away. Quiet type, one dot
   per move, newest first — a thing you glance down, not a table.
 * ------------------------------------------------------------------ */
.inv-page .inv-hist{margin-top:6px}
.inv-page .inv-hist-none{margin-top:6px;font-size:var(--sys-t-caption);color:var(--gray)}
.inv-page .inv-hrow{display:flex;align-items:flex-start;gap:10px;padding:7px 0}
.inv-page .inv-hdot{flex:none;width:7px;height:7px;margin-top:7px;border-radius:50%;background:var(--sys-fill-2);
  box-shadow:0 0 0 1px var(--hair) inset}
.inv-page .inv-hrow:first-child .inv-hdot{background:var(--blue);box-shadow:none}
.inv-page .inv-htx{flex:1;min-width:0;font-size:var(--sys-t-body);line-height:1.35}
.inv-page .inv-hwhen{display:block;font-size:var(--sys-t-caption);color:var(--gray);margin-top:1px}
.inv-page .inv-hmore{min-height:var(--sys-tap);margin-top:2px;padding:0;border:0;background:transparent;color:var(--blue);
  font:inherit;font-family:inherit;font-size:var(--sys-t-caption);font-weight:var(--sys-w-semibold);cursor:pointer}

/* ------------------------------------------------------------------ *
   THE PHASE RAIL. "Agregar una tab tipo houses en la main app… y ahí
   poner las casas coming soon, active and destaging soon."
   The manager's Houses page uses .filters/.chip and the crew's jobs hub
   uses .jz-chips/.jz-chip — the same control, in two stylesheets, and
   NEITHER is loaded by both apps. This section is one file loaded by
   both, so the language is mirrored here from the tokens both shells
   already carry, and the track SCROLLS: a label too long for the width
   moves off the edge instead of spilling, which is exactly what
   .sys-seg does wrong with a fourth word.
 * ------------------------------------------------------------------ */
.inv-page .inv-seg{display:flex;gap:2px;overflow-x:auto;margin:0 0 14px;padding:2px;
  background:var(--sys-seg-track);border-radius:var(--sys-r-segment-outer);
  -webkit-overflow-scrolling:touch;scrollbar-width:none}
.inv-page .inv-seg::-webkit-scrollbar{display:none}
/* THE FOUR FIT ANY PHONE, AT REAL COUNTS (UI-164). One-line labels need 367px at
   6 / 24 / 3 and 382 at 18 / 38 / 12 — he runs about thirty jobs, so "Staged" is in
   the tens — and a 393pt iPhone gives the rail 361 (375: 343; Display Zoom: 288).
   Taking padding off only fitted single digits, and past the edge "Destaging soon"
   lost its count with nothing saying the rail scrolls. So a pill may shrink
   (flex-shrink) and its label wraps onto a second line inside the same 44pt pill,
   the count held to the last word ("soon 12"): only when the four do not fit, and
   the rail's height never moves. Scrolling stays as the last resort. */
.inv-page .inv-segb{flex:0 0 auto;min-height:var(--sys-tap);min-width:var(--sys-tap);justify-content:center;display:inline-flex;align-items:center;gap:4px;
  padding:6px 8px;border:0;border-radius:var(--sys-r-segment);background:transparent;color:var(--ink);
  font:inherit;font-family:inherit;font-size:var(--sys-t-body);font-weight:var(--sys-w-medium);
  white-space:nowrap;cursor:pointer;-webkit-tap-highlight-color:transparent}
.inv-page .inv-segl{white-space:normal;line-height:1.15;text-align:center}
/* Shrinks only as far as its longest word: min-width back to auto, because the tap
   floor above let a pill shrink under its own label and "Staged 24" spilled out of
   it at 320. "All" keeps the floor and never shrinks. */
.inv-page .inv-segb.inv-segw{flex-shrink:1;min-width:auto}
/* A 375pt phone (SE, mini) gives the rail 343. */
@media (max-width: 380px) { .inv-page .inv-segb{padding:6px 5px} }
.inv-page .inv-segb b{font-weight:var(--sys-w-medium);color:var(--gray);font-size:var(--sys-t-small);
  font-variant-numeric:tabular-nums}
.inv-page .inv-segb.on{background:var(--sys-panel);color:var(--ink);font-weight:var(--sys-w-semibold);
  box-shadow:var(--sys-shadow-segment)}
/* The one bit of colour on the rail, and it means one thing: a job was picked up
   and the furniture is still in it. */
.inv-page .inv-segb .dot{width:7px;height:7px;border-radius:50%;background:var(--amber)}

/* The chore, as a chore: one row, drawn only when there is something to do. */
.inv-page .inv-chore{display:flex;align-items:center;gap:10px;width:100%;min-height:var(--sys-tap);
  margin:0 0 14px;padding:11px 14px;border:0;border-radius:var(--sys-r-card);background:var(--card);
  box-shadow:var(--sys-shadow-card);font:inherit;font-family:inherit;font-size:var(--sys-t-body);
  color:var(--ink);text-align:left;cursor:pointer}
.inv-page .inv-chore b{color:var(--amber);font-weight:var(--sys-w-bold);font-variant-numeric:tabular-nums}
.inv-page .inv-chore .chev{margin-left:auto;color:var(--sys-faint)}
.inv-page .inv-chore.on{box-shadow:0 0 0 2px var(--blue),var(--sys-shadow-card)}

/* The date a job is about, on the card, next to what is in it. It was computed,
   handed to the template and dropped into an attribute nobody reads. */
.inv-page .inv-plwhen{margin-left:auto;font-size:var(--sys-t-caption);color:var(--gray);white-space:nowrap}
.inv-page .inv-plsub{display:block;margin-top:5px;font-size:var(--sys-t-caption);color:var(--gray)}
/* How full a job already is, without opening it or driving to the unit. */
.inv-page .inv-bar{display:block;height:3px;margin-top:7px;border-radius:2px;background:var(--sys-fill-2);overflow:hidden}
.inv-page .inv-bar i{display:block;height:100%;border-radius:2px;background:var(--blue)}

/* What a piece cost, and the flag that says it is broken. */
.inv-page .inv-kmoney{display:inline-flex;align-items:center;gap:2px;min-height:44px;padding:0 12px;
  border-radius:var(--sys-r-control);background:var(--sys-fill);color:var(--gray);font-size:16px}
.inv-page .inv-kmoney input{width:88px;min-height:44px;border:0;background:transparent;color:var(--ink);
  font:inherit;font-family:inherit;font-size:16px;font-weight:var(--sys-w-semibold);text-align:right;
  font-variant-numeric:tabular-nums}
.inv-page .inv-kmoney input:focus{outline:none}
.inv-page .inv-kmoney:focus-within{outline:2px solid var(--blue);outline-offset:-2px}
.inv-page .inv-kflag{margin-top:8px;padding:8px 12px;border-radius:var(--sys-r-control);
  background:var(--amber-bg);color:var(--amber);font-size:var(--sys-t-caption);font-weight:var(--sys-w-semibold)}

/* Choosing several pieces at once — the first multi-select in the section. */
.inv-page .inv-shot.picked{box-shadow:0 0 0 3px var(--blue) inset}
.inv-page .inv-tick{position:absolute;right:6px;bottom:6px;width:22px;height:22px;border-radius:50%;
  background:var(--blue);color:#fff;font-size:13px;font-weight:var(--sys-w-bold);display:grid;place-items:center}

/* Saying what happened to each of six chairs. */
.inv-page .inv-splithint{margin:2px 2px 10px;font-size:var(--sys-t-caption);color:var(--gray)}
.inv-page .inv-splithint b{color:var(--ink);font-weight:var(--sys-w-semibold);font-variant-numeric:tabular-nums}

/* ------------------------------------------------------------------ *
   2026-10-09 — THE PULL SHEET MOVES THE INVENTORY (approved by Mario).
   Every value is a system.css token or a number this file already uses.
 * ------------------------------------------------------------------ */
/* A piece on the job's pull sheet the crew has not pulled yet: grey, with its room.
   Only the PHOTO is dimmed; the name is the secondary text colour, which reads
   (review S7: at .38 opacity it was 2.31:1), and what grey means is also said in
   words a screen reader hears (.inv-vh). */
.inv-page .inv-cell.pk-wait .inv-shot{opacity:.38}
.inv-page .inv-cell.pk-wait .inv-cellname{color:var(--gray)}
.inv-page .inv-vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* The pickup check: three numbers that add up. */
.inv-page .pk-card{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));background:var(--card);
  border-radius:var(--sys-r-card);box-shadow:var(--sys-shadow-card);padding:12px 0 11px;margin:2px 0 0}
.inv-page .pk-n{text-align:center;min-width:0}
.inv-page .pk-n + .pk-n{box-shadow:-1px 0 0 var(--hair)}
.inv-page .pk-n b{display:block;font-size:var(--sys-t-hero);font-weight:var(--sys-w-bold);line-height:1.1;
  letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.inv-page .pk-n span{display:block;margin-top:2px;font-size:var(--sys-t-small);color:var(--gray)}
.inv-page .pk-n.warn b{color:var(--amber)}

/* A piece that did not come back: what it is, where it stood, three answers. */
.inv-page .pk-row{background:var(--card);border-radius:14px;padding:9px 11px 11px;margin-bottom:8px}
.inv-page .pk-top{display:flex;align-items:center;gap:11px;width:100%;min-height:var(--sys-tap);padding:0;border:0;background:none;
  text-align:left;font:inherit;font-family:inherit;color:inherit;cursor:pointer}
.inv-page .pk-ch{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;margin-top:10px}
.inv-page .pk-ch .inv-mark{min-width:0;min-height:var(--sys-tap);padding:4px 6px;line-height:1.2;
  border-radius:var(--sys-r-control)}

/* SEVERAL FROM PHOTOS. The chooser's third answer wears the pull sheet's own
   "From the library" glyph. */
.inv-page .inv-choice .ic svg{width:21px;height:21px;display:block;fill:none;stroke:currentColor}
/* One row per photo — the photo, its name, how many — and under the name the
   category chips on ONE line that scrolls sideways (the same .inv-chip, never
   wrapped), running out to the edge of the glass. */
.inv-page .sv-row{padding:14px 0}
.inv-page .sv-row + .sv-row{border-top:1px solid var(--hair)}
.inv-page .sv-top{display:flex;align-items:center;gap:10px}
.inv-page .sv-pic{width:56px;height:56px;flex:none;aspect-ratio:auto;border-radius:var(--sys-r-control);cursor:default}
.inv-page .sv-top .inv-flname{min-width:0}
/* On the narrow phones the name gets the row beside the photo and the count goes
   under it (review S9: at 320 the field was 84px, a word and a half). */
@media (max-width: 380px) {
  .inv-page .sv-top{flex-wrap:wrap}
  .inv-page .sv-top .inv-flname{flex:1 1 calc(100% - 66px)}
  .inv-page .sv-top .inv-qty{margin-left:66px}
}
.inv-page .sv-chips{flex-wrap:nowrap;overflow-x:auto;margin:9px -18px 0 66px;padding-right:18px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.inv-page .sv-chips::-webkit-scrollbar{display:none}
.inv-page .sv-chips .inv-chip{flex:none}
.inv-page .sv-row .inv-err:empty{display:none}
/* The list's scroll box reaches the sheet's edge, so a strip can run to the glass. */
.inv-page .inv-flscroll.sv-list{margin-right:-18px;padding-right:18px}
.inv-page .inv-flrow .sv-go{margin-top:0}

/* THE OPEN iPHONE DUO (system.css: 600px, --sys-pane-w). The manager's list is the
   left pane; the piece sheet and the house's own page centre in what is left of
   the usable width. The crew's full-screen copy (.inv-solo) is untouched. */
@media (min-width: 600px) {
  html[data-ui="bento"] body.manager-page-inventory .inv-page .inv-sheet,
  html[data-ui="bento"] body.manager-page-inventory .inv-page .inv-scrn {
    left: calc(var(--sys-safe-l) + var(--sys-pane-w) + (100% - var(--sys-safe-l) - var(--sys-safe-r) - var(--sys-pane-w)) / 2);
    width: min(560px, calc(var(--sys-usable-w) - var(--sys-pane-w)));
  }
  /* The list is the left pane and stays while a place's page is up on the right
     (on a phone the page covers the list and the list is hidden, above). */
  html[data-ui="bento"] body.manager-page-inventory .inv-page.screen-on .inv-list { display: block; }
}
