/* Party Photos — minimal wall + squircles */

:root {
  --bg: #ffffff;
  --shadow: 0 12px 40px rgba(15, 23, 42, 0.12);
  --shadow-soft: 0 6px 24px rgba(15, 23, 42, 0.08);
  --text: #0f172a;
  --muted: #64748b;
  --danger: #b91c1c;
  --danger-bg: #fef2f2;
  --radius-squircle: 32%;
  --fab-size: clamp(4.5rem, 18vw, 6.5rem);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  min-height: 100%;
  min-height: 100dvh;
  color: var(--text);
  overflow-x: hidden;
}

body {
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
    env(safe-area-inset-bottom) env(safe-area-inset-left);
  background-color: var(--bg);
  background-image: url("/assets/rsvp-desktop.webp"),
    linear-gradient(180deg, #b8ecff 0%, #fff 100%);
  /* cover = scales to fill the viewport in both dimensions while preserving
     the image's aspect ratio (no distortion). Some edges may be cropped. */
  background-size: cover, cover;
  background-position: center center, center center;
  background-repeat: no-repeat, no-repeat;
  /* scroll avoids iOS glitches with fixed backgrounds */
  background-attachment: scroll, scroll;
}

/* Mobile / narrow viewports get the portrait-cropped artwork. */
@media (max-width: 768px) {
  body {
    background-image: url("/assets/rsvp-mobile.webp"),
      linear-gradient(180deg, #b8ecff 0%, #fff 100%);
    background-size: cover, cover;
  }
}

.app {
  position: relative;
  min-height: 100dvh;
  width: 100%;
}

.wall {
  position: relative;
  min-height: 100dvh;
  width: 100%;
}

/* Floating photo tiles — pop from center, then spin on inner layer */
.tile {
  position: absolute;
  left: 50%;
  top: 50%;
  border: none;
  padding: 0;
  /* No clipping/border-radius here — the rotor is the visible card and
     rotates as a whole so the rounded corners turn with the image. */
  background: transparent;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  --tile-pop-duration: 0.95s;
  animation-name: tile-pop;
  animation-duration: var(--tile-pop-duration);
  animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  animation-delay: var(--pop-delay, 0s);
  animation-fill-mode: forwards;
  will-change: transform, left, top;
}

.tile:focus-visible {
  outline: none;
}

.tile:focus-visible .tile__rotor {
  outline: 3px solid #3b82f6;
  outline-offset: 4px;
}

.tile__rotor {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: var(--radius-squircle);
  overflow: hidden;
  background: rgba(241, 245, 249, 0.92);
  box-shadow: var(--shadow-soft);
  transform-origin: center center;
  will-change: transform;
}

.tile__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  user-select: none;
}

@keyframes tile-pop {
  0% {
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) scale(0.12);
    opacity: 0.75;
  }
  55% {
    opacity: 1;
  }
  100% {
    left: var(--tile-cx);
    top: var(--tile-cy);
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
}

@keyframes drift-rotate {
  from {
    transform: rotate(var(--base-rot, 0deg));
  }
  to {
    transform: rotate(calc(var(--base-rot, 0deg) + 360deg));
  }
}

.tile__rotor--spin {
  animation-name: drift-rotate;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  /* Start spinning only after the parent tile-pop (0.95s) finishes */
  animation-delay: calc(var(--pop-delay, 0s) + var(--tile-pop-duration));
  animation-fill-mode: backwards;
}

@media (prefers-reduced-motion: reduce) {
  .tile {
    animation: none;
    left: var(--tile-cx);
    top: var(--tile-cy);
    transform: translate(-50%, -50%);
    opacity: 1;
    will-change: auto;
  }

  .tile__rotor--spin {
    animation: none;
    transform: rotate(var(--base-rot, 0deg));
    will-change: auto;
  }
}

/* Center camera button */
.fab {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 100;
  width: var(--fab-size);
  height: var(--fab-size);
  border: none;
  border-radius: var(--radius-squircle);
  background: #fff;
  color: var(--muted);
  box-shadow: var(--shadow);
  display: grid;
  place-items: center;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.fab:hover {
  transform: translate(-50%, -50%) scale(1.02);
}

.fab:active {
  transform: translate(-50%, -50%) scale(0.98);
}

.fab:focus-visible {
  outline: 3px solid #3b82f6;
  outline-offset: 4px;
}

.fab__icon {
  width: 42%;
  height: 42%;
}

/* Modal (above photo tiles + FAB) */
.modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 1rem;
  background: rgba(15, 23, 42, 0.45);
  backdrop-filter: blur(6px);
}

.modal[hidden] {
  display: none;
}

.modal__panel {
  width: min(100%, 28rem);
  background: #fff;
  border-radius: 1.25rem;
  padding: 1rem 1rem 1.25rem;
  box-shadow: var(--shadow);
  max-height: min(92dvh, 900px);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.modal__panel--viewer {
  width: min(100%, min(92vw, 960px));
  max-height: 92dvh;
  /* Match the camera modal — dark immersive panel, white controls. */
  background: #0b0f1a;
  color: #fff;
  padding: 0.75rem 0.75rem 1rem;
  gap: 0.75rem;
}

.modal__title {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
}

.modal__error {
  margin: 0;
  color: var(--danger);
  font-size: 0.9rem;
}

/* Modern phone-camera look: dark immersive panel, floating overlay controls. */
.modal__panel--camera {
  background: #0b0f1a;
  color: #fff;
  padding: 0.75rem 0.75rem 1rem;
  gap: 0.75rem;
}

.camera__stage {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  background: #000;
  border-radius: 1.1rem;
  overflow: hidden;
}

.camera__video,
.camera__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Mirror the live preview when shooting with a user-facing camera
   (desktop webcams + mobile front cam). The canvas matches at draw time.
   Back/environment cameras stay un-mirrored — see app.js. */
.camera__video--mirror {
  transform: scaleX(-1);
}

/* Floating close button (X) — top-right of the camera stage. */
.camera__close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.15s ease;
}

.camera__close:hover,
.camera__close:focus-visible {
  background: rgba(0, 0, 0, 0.75);
  outline: none;
}

.camera__close svg {
  width: 20px;
  height: 20px;
}

/* Error message overlays the stage (so it doesn't reflow controls). */
.camera__error {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 12px;
  margin: 0;
  padding: 0.55rem 0.75rem;
  background: rgba(185, 28, 28, 0.92);
  color: #fff;
  border-radius: 0.6rem;
  font-size: 0.85rem;
  line-height: 1.3;
}

/* Bottom action bar — 3 equal slots so the shutter stays centered
   regardless of which side buttons are visible. */
.camera__bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  justify-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.25rem 0;
  min-height: 88px;
}

