/* Pantry — Design system. HIG-inspired tokens, light + dark, mobile-first. */

/* ── Tokens ─────────────────────────────────────────────────────────────── */
:root {
  --bg: #f2f2f7;
  --surface: #ffffff;
  --surface-2: #f7f7fb;
  --label: #1c1c1e;
  --label-2: #3c3c4399;
  --label-3: #3c3c4366;
  --separator: #e5e5ea;
  --tint: #007aff;
  --tint-hover: #0061cc;
  --green: #34c759;
  --orange: #ff9500;
  --red: #ff3b30;
  --yellow: #ffcc00;
  --gray: #9aa4b2;

  --shadow-1: 0 1px 2px rgba(0,0,0,.04), 0 0 0 .5px rgba(0,0,0,.05);
  --shadow-2: 0 4px 16px rgba(0,0,0,.08), 0 0 0 .5px rgba(0,0,0,.05);
  --shadow-3: 0 24px 64px rgba(0,0,0,.18), 0 0 0 .5px rgba(0,0,0,.06);

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 18px;
  --radius-xl: 22px;

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);

  --tabbar-height: 56px;

  --ease-out: cubic-bezier(.2,.7,.3,1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000;
    --surface: #1c1c1e;
    --surface-2: #2c2c2e;
    --label: #fff;
    --label-2: #ebebf599;
    --label-3: #ebebf566;
    --separator: #38383a;
    --tint: #0a84ff;
    --tint-hover: #339cff;
    --green: #30d158;
    --orange: #ff9f0a;
    --red: #ff453a;
    --yellow: #ffd60a;
    --gray: #6e7480;
    --shadow-1: 0 1px 2px rgba(0,0,0,.3), 0 0 0 .5px rgba(255,255,255,.06);
    --shadow-2: 0 4px 16px rgba(0,0,0,.4), 0 0 0 .5px rgba(255,255,255,.06);
    --shadow-3: 0 24px 64px rgba(0,0,0,.6), 0 0 0 .5px rgba(255,255,255,.06);
  }
}

/* Manual theme override (user picked Light/Dark in Settings). When
   data-theme is unset, we keep the prefers-color-scheme defaults above. */
html[data-theme="light"] {
  --bg: #f2f2f7; --surface: #ffffff; --surface-2: #f7f7fb;
  --label: #1c1c1e; --label-2: #3c3c4399; --label-3: #3c3c4366;
  --separator: #e5e5ea; --tint: #007aff; --tint-hover: #0061cc;
  --green: #34c759; --orange: #ff9500; --red: #ff3b30;
  --yellow: #ffcc00; --gray: #9aa4b2;
  --shadow-1: 0 1px 2px rgba(0,0,0,.04), 0 0 0 .5px rgba(0,0,0,.05);
  --shadow-2: 0 4px 16px rgba(0,0,0,.08), 0 0 0 .5px rgba(0,0,0,.05);
  --shadow-3: 0 24px 64px rgba(0,0,0,.18), 0 0 0 .5px rgba(0,0,0,.06);
}
html[data-theme="dark"] {
  --bg: #000; --surface: #1c1c1e; --surface-2: #2c2c2e;
  --label: #fff; --label-2: #ebebf599; --label-3: #ebebf566;
  --separator: #38383a; --tint: #0a84ff; --tint-hover: #339cff;
  --green: #30d158; --orange: #ff9f0a; --red: #ff453a;
  --yellow: #ffd60a; --gray: #6e7480;
  --shadow-1: 0 1px 2px rgba(0,0,0,.3), 0 0 0 .5px rgba(255,255,255,.06);
  --shadow-2: 0 4px 16px rgba(0,0,0,.4), 0 0 0 .5px rgba(255,255,255,.06);
  --shadow-3: 0 24px 64px rgba(0,0,0,.6), 0 0 0 .5px rgba(255,255,255,.06);
}

/* ── Reset ──────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Inter', system-ui, 'Segoe UI', Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.45;
  background: var(--bg);
  color: var(--label);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
}
html { overscroll-behavior: none; }
/* Page lock applied while a sheet/modal is open (set from ui.js) — keeps a
   touch-scroll inside the sheet from bleeding through to the document. */
body.scroll-locked {
  position: fixed;
  left: 0; right: 0; width: 100%;
  overflow: hidden;
}
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }
img, svg, video { display: block; max-width: 100%; }
h1, h2, h3, h4, p { margin: 0; }
a { color: var(--tint); text-decoration: none; }
[hidden] { display: none !important; }
.muted { color: var(--label-2); }
.row { display: flex; align-items: center; }
.row.gap > * + * { margin-left: 8px; }
.col { display: flex; flex-direction: column; }
.spacer { flex: 1; }

/* ── App shell ──────────────────────────────────────────────────────────── */
/* Reserve the tab bar's height (bar + safe-area, floored at 10px to match
   .tabbar's own padding) so bottom content never hides behind it. */
#app { min-height: 100vh; min-height: 100dvh; padding-bottom: calc(var(--tabbar-height) + max(var(--safe-bottom), 10px)); }
#views { position: relative; }
.view { display: none; padding: 0; min-height: calc(100vh - var(--tabbar-height) - max(var(--safe-bottom), 10px)); min-height: calc(100dvh - var(--tabbar-height) - max(var(--safe-bottom), 10px)); }
.view.active { display: block; }

/* View headers */
.view-header {
  position: sticky; top: 0; z-index: 5;
  background: color-mix(in srgb, var(--bg), transparent 10%);
  backdrop-filter: saturate(1.4) blur(20px);
  -webkit-backdrop-filter: saturate(1.4) blur(20px);
  padding: calc(var(--safe-top) + 12px) 16px 12px;
  border-bottom: 1px solid var(--separator);
}
.view-title { font-size: 28px; font-weight: 800; letter-spacing: -0.02em; }
.view-sub { color: var(--label-2); font-size: 14px; margin-top: 2px; }
.view-content { padding: 12px 16px 24px; }

/* ── Tab bar ────────────────────────────────────────────────────────────── */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: color-mix(in srgb, var(--surface), transparent 8%);
  backdrop-filter: saturate(1.4) blur(20px);
  -webkit-backdrop-filter: saturate(1.4) blur(20px);
  border-top: 1px solid var(--separator);
  /* Floor of 10px so labels still clear the bottom edge on browsers that
     don't expose a safe-area-inset (older Android, desktop testing). */
  padding-bottom: max(env(safe-area-inset-bottom, 0px), 10px);
}
/* Bar sits flush at the bottom (bottom: 0 above). The safe-area padding-bottom
   lifts the labels clear of the home indicator without detaching the bar from
   the bottom edge. */
.tab {
  position: relative;
  height: var(--tabbar-height);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px;
  /* In-tab bottom padding shifts content upward so the label's descenders
     don't touch the absolute bottom edge — belt-and-braces with the bottom
     lift above. */
  padding-bottom: 6px;
  color: var(--label-2);
  transition: color .15s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.tab svg { width: 24px; height: 24px; }
.tab span {
  font-size: 10px; font-weight: 600; letter-spacing: 0.02em;
  line-height: 1.15;             /* tight but descenders stay rendered */
}
.tab.active { color: var(--tint); }
.tab:active svg { transform: scale(0.92); transition: transform .1s; }
.badge-dot {
  position: absolute; top: 6px; right: calc(50% - 18px);
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--red);
}

/* ── Auth screen ────────────────────────────────────────────────────────── */
.auth-screen {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center;
  background: var(--bg);
  padding: 24px;
}
.auth-card {
  width: 100%; max-width: 380px;
  background: var(--surface);
  border-radius: var(--radius-xl);
  padding: 32px 24px 24px;
  box-shadow: var(--shadow-2);
  text-align: center;
}
.auth-icon { font-size: 56px; line-height: 1; margin-bottom: 16px; }
.auth-card h1 { font-size: 24px; font-weight: 800; margin-bottom: 4px; letter-spacing: -0.01em; }
.auth-card p { font-size: 15px; margin-bottom: 24px; }
#auth-form { display: flex; flex-direction: column; gap: 12px; }

