/* shared/modules.css — extra components used by module views */
.alert-banner { background:#FEF3C7; color:#92400E; border-left:4px solid var(--warning); padding:12px 16px; border-radius:var(--radius-sm); margin-bottom:16px; display:flex; align-items:center; gap:8px; font-size:14px; font-weight:600; }
.chip-row { display:flex; flex-wrap:wrap; gap:8px; }
.help-steps { margin:0; padding-left:22px; }
.help-steps li { margin-bottom:10px; font-size:14px; line-height:1.55; }
.help-steps li:last-child { margin-bottom:0; }
.help-ic { display:flex; align-items:center; justify-content:center; width:34px; height:34px;
  border-radius:50%; background:var(--brand-soft); color:var(--brand-strong); flex-shrink:0; }
.trip-charge { display:flex; gap:10px; align-items:flex-start; padding:12px; margin-bottom:12px; background:var(--brand-soft);
  border:1px solid var(--brand); border-radius:var(--radius-sm); font-size:14px; font-weight:600; color:var(--ink); cursor:pointer; }
.trip-charge input { width:22px; height:22px; flex-shrink:0; accent-color:var(--brand); }
.sort-bar { display:flex; align-items:center; gap:10px; margin-bottom:12px; }
.sort-label { font-size:12px; font-weight:700; color:var(--text-secondary); text-transform:uppercase; letter-spacing:.08em; }
.sort-select { flex:1; min-height:44px; padding:8px 14px; border:2px solid var(--brand); border-radius:999px;
  background:var(--surface); color:var(--ink); font-size:14px; font-weight:700; cursor:pointer; }
.product-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(140px,1fr)); gap:8px; margin-bottom:16px; }
.product-card { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-sm); padding:14px; text-align:center; cursor:pointer; box-shadow:var(--elev-1); transition:var(--transition); }
.product-card.selected { border-color:var(--gold-primary); background:var(--gold-pale); }
.product-card:active { transform:scale(.97); }
.product-name { font-size:13px; font-weight:700; margin-bottom:4px; }
.product-price { font-size:15px; color:var(--ink); font-weight:800; }
.product-stock { font-size:12px; color:var(--text-secondary); }
.product-stock.low { color:var(--warning); font-weight:700; }
.product-stock.critical { color:var(--danger); font-weight:800; }
.cart-panel { background:var(--white); border:1px solid rgba(20,16,11,.06); border-radius:var(--radius); padding:16px; margin-bottom:16px; box-shadow:var(--elev-1); }
.cart-item { display:flex; justify-content:space-between; padding:8px 0; border-bottom:1px solid var(--border); font-size:14px; }
.cart-total { display:flex; justify-content:space-between; padding-top:12px; font-size:18px; font-weight:800; color:var(--ink); }
.activity-item { display:flex; gap:10px; align-items:center; padding:10px 12px; background:var(--inset); border-radius:var(--radius-sm); margin-bottom:8px; font-size:13px; }
.activity-time { font-weight:700; color:var(--muted); min-width:44px; }
.pnl-row { display:flex; justify-content:space-between; padding:12px; background:var(--inset); border-radius:var(--radius-sm); margin-bottom:8px; font-size:14px; gap:8px; }
.pnl-row .neg { color:var(--danger); font-weight:800; }
.pnl-row .pos { color:var(--success); font-weight:800; }
.stock-dot { width:12px; height:12px; border-radius:50%; flex-shrink:0; }
.stock-dot.healthy{background:var(--success);} .stock-dot.low{background:var(--warning);} .stock-dot.critical{background:var(--danger);}
.profile-card { background:var(--white); border:1px solid rgba(20,16,11,.06); border-radius:var(--radius); padding:14px; margin-bottom:14px; display:flex; align-items:center; gap:12px; box-shadow:var(--elev-1); }
.avatar { width:44px; height:44px; border-radius:50%; background:var(--brand); color:var(--on-brand); display:flex; align-items:center; justify-content:center; font-size:18px; font-weight:800; flex-shrink:0; }
.quick-actions { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-bottom:20px; }
.quick-btn { padding:16px 14px; min-height:64px; font-size:14px; flex-direction:column; gap:4px; border-radius:var(--radius-sm); }
.quick-btn-primary { background:var(--brand); color:var(--on-brand); }
.quick-btn-secondary { background:var(--gold-pale); color:var(--gold-dark); border:2px solid var(--gold-light); }
.transaction-item { display:flex; justify-content:space-between; padding:12px; background:var(--inset); border-radius:var(--radius-sm); margin-bottom:8px; }
.transaction-date { font-size:12px; color:var(--text-secondary); }
.transaction-amount { font-weight:800; }

