/* ══════════════════════════════════════════════════════════════
   OurStuff — 家庭物品台账

   Built on the shared shell's tokens (--on-ink, --on-line, --on-radius-lg,
   --on-shadow-sm …) and its components (.on-card, .on-button, .on-status).
   The composer's measurements follow MailRoom's workspace.css so the two apps
   feel like the same suite.

   The home page is one chat surface: empty state centres a single composer in
   the viewport below the header and leaves the inventory below the fold; while
   conversing, the composer pins to the bottom and the inventory is removed.
   ══════════════════════════════════════════════════════════════ */

.on-app { background: var(--on-bg); }

/* The shared sheet sets a button's border colour and background but never
   resets border-width or border-style, so Chrome's `2px outset` default shows
   through as a dark rim on the bottom edge. Reset it here and give the two
   non-primary variants their own surface. */
.on-app button { border: 0; }

.on-app .on-button:not(.on-button--primary):not(.danger-button) {
  border: 1px solid var(--on-line-strong);
  background: var(--on-surface);
  color: var(--on-ink);
}

.on-app .on-button:not(.on-button--primary):not(.danger-button):hover {
  border-color: var(--on-accent);
  color: var(--on-accent-strong);
}

.on-app .danger-button {
  border: 1px solid #e0b2ad;
  background: var(--on-danger-soft);
  color: #8d3c36;
}

.on-app .danger-button:hover { border-color: var(--on-danger); color: #7d332d; }

.on-app button:disabled { opacity: .45; cursor: not-allowed; box-shadow: none !important; }

/* ── settings entry (page content, upper right) ───────────── */
/* The entry lives in an in-flow row at the top of main rather than in the
   global header. The row is transparent and only reserves the icon's height,
   so it never reads as a toolbar, but it keeps the icon clear of each page's
   own heading and actions and scrolls away with the content. */
.stuff-toolbar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  margin: 0 0 8px;
}
.stuff-settings {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  color: var(--on-muted);
  text-decoration: none;
}
.stuff-settings:hover { background: var(--on-line); color: var(--on-ink); }
.stuff-settings:focus-visible { outline: 2px solid var(--on-accent); outline-offset: 2px; }
.stuff-settings svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.stuff-settings[aria-current="page"] { background: var(--on-accent-soft); color: var(--on-accent-strong); }

