/* Form feedback layer — additive styles only; the form's own layout is
   untouched. Covers the talk fill-flash, the consignor-name strip, the TALK
   button, and the motion/feel polish. */

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* Talk fill-flash — the signature "it landed in the right field" beat: a green
   glow-ring blooms on the touched field (pill / chip / notes) and settles, so a
   talk note splitting across fields reads as deliberate. Toggled by flashEl. */
.fill-flash { animation: fill-flash 1100ms var(--ease-out, cubic-bezier(.22,1,.36,1)) 1; }
@keyframes fill-flash {
  0%   { background: #dcfce7; box-shadow: 0 0 0 0 rgba(34, 197, 94, .55); }
  35%  { background: #dcfce7; box-shadow: 0 0 0 4px rgba(34, 197, 94, .26); }
  100% { background: #fff;    box-shadow: 0 0 0 4px rgba(34, 197, 94, 0); }
}
.chip.fill-flash { animation: fill-flash 900ms ease-out 1; }

/* Consignor verified-name strip — pinned to the fixed header's bottom edge,
   full width; never a fourth flex child squeezing the three pills. Takes no
   layout space and hides itself when empty. */
#cons-name {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  font: 500 12px/1.3 -apple-system, system-ui, sans-serif;
  padding: 3px 12px 4px;
  text-align: center;
  color: var(--label, #6b7280);
  background: rgba(255, 255, 255, .96);
  border-bottom: 1px solid var(--hair, #e5e7eb);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#cons-name:empty { display: none; }
#cons-name.ok { color: #15803d; font-weight: 600; }

/* ---- walkie-talkie TALK button ---- */
#talk-fab {
  position: fixed;
  left: 14px;
  bottom: calc(96px + env(safe-area-inset-bottom));
  z-index: 40;
  padding: 14px 18px;
  border-radius: 999px;
  border: none;
  background: #111;
  color: #fff;
  font: 600 15px/1 -apple-system, system-ui, sans-serif;
  letter-spacing: .06em;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
  cursor: pointer;
  touch-action: none;          /* hold-to-talk: no scroll steal mid-press */
  -webkit-user-select: none;
  user-select: none;
}
#talk-fab.rec {
  background: #b91c1c;
  box-shadow: 0 0 0 6px rgba(185, 28, 28, .25);
  animation: talk-pulse 1.2s ease-in-out infinite;
}
#talk-fab.busy { opacity: .6; }
@keyframes talk-pulse {
  50% { box-shadow: 0 0 0 12px rgba(185, 28, 28, .12); }
}

/* ============================================================================
   UX POLISH PASS — motion & feel (2026-08-19)
   Additive only. No layout, fields, copy, or flow changed — this amplifies the
   form's existing feedback vocabulary so high-volume cataloging feels fast,
   tactile, and rewarding. Research basis for repeatable data-entry forms:
   (1) every action needs instant, unmistakable feedback; (2) one consistent
   motion language everywhere lowers cognitive load; (3) a small reward on each
   commit builds rhythm and momentum. All effects respect reduced-motion.
   ============================================================================ */
:root {
  --ease-spring: cubic-bezier(.34, 1.4, .5, 1);   /* tactile overshoot for presses */
  --ease-out:    cubic-bezier(.22, 1, .36, 1);    /* calm settle for state changes */
  --feel-fast: .11s;
  --feel-med:  .2s;
}

/* Fluid state changes — focus, selection, enable/disable no longer snap. */
.pill, .dim, .chip, .slot, .save, .side, .foot-row select, #talk-fab {
  transition: transform var(--feel-fast) var(--ease-spring),
              background-color var(--feel-med) var(--ease-out),
              border-color var(--feel-med) var(--ease-out),
              box-shadow var(--feel-med) var(--ease-out),
              opacity var(--feel-med) var(--ease-out);
}

/* Tactile press — every tap target gives way slightly under the finger, then
   springs back. Transform-only, so nothing reflows. */
.chip:active, .foot-row select:active     { transform: scale(.96); }
.slot:not(.filled):active                 { transform: scale(.95); }
.save:not(:disabled):active               { transform: scale(.97); }
#talk-fab:active                         { transform: scale(.93); }
.side:active                              { transform: scale(.84); }
.pill:focus-within                        { transform: translateY(-1px); }

/* Chip selection gets a hair of lift so "chosen" is felt, not just seen. */
.chip.on                                  { transform: translateY(-1px); }

/* Save & Next — the pivot of the whole loop. Enabled it sits confident; the
   reward pulse (added by feel.js on lot-saved) gives the satisfying "next". */
.save:not(:disabled)                      { box-shadow: 0 2px 10px rgba(17, 17, 17, .18); }
.save.saved-pulse                         { animation: save-pop 440ms var(--ease-spring) 1; }
@keyframes save-pop {
  0%   { transform: scale(1);     box-shadow: 0 0 0 0 rgba(34, 197, 94, .5); }
  40%  { transform: scale(1.045); box-shadow: 0 0 0 9px rgba(34, 197, 94, .22); }
  100% { transform: scale(1);     box-shadow: 0 0 0 9px rgba(34, 197, 94, 0); }
}

/* "Today: N" ticks up with a small spring — a visible reward for each lot
   that lands, the counter people watch climb through a shift. */
.counter                                  { display: inline-block; will-change: transform; }
.counter.tick                             { animation: counter-tick 520ms var(--ease-spring) 1; }
@keyframes counter-tick {
  0%   { transform: translateY(0); }
  28%  { transform: translateY(-3px); color: #15803d; }
  100% { transform: translateY(0); }
}

/* Filled photo slot sits a touch richer so the shot-vs-empty read is instant. */
.slot.filled                              { box-shadow: 0 1px 6px rgba(0, 0, 0, .18); }

@media (prefers-reduced-motion: reduce) {
  .pill, .dim, .chip, .slot, .save, .side, .foot-row select, #talk-fab,
  .counter, .fill-flash, .save.saved-pulse, .counter.tick {
    transition: none !important;
    animation: none !important;
    transform: none !important;
  }
}
