/* Background Remover — a split that is up from the start: the uploader
   (after="hide"), then the Preview card and the mask brush, in the detail
   pane; cutout quality and the cutout options in the inspector. The layout is
   styles/components/form.css and the two stages are
   styles/components/preview.css; the processing overlay and the reveal are
   the page's own. */

/* ── Stages: original | cutout, two styles/components/preview.css stages in
   the cells of a .row-grid (equal height, the image whole and centred). The
   cutout stage is #result-panel: it carries the processing state. */

/* Processing overlay — fills the whole cutout cell. Square: the card's own
   corner (the grid inherits it and clips) is the only rounding it gets. */
.processing-overlay {
  position: absolute;
  inset: 0;
  margin: 0; /* not the stage's block rhythm: it is laid over, not after */
  background: color-mix(in srgb, var(--bg-elev) 88%, transparent);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-5);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s var(--ease-standard);
}

#result-panel.is-processing .processing-overlay {
  opacity: 1;
  pointer-events: auto;
}

#result-panel.is-processing #result-img {
  visibility: hidden;
}

.processing-overlay__label {
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: -0.01em;
}

.processing-overlay__hint {
  font-size: 12px;
  color: var(--text-muted);
  max-width: 260px;
  line-height: 1.5;
  letter-spacing: -0.005em;
}

.processing-overlay .progress { width: min(200px, 100%); }

/* Mask brush + Solid-subject fill ---------------------------------------- */
/* Every control is a native button or input, so it is reachable and operable
   from the keyboard. Disabled while a run is in flight or there is no mask. */
.br-refine .segment__btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.br-refine .toggle input:disabled ~ .toggle__track {
  opacity: 0.45;
}

/* The download is an <a>, which inherits the body's line-height where the
   <button>s beside it keep the UA's `normal` — pin it so the whole tray
   shares one button height. */
#download-btn {
  line-height: normal;
}

/* Never a target smaller than 32 px tall for a mouse… */
.br-refine .segment__btn,
.br-refine .btn--sm {
  min-height: 32px;
}

/* …and a finger-sized 44 px wherever the pointer is a finger. The sliders
   keep their thin rail; the taller box is what a tap has to land in. */
@media (pointer: coarse) {
  .br-refine .segment__btn,
  .br-refine .btn--sm,
  .br-actions .btn {
    min-height: 44px;
  }
  .br-refine .segment__btn {
    min-width: 44px;
  }
  .br-refine input[type="range"] {
    height: 44px;
  }
}

/* The brush's canvas sits exactly over the result image (the stage
   shrink-wraps it). It never takes pointer events — the stage does — and it
   is never part of the download, which is encoded from the matte. */
.brush-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

#result-panel.is-processing .brush-overlay {
  visibility: hidden;
}

/* While a brush is picked the result is a paint surface: no page scroll or
   pinch from a finger that starts on it, no text selection, no native image
   drag. Every other state leaves the image scrollable and draggable. */
.result-stage.is-painting {
  cursor: crosshair;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

.result-stage.is-painting > #result-img {
  -webkit-user-drag: none;
}

/* From the keyboard the cutout itself takes focus (it is the brush's
   surface), so it shows the same focus ring as every other control. */
.result-stage:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Indeterminate progress — the background-removal inference is a single blocking
   WASM call, so real sub-progress can't repaint mid-compute. This slides the bar
   with a transform (compositor-driven), so it keeps moving even while the main
   thread is busy; a width-based fill would appear frozen at 0%. */
.progress.is-indeterminate .progress__bar {
  width: 40%;
  transition: none;
  animation: progress-slide 1.1s ease-in-out infinite;
}

@keyframes progress-slide {
  0% {
    transform: translateX(-120%);
  }
  100% {
    transform: translateX(320%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .progress.is-indeterminate .progress__bar {
    animation: none;
    width: 100%;
    opacity: 0.55;
  }
}

/* iPhone-style "lift subject" reveal ------------------------------------ */
/* The stage shrink-wraps the result image so an overlay masked with the
   same cutout lines up pixel-for-pixel with the subject silhouette. */
.result-stage {
  position: relative;
  display: inline-block;
  line-height: 0;
  max-width: 100%;
  max-height: var(--preview-max-h);
}

/* Keep the result image governed by the same sizing rules as before, but let
   the cutout float on a silhouette shadow instead of a rectangular one. */
.result-stage > #result-img {
  max-width: 100%;
  max-height: var(--preview-max-h);
  box-shadow: none;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.22));
}

/* A glowing bead that traces the subject's outline. Masked to a thin band
   sitting on the silhouette edge (built in JS from the cutout's alpha), so the
   light only runs along the contour — not across the fill or the checkerboard. */
.result-stage__shimmer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  border-radius: var(--radius-sm);
  opacity: 0;
  -webkit-mask-image: var(--rim-mask, none);
  mask-image: var(--rim-mask, none);
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* A large square centered on the cutout. Its conic gradient holds one bright
   bead; rotating the element sweeps that bead around the masked rim band. */
.result-stage__shimmer::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 220vmax;
  height: 220vmax;
  transform: translate(-50%, -50%) rotate(-40deg);
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    rgba(255, 255, 255, 0.2) 8deg,
    rgba(255, 255, 255, 0.98) 20deg,
    rgba(255, 255, 255, 0.2) 32deg,
    transparent 46deg,
    transparent 360deg
  );
  mix-blend-mode: screen;
}

/* Trigger — added in JS once the cutout has loaded. */
.result-stage.is-revealing > #result-img {
  animation: subject-lift 0.9s var(--ease-standard) both;
}
.result-stage.is-revealing .result-stage__shimmer {
  animation: shimmer-fade 1.5s ease-out both;
}
.result-stage.is-revealing .result-stage__shimmer::before {
  animation: rim-trace 1.5s cubic-bezier(0.4, 0, 0.2, 1) both;
}

/* Basic reveal tier — used when app.js's feature check finds mask-image,
   conic-gradient, or mix-blend-mode unsupported (see revealMode in app.js).
   No mask/blend/huge pseudo-element, so it renders correctly even without
   GPU compositing. The shimmer markup stays in the DOM but is hidden. */
.result-stage.reveal-basic .result-stage__shimmer {
  display: none;
}
.result-stage.reveal-basic.is-revealing > #result-img {
  animation: subject-lift-basic 0.5s var(--ease-standard) both;
}

@keyframes subject-lift-basic {
  0% {
    opacity: 0;
    transform: translateY(6px) scale(0.98);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes subject-lift {
  0% {
    opacity: 0;
    transform: scale(0.94);
    filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.22));
  }
  15% {
    opacity: 1;
  }
  40% {
    transform: scale(1.035);
    filter: drop-shadow(0 0 16px rgba(255, 255, 255, 0.95))
      drop-shadow(0 10px 22px rgba(0, 0, 0, 0.32));
  }
  100% {
    opacity: 1;
    transform: scale(1);
    filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.22));
  }
}

@keyframes shimmer-fade {
  0%,
  100% {
    opacity: 0;
  }
  12%,
  82% {
    opacity: 1;
  }
}

/* One and a bit turns so the bead clearly travels all the way around. */
@keyframes rim-trace {
  0% {
    transform: translate(-50%, -50%) rotate(-40deg);
  }
  100% {
    transform: translate(-50%, -50%) rotate(380deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .result-stage.is-revealing > #result-img,
  .result-stage.reveal-basic.is-revealing > #result-img,
  .result-stage.is-revealing .result-stage__shimmer,
  .result-stage.is-revealing .result-stage__shimmer::before {
    animation: none;
  }
  .result-stage__shimmer {
    display: none;
  }
}
