/* --- scan capture tray -------------------------------------------------- */ .scan-tray { margin: 16px; background: var(--surface); border: 2px solid var(--ink); box-shadow: var(--shadow-sm); } .scan-tray__header { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--line); } .scan-tray__count { font: 700 13px/1 var(--mono); letter-spacing: 0.4px; /* Grows as barcodes land; fixed-width digits stop the label re-flowing. */ font-variant-numeric: tabular-nums; } .scan-tray__hint { font-size: 12px; color: var(--ink-muted); } .scan-tray__rows { margin: 0; padding: 0; list-style: none; max-height: 260px; overflow-y: auto; } .scan-tray__row { display: flex; align-items: center; gap: 10px; padding: 8px 14px; } .scan-tray__row + .scan-tray__row { border-top: 1px solid var(--line); } .scan-tray__item { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; } .scan-tray__item .cover { width: 36px; height: 36px; } .scan-tray__info { flex: 1; min-width: 0; } .scan-tray__info strong { display: block; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .scan-tray__state { flex: 1; font-size: 12px; color: var(--ink-muted); } .scan-tray__cta { padding: 12px 14px; } .scan-tray__cta .btn { width: 100%; } /* --- review page (buckets) ---------------------------------------------- */ .scan-review .scan-rows { margin: 0; padding: 0; list-style: none; } .scan-review .scan-row + .scan-row { border-top: 1px solid var(--line); } .item-meta--alert { color: var(--danger); } .scan-suggestions { margin: 0 0 6px; padding-left: 12px; border-left: 2px solid var(--line); } .scan-suggestions .section-label { margin-top: 4px; } /* Fixed at the bottom of the page-scroll body, above the safe area, so the CTA is always reachable regardless of how many rows are in each bucket. */ .scan-review__cta { position: sticky; bottom: 0; padding: 12px 0 calc(4px + env(safe-area-inset-bottom)); background: var(--bg); } /* --- done page (import ceremony) ---------------------------------------- */ .done-state { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; background: var(--surface); border: 2px solid var(--ink); box-shadow: var(--shadow-md); padding: 32px 20px 22px; margin-top: 24px; } .done-state__sticker { background: var(--owned); color: var(--cream-fixed); border: 2px solid var(--ink); box-shadow: var(--shadow-xs); padding: 5px 10px; font: 700 12px/1 var(--mono); letter-spacing: 0.5px; text-transform: uppercase; } .done-state__title { font: 400 30px/1.05 var(--display); letter-spacing: 0.5px; margin: 6px 0 0; } .done-state__sub { font: italic 400 14px/1.4 var(--serif); color: var(--ink-muted); margin: 0 0 4px; } .done-state__count { display: flex; align-items: baseline; gap: 8px; font: 700 22px/1 var(--mono); margin: 6px 0 14px; /* Fixed-width digits keep the layout still while the count ticks up. */ font-variant-numeric: tabular-nums; } .done-state__count-old { color: var(--ink-muted); } /* Registered so --count interpolates; without @property support the animation flips discretely and still lands on --count-to. */ @property --count { syntax: ""; inherits: false; initial-value: 0; } .done-state__count-new { color: var(--owned); --count: var(--count-to); animation: count-up 300ms ease-out; } .done-state__count-new::before { counter-reset: count var(--count); content: counter(count); } @keyframes count-up { from { --count: var(--count-from); } } .done-state .btn { width: 100%; } @media (prefers-reduced-motion: reduce) { .done-state__count-new { animation: none; } }