/* ── Forms / inputs ─────────────────────────────────────────────────────── */
input[type="text"], input[type="password"], input[type="number"],
input[type="search"], input[type="date"], input[type="email"],
select, textarea {
  width: 100%;
  padding: 12px 14px;
  background: var(--surface-2);
  border: 1px solid var(--separator);
  border-radius: var(--radius-md);
  color: var(--label);
  outline: none;
  transition: border-color .15s, background .15s;
  -webkit-appearance: none;
  appearance: none;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--tint);
  background: var(--surface);
}
textarea { resize: vertical; min-height: 80px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.field-label { font-size: 13px; font-weight: 600; color: var(--label-2); padding-left: 4px; }
.form-err { color: var(--red); font-size: 13px; padding: 4px; text-align: left; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

/* ── Buttons ───────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 18px; gap: 6px;
  border-radius: var(--radius-md);
  font-weight: 600; font-size: 15px;
  transition: opacity .15s, transform .1s, background .15s;
  -webkit-tap-highlight-color: transparent;
  white-space: nowrap;
}
.btn:active { transform: scale(.98); opacity: .8; }
.btn:disabled { opacity: .4; pointer-events: none; }
.btn-primary { background: var(--tint); color: #fff; }
.btn-primary:hover { background: var(--tint-hover); }
.btn-secondary { background: var(--surface-2); color: var(--label); border: 1px solid var(--separator); }
.btn-flat { background: transparent; color: var(--label); }
.btn-danger { background: var(--red); color: #fff; }
.btn-block { width: 100%; }
.btn-sm { min-height: 36px; padding: 0 12px; font-size: 14px; }
.btn-icon {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--surface-2);
  display: inline-flex; align-items: center; justify-content: center;
}
.btn-icon svg { width: 20px; height: 20px; }
.fab {
  position: fixed; right: 16px; bottom: calc(var(--tabbar-height) + var(--safe-bottom) + 16px);
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--tint); color: #fff;
  box-shadow: 0 8px 24px color-mix(in srgb, var(--tint), transparent 50%);
  display: inline-flex; align-items: center; justify-content: center;
  z-index: 30;
}
.fab svg { width: 26px; height: 26px; }

/* ── Search bar ─────────────────────────────────────────────────────────── */
.search-bar {
  position: relative;
  margin-bottom: 12px;
}
.search-bar input { padding-left: 38px; background: var(--surface-2); border-color: transparent; }
.search-bar svg {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; color: var(--label-3);
}

/* ── Filter chips ───────────────────────────────────────────────────────── */
.chips { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; margin: 0 -16px; padding-left: 16px; padding-right: 16px; }
.chips::-webkit-scrollbar { display: none; }
.chip {
  padding: 6px 14px;
  background: var(--surface-2);
  border-radius: 999px;
  font-size: 13px; font-weight: 500;
  white-space: nowrap;
  border: 1px solid transparent;
}
.chip.active { background: var(--tint); color: #fff; }

/* ── List rows ──────────────────────────────────────────────────────────── */
.list { background: var(--surface); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-1); margin-bottom: 16px; }
.list-section-title { font-size: 13px; font-weight: 600; color: var(--label-2); text-transform: uppercase; letter-spacing: 0.05em; padding: 16px 4px 8px; }
.list-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--separator);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background .1s;
}
.list-row:last-child { border-bottom: 0; }
.list-row:active { background: var(--surface-2); }
.row-thumb {
  width: 44px; height: 44px;
  flex: 0 0 44px;
  border-radius: 10px;
  background: var(--surface-2);
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
  overflow: hidden;
}
.row-thumb img { width: 100%; height: 100%; object-fit: cover; }
.row-main { flex: 1; min-width: 0; }
.row-title { font-weight: 600; font-size: 15px; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-sub { font-size: 13px; color: var(--label-2); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-right { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; }
.row-qty { font-size: 13px; font-weight: 600; color: var(--label-2); }

/* ── Expiry badges ──────────────────────────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center;
  padding: 3px 10px;
  font-size: 12px; font-weight: 700;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--label-2);
}
.badge.tone-red { background: color-mix(in srgb, var(--red), transparent 85%); color: var(--red); }
.badge.tone-orange { background: color-mix(in srgb, var(--orange), transparent 82%); color: var(--orange); }
.badge.tone-yellow { background: color-mix(in srgb, var(--yellow), transparent 80%); color: #b58f00; }
.badge.tone-green { background: color-mix(in srgb, var(--green), transparent 85%); color: var(--green); }
.badge.tone-gray { background: var(--surface-2); color: var(--label-2); }
@media (prefers-color-scheme: dark) {
  .badge.tone-yellow { color: var(--yellow); }
}

/* ── Skeletons ──────────────────────────────────────────────────────────── */
@keyframes shimmer { 0%{background-position:-400px 0} 100%{background-position:400px 0} }
.skel {
  background: linear-gradient(90deg, var(--surface-2) 0%, color-mix(in srgb, var(--surface-2), var(--separator) 40%) 50%, var(--surface-2) 100%);
  background-size: 800px 100%;
  animation: shimmer 1.4s linear infinite;
  border-radius: 6px;
}
.skel-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--separator);
}
.skel-thumb { width: 44px; height: 44px; border-radius: 10px; }
.skel-line { height: 12px; }
.skel-line.s { width: 50%; }
.skel-line.m { width: 70%; }
.skel-line.l { width: 90%; }
@media (prefers-reduced-motion: reduce) {
  .skel { animation: none; }
}

/* ── Empty state ────────────────────────────────────────────────────────── */
.empty {
  text-align: center;
  padding: 48px 24px;
  color: var(--label-2);
}
.empty-emoji { font-size: 56px; line-height: 1; margin-bottom: 14px; }
.empty-title { font-size: 18px; font-weight: 700; color: var(--label); margin-bottom: 6px; }
.empty-msg { font-size: 14px; margin-bottom: 18px; }

/* ── Sheet + modal ──────────────────────────────────────────────────────── */
.sheet-backdrop, .modal-backdrop {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(0,0,0,.4);
  opacity: 0;
  transition: opacity .25s var(--ease-out);
  touch-action: none;   /* dragging the dimmed area never scrolls the page */
}
.sheet-backdrop.open, .modal-backdrop.open { opacity: 1; }
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 91;
  max-height: 88dvh;
  background: var(--surface);
  border-radius: 22px 22px 0 0;
  transform: translateY(100%);
  transition: transform .3s var(--ease-out);
  overflow: hidden auto;
  overscroll-behavior: contain;
  padding-bottom: var(--safe-bottom);
  box-shadow: var(--shadow-3);
  display: flex;
  flex-direction: column;
}
.sheet.open { transform: translateY(0); }
.sheet-handle {
  width: 36px; height: 4px;
  background: var(--separator);
  border-radius: 2px;
  margin: 8px auto 4px;
  flex-shrink: 0;
}
.sheet-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 16px 4px;
  flex-shrink: 0;
}
.sheet-title { font-size: 17px; font-weight: 700; }
.sheet-close { font-size: 17px; color: var(--tint); padding: 8px; min-height: 36px; }
/* Left-side header action (e.g. Consume in the item sheet) — a tinted chip so
   it reads as a tappable action, distinct from the plain "Done" dismiss. */
.sheet-act {
  font-size: 15px; font-weight: 600;
  color: var(--tint);
  padding: 7px 14px; min-height: 36px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tint), transparent 86%);
}
.sheet-act:active { background: color-mix(in srgb, var(--tint), transparent 75%); }
.sheet-pad { padding: 12px 16px 24px; }
.sheet-content { padding: 8px 16px 24px; overflow-y: auto; overscroll-behavior: contain; flex: 1; }

@media (min-width: 769px) {
  .sheet {
    left: 50%; right: auto; bottom: 50%;
    transform: translate(-50%, calc(50% + 24px));
    width: min(560px, calc(100vw - 32px));
    max-height: 80dvh;
    border-radius: var(--radius-xl);
  }
  .sheet.open { transform: translate(-50%, 50%); }
  .sheet-handle { display: none; }
}

.confirm-msg { font-size: 15px; margin-bottom: 16px; line-height: 1.4; }