/* ── banners ──────────────────────────────────────────────── */
.banner {
  margin: 0 0 18px;
  padding: 12px 15px;
  border: 1px solid var(--on-line);
  border-radius: var(--on-radius);
  background: var(--on-surface);
  font-size: .85rem;
  line-height: 1.6;
}
.banner a { color: var(--on-accent); font-weight: 800; }
.banner--warning { border-color: #f0dcb0; background: var(--on-warning-soft); color: #7a5410; }
.banner--danger { border-color: #f0cfcb; background: var(--on-danger-soft); color: #8d3c36; }
.banner--ok { border-color: #c7e3d9; background: var(--on-accent-soft); color: var(--on-accent-strong); }

/* ── chat surface ─────────────────────────────────────────── */
.stuff { position: relative; }

/* Empty: the composer is the only thing in the first viewport. --stuff-top is
   the measured offset of the chat surface itself (header plus the shell's top
   padding), so filling 100svh minus that lands the inventory exactly at the
   viewport boundary. There is deliberately no extra subtraction: a stray px
   fudge let the inventory title peek into the first viewport. */
.stuff.is-empty .stuff__composer {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100svh - var(--stuff-top, var(--on-header-height, 78px)));
  padding-bottom: 7vh;
}
.stuff.is-empty .stuff__log { display: none; }
.stuff__inventory { padding-top: 6px; }

/* Conversing: the inventory is gone (render and assistive tech), the log takes
   the page and the composer pins to the bottom edge. The page itself is the one
   scroll container, so there is never a second nested scrollbar. */
.stuff.is-chatting .stuff__inventory { display: none; }
/* The log clears the real, measured dock (composer + tray + status) and the
   on-screen keyboard, both published as CSS variables by the script. The clamp
   is only the pre-measurement fallback, so a tall tray or a grown textarea can
   never leave the last message hidden behind the composer. */
.stuff.is-chatting .stuff__log {
  padding-bottom: calc(var(--stuff-dock, clamp(150px, 20vh, 240px)) + var(--stuff-keyboard, 0px));
}
.stuff.is-chatting .stuff__composer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: var(--stuff-keyboard, 0px);
  z-index: 40;
  padding: 10px 24px calc(12px + env(safe-area-inset-bottom));
  background: linear-gradient(to bottom, rgba(244, 247, 245, 0), rgba(244, 247, 245, .92) 26%, rgba(244, 247, 245, .98));
  backdrop-filter: blur(8px);
}
.stuff.is-chatting .stuff__log ~ .stuff__inventory { display: none; }

/* The active conversation is a centred column, the same min(760px, 100%)
   measure as the composer input (MailRoom's reading width), so assistant cards
   sit left and user bubbles right of one shared axis instead of spanning the
   full shell. Horizontal auto margins centre it; on phones the min() collapses
   to full width. */
.stuff__log {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: min(760px, 100%);
  max-width: min(760px, 100%);
  margin-left: auto;
  margin-right: auto;
  padding: 4px 0 20px;
}
.stuff__log[hidden] { display: none; }

/* ── composer ──────────────────────────────────────────────── */
.composer { display: flex; flex-direction: column; gap: 8px; align-items: center; width: min(760px, 100%); }
.stuff.is-chatting .composer { width: 100%; }

.composer__tray {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: min(760px, 100%);
  justify-content: flex-start;
}
.tray__chip { position: relative; width: 62px; height: 62px; }
.tray__chip img { width: 100%; height: 100%; border-radius: 10px; object-fit: cover; border: 1px solid var(--on-line); }
.tray__x {
  position: absolute;
  top: -6px;
  right: -6px;
  display: grid;
  width: 21px;
  height: 21px;
  place-items: center;
  border-radius: 50%;
  background: var(--on-ink);
  color: #fff;
  font-size: .82rem;
  line-height: 1;
  cursor: pointer;
}

/* Measurements from MailRoom's workspace.css. */
.composer__inner {
  display: flex;
  width: min(760px, 100%);
  align-items: flex-end;
  gap: 8px;
  padding: 7px 8px 7px 10px;
  border: 1px solid var(--on-line-strong);
  border-radius: 16px;
  background: var(--on-surface);
  box-shadow: 0 6px 26px rgba(30, 60, 45, .09);
  transition: border-color .18s;
}
.composer__inner:focus-within { border-color: var(--on-accent); }
.composer.is-drop .composer__inner { border-color: var(--on-accent); border-style: dashed; }

/* ournest-ui.css paints border/background/border-radius/min-height/box-shadow on
   every .on-app textarea with !important. This sheet is now loaded *after* the
   shared one, and the .on-app prefix gives the composer's flat field the extra
   weight it needs, so no second rounded/shadowed box appears on focus. */
.on-app .composer__inner textarea {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
  min-height: 40px !important;
  max-height: 168px;
  padding: 8px 0;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  font: inherit;
  font-size: .95rem;
  line-height: 1.55;
  resize: none !important;
  box-shadow: none !important;
  outline: 0;
  overflow-y: hidden;
}
.on-app .composer__inner textarea:focus,
.on-app .composer__inner textarea:focus-visible {
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  outline: 0 !important;
}

.composer__camera,
.composer__send,
.composer__close {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 10px;
  cursor: pointer;
}
.composer__camera { background: transparent; color: var(--on-muted); }
.composer__camera:hover:not(:disabled) { background: var(--on-line); color: var(--on-ink); }
.composer__camera svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.5; }
.composer__send { background: #214f46; color: #f4f7f5; }
.composer__send svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.composer__send:hover:not(:disabled) { background: #173f36; }
.composer__close { background: transparent; color: var(--on-muted); font-size: 1.15rem; line-height: 1; }
.composer__close:hover:not(:disabled) { background: var(--on-line); color: var(--on-ink); }
/* display:inline-flex would beat the hidden attribute under the shared shell. */
.composer__close[hidden] { display: none; }

.composer__status {
  min-height: 17px;
  width: min(760px, 100%);
  margin: 0;
  color: var(--on-muted);
  font-size: .8rem;
  text-align: center;
}
.composer__status.is-error { color: #94413b; font-weight: 700; }

/* ── messages ─────────────────────────────────────────────── */
.msg { display: flex; flex-direction: column; gap: 8px; max-width: 78%; }
.msg--me { align-self: flex-end; align-items: flex-end; }
.msg--ai { align-self: flex-start; width: min(100%, 760px); max-width: 100%; }
.msg__bubble { padding: 12px 15px; border-radius: 15px; font-size: .93rem; line-height: 1.72; white-space: pre-wrap; word-break: break-word; }
.msg--me .msg__bubble { background: var(--on-accent); color: #fff; border-bottom-right-radius: 4px; }
.msg--ai .msg__bubble { background: var(--on-surface); border: 1px solid var(--on-line); border-bottom-left-radius: 4px; }
.msg--ai.is-busy .msg__bubble { color: var(--on-muted); font-style: italic; }
.msg__bubble a { color: var(--on-accent); font-weight: 800; }
.msg--me .msg__bubble a { color: #fff; text-decoration: underline; }

.msg__shots { display: flex; flex-wrap: wrap; gap: 7px; }
.msg__shots > img { width: 74px; height: 74px; border-radius: 9px; object-fit: cover; border: 1px solid var(--on-line); }
.msg__shot { display: flex; flex-direction: column; gap: 4px; width: 108px; padding: 6px; border: 1px solid var(--on-line); border-radius: 10px; background: var(--on-surface); text-decoration: none; }
.msg__shot img { width: 100%; aspect-ratio: 1; border-radius: 6px; object-fit: cover; }
.msg__shot span { color: var(--on-ink); font-size: .71rem; font-weight: 700; line-height: 1.3; }
.msg__advice {
  padding: 10px 13px; border: 1px dashed var(--on-line-strong); border-radius: 12px;
  background: var(--on-surface-muted, var(--on-bg)); color: var(--on-muted);
  font-size: .84rem; line-height: 1.7;
}
.msg__advice strong { display: block; color: var(--on-ink); font-size: .74rem; font-weight: 800; margin-bottom: 4px; }
.msg__advice p { margin: 0; white-space: pre-wrap; }
.msg__foot { color: var(--on-faint); font-size: .7rem; }

/* ── inline confirmation cards ────────────────────────────── */
/* The confirmation cards belong to the assistant's reply: the bubble and the
   first card read as one message, with no modal or overlay. */
.msg--confirm { gap: 6px; }
.msg--confirm .msg__bubble { border-bottom-left-radius: 4px; }
.msg--confirm .stuff-cards { margin-top: -2px; }

.stuff-cards { display: flex; flex-direction: column; gap: 12px; }
.stuff-card {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr);
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--on-line);
  border-radius: var(--on-radius-lg);
  background: var(--on-surface);
}
.stuff-card.is-saved { border-color: #c7e3d9; background: var(--on-accent-soft); }
.stuff-card.is-skipped { opacity: .72; }
/* A manual entry has no photo. Without this the card wasted a whole empty
   column on a bogus src="" image, squeezing the fields on a phone. */
.stuff-card.stuff-card--nophoto { grid-template-columns: minmax(0, 1fr); }
.stuff-card--nophoto .stuff-card__photo { display: none; }
.stuff-card__photo { width: 88px; height: 110px; border-radius: 10px; object-fit: cover; background: var(--on-surface-soft); border: 1px solid var(--on-line); }
.stuff-card__body { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.stuff-card__title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.stuff-card__title h3 { margin: 0; font-family: var(--on-display-font); font-size: 1.1rem; font-weight: 500; }
.stuff-card__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.stuff-card__note { margin: 0; padding: 7px 10px; border-radius: 9px; background: var(--on-warning-soft); color: #8a5d14; font-size: .78rem; font-weight: 700; }
.stuff-card__error { margin: 0; padding: 7px 10px; border-radius: 9px; background: #f3d9d6; color: #94413b; font-size: .78rem; font-weight: 700; }
.stuff-card__error[hidden] { display: none; }
.stuff-card__foot { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.stuff-card__status { color: var(--on-faint); font-size: .76rem; }
.stuff-card__saved { display: flex; flex-direction: column; gap: 6px; font-size: .86rem; line-height: 1.6; }
.stuff-card__saved[hidden], .stuff-card__editor[hidden] { display: none; }
.stuff-card__saved a { color: var(--on-accent); font-weight: 800; }
.stuff-card__facts { display: flex; flex-direction: column; gap: 3px; margin: 0; }
.stuff-card__facts > div { display: flex; gap: 8px; }
.stuff-card__facts dt { flex: 0 0 auto; min-width: 4.2em; margin: 0; color: var(--on-muted); font-size: .72rem; }
.stuff-card__facts dd { margin: 0; color: var(--on-ink); font-size: .82rem; word-break: break-word; }
.stuff-card__skipped { margin: 0; color: var(--on-muted); font-size: .84rem; }
.stuff-card :disabled { opacity: .55; }

/* in-chat close confirmation, never a popup */
.stuff-confirm {
  align-self: center;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: min(100%, 560px);
  padding: 12px 14px;
  border: 1px solid var(--on-line-strong);
  border-radius: 12px;
  background: var(--on-surface);
  font-size: .85rem;
}
.stuff-confirm__note { margin: 0; color: var(--on-ink); }

/* ── fields ───────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field--wide { grid-column: 1 / -1; }
.field__label { color: var(--on-muted); font-size: .71rem; font-weight: 800; letter-spacing: .04em; }
.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 40px;
  padding: 8px 11px;
  border: 1px solid var(--on-line-strong);
  background: var(--on-surface);
  font: inherit;
  font-size: .9rem;
  resize: vertical;
}
.field textarea { min-height: 62px; line-height: 1.55; }
.field.is-flagged input,
.field.is-flagged select { border-color: #d8b06a; box-shadow: 0 0 0 3px rgba(180, 120, 29, .1) !important; }

/* ── inventory ────────────────────────────────────────────── */
/* An inline retry keeps the composer, attachments and typing in place: a failed
   filter used to hard-navigate to the standalone page and drop them all. */
.inv-error { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.filters { display: flex; flex-direction: column; gap: 13px; margin: 0 0 20px; }
.filters input[type="search"] {
  width: min(400px, 100%);
  min-height: 40px;
  padding: 8px 14px;
  border: 1px solid var(--on-line-strong);
  border-radius: 999px;
  background: var(--on-surface);
  font: inherit;
  font-size: .89rem;
}
.filters__chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 13px;
  border: 1px solid var(--on-line);
  border-radius: 999px;
  background: var(--on-surface);
  color: var(--on-muted);
  font-size: .79rem;
  font-weight: 700;
  text-decoration: none;
}
.chip b { color: var(--on-faint); font-size: .71rem; }
.chip:hover { border-color: var(--on-line-strong); color: var(--on-ink); }
.chip.is-active { border-color: var(--on-accent); background: var(--on-accent); color: #fff; }
.chip.is-active b { color: rgba(255, 255, 255, .78); }

.pagehead { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin: 0 0 18px; flex-wrap: wrap; }
.pagehead h1, .pagehead__title { margin: 0; font-family: var(--on-display-font); font-size: clamp(1.7rem, 3vw, 2.5rem); font-weight: 500; letter-spacing: -.03em; }
.pagehead__count { color: var(--on-faint); font-size: .84rem; }
.inventory-manual {
  color: var(--on-muted);
  font-size: .82rem;
  font-weight: 700;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.inventory-manual:hover { color: var(--on-accent-strong); border-bottom-color: currentColor; }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(184px, 1fr)); gap: 16px; margin: 0; padding: 0; list-style: none; }
.tile { display: flex; flex-direction: column; height: 100%; overflow: hidden; text-decoration: none; }
.tile__shot { display: block; aspect-ratio: 4 / 5; background: var(--on-surface-soft); overflow: hidden; }
.tile__shot img { width: 100%; height: 100%; object-fit: cover; }
.tile__nophoto { display: grid; height: 100%; place-items: center; background: var(--on-surface-soft); }
.tile__nophoto svg { width: 36px; height: 36px; fill: none; stroke: var(--on-line-strong); stroke-width: 1.3; }
.tile__body { display: flex; flex-direction: column; gap: 4px; padding: 12px 13px 13px; }
.tile__name { color: var(--on-ink); font-size: .93rem; font-weight: 800; line-height: 1.3; }
.tile__meta { display: flex; flex-wrap: wrap; gap: 5px; font-size: .73rem; }
.tile__cat { color: var(--on-accent); font-weight: 800; }
.tile__sub { color: var(--on-faint); }
.tile__amount { color: var(--on-muted); font-size: .78rem; font-weight: 700; }
.tile__note { color: var(--on-faint); font-size: .74rem; line-height: 1.45; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.tile__foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: auto; padding-top: 5px; flex-wrap: nowrap; }
.tile__by { color: var(--on-faint); font-size: .69rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile__expiry { flex: none; white-space: nowrap; }

/* ── detail ───────────────────────────────────────────────── */
.crumb { margin: 0 0 14px; font-size: .83rem; }
.crumb a { color: var(--on-accent); font-weight: 700; text-decoration: none; }
.crumb span { color: var(--on-faint); margin: 0 6px; }
.detail { display: grid; grid-template-columns: minmax(220px, 300px) minmax(0, 1fr); gap: 20px; align-items: start; }
.detail__shot { padding: 13px; }
.detail__shot img { display: block; width: 100%; border-radius: 11px; background: var(--on-surface-soft); }
.detail__shotnote { margin: 10px 2px 0; color: var(--on-faint); font-size: .73rem; line-height: 1.6; }
.detail__nophoto { display: grid; place-items: center; gap: 9px; padding: 30px 14px; color: var(--on-faint); text-align: center; font-size: .82rem; }
.detail__nophoto svg { width: 38px; height: 38px; fill: none; stroke: var(--on-line-strong); stroke-width: 1.3; }
.detail__form { padding: 20px; display: flex; flex-direction: column; gap: 14px; }
.detail__stamp { margin: 0; color: var(--on-faint); font-size: .73rem; }
.dangerzone { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 18px; padding: 16px 20px; border-color: #f0cfcb !important; background: var(--on-danger-soft) !important; }
.dangerzone__title { margin: 0; color: #8d3c36; font-size: .9rem; font-weight: 800; }
.dangerzone__note { margin: 3px 0 0; color: #a4574f; font-size: .75rem; }

/* ── settings ─────────────────────────────────────────────── */
.settings { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; align-items: start; }
.settings__card { padding: 20px; display: flex; flex-direction: column; gap: 14px; }
.settings__row { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.settings__label { margin: 0; color: var(--on-muted); font-size: .71rem; font-weight: 800; letter-spacing: .04em; }
.settings__value { margin: 5px 0 0; }
.settings__form { display: flex; flex-direction: column; gap: 11px; align-items: flex-start; }
.settings__form .field { width: 100%; }
.settings__hint { margin: 0; color: var(--on-faint); font-size: .76rem; }
.facts { display: flex; flex-direction: column; gap: 9px; margin: 0; }
.facts > div { display: flex; justify-content: space-between; gap: 14px; padding-bottom: 8px; border-bottom: 1px solid var(--on-line); }
.facts dt { color: var(--on-muted); font-size: .8rem; }
.facts dd { margin: 0; color: var(--on-ink); font-size: .82rem; font-weight: 700; text-align: right; }

/* ── empty ────────────────────────────────────────────────── */
.empty { padding: 42px 24px; text-align: center; }
.empty__title { margin: 0 0 7px; font-family: var(--on-display-font); font-size: 1.5rem; font-weight: 500; }
.empty__note { margin: 0 0 18px; color: var(--on-muted); font-size: .88rem; line-height: 1.7; }
/* The shared .on-button rules do not give a bare anchor complete box or
   typography styling, so this dedicated action owns its own compact, muted
   green presentation instead of inheriting oversized serif link text. */
.empty__action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 9px 18px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: var(--on-accent-soft);
  color: var(--on-accent-strong);
  font-family: var(--on-font);
  font-size: .85rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  transition: background .15s, color .15s, border-color .15s;
}
.empty__action:hover { background: var(--on-accent); color: #fff; }
.empty__action:focus-visible { outline: 2px solid var(--on-accent); outline-offset: 2px; }

/* ── pager ────────────────────────────────────────────────── */
.pager {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 20px 0 6px;
}
.pager__link {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 36px; height: 34px; padding: 0 10px;
  border: 1px solid var(--on-line-strong); border-radius: var(--on-radius);
  background: var(--on-surface); color: var(--on-ink);
  font-size: .84rem; font-weight: 600; text-decoration: none;
}
.pager__link:hover { border-color: var(--on-accent); color: var(--on-accent-strong); }
.pager__link.is-active {
  border-color: var(--on-accent); background: var(--on-accent-soft);
  color: var(--on-accent-strong);
}
.pager__gap { padding: 0 2px; color: var(--on-faint); }

/* ── narrow ───────────────────────────────────────────────── */
@media (max-width: 900px) {
  .detail, .settings { grid-template-columns: minmax(0, 1fr); }
  .detail__shot img { max-height: 280px; object-fit: contain; }
}

@media (max-width: 640px) {
  .msg { max-width: 92%; }
  /* A recognized photo's side column left only ~160px of input at 320px, so the
     card stacks: a restrained thumbnail above the title, with every field
     full-width below it. The manual (no-photo) card is already one column. */
  .stuff-card { grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 12px; }
  .stuff-card__photo { width: 100%; height: 132px; border-radius: 10px; }
  .stuff-card__grid { grid-template-columns: minmax(0, 1fr); }
  .field input, .field select, .field textarea { width: 100%; }
  .stuff.is-chatting .stuff__composer { padding: 8px 12px calc(10px + env(safe-area-inset-bottom)); }
  .grid { grid-template-columns: repeat(auto-fill, minmax(142px, 1fr)); gap: 12px; }
  .composer__tray { gap: 6px; }
  .tray__chip { width: 54px; height: 54px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .stuff.is-chatting .stuff__composer { background: var(--on-bg); backdrop-filter: none; }
}