.camera__bar[hidden] {
  display: none;
}

.camera__bar-slot {
  width: 56px;
  height: 56px;
}

/* The big circular shutter button (camera capture). */
.shutter {
  appearance: none;
  position: relative;
  width: 76px;
  height: 76px;
  border: none;
  border-radius: 50%;
  background: transparent;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  display: grid;
  place-items: center;
  transition: transform 0.12s ease;
}

.shutter:active {
  transform: scale(0.94);
}

.shutter:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.shutter:focus-visible {
  outline: 3px solid #3b82f6;
  outline-offset: 4px;
  border-radius: 50%;
}

.shutter__ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 4px solid #fff;
  box-sizing: border-box;
}

.shutter__dot {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #fff;
  transition: background 0.15s ease, transform 0.15s ease;
}

.shutter:hover .shutter__dot {
  transform: scale(0.95);
}

/* Save / confirm variant — green check shutter. */
.shutter--confirm .shutter__dot {
  display: none;
}

.shutter--confirm {
  background: #22c55e;
  border: 4px solid #fff;
  box-sizing: border-box;
  color: #fff;
}

.shutter--confirm .shutter__ring {
  display: none;
}

.shutter__check {
  width: 36px;
  height: 36px;
}

/* Round icon-only secondary actions (Flip, Retake). */
.icon-action {
  appearance: none;
  width: 52px;
  height: 52px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.15s ease, transform 0.12s ease;
}

.icon-action[hidden] {
  display: none;
}

.icon-action:hover,
.icon-action:focus-visible {
  background: rgba(255, 255, 255, 0.22);
  outline: none;
}

.icon-action:active {
  transform: scale(0.94);
}

.icon-action svg {
  width: 28px;
  height: 28px;
}

.btn {
  appearance: none;
  border: 1px solid #e2e8f0;
  background: #fff;
  color: var(--text);
  padding: 0.65rem 1rem;
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
}

.btn--primary {
  background: #0f172a;
  color: #fff;
  border-color: #0f172a;
}