/* floating cart button + quantity controls */
.fab-cart { position: fixed; right: 16px; bottom: calc(var(--bottom-chrome) + 22px); z-index: 90; display: flex; align-items: center; gap: 10px; background: var(--brand); color: var(--on-brand); border: none; border-radius: 999px; padding: 14px 18px; font-weight: 800; font-size: 14px; box-shadow: var(--elev-3); cursor: pointer; animation: slideIn 0.3s ease; }
.fab-cart .fab-count { background: var(--shell); color: var(--gold-light); border-radius: 999px; padding: 2px 10px; font-size: 12px; font-weight: 800; }
.cart-row { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.qty-btn { width: 44px; height: 44px; border-radius: 50%; border: 2px solid var(--gold-primary); background: var(--white); color: var(--gold-dark); font-size: 18px; font-weight: 800; cursor: pointer; flex-shrink: 0; }
.qty-btn:active { transform: scale(.9); }
.card-stepper { display:flex; align-items:center; justify-content:center; gap:8px; margin-top:6px; }

.search-wrap { position:relative; }
.search-wrap .input-field { padding-right:48px; }
.search-clear { position:absolute; right:2px; top:50%; transform:translateY(-50%); width:44px; height:44px; border:none; background:none; color:var(--text-secondary); font-size:22px; line-height:1; cursor:pointer; border-radius:50%; }
.search-clear:active { background:var(--inset); }
.search-results { margin-top:6px; border:1px solid var(--border); border-radius:var(--radius-sm); overflow:hidden; background:var(--white); }
.search-result { display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%; min-height:44px; padding:10px 12px; border:none; border-bottom:1px solid var(--border); background:none; color:var(--text-primary); font-size:14px; font-weight:600; text-align:left; cursor:pointer; }
.search-result:last-child { border-bottom:none; }
.search-result:active { background:var(--inset); }
.search-chosen { margin-top:6px; display:flex; align-items:center; gap:6px; font-size:13px; font-weight:700; color:var(--success); }
.search-empty { margin-top:6px; display:flex; flex-direction:column; align-items:flex-start; gap:8px; }
.card-qty { min-width:44px; min-height:44px; padding:0 6px; border:none; background:none; color:var(--text-primary); font-size:16px; font-weight:800; cursor:pointer; border-radius:var(--radius-sm); }
.card-qty:active { background:var(--inset); }

.confirm-row { display:flex; justify-content:space-between; align-items:baseline; gap:12px; padding:9px 6px; border-bottom:1px solid var(--border); font-size:14px; }
.confirm-row:last-child { border-bottom:none; }
.confirm-row span { color:var(--text-secondary); }
.list-item { cursor:pointer; }

/* pointer devices only - a touch screen keeps hover styles stuck after a tap */
@media (hover: hover) and (pointer: fine) {
  .product-card { transition: transform 150ms cubic-bezier(0.22,1,0.36,1), box-shadow 150ms ease, border-color 150ms ease; }
  .product-card:hover { transform: translate3d(0,-2px,0); box-shadow: var(--elev-2); border-color: var(--gold-primary); }
  .list-item { transition: background 150ms ease; }
  .list-item:hover { background: var(--inset); }
  .search-result:hover { background: var(--inset); }
  .qty-btn:hover, .card-qty:hover, .search-clear:hover { background: var(--gold-pale); }
  .nav-item:hover { color: var(--gold-dark); }
  .btn:hover { filter: brightness(1.04); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}
.pay-trail { font-size:12px; color:var(--text-secondary); padding:3px 0 0 2px; display:flex; align-items:center; gap:5px; }
.product-card { position:relative; }
.promo-badge { position:absolute; top:-7px; right:6px; background:var(--danger); color:#fff; font-size:9px; font-weight:800; letter-spacing:.06em; padding:2px 6px; border-radius:9px; }
.promo-was { color:var(--text-secondary); font-weight:600; margin-right:4px; }
.promo-tag { background:var(--danger); color:#fff; font-size:9px; font-weight:800; padding:1px 5px; border-radius:7px; }

/* the basket count is the "did that register?" signal - it replays on every change */
@keyframes countPop { 0% { transform: scale(1); } 40% { transform: scale(1.3); } 100% { transform: scale(1); } }
@keyframes fabIn { from { transform: scale(.94); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.fab-cart { animation: fabIn 200ms cubic-bezier(0.22,1,0.36,1); }
.fab-cart .fab-count { display:inline-block; animation: countPop 280ms cubic-bezier(0.22,1,0.36,1); }

/* one switch the vendor controls, for a slow phone or simply a preference */
:root[data-motion="off"] *, :root[data-motion="off"] *::before, :root[data-motion="off"] *::after {
  animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important;
}

/* --- the door --- */
.door-motif { width:132px; height:104px; display:block; margin:0 auto 12px; }
.pin-display { justify-content: center; }
.pin-note { font-size:13px; min-height:20px; margin-top:4px; color:var(--gold-light); }
.pin-note-error { color:#FFB4AB; font-weight:700; }
.pin-pad-locked { opacity:.45; pointer-events:none; }
@keyframes pinShake {
  10%,90% { transform: translate3d(-2px,0,0); }
  20%,80% { transform: translate3d(4px,0,0); }
  30%,50%,70% { transform: translate3d(-7px,0,0); }
  40%,60% { transform: translate3d(7px,0,0); }
}
.pin-display.wrong { animation: pinShake 550ms cubic-bezier(.36,.07,.19,.97); }
.pin-display.wrong .pin-dot { border-color: var(--danger); }
.pin-note { display:block; line-height:1.5; }
.pin-note .ic { vertical-align:-2px; margin-right:4px; }
.pin-note-help { display:block; font-size:12px; font-weight:600; opacity:.75; margin-top:4px; }
.btn-exit { display:inline-flex; align-items:center; gap:6px; min-height:36px; padding:0 12px; border-radius:999px;
  background:rgba(255,255,255,.10); color:var(--on-shell); border:1px solid rgba(255,255,255,.22);
  font-size:12px; font-weight:700; cursor:pointer; white-space:nowrap; }
.btn-exit:active { transform:scale(.96); }
.avatar { overflow:hidden; }
.door-motif { color: var(--on-shell); }
/* the role indicator sits on the fixed dark bar, so it takes the shell's ink, not the page's */
.demo-badge { color: var(--on-shell); background: color-mix(in srgb, var(--on-shell) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--on-shell) 30%, transparent); padding: 3px 10px;
  border-radius: 999px; font-size: 11px; font-weight: 800; letter-spacing: .06em; }

/* --- first run --- */
.setup-wrap { width:100%; max-width:420px; margin:0 auto; text-align:left; color:var(--on-shell); }
.setup-wrap h2 { color:var(--on-shell); margin-bottom:6px; }
.setup-wrap .subheading { color:color-mix(in srgb, var(--on-shell) 78%, transparent); margin-bottom:18px; }
.setup-wrap .input-label { color:color-mix(in srgb, var(--on-shell) 82%, transparent); }
.setup-wrap .input-field { background:rgba(255,255,255,.07); border-color:color-mix(in srgb, var(--on-shell) 30%, transparent); color:var(--on-shell); }
.setup-wrap .input-field::placeholder { color:color-mix(in srgb, var(--on-shell) 45%, transparent); }
.setup-wrap .card { background:rgba(255,255,255,.07); border-color:color-mix(in srgb, var(--on-shell) 20%, transparent); color:color-mix(in srgb, var(--on-shell) 85%, transparent); }
.setup-wrap .scheme-chip { background:rgba(255,255,255,.07); border-color:color-mix(in srgb, var(--on-shell) 26%, transparent); color:var(--on-shell); }
.setup-wrap .scheme-chip.on { border-color:var(--on-shell); background:rgba(255,255,255,.16); }
.setup-brand { font-size:20px; font-weight:800; color:var(--on-shell); margin-bottom:20px; letter-spacing:-.3px; }
.setup-dots { display:flex; gap:7px; margin-bottom:18px; }
.setup-dot { width:26px; height:4px; border-radius:2px; background:color-mix(in srgb, var(--on-shell) 22%, transparent); }
.setup-dot.on, .setup-dot.done { background:var(--on-shell); }
.recovery-code { font-family:ui-monospace,Menlo,Consolas,monospace; font-size:30px; font-weight:800; letter-spacing:3px;
  text-align:center; padding:18px 10px; border-radius:var(--radius); background:rgba(255,255,255,.10);
  border:1px dashed color-mix(in srgb, var(--on-shell) 45%, transparent); color:var(--on-shell); }
.pin-forgot { display:block; margin:10px auto 0; background:none; border:none; min-height:44px; padding:0 12px;
  color:color-mix(in srgb, var(--on-shell) 85%, transparent); font-size:13px; font-weight:700;
  text-decoration:underline; cursor:pointer; }

/* the mark, small, beside the name */
.brand-mark { width:22px; height:22px; flex-shrink:0; color:var(--on-shell); margin-right:-2px; }

/* Primary "add" actions live where the thumb already is: bottom-right, never the top
   corner. Same corner as the basket, and they never appear on the same screen. */
.fab-add { position:fixed; right:16px; bottom:calc(var(--bottom-chrome) + 22px); z-index:90; display:flex; align-items:center; gap:8px;
  min-height:52px; padding:0 20px; border:none; border-radius:999px; cursor:pointer;
  background:var(--brand); color:var(--on-brand); font-size:14px; font-weight:800;
  box-shadow:var(--elev-3); animation:fabIn 200ms cubic-bezier(0.22,1,0.36,1); }
.fab-add:active { transform:scale(.96); }

/* First run is a light screen: nobody's first impression of their own shop should be a
   dark box. The returning-user PIN door keeps the brand treatment. */
.pin-gate.is-setup { background: var(--bg); overflow-y: auto; align-items: flex-start; padding: 32px 20px 48px; }
.pin-gate.is-setup .setup-wrap,
.pin-gate.is-setup .setup-wrap h2 { color: var(--ink); }
.pin-gate.is-setup .setup-brand { color: var(--brand-strong); }
.pin-gate.is-setup .setup-wrap .subheading,
.pin-gate.is-setup .setup-wrap .input-label { color: var(--muted); }
.pin-gate.is-setup .setup-wrap .input-field { background: var(--surface); border-color: var(--border); color: var(--ink); }
.pin-gate.is-setup .setup-wrap .input-field::placeholder { color: var(--muted); opacity: .7; }
.pin-gate.is-setup .setup-wrap .card { background: var(--surface); border-color: var(--border); color: var(--muted); }
.pin-gate.is-setup .setup-wrap .scheme-chip { background: var(--surface); border-color: var(--border); color: var(--ink); }
.pin-gate.is-setup .setup-wrap .scheme-chip.on { border-color: var(--brand); background: var(--brand-soft); }
.pin-gate.is-setup .setup-dot { background: var(--border); }
.pin-gate.is-setup .setup-dot.on, .pin-gate.is-setup .setup-dot.done { background: var(--brand); }
.pin-gate.is-setup .recovery-code { background: var(--brand-soft); border-color: var(--brand); color: var(--brand-strong); }

/* --- where is my money: the link pill --- */
.link-pill { display:inline-flex; align-items:center; gap:6px; min-height:36px; padding:0 12px;
  border-radius:999px; border:1px solid var(--border);
  background:var(--surface-2); color:var(--text-secondary);
  font-size:11px; font-weight:800; letter-spacing:.02em; cursor:pointer; white-space:nowrap; }
.link-dot { width:8px; height:8px; border-radius:50%; background:currentColor; flex-shrink:0; }
/* the pill colours the icon, not a separate dot - one shape to learn */
.link-pill .ic { flex-shrink:0; }
/* on the light strip these have to carry contrast themselves, so they are tokens
   with a value per theme rather than one set tuned for the dark header */
.link-ok   { color:var(--link-ok);   border-color:color-mix(in srgb, var(--link-ok) 40%, transparent);   background:color-mix(in srgb, var(--link-ok) 8%, transparent); }
.link-warn { color:var(--warning);   border-color:color-mix(in srgb, var(--warning) 40%, transparent);   background:color-mix(in srgb, var(--warning) 8%, transparent); }
.link-bad  { color:var(--danger);    border-color:color-mix(in srgb, var(--danger) 40%, transparent);    background:color-mix(in srgb, var(--danger) 8%, transparent); }
.link-busy { color:var(--link-busy); border-color:color-mix(in srgb, var(--link-busy) 40%, transparent); background:color-mix(in srgb, var(--link-busy) 8%, transparent); }
.link-pill.is-saving .ic { animation:pulseIcon 900ms ease-in-out infinite; }
@keyframes pulseIcon { 0%,100% { opacity:1; } 50% { opacity:.35; } }
.row-wait { display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:700; color:var(--warning); }
/* touch targets never shrink; the wordmark yields instead */
.top-bar .theme-btn, .top-bar .demo-badge, .top-bar .brand-mark { flex-shrink: 0; }
.status-strip .link-pill { min-width: 0; overflow: hidden; text-overflow: ellipsis; display: inline-flex; }
/* the badge used to go at 400px to make room for the link pill; with the pill on the
   status strip the header has the width to say which door you came through */

/* --- switches ---------------------------------------------------------------
   The whole row is the control, so the target is the full width rather than a
   52px track someone has to hit precisely with a thumb. Four states only:
   off, on, disabled, disabled-on. No vertical, no indeterminate - a setting
   that cannot say which way it is set is not a setting. */
.setting-row { display:flex; align-items:center; gap:14px; width:100%; min-height:56px;
  padding:12px 0; background:none; border:none; border-bottom:1px solid var(--border);
  text-align:left; cursor:pointer; color:var(--ink); font:inherit; }
.setting-row:last-of-type { border-bottom:none; }
.setting-row:active:not([disabled]) .switch { transform:scale(.97); }
.setting-text { flex:1; min-width:0; }
.setting-title { display:block; font-weight:700; font-size:14px; margin-bottom:2px; }
.setting-note { display:block; font-size:12px; color:var(--muted); line-height:1.45; }

.switch { position:relative; width:52px; height:30px; border-radius:999px; flex-shrink:0;
  background:color-mix(in srgb, var(--ink) 20%, transparent);
  transition:background 200ms cubic-bezier(.22,1,.36,1), transform 120ms ease; }
.switch::after { content:''; position:absolute; top:3px; left:3px; width:24px; height:24px;
  border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.28), 0 1px 1px rgba(0,0,0,.16);
  transition:transform 220ms cubic-bezier(.22,1,.36,1); }

.setting-row[aria-checked="true"] .switch { background:var(--brand); }
.setting-row[aria-checked="true"] .switch::after { transform:translateX(22px); }

.setting-row[disabled] { cursor:not-allowed; }
.setting-row[disabled] .setting-title, .setting-row[disabled] .setting-note { opacity:.55; }
.setting-row[disabled] .switch { background:color-mix(in srgb, var(--ink) 12%, transparent); }
.setting-row[disabled] .switch::after { background:#f2f2f0; box-shadow:none; }
.setting-row[disabled][aria-checked="true"] .switch { background:color-mix(in srgb, var(--brand) 45%, transparent); }

.setting-row:focus-visible { outline:3px solid color-mix(in srgb, var(--brand) 55%, transparent); outline-offset:3px; border-radius:var(--radius-sm); }

/* a phone told to stop animating gets an instant flip, not a slow one */
:root[data-motion="off"] .switch, :root[data-motion="off"] .switch::after { transition:none; }

/* --- header theme switch -----------------------------------------------------
   The icon rides IN the knob and shows the mode you are in RIGHT NOW: sun on the
   left in light, moon on the right in dark. The alternative - a blank knob with
   the other mode's icon showing on the track - is common, but it means the only
   icon on screen is the one you are NOT in, which reads as the opposite of the
   truth to anyone who has not used one before. Position says what will happen;
   the icon says where you are. */
.theme-switch { position:relative; width:56px; height:30px; flex-shrink:0; padding:0; border:none;
  border-radius:999px; cursor:pointer;
  background:var(--surface-2);
  box-shadow:inset 0 0 0 1px var(--border);
  transition:background 220ms cubic-bezier(.22,1,.36,1); }
.theme-switch[aria-checked="true"] { background:color-mix(in srgb, var(--text-primary) 34%, transparent); }
.theme-switch::before { content:''; position:absolute; inset:-7px; }   /* 44px target, 30px chrome */

.ts-knob { position:absolute; z-index:1; top:3px; left:3px; width:24px; height:24px; border-radius:50%;
  background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.3);
  transition:transform 240ms cubic-bezier(.22,1,.36,1); pointer-events:none; }
.theme-switch[aria-checked="true"] .ts-knob { transform:translateX(26px); }

.ts-knob { display:flex; align-items:center; justify-content:center; color:#16150F; }
.ts-ico { pointer-events:none; }
.theme-switch:active .ts-knob { box-shadow:0 1px 2px rgba(0,0,0,.35); }
:root[data-motion="off"] .theme-switch, :root[data-motion="off"] .ts-knob, :root[data-motion="off"] .ts-ico { transition:none; }

/* With the pill and the switch moved to the status strip the header holds the mark, the
   name and two round buttons - so on a narrow phone the name keeps its full size and the
   mark stays. Only the role badge still goes, at 400px, above. */
@media (max-width: 460px) {
  .top-bar { gap: 10px; padding: 10px 14px; }
  .top-bar-title { font-size: 17px; }
}

/* --- profile picture --- */
.photo-row { display:flex; align-items:center; gap:16px; }
.photo-slot { position:relative; padding:0; border:none; background:none; cursor:pointer; border-radius:50%;
  min-width:72px; min-height:72px; flex-shrink:0; }
.photo-slot .avatar { border:2px dashed color-mix(in srgb, var(--ink) 22%, transparent); }
.photo-slot.has-photo .avatar { border:2px solid var(--brand); }
.photo-plus { position:absolute; right:-2px; bottom:-2px; width:26px; height:26px; border-radius:50%;
  background:var(--brand); color:var(--on-brand); font-size:19px; font-weight:800; line-height:24px;
  display:flex; align-items:center; justify-content:center; box-shadow:0 1px 4px rgba(0,0,0,.25); }
.avatar img { border-radius:50%; }

/* --- P&L drill-down --- */
.pnl-open { width:100%; border:none; font:inherit; text-align:left; cursor:pointer; align-items:center; }
.pnl-open span:last-child { display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
.pnl-open.is-open { background:var(--brand-soft); }
.drill { margin:-4px 0 8px; padding:4px 10px 8px; border-left:3px solid var(--brand);
  background:var(--surface); border-radius:0 var(--radius-sm) var(--radius-sm) 0; }
.drill-item { display:flex; justify-content:space-between; align-items:center; gap:10px;
  padding:9px 4px; border-bottom:1px solid var(--border); font-size:13px; }
.drill-item:last-child { border-bottom:none; }
.drill-main { font-weight:700; }
.drill-sub { font-size:12px; color:var(--muted); }
.drill-tap { width:100%; background:none; border:none; border-bottom:1px solid var(--border); font:inherit;
  text-align:left; cursor:pointer; color:var(--ink); min-height:56px; }
.drill-tap:last-child { border-bottom:none; }
.drill-tap span { display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
.drill-tap:active { background:var(--surface-2); }