/* ── Toasts ─────────────────────────────────────────────────────────────── */
.toasts {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--tabbar-height) + var(--safe-bottom) + 16px);
  z-index: 200;
  display: flex; flex-direction: column-reverse; gap: 8px;
  pointer-events: none;
  width: max-content; max-width: calc(100vw - 32px);
}
.toast {
  background: color-mix(in srgb, var(--label), transparent 12%);
  color: var(--surface);
  padding: 10px 16px;
  border-radius: var(--radius-md);
  font-size: 14px; font-weight: 500;
  opacity: 0; transform: translateY(8px);
  transition: opacity .25s var(--ease-out), transform .25s var(--ease-out);
  box-shadow: var(--shadow-2);
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast-success { background: var(--green); color: #fff; }
.toast-error { background: var(--red); color: #fff; }
.toast-warning { background: var(--orange); color: #fff; }

/* Action toast (Undo etc.) */
.toast-action {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px 10px 16px;
  pointer-events: auto;
  position: relative;
  overflow: hidden;
}
.toast-action .toast-text { flex: 1; }
.toast-action-btn {
  font-weight: 700; font-size: 14px;
  background: rgba(255,255,255,.18);
  color: inherit;
  padding: 6px 12px;
  border-radius: 999px;
  -webkit-tap-highlight-color: transparent;
  transition: background .15s, transform .1s;
}
.toast-action-btn:active { transform: scale(.94); background: rgba(255,255,255,.32); }
.toast-bar {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px;
  background: rgba(255,255,255,.45);
  transform: scaleX(1);
  transform-origin: left center;
}

/* ── Scanner UI ─────────────────────────────────────────────────────────── */
.scanner {
  position: relative;
  width: 100%;
  /* Stop the camera exactly at the tab bar top so the shutter is never hidden
     behind it. vh first as a fallback for browsers without dvh. */
  height: calc(100vh - var(--tabbar-height) - max(var(--safe-bottom), 10px));
  height: calc(100dvh - var(--tabbar-height) - max(var(--safe-bottom), 10px));
  background: #000;
  overflow: hidden;
}
.scanner video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.scanner-overlay {
  position: absolute; inset: 0;
  pointer-events: none;
  display: flex; flex-direction: column;
  z-index: 2;
}
.scanner-top {
  padding: calc(var(--safe-top) + 12px) 16px 12px;
  display: flex; align-items: center; justify-content: space-between;
  pointer-events: auto;
}
.scanner-top .btn-icon { background: rgba(0,0,0,.5); color: #fff; backdrop-filter: blur(10px); }
.scanner-mid {
  flex: 1;
  min-height: 0;   /* allow shrink so the bottom controls + photo queue never clip */
  display: flex; align-items: center; justify-content: center;
}
.reticle {
  position: relative;
  width: min(75vw, 320px);
  height: min(50vw, 220px);
  max-height: 220px;
}
.reticle::before, .reticle::after,
.reticle > span:nth-child(1), .reticle > span:nth-child(2) {
  content: '';
  position: absolute; width: 32px; height: 32px;
  border: 3px solid #fff;
}
.reticle::before { top: 0; left: 0; border-right: 0; border-bottom: 0; border-top-left-radius: 8px; }
.reticle::after { top: 0; right: 0; border-left: 0; border-bottom: 0; border-top-right-radius: 8px; }
.reticle > span:nth-child(1) { bottom: 0; left: 0; border-right: 0; border-top: 0; border-bottom-left-radius: 8px; }
.reticle > span:nth-child(2) { bottom: 0; right: 0; border-left: 0; border-top: 0; border-bottom-right-radius: 8px; }
.scanner-bottom {
  padding: 16px;
  /* .scanner already ends above the tab bar, so just a normal gap here (no need
     to reserve the tab bar height again — that previously left the shutter low). */
  padding-bottom: 24px;
  text-align: center;
  pointer-events: auto;
}
.scanner-hint {
  display: inline-block;
  background: rgba(0,0,0,.6);
  color: #fff;
  padding: 8px 16px;
  border-radius: 999px;
  font-size: 14px; font-weight: 500;
  backdrop-filter: blur(10px);
  margin-bottom: 16px;
}
.scanner-actions { display: flex; gap: 12px; justify-content: center; }
.scanner-actions .btn { background: rgba(255,255,255,.95); color: #111; }
.scanner-actions .btn-primary { background: var(--tint); color: #fff; }

.capture-btn {
  width: 72px; height: 72px;
  border-radius: 50%;
  background: rgba(255,255,255,.18);
  border: 4px solid #fff;
  display: inline-flex; align-items: center; justify-content: center;
  margin: 0 auto;
}
.capture-btn::after {
  content: '';
  width: 56px; height: 56px;
  border-radius: 50%;
  background: #fff;
  transition: transform .1s;
}
.capture-btn:active::after { transform: scale(.92); }

/* ── Product card (after scan) ──────────────────────────────────────────── */
.product-card {
  background: var(--surface);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-2);
  margin-bottom: 16px;
}
.product-card-img {
  width: 100%; height: 180px;
  background: var(--surface-2);
  display: flex; align-items: center; justify-content: center;
  font-size: 56px;
}
.product-card-img img { width: 100%; height: 100%; object-fit: contain; }
.product-card-body { padding: 16px; }
.product-card-title { font-size: 18px; font-weight: 700; margin-bottom: 2px; }
.product-card-sub { font-size: 14px; color: var(--label-2); }

/* ── Location card ──────────────────────────────────────────────────────── */
.loc-card {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  margin-bottom: 8px;
  box-shadow: var(--shadow-1);
  cursor: pointer;
  transition: transform .1s;
}
.loc-card:active { transform: scale(0.98); }
.loc-emoji {
  width: 44px; height: 44px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
  flex-shrink: 0;
}
.loc-name { font-size: 16px; font-weight: 600; }
.loc-sub { font-size: 13px; color: var(--label-2); }

/* ── Settings rows ──────────────────────────────────────────────────────── */
.settings-section { margin-bottom: 24px; }
.settings-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--separator);
}
.settings-row:first-child { border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.settings-row:last-child { border-radius: 0 0 var(--radius-lg) var(--radius-lg); border-bottom: 0; }
.settings-row:only-child { border-radius: var(--radius-lg); }
.settings-label { font-size: 15px; font-weight: 500; }
.settings-value { color: var(--label-2); font-size: 14px; }

/* Item editor grouped rows: render the Place picker + Expiry date as compact,
   right-aligned value pills (iOS grouped-list style) so the two rows match,
   instead of the select sprawling full-width. Scoped to .item-fields so the
   Settings tab's own rows are untouched. */
.item-fields .settings-label { flex-shrink: 0; }
.item-fields select,
.item-fields input[type="date"] {
  width: auto;
  max-width: 62%;
  margin-left: auto;
  text-align: right;
  padding: 8px 12px;
  font-size: 15px; font-weight: 500;
  background: var(--surface-2);
  border: 1px solid var(--separator);
  border-radius: var(--radius-md);
  color: var(--label);
}

/* Toggle */
.toggle { position: relative; width: 50px; height: 30px; flex-shrink: 0; }
.toggle input { opacity: 0; width: 0; height: 0; position: absolute; }
.toggle-slider {
  position: absolute; inset: 0;
  background: var(--separator);
  border-radius: 999px;
  transition: background .2s;
}
.toggle-slider::before {
  content: '';
  position: absolute; left: 2px; top: 2px;
  width: 26px; height: 26px;
  background: #fff;
  border-radius: 50%;
  transition: transform .2s var(--ease-out);
  box-shadow: 0 2px 4px rgba(0,0,0,.2);
}
.toggle input:checked + .toggle-slider { background: var(--green); }
.toggle input:checked + .toggle-slider::before { transform: translateX(20px); }

/* Detail sheet */
.detail-img {
  width: 96px; height: 96px;
  border-radius: 16px;
  background: var(--surface-2);
  display: flex; align-items: center; justify-content: center;
  font-size: 44px;
  overflow: hidden;
  margin: 0 auto 12px;
}
.detail-img img { width: 100%; height: 100%; object-fit: cover; }
.detail-name { font-size: 22px; font-weight: 800; text-align: center; letter-spacing: -0.01em; }
.detail-brand { color: var(--label-2); text-align: center; margin-bottom: 16px; }

.qty-stepper { display: inline-flex; align-items: center; background: var(--surface-2); border-radius: 999px; padding: 4px; gap: 4px; }
.qty-stepper button {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--surface);
  font-size: 18px; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-1);
}
.qty-stepper input {
  width: 60px; text-align: center;
  background: transparent; border: 0; padding: 0; font-weight: 600;
}

/* Fractional consume — "Use part: ½ ⅓ ¼" portion chips in the item sheet. */
.consume-portions {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 8px; margin: 0 0 16px;
}
.consume-portions-label { color: var(--label-2); font-size: 13px; margin-right: 2px; }
.frac-btn {
  min-width: 42px; height: 38px; padding: 0 12px;
  border-radius: 999px; border: 1px solid var(--separator);
  background: var(--surface-2); color: var(--tint);
  font-size: 18px; font-weight: 600; cursor: pointer;
  transition: transform .1s ease, background .15s ease;
}
.frac-btn:active {
  transform: scale(.94);
  background: color-mix(in srgb, var(--tint), transparent 85%);
}

/* Banner */
.banner {
  background: color-mix(in srgb, var(--orange), transparent 85%);
  color: var(--orange);
  padding: 12px 16px;
  border-radius: var(--radius-md);
  margin-bottom: 12px;
  font-size: 14px; font-weight: 600;
  display: flex; align-items: center; gap: 10px;
  cursor: pointer;
}
.banner-info { background: color-mix(in srgb, var(--tint), transparent 88%); color: var(--tint); }

/* Responsive */
@media (min-width: 769px) {
  .view-content { max-width: 720px; margin: 0 auto; }
}
@media (min-width: 1024px) {
  .view-content { max-width: 880px; }
}

/* ── Segmented control (Scan modes, Lists sub-tabs) ──────────────────── */
.seg {
  display: inline-flex;
  background: rgba(0,0,0,.45);
  border-radius: 999px;
  padding: 4px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  pointer-events: auto;
  gap: 2px;
}
/* Lists has up to 5 tabs (Alerts/Shopping/Saved/Wasted/Used) and long BG
   labels — let the pill scroll horizontally instead of clipping/overflowing. */
#lists-seg {
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
#lists-seg::-webkit-scrollbar { display: none; }
.seg-btn {
  padding: 7px 14px;
  border-radius: 999px;
  color: rgba(255,255,255,.75);
  font-size: 13px; font-weight: 600;
  white-space: nowrap;
  transition: background .2s var(--ease-out), color .2s var(--ease-out);
}
.seg-btn.active { background: #fff; color: #000; }
.seg-btn:active { transform: scale(.96); }
.seg-light {
  background: var(--surface-2);
}
.seg-light .seg-btn { color: var(--label-2); }
.seg-light .seg-btn.active { background: var(--tint); color: #fff; }
.seg-count {
  display: inline-block;
  margin-left: 6px;
  background: var(--red);
  color: #fff;
  font-size: 11px; font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  min-width: 18px;
  text-align: center;
  line-height: 1.4;
}
.seg-light .seg-btn.active .seg-count { background: rgba(255,255,255,.25); }

/* Lists sub-tab bar: with a 4th segment, let it scroll horizontally instead of
   overflowing the header on narrow phones (the seg is inline-flex + nowrap). */
#lists-seg { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
#lists-seg::-webkit-scrollbar { display: none; }
/* Thrown-out rows read as "gone": dim the thumbnail. */
.list-row.is-discarded .row-thumb { opacity: .55; }

/* ── Stats strip on Pantry header ────────────────────────────────────── */
.stats-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-top: 12px;
}
.stat-cell {
  background: var(--surface);
  border-radius: var(--radius-md);
  padding: 10px 8px;
  text-align: center;
  box-shadow: var(--shadow-1);
  border: 1px solid transparent;
  transition: transform .1s var(--ease-out);
}
.stat-cell:active { transform: scale(.96); }
.stat-tap-hint:active { opacity: .6; }
.stat-value { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; line-height: 1; }
.stat-label { font-size: 11px; color: var(--label-2); margin-top: 4px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
.stat-tint .stat-value { color: var(--tint); }
.stat-orange .stat-value { color: var(--orange); }
.stat-red .stat-value { color: var(--red); }
.stat-green .stat-value { color: var(--green); }

/* ── Quick consume button on pantry rows ─────────────────────────────── */
.quick-consume {
  margin-top: 4px;
  background: var(--surface-2);
  color: var(--label);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 12px; font-weight: 700;
  border: 1px solid var(--separator);
  transition: transform .1s, background .15s;
  -webkit-tap-highlight-color: transparent;
  /* Long-press opens the portion menu — don't let the OS select the label or
     fire its own callout while the finger/mouse is held. */
  -webkit-touch-callout: none;
  user-select: none; -webkit-user-select: none;
  touch-action: manipulation;
}
.quick-consume:active { transform: scale(.92); background: var(--tint); color: #fff; }
/* Subtle "hold for more" hint (½ / ⅓ / ¼ + Opened menu lives behind a press). */
.qc-more { margin-left: 5px; opacity: .5; font-weight: 700; letter-spacing: 1px; }

/* Long-press portion/opened menu rendered inside the shared sheet. */
.qmenu { padding: 2px 0 6px; }
.qmenu-title {
  font-size: 13px; font-weight: 600; color: var(--label-2);
  text-align: center; padding: 2px 20px 10px;
}
.qmenu-item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; min-height: 52px; padding: 0 22px;
  background: transparent; border: 0; border-top: 1px solid var(--separator);
  color: var(--label); font-size: 17px; text-align: left; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.qmenu-item:active { background: var(--surface-2); }
.qmenu-meta { font-size: 13px; color: var(--label-2); font-weight: 400; }
.qmenu-opened { color: var(--tint); font-weight: 600; }
.qmenu-cancel { justify-content: center; color: var(--label-2); font-weight: 600; }

/* ── Capture / shutter button (Bag/Item modes) ───────────────────────── */
.capture-btn[disabled],
.capture-btn.busy {
  opacity: .55;
  pointer-events: none;
}
.capture-btn.busy::after {
  background: linear-gradient(135deg, var(--tint), var(--green));
  animation: pulse 1.2s ease-in-out infinite;
}
@keyframes pulse { 0%,100%{transform:scale(1)} 50%{transform:scale(.85)} }
.shutter-flash {
  position: fixed; inset: 0; background: #fff;
  z-index: 200; pointer-events: none;
  opacity: 0; transition: opacity .12s ease-out;
}
.shutter-flash.on { opacity: 0.85; }

/* Scene capture frame (Bag / Item modes) */
.scene-frame {
  width: min(85vw, 440px);
  height: min(60vh, 380px);
  max-height: 100%;   /* shrink within .scanner-mid as the photo queue grows */
  border: 2px dashed rgba(255,255,255,.7);
  border-radius: 22px;
  position: relative;
}
.scene-frame::before, .scene-frame::after,
.scene-frame > span {
  display: none;
}
.scanner-hint {
  transition: background .2s, color .2s;
}
.scanner-hint.busy {
  background: var(--tint);
}
.scanner-hint.busy::after {
  content: '';
  display: inline-block;
  width: 14px; height: 14px;
  border: 2px solid rgba(255,255,255,.4);
  border-top-color: #fff;
  border-radius: 50%;
  margin-left: 8px;
  vertical-align: -2px;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Bulk-review sheet ───────────────────────────────────────────────── */
.bulk-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 8px; }
.bulk-card {
  background: var(--surface-2);
  border: 1px solid var(--separator);
  border-radius: var(--radius-lg);
  padding: 12px;
  display: flex; flex-direction: column; gap: 10px;
  animation: bulk-pop .25s var(--ease-out);
}
@keyframes bulk-pop {
  from { transform: translateY(6px) scale(.98); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.bulk-card-head {
  display: flex; align-items: flex-start; gap: 10px;
}
.bulk-emoji {
  width: 40px; height: 40px;
  border-radius: 12px;
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; flex-shrink: 0;
  box-shadow: var(--shadow-1);
}
.bulk-card-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.bulk-name {
  background: var(--surface);
  font-weight: 700; font-size: 15px;
  padding: 8px 10px; border-radius: 8px;
}
.bulk-brand {
  background: var(--surface);
  font-size: 13px; color: var(--label-2);
  padding: 6px 10px; border-radius: 8px;
}
.bulk-x {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--surface);
  color: var(--label-2);
  font-size: 18px; font-weight: 600;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.bulk-x:active { background: var(--red); color: #fff; }
.bulk-card-row {
  display: flex; align-items: center; gap: 8px;
}
.bulk-card-row > * { flex: 1; min-width: 0; }
.bulk-card-row select, .bulk-card-row input { padding: 8px 10px; font-size: 14px; background: var(--surface); }
.qty-stepper.sm { padding: 2px; flex: 0 0 auto; }
.qty-stepper.sm button { width: 28px; height: 28px; font-size: 16px; }
.qty-stepper.sm input { width: 44px; font-size: 14px; }
.bulk-hint {
  font-size: 12px; color: var(--label-2);
  background: var(--surface);
  padding: 6px 10px; border-radius: 8px;
}
/* "Which photo did this item come from?" strip on a bag-scan review card. */
.bulk-photos {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin-top: 8px;
}
.bulk-photos-lbl { font-size: 11px; color: var(--label-2); }
.bulk-photo-thumb {
  width: 40px; height: 40px; padding: 0;
  border-radius: 8px; overflow: hidden;
  border: 1px solid var(--separator);
  cursor: pointer; flex-shrink: 0;
}
.bulk-photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bulk-photo-thumb:active { transform: scale(.94); }

/* ── Full-screen image viewer (lightbox) ───────────────────────────────── */
.img-viewer {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.92);
  padding: max(env(safe-area-inset-top), 16px) 16px max(env(safe-area-inset-bottom), 16px);
  opacity: 0; transition: opacity .2s var(--ease-out);
  touch-action: none;
}
.img-viewer.on { opacity: 1; }
.img-viewer-img {
  max-width: 100%; max-height: 100%;
  object-fit: contain; border-radius: 8px;
}
.img-viewer-x {
  position: absolute; top: calc(env(safe-area-inset-top) + 8px); right: 14px;
  width: 40px; height: 40px; border-radius: 50%;
  background: rgba(0,0,0,.55); color: #fff; font-size: 18px;
  display: flex; align-items: center; justify-content: center;
}
.img-viewer-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(0,0,0,.5); color: #fff; font-size: 30px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.img-viewer-nav.prev { left: 10px; }
.img-viewer-nav.next { right: 10px; }
.img-viewer-dots {
  position: absolute; bottom: calc(env(safe-area-inset-bottom) + 14px);
  left: 0; right: 0; display: flex; gap: 6px; justify-content: center;
}
.img-viewer-dots span {
  width: 7px; height: 7px; border-radius: 50%;
  background: rgba(255,255,255,.4);
}
.img-viewer-dots span.on { background: #fff; }
.bulk-prodnote {
  margin-top: 6px;
  font-size: 12px; color: var(--orange);
  background: color-mix(in srgb, var(--orange), transparent 88%);
  padding: 6px 10px; border-radius: 8px;
}
.conf-pill {
  font-size: 11px; font-weight: 700;
  padding: 3px 8px;
  border-radius: 999px;
  flex: 0 0 auto;
}
.conf-good { background: color-mix(in srgb, var(--green), transparent 80%); color: var(--green); }
.conf-mid  { background: color-mix(in srgb, var(--orange), transparent 80%); color: var(--orange); }
.conf-low  { background: color-mix(in srgb, var(--red), transparent 80%); color: var(--red); }
.bulk-bottom {
  position: sticky; bottom: 0;
  background: linear-gradient(to top, var(--surface) 70%, transparent);
  padding-top: 12px;
  margin: 0 -16px -8px;
  padding: 12px 16px 8px;
}
.btn-lg { min-height: 52px; font-size: 16px; }

/* ── Shopping list ───────────────────────────────────────────────────── */
.shopping-add {
  display: flex; gap: 8px; margin-bottom: 14px; align-items: center;
}
.shopping-add input {
  flex: 1; min-width: 0;
}
.shopping-add #shop-add-btn {
  width: 44px; flex-shrink: 0; padding: 0; font-size: 22px; line-height: 1;
}
.shop-row { gap: 12px; }
.shop-check {
  width: 24px; height: 24px;
  border-radius: 50%;
  border: 2px solid var(--separator);
  background: var(--surface);
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, border-color .15s;
}
.shop-check.checked {
  background: var(--green);
  border-color: var(--green);
}
.shop-check.checked::after {
  content: ''; width: 10px; height: 6px;
  border-left: 2px solid #fff; border-bottom: 2px solid #fff;
  transform: rotate(-45deg) translate(1px, -1px);
}
.shop-row-done .row-title, .shop-row-done .row-sub {
  text-decoration: line-through;
  color: var(--label-2);
}
.btn-pill {
  display: inline-flex; align-items: center;
  font-size: 12px; font-weight: 700;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--tint);
  color: #fff;
  white-space: nowrap;
  transition: transform .1s, opacity .15s;
  -webkit-tap-highlight-color: transparent;
}
.btn-pill:active { transform: scale(.94); opacity: .85; }
.btn-pill.ghost {
  background: var(--surface-2);
  color: var(--label-2);
  border: 1px solid var(--separator);
}

/* ── Swipe-to-action rows on Pantry ──────────────────────────────────── */
.swipe-wrap {
  position: relative;
  overflow: hidden;
}
.swipe-wrap + .swipe-wrap { border-top: 1px solid var(--separator); }
.list .swipe-wrap:first-child .swipe-row { border-top: 0; }
.swipe-row {
  position: relative;
  background: var(--surface);
  transition: transform .25s var(--ease-out);
  touch-action: pan-y;
  z-index: 1;
}
.swipe-actions {
  position: absolute; right: 0; top: 0; bottom: 0;
  display: flex;
  align-items: stretch;
  z-index: 0;
}
.swipe-action {
  width: 80px;
  font-weight: 700;
  color: #fff;
  font-size: 14px;
  border-radius: 0;
}
.sa-consume { background: var(--orange); }
.sa-discard { background: var(--red); }
.sa-delete { background: var(--red); }
.swipe-action:active { filter: brightness(.92); }

/* ── FAB long-press menu ─────────────────────────────────────────────── */
.fab-menu {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.fab-menu-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  background: var(--surface-2);
  border: 1px solid var(--separator);
  border-radius: var(--radius-lg);
  padding: 14px 14px;
  text-align: left;
  transition: transform .12s, background .15s;
}
.fab-menu-item:active { transform: scale(.97); background: var(--surface); }
.fab-menu-item .fme { font-size: 26px; line-height: 1; }
.fab-menu-item .fmt { font-weight: 700; font-size: 15px; }
.fab-menu-item .fms { font-size: 12px; color: var(--label-2); }

/* ── BAM analyze overlay ─────────────────────────────────────────────── */
.analyze-overlay {
  position: fixed; inset: 0; z-index: 220;
  background: rgba(0,0,0,.55);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .2s var(--ease-out);
  padding: 24px;
}
.analyze-overlay.on { opacity: 1; }
.analyze-card {
  background: var(--surface);
  border-radius: var(--radius-xl);
  padding: 22px 22px 18px;
  width: min(420px, calc(100vw - 48px));
  box-shadow: var(--shadow-3);
  text-align: center;
}
.analyze-spinner {
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 3px solid var(--separator);
  border-top-color: var(--tint);
  animation: spin .8s linear infinite;
  margin: 0 auto 10px;
}
.analyze-title { font-size: 17px; font-weight: 700; }
.analyze-sub { font-size: 13px; color: var(--label-2); margin: 4px 0 14px; }
.analyze-skel {
  display: grid; gap: 8px;
  text-align: left;
}
.analyze-skel .skel { height: 12px; }

/* ── Drag handle on shopping rows ────────────────────────────────────── */
.drag-handle {
  flex-shrink: 0;
  font-size: 14px; line-height: 1;
  color: var(--label-3);
  letter-spacing: -2px;
  padding: 0 4px;
  cursor: grab;
  user-select: none;
}
.shop-row[draggable="true"] { cursor: grab; }
.shop-row.dragging { opacity: .5; }
.shop-row.drop-above { box-shadow: inset 0 2px 0 var(--tint); }
.shop-row.drop-below { box-shadow: inset 0 -2px 0 var(--tint); }

/* ── Recipe cards ────────────────────────────────────────────────────── */
/* Recipe list (master) — tap a row to open the full recipe + refine. */
.recipe-list { display: flex; flex-direction: column; gap: 8px; }
.recipe-list-item {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 14px; border-radius: var(--radius-lg);
  background: var(--surface-2); text-align: left;
}
.recipe-list-item:active { background: var(--surface); transform: scale(.99); }
.recipe-list-item .recipe-emoji { font-size: 28px; flex-shrink: 0; }
.recipe-list-item .recipe-li-main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.recipe-list-item .recipe-title { font-weight: 700; font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recipe-list-item .recipe-meta { color: var(--label-2); font-size: 13px; margin-top: 2px; }
.recipe-list-item .recipe-li-arrow { color: var(--label-3); font-size: 22px; flex-shrink: 0; }
.recipe-back {
  display: inline-flex; align-items: center; gap: 4px; min-height: 36px;
  color: var(--tint); font-size: 15px; font-weight: 600; padding: 6px 4px; margin-bottom: 6px;
}
.recipe-spinner {
  width: 40px; height: 40px; margin: 0 auto 14px;
  border: 3px solid var(--separator); border-top-color: var(--tint);
  border-radius: 50%; animation: spin .8s linear infinite;
}
.recipe-card {
  background: var(--surface-2);
  border: 1px solid var(--separator);
  border-radius: var(--radius-lg);
  padding: 14px;
  margin-bottom: 12px;
  opacity: 0;
  transform: translateY(8px);
  animation: recipe-pop .42s var(--ease-out) forwards;
}
.recipe-card:nth-child(1) { animation-delay: .05s; }
.recipe-card:nth-child(2) { animation-delay: .14s; }
.recipe-card:nth-child(3) { animation-delay: .23s; }
.recipe-card:nth-child(4) { animation-delay: .32s; }
.recipe-card:nth-child(5) { animation-delay: .41s; }
.recipe-card:nth-child(6) { animation-delay: .50s; }
@keyframes recipe-pop {
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .recipe-card { opacity: 1; transform: none; animation: none; }
}
.recipe-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.recipe-emoji { font-size: 28px; line-height: 1; }
.recipe-main { flex: 1; min-width: 0; }
.recipe-title { font-size: 16px; font-weight: 700; }
.recipe-meta { font-size: 12px; color: var(--label-2); }
.recipe-tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 4px; }
.recipe-tag {
  font-size: 12px; font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
}
.recipe-tag.use {
  background: color-mix(in srgb, var(--green), transparent 82%);
  color: var(--green);
}
.recipe-tag.miss {
  background: var(--surface);
  color: var(--label-2);
  border: 1px dashed var(--separator);
}
.recipe-steps {
  margin: 8px 0 0;
  padding-left: 22px;
  font-size: 14px;
  color: var(--label);
}
.recipe-steps li { margin-bottom: 4px; }

/* ── Responsive stats strip ──────────────────────────────────────────── */
@media (max-width: 380px) {
  .stats-strip { grid-template-columns: 1fr 1fr; }
}

/* ── Live expiry-scan overlay ────────────────────────────────────────── */
.expiry-scan-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: #000;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.expiry-scan-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.expiry-scan-shade {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 280px 160px at 50% 50%, transparent 0, transparent 70%, rgba(0,0,0,0.55) 100%);
  pointer-events: none;
}
.expiry-scan-top {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: space-between;
  padding: max(env(safe-area-inset-top, 12px), 12px) 16px 12px;
  color: #fff;
}
.expiry-scan-title {
  font-weight: 600; font-size: 15px;
  background: rgba(0,0,0,.5);
  padding: 8px 14px; border-radius: 999px;
  backdrop-filter: blur(10px);
}
.expiry-scan-cancel {
  width: 40px; height: 40px;
  background: rgba(0,0,0,.5);
  color: #fff;
  border-radius: 999px;
  backdrop-filter: blur(10px);
  display: inline-flex; align-items: center; justify-content: center;
}
.expiry-scan-cancel svg { width: 22px; height: 22px; }
.expiry-scan-mid {
  flex: 1; position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: center;
}
.expiry-scan-frame {
  width: 280px; height: 160px;
  border: 2px solid rgba(255,255,255,.85);
  border-radius: 14px;
  box-shadow: 0 0 0 9999px rgba(0,0,0,0.18);
  position: relative;
}
.expiry-scan-frame::before,
.expiry-scan-frame::after {
  content: ''; position: absolute;
  width: 24px; height: 24px;
  border: 3px solid var(--tint, #007aff);
}
.expiry-scan-frame::before { top: -3px; left: -3px; border-right: 0; border-bottom: 0; border-top-left-radius: 14px; }
.expiry-scan-frame::after  { bottom: -3px; right: -3px; border-left: 0; border-top: 0; border-bottom-right-radius: 14px; }
.expiry-scan-bottom {
  position: relative; z-index: 2;
  padding: 16px 24px max(env(safe-area-inset-bottom, 16px), 24px);
  color: #fff;
  text-align: center;
  background: linear-gradient(to top, rgba(0,0,0,.55), transparent);
}
.expiry-scan-status {
  font-size: 15px; font-weight: 500;
  margin-bottom: 8px;
  min-height: 22px;
}
.expiry-scan-dots {
  font-size: 18px; letter-spacing: 4px; opacity: 0.85;
  min-height: 22px;
}

/* ── Search highlight ─────────────────────────────────────────────────── */
.row-title mark, .row-sub mark {
  background: color-mix(in srgb, var(--yellow), transparent 60%);
  color: var(--label);
  padding: 0 1px;
  border-radius: 3px;
}

/* ── Stats strip → tap hint ───────────────────────────────────────────── */
.stats-strip {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s var(--ease-out);
}
.stats-strip:active { transform: scale(.985); }
.stat-tap-hint {
  grid-column: 1 / -1;
  font-size: 11px; color: var(--label-3);
  text-align: right;
  padding-top: 2px;
  letter-spacing: 0.02em;
}

/* ── Predictions banner ───────────────────────────────────────────────── */
.predict-banner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  margin: 12px 0 0;
  background: color-mix(in srgb, var(--orange), transparent 86%);
  color: var(--orange);
  border: 1px solid color-mix(in srgb, var(--orange), transparent 70%);
  cursor: pointer;
}
.predict-banner:active { transform: scale(.99); }

/* ── Insights dashboard ───────────────────────────────────────────────── */
.insight-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  margin-bottom: 16px;
}
.insight-tile {
  background: var(--surface-2);
  border-radius: var(--radius-lg);
  padding: 14px;
}
.insight-num {
  font-size: 32px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.15;
}
.insight-num.insight-red { color: var(--red); }
.insight-num.insight-orange { color: var(--orange); }
.insight-num.insight-green { color: var(--green); }
.insight-lab { font-size: 13px; color: var(--label-2); margin-top: 6px; font-weight: 600; }
.insight-sub { font-size: 11px; color: var(--label-3); margin-top: 2px; }
.insight-section-title {
  font-size: 13px; font-weight: 700; color: var(--label-2);
  text-transform: uppercase; letter-spacing: 0.05em;
  margin: 16px 4px 8px;
}
.bar-stack { background: var(--surface-2); border-radius: var(--radius-lg); padding: 10px 14px; }
.bar-row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 0;
}
.bar-label { font-size: 13px; flex: 0 0 90px; color: var(--label-2); }
.bar-track {
  flex: 1; height: 10px;
  background: var(--surface);
  border-radius: 999px; overflow: hidden;
}
.bar-fill {
  height: 100%;
  border-radius: 999px;
  transition: width .5s var(--ease-out);
}
.bar-red { background: var(--red); }
.bar-orange { background: var(--orange); }
.bar-yellow { background: var(--yellow); }
.bar-green { background: var(--green); }
.bar-tint { background: var(--tint); }
.bar-gray { background: var(--gray); }
.bar-num { font-weight: 700; font-size: 13px; flex: 0 0 28px; text-align: right; }
.cat-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px;
}
.cat-tile {
  background: var(--surface-2);
  border-radius: var(--radius-md);
  padding: 12px;
  display: flex; align-items: center; gap: 10px;
  font-size: 14px;
  min-width: 0; overflow: hidden;
}
.cat-emoji { font-size: 22px; flex-shrink: 0; }
.cat-name {
  flex: 1; min-width: 0;
  font-weight: 600; text-transform: capitalize;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cat-num { color: var(--label-2); font-weight: 700; flex-shrink: 0; }

/* ── Voice capture sheet ──────────────────────────────────────────────── */
.voice-mic {
  width: 96px; height: 96px;
  border-radius: 50%;
  margin: 8px auto 14px;
  background: var(--tint); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 12px 28px color-mix(in srgb, var(--tint), transparent 60%);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .15s var(--ease-out);
}
.voice-mic:active { transform: scale(.93); }
.voice-mic svg { width: 40px; height: 40px; }
.voice-mic.listening {
  background: var(--red);
  animation: voice-pulse 1.25s ease-in-out infinite;
}
@keyframes voice-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--red), transparent 30%); }
  50%      { box-shadow: 0 0 0 22px color-mix(in srgb, var(--red), transparent 100%); }
}
.voice-status {
  font-weight: 600; font-size: 15px;
  margin-bottom: 6px;
  min-height: 22px;
}
.voice-transcript {
  background: var(--surface-2);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  min-height: 56px;
  text-align: left;
  font-size: 15px; line-height: 1.4;
  color: var(--label);
}
.voice-transcript:empty::before {
  content: '…';
  color: var(--label-3);
}