.btn--ghost {
  border-color: transparent;
  color: var(--muted);
}

.btn--danger {
  background: var(--danger-bg);
  border-color: #fecaca;
  color: var(--danger);
}

.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Viewer stage mirrors the camera stage: rounded black surface that
   the photo sits inside, with the close button overlaid in the corner. */
.viewer__stage {
  position: relative;
  width: 100%;
  background: #000;
  border-radius: 1.1rem;
  overflow: hidden;
  display: grid;
  place-items: center;
}

.viewer__img {
  display: block;
  width: 100%;
  max-height: min(70dvh, 640px);
  object-fit: contain;
  background: #000;
}

/* Bottom bar in the viewer reuses the camera bar grid, but icons live in
   the outer slots (Download left, Delete right) with the middle slot blank
   so spacing matches the camera. */
.viewer__bar {
  min-height: 72px;
}

/* Danger tint for the trash button. */
.icon-action--danger {
  background: rgba(239, 68, 68, 0.18);
  color: #fecaca;
}

.icon-action--danger:hover,
.icon-action--danger:focus-visible {
  background: rgba(239, 68, 68, 0.32);
  color: #fff;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.modal--viewer .modal__panel {
  position: relative;
}

@media (max-width: 480px) {
  .modal__panel {
    padding: 0.85rem;
  }

  .fab {
    --fab-size: clamp(4rem, 22vw, 5.75rem);
  }
}

/* ---- QR mode toggle (small pill switch, top-right) ---- */
.qr-toggle {
  position: fixed;
  top: calc(env(safe-area-inset-top) + 12px);
  right: calc(env(safe-area-inset-right) + 12px);
  z-index: 150;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.6rem 0.35rem 0.45rem;
  background: rgba(255, 255, 255, 0.92);
  border-radius: 999px;
  box-shadow: var(--shadow-soft);
  font: 600 0.8rem/1 system-ui, -apple-system, sans-serif;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.qr-toggle__input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.qr-toggle__track {
  position: relative;
  display: inline-block;
  width: 34px;
  height: 20px;
  border-radius: 999px;
  background: #cbd5e1;
  transition: background 0.18s ease;
}

.qr-toggle__thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.25);
  transition: transform 0.18s ease;
}

.qr-toggle__input:checked + .qr-toggle__track {
  background: #f97316; /* match QR text accent */
}

.qr-toggle__input:checked + .qr-toggle__track .qr-toggle__thumb {
  transform: translateX(14px);
}

.qr-toggle__input:focus-visible + .qr-toggle__track {
  outline: 2px solid #3b82f6;
  outline-offset: 2px;
}

/* ---- QR overlay (above background + wall, below modals + toggle) ---- */
.qr-overlay {
  position: fixed;
  inset: 0;
  /* High enough to sit above any photo tile (tiles use 10 + N from JS) */
  z-index: 140;
  pointer-events: none; /* don't block the wall behind it */
  background: transparent;
}

.qr-overlay[hidden] {
  display: none;
}

.qr-overlay__img {
  position: absolute;
  top: 10%;
  left: 12%;
  /* Scale with viewport width so the QR keeps the same visual share of the
     screen at 1280, 1920, 2560, and beyond. The min keeps it scannable on
     small desktop windows. */
  width: max(220px, 22vw);
  height: auto;
  filter: drop-shadow(0 8px 20px rgba(15, 23, 42, 0.15));
  pointer-events: auto;
}

@media (max-width: 768px) {
  .qr-overlay__img {
    top: 6%;
    left: 50%;
    transform: translateX(-50%);
    width: clamp(220px, 70vw, 360px);
  }

  .qr-toggle {
    display: none;
  }
}

/* When QR mode is active, hide the camera FAB. */
body.qr-mode .fab {
  display: none;
}

/* ---- Delete confirmation modal ---- */
.modal--confirm {
  /* Sit above the viewer (viewer is .modal at z 200; confirm goes higher). */
  z-index: 300;
}

.modal__panel--confirm {
  width: min(100%, 22rem);
  text-align: center;
  padding: 1.25rem 1.25rem 1rem;
  gap: 0.5rem;
}

.confirm__title {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text);
}

.confirm__body {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.4;
  color: var(--muted);
}

.confirm__actions {
  display: flex;
  gap: 0.5rem;
  justify-content: stretch;
  margin-top: 0.5rem;
}

.confirm__actions .btn {
  flex: 1;
}
