/* DUBO effects: Glow Wipe / Card Lift / Split Gate.
   Motion is presentation only: native links, form submissions and focus remain. */
@view-transition { navigation: auto; }
:root {
  --motion-lift-ease: cubic-bezier(.16,1,.3,1);
  --motion-gate: #0b0b0b;
}
[data-theme="light"] { --motion-gate: #f7f4ef; }

/* Only the page content moves. The root/background and fixed bars stay still,
   including when late-parsed content joins the live root snapshot. */
body > main.container { view-transition-name: dubo-content; }
.topbar { view-transition-name: dubo-topbar; }
.home-bar, .hd-bottom-nav { view-transition-name: dubo-home; }
::view-transition { pointer-events: none; }
::view-transition-group(root) { animation: none; z-index: 0; }
::view-transition-old(root), ::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}
::view-transition-group(dubo-content) { animation: none; z-index: 1; }
::view-transition-old(dubo-content), ::view-transition-new(dubo-content) {
  animation: none;
  mix-blend-mode: normal;
}
::view-transition-group(dubo-topbar), ::view-transition-group(dubo-home) {
  animation: none;
  z-index: 2;
}
::view-transition-old(dubo-topbar), ::view-transition-old(dubo-home) { display: none; }
::view-transition-new(dubo-topbar), ::view-transition-new(dubo-home) { animation: none; }

html[data-motion="lift"]::view-transition-old(dubo-content) { animation: dubo-lift-out .5s var(--motion-lift-ease) both; }
html[data-motion="lift"]::view-transition-new(dubo-content) { animation: dubo-lift-in .5s var(--motion-lift-ease) both; }

@keyframes dubo-lift-out {
  to { transform: scale(.92) translateY(-12px); opacity: .38; filter: blur(3px); }
}
@keyframes dubo-lift-in {
  from { transform: translateY(100%) scale(.96); border-radius: 34px; }
  to { transform: translateY(0) scale(1); border-radius: 0; }
}

/* CSS entry fallback for browsers without cross-document View Transitions.
   No persistent transforms: fixed overlays and sticky list headers recover. */
html[data-motion-enter] { overflow-x: clip; }
html[data-motion-enter="lift"] main.container { animation: dubo-lift-in .5s var(--motion-lift-ease) both; }
html[data-motion-leaving="lift"] main.container { animation: dubo-lift-out .18s var(--motion-lift-ease); }

/* Split Gate also covers POST logout and warehouse reloads, where a native
   cross-document transition is not guaranteed. The panels never take input. */
html[data-motion-enter="split"]::before,
html[data-motion-enter="split"]::after,
html[data-motion-leaving="split"]::before,
html[data-motion-leaving="split"]::after {
  content: "";
  position: fixed;
  top: 0;
  bottom: 0;
  width: 50%;
  z-index: 100000;
  pointer-events: none;
  background: var(--motion-gate);
}
html[data-motion-enter="split"]::before,
html[data-motion-leaving="split"]::before { left: 0; border-right: 1px solid rgba(255,122,0,.35); }
html[data-motion-enter="split"]::after,
html[data-motion-leaving="split"]::after { right: 0; border-left: 1px solid rgba(255,122,0,.35); }
html[data-motion-enter="split"]::before { animation: dubo-gate-left .55s cubic-bezier(.65,0,.18,1) both; }
html[data-motion-enter="split"]::after { animation: dubo-gate-right .55s cubic-bezier(.65,0,.18,1) both; }
html[data-motion-leaving="split"]::before { animation: dubo-gate-left .2s ease-in reverse both; }
html[data-motion-leaving="split"]::after { animation: dubo-gate-right .2s ease-in reverse both; }
html[data-motion-enter="split"] main.container { animation: dubo-context-in .55s ease-out both; }
@keyframes dubo-gate-left { from { transform: translateX(0); } to { transform: translateX(-100%); } }
@keyframes dubo-gate-right { from { transform: translateX(0); } to { transform: translateX(100%); } }
@keyframes dubo-context-in {
  from { transform: scale(1.045); filter: brightness(.7); }
  to { transform: scale(1); filter: brightness(1); }
}

/* Card Lift for detail dialogs and custom detail overlays. Camera and blocking
   maintenance overlays retain their existing behavior. */
dialog[open],
.modal:not(.hidden):not(#scanner-modal):not(.modal-blocking) > .modal-content,
.wt-modal-overlay > .wt-modal {
  animation: dubo-card-lift .5s var(--motion-lift-ease) both;
}
dialog::backdrop {
  background: rgba(0,0,0,.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: dubo-backdrop-in .2s ease-out;
}
.wt-modal-overlay { backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
dialog[open].dubo-popup-closing,
.modal.dubo-popup-closing:not(.hidden):not(#scanner-modal):not(.modal-blocking) > .modal-content,
.wt-modal-overlay.dubo-popup-closing > .wt-modal {
  animation: dubo-card-drop .26s cubic-bezier(.7,0,.84,0) both;
}
dialog.dubo-popup-closing::backdrop { animation: dubo-backdrop-in .26s ease-in reverse both; }
@keyframes dubo-card-lift {
  from { transform: translateY(min(65vh,480px)) scale(.96); opacity: .3; }
  to { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes dubo-card-drop {
  from { transform: var(--motion-card-start, translateY(0) scale(1)); opacity: var(--motion-card-opacity, 1); }
  to { transform: translateY(min(65vh,480px)) scale(.96); opacity: 0; }
}
@keyframes dubo-backdrop-in { from { opacity: 0; } to { opacity: 1; } }
/* Avoid making a fixed custom modal relative to an animating fallback main. */
html[data-motion-enter] main.container:has(dialog[open], .modal:not(.hidden), .wt-modal-overlay[style*="flex"]) { animation: none; }

/* A 260ms amber sweep, clipped inside the success surface. It neither blocks
   the camera nor moves the scanned list, and is replaced on the next scan. */
.dubo-glow-surface { position: relative; }
.dubo-glow-wipe {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  z-index: 20;
  pointer-events: none;
}
.dubo-glow-wipe::before {
  content: "";
  position: absolute;
  inset: -20%;
  background: linear-gradient(90deg, transparent 0%, rgba(255,102,0,.12) 43%, rgba(255,154,50,.8) 50%, rgba(255,102,0,.12) 57%, transparent 100%);
  filter: blur(1px);
  animation: dubo-glow-wipe .26s cubic-bezier(.55,0,.2,1) both;
}
@keyframes dubo-glow-wipe {
  0% { transform: translateX(-120%) rotate(-8deg); opacity: 0; }
  15% { opacity: 1; }
  100% { transform: translateX(120%) rotate(-8deg); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
  html[data-motion-enter] main.container,
  html[data-motion-leaving] main.container,
  dialog[open], dialog::backdrop, .modal, .modal-content, .wt-modal { animation: none !important; }
  html[data-motion-enter]::before, html[data-motion-enter]::after,
  html[data-motion-leaving]::before, html[data-motion-leaving]::after,
  .dubo-glow-wipe { display: none !important; }
}
@media print {
  html[data-motion-enter]::before, html[data-motion-enter]::after,
  html[data-motion-leaving]::before, html[data-motion-leaving]::after,
  .dubo-glow-wipe { display: none !important; }
  main.container { animation: none !important; }
}