/* ── Pull-to-refresh indicator ────────────────────────────────────────── */
.ptr-indicator {
  position: absolute;
  left: 50%; top: -32px;
  transform: translateY(0);
  width: 32px; height: 32px;
  margin-left: -16px;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
  opacity: 0;
  z-index: 4;
}
.ptr-spin {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2.5px solid var(--separator);
  border-top-color: var(--tint);
  transition: transform .15s ease-out;
}
.ptr-indicator.ready .ptr-spin { transform: scale(1.15); border-top-color: var(--green); }
.ptr-indicator.refreshing .ptr-spin { animation: spin .8s linear infinite; }

.view { position: relative; }

/* ── Receipt: price pill on bulk cards ────────────────────────────────── */
.price-pill {
  font-size: 12px; font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--surface);
  color: var(--label);
  flex: 0 0 auto;
}

/* ── Scan: torch button ───────────────────────────────────────────────── */
#scan-torch {
  background: rgba(0,0,0,.5); color: #fff; backdrop-filter: blur(10px);
  transition: background .15s, color .15s;
}
#scan-torch.active {
  background: var(--yellow);
  color: #1c1c1e;
}

/* ── Onboarding overlay ───────────────────────────────────────────────── */
.onboard-overlay {
  position: fixed; inset: 0; z-index: 300;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--tint), transparent 70%),
    color-mix(in srgb, var(--surface), transparent 0%) 60%);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px;
  opacity: 0; transition: opacity .25s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.onboard-overlay.on { opacity: 1; }
.onboard-card {
  position: relative;
  width: 100%; max-width: 420px;
  background: var(--surface);
  border-radius: var(--radius-xl);
  padding: 28px 22px 22px;
  box-shadow: var(--shadow-3);
  text-align: center;
  animation: onb-in .35s var(--ease-out);
}
@keyframes onb-in {
  from { transform: translateY(12px) scale(.96); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.onboard-skip {
  position: absolute; top: 8px; right: 10px;
  width: 32px; height: 32px;
  font-size: 24px; line-height: 1;
  color: var(--label-2);
  border-radius: 50%;
}
.onboard-skip:active { background: var(--surface-2); }
.onboard-hero {
  font-size: 64px; line-height: 1;
  margin-bottom: 12px;
  filter: drop-shadow(0 6px 16px color-mix(in srgb, var(--tint), transparent 70%));
  animation: onb-bob 2.4s ease-in-out infinite;
}
@keyframes onb-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
.onboard-title {
  font-size: 24px; font-weight: 800;
  letter-spacing: -0.02em;
  margin-bottom: 8px;
}
.onboard-body {
  font-size: 15px; color: var(--label-2);
  margin-bottom: 16px;
  line-height: 1.4;
}
.onboard-bullets {
  text-align: left;
  background: var(--surface-2);
  border-radius: var(--radius-lg);
  padding: 12px 14px;
  margin-bottom: 16px;
}
.onboard-bullet {
  display: flex; align-items: center; gap: 12px;
  padding: 6px 0;
  font-size: 14px;
}
.ob-emo {
  width: 36px; height: 36px;
  border-radius: 12px;
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  font-size: 20px;
  flex-shrink: 0;
}
.onboard-key {
  background: var(--surface-2);
  border-radius: var(--radius-md);
  padding: 12px 12px 8px;
  margin-bottom: 14px;
  text-align: left;
}
.onboard-key-label { font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.onboard-key-row { display: flex; gap: 8px; }
.onboard-key-row input { background: var(--surface); flex: 1; }
.onboard-key-hint { font-size: 11px; margin-top: 6px; line-height: 1.35; }
.onboard-key-ok {
  background: color-mix(in srgb, var(--green), transparent 85%);
  color: var(--green);
  border-radius: var(--radius-md);
  padding: 10px;
  font-weight: 700; font-size: 14px;
  margin-bottom: 14px;
}
.onboard-cta { margin-top: 4px; }
.onboard-dots {
  display: flex; gap: 6px; margin-top: 18px;
}
.onboard-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: rgba(255,255,255,.4);
  transition: background .2s, transform .2s;
}
.onboard-dot.active {
  background: #fff;
  transform: scale(1.4);
}
@media (prefers-color-scheme: dark) {
  .onboard-dot { background: rgba(255,255,255,.25); }
  .onboard-dot.active { background: #fff; }
}

/* ── Auth screen polish: gradient background + animated icon ──────────── */
.auth-bg {
  position: absolute; inset: 0;
  overflow: hidden; pointer-events: none;
  z-index: 0;
}
.bg-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(64px);
  opacity: 0.45;
  animation: blob 22s ease-in-out infinite;
}
.bg-blob.b1 {
  width: 360px; height: 360px;
  background: var(--tint);
  top: -80px; left: -100px;
  animation-delay: 0s;
}
.bg-blob.b2 {
  width: 320px; height: 320px;
  background: var(--green);
  bottom: -60px; right: -120px;
  animation-delay: -7s;
}
.bg-blob.b3 {
  width: 240px; height: 240px;
  background: var(--orange);
  bottom: 30%; left: 20%;
  animation-delay: -14s;
  opacity: 0.25;
}
@keyframes blob {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33%      { transform: translate(40px, -28px) scale(1.08); }
  66%      { transform: translate(-30px, 20px) scale(.94); }
}
.auth-card { position: relative; z-index: 1; }
.auth-icon {
  position: relative;
  font-size: 56px; line-height: 1; margin-bottom: 16px;
}
.auth-icon-jar {
  display: inline-block;
  animation: jar-bob 3s ease-in-out infinite;
}
.auth-icon-spark {
  position: absolute; top: -6px; right: 50%;
  margin-right: -42px;
  font-size: 24px;
  animation: spark 2.4s ease-in-out infinite;
}
@keyframes jar-bob {
  0%, 100% { transform: translateY(0) rotate(0); }
  50%      { transform: translateY(-6px) rotate(-3deg); }
}
@keyframes spark {
  0%, 100% { transform: scale(1) rotate(0); opacity: 0.9; }
  50%      { transform: scale(1.2) rotate(20deg); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .auth-icon-jar, .auth-icon-spark, .bg-blob { animation: none; }
}

/* ── Hero empty pantry state ──────────────────────────────────────────── */
/* Empty-state hero: deliberately compact so the four scan actions fit above
   the fixed tab bar on a typical phone (≈ 750–800 px content area) without
   forcing the user to scroll on first paint. The action list still scrolls
   if the device is shorter. */
.hero-empty { padding-top: 8px; padding-bottom: 16px; }
.hero-emoji-stack {
  position: relative;
  width: 92px; height: 92px;
  margin: 0 auto 8px;
}
.hero-emoji {
  position: absolute;
  font-size: 34px;
  filter: drop-shadow(0 6px 12px rgba(0,0,0,.12));
  animation: hero-bob 3.6s ease-in-out infinite;
}
.hero-emoji.e1 { top: 6px;  left: 4px;   animation-delay: 0s; }
.hero-emoji.e2 { top: 0;    right: 6px;  animation-delay: -.8s; }
.hero-emoji.e3 { bottom: 0; left: 16px;  animation-delay: -1.6s; }
.hero-emoji.e4 { bottom: 2px; right: 0;  animation-delay: -2.4s; }
@keyframes hero-bob {
  0%, 100% { transform: translateY(0) rotate(0); }
  50%      { transform: translateY(-8px) rotate(4deg); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-emoji { animation: none; }
}
.hero-empty .empty-title { margin-top: 4px; }
.hero-actions {
  display: grid; gap: 6px;
  margin-top: 12px;
  max-width: 360px;
  margin-left: auto; margin-right: auto;
}
.hero-action {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface);
  border: 1px solid var(--separator);
  border-radius: var(--radius-lg);
  padding: 9px 12px;
  text-align: left;
  transition: transform .12s, background .15s;
  -webkit-tap-highlight-color: transparent;
}
.hero-action:active { transform: scale(.98); background: var(--surface-2); }
.hero-action .ha-emo {
  width: 34px; height: 34px;
  border-radius: 10px;
  background: var(--surface-2);
  display: flex; align-items: center; justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
}
.hero-action .ha-main { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.hero-action .ha-title { font-size: 14px; font-weight: 700; line-height: 1.2; }
.hero-action .ha-sub { font-size: 12px; color: var(--label-2); line-height: 1.25; }
.hero-action .ha-arrow { color: var(--label-3); font-size: 20px; }

/* ── Coach tips (one-time discoverability) ────────────────────────────── */
.coach-tip {
  position: fixed; z-index: 250;
  background: var(--label);
  color: var(--surface);
  font-size: 13px; font-weight: 600;
  padding: 10px 36px 10px 14px;
  border-radius: 10px;
  max-width: 240px;
  box-shadow: var(--shadow-2);
  opacity: 0;
  transform: scale(.94);
  transition: opacity .2s, transform .2s var(--ease-out);
  pointer-events: auto;
}
.coach-tip.on { opacity: 1; transform: scale(1); }
.coach-tip::before {
  content: '';
  position: absolute;
  width: 0; height: 0;
}
.coach-tip.coach-right::before {
  left: -6px; top: 50%; margin-top: -6px;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-right: 6px solid var(--label);
}
.coach-tip.coach-top::before {
  bottom: -6px; left: 50%; margin-left: -6px;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid var(--label);
}
.coach-x {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 24px; height: 24px;
  font-size: 16px; line-height: 1;
  color: var(--surface);
  border-radius: 50%;
}
.coach-x:active { background: rgba(255,255,255,.15); }

/* ── Tab cross-fade transition ────────────────────────────────────────── */
.view {
  opacity: 1;
  transition: opacity .22s var(--ease-out);
}
.view.view-enter {
  opacity: 0;
  transform: translateY(2px);
  transition: none;
}
.view.view-entered {
  opacity: 1;
  transform: translateY(0);
  transition: opacity .22s var(--ease-out), transform .22s var(--ease-out);
}
@media (prefers-reduced-motion: reduce) {
  .view, .view.view-enter, .view.view-entered {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
}

/* ── Multi-select toolbar + selected row ──────────────────────────────── */
.select-bar {
  position: sticky; top: calc(var(--safe-top) + 0px); z-index: 6;
  display: flex; align-items: center; gap: 12px;
  background: var(--tint); color: #fff;
  padding: 10px 12px;
  margin: 0 -16px 12px;
  box-shadow: 0 4px 12px color-mix(in srgb, var(--tint), transparent 70%);
  animation: sb-slide .22s var(--ease-out);
}
@keyframes sb-slide {
  from { transform: translateY(-12px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.sb-cancel {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: rgba(255,255,255,.2);
  color: #fff; font-size: 22px; line-height: 1;
}
.sb-count { font-weight: 700; font-size: 15px; }
.select-bar .btn-pill { background: rgba(255,255,255,.22); color: #fff; }
.select-bar .btn-pill:active { background: rgba(255,255,255,.32); }

.swipe-row.row-selected {
  background: color-mix(in srgb, var(--tint), transparent 88%);
  box-shadow: inset 3px 0 0 var(--tint);
}
.swipe-row.row-selected::after {
  content: '✓';
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px;
  background: var(--tint); color: #fff;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700;
}

/* ── Aisle grouping toolbar + headers ─────────────────────────────────── */
.aisle-toolbar {
  display: flex; justify-content: flex-end;
  margin: 4px 0 -4px;
}
.aisle-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-2);
  border: 1px solid var(--separator);
  color: var(--label);
  font-size: 13px; font-weight: 600;
  padding: 6px 12px;
  border-radius: 999px;
  transition: background .15s, color .15s, transform .1s;
}
.aisle-toggle:active { transform: scale(.96); }
.aisle-toggle.on {
  background: var(--tint); color: #fff;
  border-color: var(--tint);
}
.aisle-toggle.busy { opacity: .7; pointer-events: none; }
.list-section-title.aisle-title {
  display: flex; align-items: center; gap: 8px;
  text-transform: none; letter-spacing: 0;
  font-weight: 700; font-size: 14px;
  color: var(--label);
  padding-top: 14px;
}
.aisle-emoji { font-size: 18px; line-height: 1; }

/* ── Bag-mode multi-shot queue ──────────────────────────────────────────── */
/* A horizontal thumbnail strip that appears in the scanner overlay as the
   user queues photos. The Analyze button sits below the shutter and shows
   the live queue count. Both hide when the queue is empty. */
.bag-queue {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 0 16px 8px;
  scrollbar-width: thin;
}
.bag-queue::-webkit-scrollbar { height: 4px; }
.bag-queue-thumb {
  position: relative;
  flex: 0 0 auto;
  width: 56px; height: 56px;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.4);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}
.bag-queue-thumb img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.bag-queue-x {
  position: absolute;
  top: 2px; right: 2px;
  width: 20px; height: 20px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  font-size: 14px; line-height: 18px;
  padding: 0;
  cursor: pointer;
}
.bag-queue-x:active { background: rgba(0, 0, 0, 0.9); }
/* Little badge on a queued thumb when we decoded a barcode from it. */
.bag-queue-bc {
  position: absolute;
  bottom: 2px; left: 2px;
  font-size: 12px; line-height: 1;
  background: rgba(0, 0, 0, 0.6);
  border-radius: 6px;
  padding: 2px 3px;
}
/* Analyze button sits inside .scanner-actions next to the shutter so the
   tab-bar / safe-area can't clip it (the previous full-width-below layout
   pushed it off screen on shorter viewports). */
.bag-analyze {
  align-self: center;
  min-height: 48px;
  padding: 0 18px;
  font-weight: 600;
  white-space: nowrap;
}
.bag-analyze[disabled] { opacity: 0.6; }

/* ── Shopping list quick-add: voice + barcode buttons ────────────────────── */
.shopping-add .shop-add-icon {
  width: 40px; height: 40px;
  font-size: 18px;
  flex-shrink: 0;
}
.shopping-add .shop-add-icon svg { width: 18px; height: 18px; }

/* Voice quick-add overlay ─ centered card with a pulsing mic. */
.voice-overlay {
  position: fixed; inset: 0;
  z-index: 1000;
  background: rgba(0, 0, 0, 0.6);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: fadeIn .18s ease-out;
}
.voice-card {
  background: var(--surface);
  border-radius: 20px;
  padding: 28px 24px;
  max-width: 360px; width: 100%;
  display: flex; flex-direction: column; gap: 16px; align-items: center;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
}
.voice-pulse {
  width: 76px; height: 76px;
  border-radius: 50%;
  background: var(--tint);
  display: flex; align-items: center; justify-content: center;
  font-size: 36px;
  animation: voicePulse 1.4s ease-in-out infinite;
}
@keyframes voicePulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 color-mix(in srgb, var(--tint), transparent 50%); }
  50%      { transform: scale(1.06); box-shadow: 0 0 0 14px color-mix(in srgb, var(--tint), transparent 100%); }
}
.voice-title { font-size: 17px; font-weight: 600; color: var(--label); }
.voice-sub {
  font-size: 14px; color: var(--label-2);
  text-align: center; min-height: 1.4em;
  line-height: 1.4;
}

/* Shopping barcode scan overlay ─ full-screen camera. */
.shop-scan-overlay {
  position: fixed; inset: 0;
  z-index: 1000;
  background: #000;
  display: flex; flex-direction: column;
  animation: fadeIn .18s ease-out;
}
.shop-scan-overlay video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.shop-scan-top, .shop-scan-bottom {
  position: relative; z-index: 2;
  padding: 16px;
  display: flex; align-items: center; gap: 12px;
  color: #fff;
}
.shop-scan-top {
  background: linear-gradient(to bottom, rgba(0,0,0,0.55), rgba(0,0,0,0));
  padding-top: max(16px, env(safe-area-inset-top));
}
.shop-scan-bottom {
  margin-top: auto;
  background: linear-gradient(to top, rgba(0,0,0,0.55), rgba(0,0,0,0));
  padding-bottom: max(16px, env(safe-area-inset-bottom));
  justify-content: center;
}
.shop-scan-title { font-weight: 600; flex: 1; }
.shop-scan-cancel {
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: 22px;
  line-height: 1;
}
.shop-scan-mid {
  flex: 1; position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: center;
}
.shop-scan-reticle {
  width: min(280px, 76vw); height: 170px;
  border: 2px solid rgba(255, 255, 255, 0.75);
  border-radius: 16px;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.35);
}
.shop-scan-hint {
  font-size: 14px;
  background: rgba(0, 0, 0, 0.45);
  border-radius: 999px;
  padding: 8px 14px;
}

@keyframes fadeIn {
  from { opacity: 0; } to { opacity: 1; }
}

/* ── Bulk review extras ───────────────────────────────────────────────── */
/* Inline "already have N" badge + merge button + merge picker list.
   Appended (not inserted) so the original .bulk-card rules above stay
   untouched; these only add new selectors. */
.bulk-card-actions {
  display: flex; flex-direction: column; align-items: center;
  gap: 4px; flex-shrink: 0;
}
.bulk-merge {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--surface);
  color: var(--label-2);
  font-size: 14px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.bulk-merge:active { background: var(--blue); color: #fff; }
.bulk-existing-badge {
  display: inline-flex; align-items: center; gap: 4px;
  align-self: flex-start;
  margin-top: 2px;
  font-size: 11px; font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--blue), transparent 85%);
  color: var(--blue);
}
.bulk-merge-list {
  display: flex; flex-direction: column; gap: 8px;
  margin-bottom: 12px;
}
.bulk-merge-target {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  border: 1px solid var(--separator);
  text-align: left;
  font-size: 14px;
  color: var(--label-1);
}
.bulk-merge-target:active { background: var(--surface); }
.bulk-merge-emoji { font-size: 20px; flex-shrink: 0; }
.bulk-merge-name { flex: 1; min-width: 0; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bulk-merge-qty { font-size: 12px; color: var(--label-2); flex-shrink: 0; }

/* One-tap "use estimated expiry" chip — shown only when no real date was read
   and the category has a shelf-life estimate. Dashed to read as a suggestion. */
.bulk-est {
  margin-top: 6px;
  font-size: 12px; font-weight: 600;
  color: var(--tint);
  background: color-mix(in srgb, var(--tint), transparent 90%);
  border: 1px dashed color-mix(in srgb, var(--tint), transparent 50%);
  border-radius: 999px;
  padding: 4px 10px;
}
.bulk-est:active { background: color-mix(in srgb, var(--tint), transparent 80%); }

/* ── Shopping row edit + barcode-overlay torch ───────────────────────── */
/* Inline pencil button sits between the row body and the delete x.
   Smaller than the default .btn-icon (44×44) so it fits the row chrome. */
.shop-row .shop-edit {
  width: 36px; height: 36px;
  background: transparent;
  color: var(--label-2);
  flex-shrink: 0;
}
.shop-row .shop-edit svg { width: 16px; height: 16px; }
.shop-row .shop-edit:active { background: var(--surface-2); }
.shop-row-done .shop-edit { opacity: .3; }

/* Torch in the shopping-list barcode overlay mirrors the Scan view —
   translucent dark chip, white icon, "active" state gets the tint. */
.shop-scan-top .shop-scan-torch {
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  width: 38px; height: 38px;
}
.shop-scan-top .shop-scan-torch svg { width: 18px; height: 18px; }
.shop-scan-top .shop-scan-torch.active {
  background: var(--tint);
  color: #fff;
}

/* ── Rich recipe template (ingredients table, steps with chips, nutrition) ── */
/* "Prioritize expiring soon" checkbox above the recipes list. */
.recipes-toggle {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  margin-bottom: 12px;
  background: var(--surface-2);
  border-radius: 10px;
  font-size: 14px;
  color: var(--label);
  cursor: pointer;
}
.recipes-toggle input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--tint); }

.recipe-section { margin-top: 12px; }
.recipe-section-title {
  font-size: 13px; font-weight: 600;
  color: var(--label-2);
  text-transform: uppercase; letter-spacing: 0.04em;
  margin-bottom: 6px;
}

/* Ingredients table: name | qty | pill. Compact, dense, scannable. */
.recipe-ings {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.recipe-ings tr + tr { border-top: 1px solid var(--separator); }
.recipe-ings td { padding: 6px 0; vertical-align: middle; }
.recipe-ings .ing-name { color: var(--label); }
.recipe-ings .ing-qty { color: var(--label-2); text-align: right; padding-right: 10px; white-space: nowrap; }
.recipe-ings .ing-tag { text-align: right; width: 1%; white-space: nowrap; }
.ing-pill {
  display: inline-block;
  font-size: 11px; font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  letter-spacing: 0.02em;
}
.ing-pill.have    { background: color-mix(in srgb, var(--green), transparent 80%); color: var(--green); }
.ing-pill.staple  { background: var(--surface-2); color: var(--label-2); }
.ing-pill.missing { background: color-mix(in srgb, var(--orange), transparent 80%); color: var(--orange); }

/* Numbered steps with optional temperature / time / setting chips. */
.recipe-steps {
  margin: 0; padding: 0 0 0 22px;
  color: var(--label);
  font-size: 14px; line-height: 1.45;
}
.recipe-steps li { margin: 6px 0; }
.step-body {}
.step-chips {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin-top: 4px;
}
.step-chip {
  display: inline-flex; align-items: center;
  font-size: 11px; font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tint), transparent 88%);
  color: var(--tint);
}

/* Nutrition estimate row — labeled as approximate, never exact. */
.recipe-nutrition .nut-row {
  display: flex; flex-wrap: wrap; gap: 8px 14px;
  font-size: 13px;
  color: var(--label-2);
}
.recipe-nutrition .nut b { color: var(--label); font-weight: 700; }

/* ── Recipe refinement: chips above the card + inline ingredient actions ── */
/* Refinement chips are a visible history of the user's applied notes. Tap
   one to remove THAT change (chained refinements re-run server-side). */
.refine-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 8px 0 4px;
}
.refine-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600;
  padding: 4px 4px 4px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tint), transparent 88%);
  color: var(--tint);
  border: 1px solid color-mix(in srgb, var(--tint), transparent 60%);
  cursor: pointer;
  max-width: 100%;
}
.refine-chip[disabled] { opacity: 0.5; cursor: default; }
.refine-chip > span:first-child {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px;
}
.refine-chip .x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px;
  background: var(--tint); color: #fff;
  border-radius: 50%; font-size: 11px; line-height: 1;
}

/* Free-text refinement row at the bottom of the card. */
.refine-row {
  display: flex; gap: 8px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--separator);
}
.refine-row .refine-input {
  flex: 1; min-width: 0;
}
.refine-row .refine-apply { white-space: nowrap; flex-shrink: 0; }

/* ── Recipe Q&A (Ask) — explains the recipe; separate from Refine ───────── */
.recipe-ask { margin-top: 4px; }
.ask-thread {
  display: flex; flex-direction: column; gap: 8px;
  margin-bottom: 10px;
}
.ask-q, .ask-a {
  max-width: 88%;
  padding: 8px 12px; border-radius: 14px;
  font-size: 14px; line-height: 1.4;
  white-space: pre-wrap; word-break: break-word;
}
.ask-q {
  align-self: flex-end;
  background: var(--tint); color: #fff;
  border-bottom-right-radius: 4px;
}
.ask-a {
  align-self: flex-start;
  background: var(--surface-2); color: var(--label);
  border-bottom-left-radius: 4px;
}
.ask-typing { letter-spacing: 2px; opacity: 0.6; }
.ask-row { display: flex; gap: 8px; align-items: center; }
.ask-row .ask-input {
  flex: 1; min-width: 0;
  padding: 8px 12px; font-size: 14px;
  background: var(--surface);
  border: 1px solid var(--separator); border-radius: 10px;
  color: var(--label);
}
.ask-row .ask-send { white-space: nowrap; flex-shrink: 0; }

/* "Add recipe from photo" toolbar above the saved list. */
.saved-toolbar { margin-bottom: 12px; }

/* Inline per-missing-ingredient actions: "I have" / "+🛒". Sit under the
   ingredient name so they don't break the qty/pill column alignment. */
.ing-actions {
  display: flex; gap: 6px;
  margin-top: 4px;
}
.ing-actions .ing-act {
  font-size: 11px; font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--label-2);
  border: 1px solid var(--separator);
}
.ing-actions .ing-act:active { background: var(--surface); color: var(--label); }

/* While a refine call is in-flight, dim the card to signal something's
   happening — buttons inside the card already have [disabled] set. */
.recipe-card.refining { opacity: 0.7; pointer-events: none; }
.recipe-card.refining .refine-row,
.recipe-card.refining .refine-chip { pointer-events: auto; }

/* Settings: chip-style display of the current staples list above the editor. */
.staples-list {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 6px 0 8px;
}
.staples-list .staple-chip {
  font-size: 12px; font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--label-2);
}

/* Saved recipes list row — uses the existing .list-row chrome; saved-thumb
   centers the emoji big and friendly. */
.saved-row { cursor: pointer; }
.saved-row .saved-thumb {
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
  background: var(--surface-2);
}

/* Live-update overlay — full-screen dim + centered card with a spinner, shown
   while the server pulls the latest code and restarts. Reuses @keyframes spin. */
.restart-overlay {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  animation: fade-in .18s ease both;
}
.restart-overlay[hidden] { display: none; }
.restart-card {
  background: var(--surface); border-radius: var(--radius-lg, 18px);
  padding: 32px 28px; text-align: center; max-width: 320px; width: 100%;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
}
.restart-spinner {
  width: 38px; height: 38px; margin: 0 auto 18px;
  border: 3px solid var(--separator);
  border-top-color: var(--tint);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
.restart-title { font-size: 17px; font-weight: 700; color: var(--label); margin-bottom: 6px; }
.restart-sub { font-size: 13px; line-height: 1.5; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
