/*
 * Garden at Dusk, toned down. The working surfaces of Emily & Ben's wedding:
 * a drenched deep-green ground, a low gold flame, guests' photos carry the color.
 * See DESIGN.md. Shared by index.html (uploader chrome) and gallery.html.
 */

:root {
  /* Ground (drenched) */
  --ground: #032215;
  --ground-deep: #001108;
  --ground-glow: #0b2f1f;
  --surface: #0f3222; /* the only "card" color: lift is a lighter green */
  --line: #1b452d;

  /* Ink */
  --ink: #f2efe1;
  --muted: #d8d1bd;

  /* Candlelight */
  --gold: #f2c36a;
  --gold-soft: #d9b97e;

  /* Semantic */
  --success: #69c27e;
  --danger: #e26943;

  /* Type */
  --font-display: "Italiana", "Times New Roman", Georgia, serif;
  --font-body: "Hanken Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Shape */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-pill: 999px;

  /* Motion */
  --ease: cubic-bezier(0.16, 1, 0.3, 1); /* ease-out-expo */
  --dur: 180ms;

  /* The low gold flame around a focused element */
  --halo: 0 0 0 3px rgba(242, 195, 106, 0.45);

  /* Semantic z-index scale */
  --z-sticky: 10;
  --z-lightbox: 50;
}

* { box-sizing: border-box; }

/* A class rule can out-specify the UA [hidden] display:none; enforce it. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  background-color: var(--ground-deep);
}

body {
  margin: 0;
  min-height: 100svh;
  padding: clamp(1.25rem, 4vw, 3rem);
  /* Flex (not grid) centering: a grid auto-track sizes to the child's max-width
     and lets `.card`/`.gallery-shell` exceed the viewport on narrow screens. */
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: var(--ground-deep);
  background-image:
    radial-gradient(125% 80% at 50% -6%,
      var(--ground-glow) 0%,
      var(--ground) 44%,
      var(--ground-deep) 100%);
  background-repeat: no-repeat;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: clamp(1rem, 0.97rem + 0.15vw, 1.06rem);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: rgba(242, 195, 106, 0.28); color: var(--ink); }

a { color: var(--gold); text-underline-offset: 3px; }

/* Keyboard focus: the low flame, never a fill. Uppy keeps its own widget styles. */
:where(a, button, input, summary, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--halo);
  border-radius: var(--r-sm);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--gold);
  color: var(--ground-deep);
  font-weight: 600;
  padding: 0.6rem 1rem;
  border-radius: 0 0 var(--r-sm) 0;
}
.skip-link:focus { left: 0; }

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font: 600 1rem/1 var(--font-body);
  padding: 0.85rem 1.6rem;
  min-height: 2.9rem;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    border-color var(--dur) var(--ease), color var(--dur) var(--ease),
    background-color var(--dur) var(--ease);
}
.btn:active { transform: translateY(0); }

/* The one gold fill on a page (The Low Flame Rule). */
.btn--primary {
  background: var(--gold);
  color: var(--ground-deep);
}
.btn--primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 0 4px rgba(242, 195, 106, 0.22);
}

/* The default button of the system: quiet, hairline, warms to gold. */
.btn--ghost {
  background: transparent;
  color: var(--ink);
  font-weight: 500;
  border-color: var(--line);
}
.btn--ghost:hover {
  border-color: var(--gold-soft);
  color: var(--gold);
}

.btn svg { display: block; }

/* ==========================================================================
   Shared chrome (uploader page: index.html)
   ========================================================================== */

.card {
  width: 100%;
  max-width: 36rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 4vw, 2.5rem);
}

/* Centered masthead: the "Emily & Ben" names lead here exactly as on the gallery. */
.intro {
  margin-bottom: 1.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.7rem;
}
.intro > * { margin: 0; }

h1 {
  margin: 0 0 0.6rem;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 1.4rem + 2.6vw, 3.25rem);
  line-height: 1.05;
  letter-spacing: 0.01em;
  text-wrap: balance;
}

.lede {
  margin: 0;
  max-width: 60ch;
  color: var(--muted);
  text-wrap: pretty;
}

.textlink {
  color: var(--gold);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--ease);
}
.textlink:hover { border-bottom-color: currentColor; }

.textlink__chevron {
  display: inline-block;
  font-size: 1.6em;
  line-height: 0.5em;
  margin-left: 0.3em;
  font-family: var(--font-display);
  transition: transform var(--dur) var(--ease);
}

/* ==========================================================================
   Gallery
   ========================================================================== */

.gallery-shell {
  width: 100%;
  max-width: 62rem;
}

.gallery-head {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  padding: clamp(0.5rem, 3vw, 2rem) 0 clamp(1.5rem, 4vw, 2.5rem);
}

.names {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.6rem, 1.8rem + 4vw, 4.5rem);
  line-height: 1;
  letter-spacing: 0.01em;
  text-wrap: balance;
}
.names .amp {
  color: var(--gold);
  font-size: 0.7em;
  margin: 0 0.06em;
  vertical-align: 0.04em;
}

.gallery-head .lede {
  margin: 0;
  font-size: clamp(0.98rem, 0.94rem + 0.3vw, 1.12rem);
}

.gallery-head .btn { margin-top: 0.4rem; }

/* A single gold hairline separating the header from the wall of photos. */
.gallery-rule {
  height: 1px;
  border: 0;
  margin: 0 auto clamp(1.25rem, 4vw, 2rem);
  width: min(100%, 14rem);
  background: linear-gradient(90deg, transparent, rgba(242, 195, 106, 0.5), transparent);
}

/* The wall: quiet frames, the photos carry the color. */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(clamp(6.5rem, 26vw, 10.5rem), 1fr));
  gap: clamp(0.4rem, 1.4vw, 0.7rem);
}

.tile {
  position: relative;
  margin: 0;
  padding: 0;
  aspect-ratio: 1 / 1;
  border: 1px solid transparent;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
  cursor: pointer;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    border-color var(--dur) var(--ease), opacity 0.5s var(--ease);
}
.tile img,
.tile video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.tile:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 26px -14px rgba(0, 0, 0, 0.6);
  border-color: rgba(217, 185, 126, 0.55);
}
.tile:focus-visible {
  box-shadow: var(--halo);
  border-color: transparent;
}
/* Expired signed URL or decode failure: dim and disable, never a broken icon. */
.tile.is-broken { opacity: 0.3; pointer-events: none; }

/* Video tiles: a low gold flame in the corner, not a loud play button. */
.tile__play {
  position: absolute;
  right: 0.5rem;
  bottom: 0.5rem;
  width: 1.7rem;
  height: 1.7rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(0, 17, 8, 0.6);
  color: var(--gold);
  pointer-events: none;
}
.tile__play svg { width: 0.82rem; height: 0.82rem; }

/* Skeleton tiles while the first page loads (not a spinner). */
.tile--skeleton {
  cursor: default;
  background:
    linear-gradient(100deg,
      var(--surface) 30%,
      #143b2a 50%,
      var(--surface) 70%) 0 0 / 220% 100%;
}

.empty {
  text-align: center;
  padding: clamp(2.5rem, 8vw, 4.5rem) 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}
.empty__mark {
  width: 3.25rem;
  height: 3.25rem;
  color: var(--gold);
  opacity: 0.9;
}
.empty__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
  line-height: 1.15;
}
.empty p { margin: 0; max-width: 38ch; color: var(--muted); }
.empty .btn { margin-top: 0.4rem; }

.loadmore {
  display: flex;
  justify-content: center;
  margin-top: clamp(1.25rem, 4vw, 2rem);
}

.gallery-foot {
  display: flex;
  justify-content: center;
  margin-top: clamp(2rem, 6vw, 3.5rem);
}

/* ==========================================================================
   Lightbox: a lit frame in a dark room
   ========================================================================== */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: grid;
  grid-template-rows: 1fr auto;
  place-items: center;
  padding: clamp(0.75rem, 3vw, 2.5rem);
  background: rgba(0, 17, 8, 0.92);
  backdrop-filter: blur(4px);
}
.lightbox[hidden] { display: none; }

.lightbox__stage {
  grid-row: 1;
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 0;
}
.lightbox__body { display: grid; place-items: center; min-height: 0; }
.lightbox__body img,
.lightbox__body video {
  max-width: min(94vw, 70rem);
  max-height: 78svh;
  display: block;
  border-radius: var(--r-md);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.7);
}

.lightbox__caption {
  grid-row: 2;
  margin-top: 0.9rem;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  color: var(--muted);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
}
.lightbox__count { color: var(--gold-soft); font-variant-numeric: tabular-nums; }

/* Round controls: ink glyph on a faint raised surface, gold halo on focus. */
.lb-btn {
  position: absolute;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: none;
  border-radius: 50%;
  background: rgba(242, 239, 225, 0.12);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.lb-btn:hover { background: rgba(242, 239, 225, 0.22); }
.lb-btn svg { width: 1.25rem; height: 1.25rem; }
.lightbox__close { top: clamp(0.75rem, 3vw, 1.5rem); right: clamp(0.75rem, 3vw, 1.5rem); }
.lightbox__nav--prev { left: clamp(0.5rem, 2vw, 1.5rem); top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: clamp(0.5rem, 2vw, 1.5rem); top: 50%; transform: translateY(-50%); }
.lightbox__nav--prev:hover { transform: translateY(-50%) scale(1.06); }
.lightbox__nav--next:hover { transform: translateY(-50%) scale(1.06); }
.lb-btn[hidden] { display: none; }

/* ==========================================================================
   Motion: toned-down reveals; full reduced-motion fallback
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  .tile--skeleton { animation: dusk-shimmer 1.4s linear infinite; }
  .lightbox:not([hidden]) .lightbox__body { animation: dusk-pop 0.32s var(--ease) both; }
}

@keyframes dusk-shimmer {
  to { background-position: -220% 0; }
}
@keyframes dusk-pop {
  from { opacity: 0; transform: scale(0.985); }
  to { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ==========================================================================
   Uppy Dashboard, themed into the garden (theme: "dark" + scoped overrides).
   Uppy v5 exposes no CSS variables, so we out-specify its class rules with
   the #uppy id. The white widget becomes part of the dusk.
   ========================================================================== */

#uppy .uppy-Dashboard,
#uppy .uppy-Dashboard *:not(svg):not(svg *) {
  font-family: var(--font-body);
}

/* Panel: let the card's green show through; frame it with a hairline. */
#uppy .uppy-Dashboard-inner,
#uppy .uppy-Dashboard-innerWrap {
  background: transparent;
  border: 0;
  border-radius: var(--r-md);
}

/* The add-files zone. No drag affordance is needed on mobile, so it's a calm
   framed area, not a dashed drop target. */
#uppy .uppy-Dashboard-AddFiles {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  margin: 0.5rem;
}
#uppy .uppy-Dashboard-AddFiles-title {
  color: var(--muted);
  font-size: 1rem;
}
#uppy .uppy-Dashboard-note {
  color: var(--muted);
}

/* The primary action: the one gold flame on this page. */
#uppy .uppy-Dashboard-browse {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.25rem;
  padding: 0.85rem 1.6rem;
  border: none;
  border-radius: var(--r-pill);
  background: var(--gold);
  color: var(--ground-deep);
  font-weight: 600;
  text-decoration: none;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
/* Camera glyph before the label, matching the gallery's "Add your photos" CTAs.
   Uppy's locale string can't hold an <svg>, so we draw it as a CSS background.
   Stroke baked to ground-deep (#001108) to read on the gold pill. */
#uppy .uppy-Dashboard-browse::before {
  content: "";
  flex: none;
  width: 1.25em;
  height: 1.25em;
  background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23001108' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'><path d='M3 8.5A2.5 2.5 0 0 1 5.5 6h1.2l.9-1.4A1.5 1.5 0 0 1 8.9 4h6.2a1.5 1.5 0 0 1 1.3.6l.9 1.4h1.2A2.5 2.5 0 0 1 21 8.5v8A2.5 2.5 0 0 1 18.5 19h-13A2.5 2.5 0 0 1 3 16.5z'/><circle cx='12' cy='12.5' r='3.2'/></svg>") center / contain no-repeat;
}
#uppy .uppy-Dashboard-browse:hover,
#uppy .uppy-Dashboard-browse:focus {
  background: var(--gold);
  color: var(--ground-deep);
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: 0 0 0 4px rgba(242, 195, 106, 0.22);
}

/* Toolbars and status bar: transparent over the card. */
#uppy .uppy-DashboardContent-bar,
#uppy .uppy-StatusBar:not([aria-hidden="true"]),
#uppy .uppy-StatusBar.is-waiting {
  background: transparent;
  border-color: var(--line);
}
#uppy .uppy-DashboardContent-title,
#uppy .uppy-StatusBar-statusPrimary {
  color: var(--ink);
}

/* Header / dismiss buttons warm to gold. */
#uppy .uppy-DashboardContent-back,
#uppy .uppy-DashboardContent-addMore,
#uppy .uppy-Dashboard-Item-action {
  color: var(--gold-soft);
}

#uppy .uppy-Dashboard-Item-action--remove {
  color: #7a141e;
}

/* Progress is a lit-leaf green; the upload button is the gold flame. */
#uppy .uppy-StatusBar-progress,
#uppy .uppy-StatusBar.is-preprocessing .uppy-StatusBar-progress,
#uppy .uppy-Dashboard-Item-progressIndicator .uppy-c-icon circle:last-child {
  background: var(--success);
}
#uppy .uppy-StatusBar-actionBtn--upload {
  background: var(--gold);
  color: var(--ground-deep);
  border-radius: var(--r-pill);
  padding: 0.5rem 1.25rem;
  font-weight: 600;
}
#uppy .uppy-StatusBar-actionBtn--upload:hover {
  background: var(--gold-soft);
}

/* File preview cards lift on the lighter green. */
#uppy .uppy-Dashboard-Item {
  border-color: var(--line);
}
#uppy .uppy-Dashboard-Item-previewinnerWrap {
  background: var(--ground);
}

/* Center the add action within the panel instead of pinning it to the top. */
#uppy .uppy-Dashboard-AddFiles {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
#uppy .uppy-Dashboard-AddFiles-info {
  position: static;
  margin-top: 0.6rem;
}

/* No import sources (no Drive/Dropbox), so the import list is an empty void. */
#uppy .uppy-Dashboard-AddFiles-list { display: none; }

/* Surface the note (it ships collapsed inside AddFiles-info). */
#uppy .uppy-Dashboard-AddFiles-info {
  position: static;
  height: auto;
  margin-top: 0.85rem;
  opacity: 1;
  overflow: visible;
}
#uppy .uppy-Dashboard-note {
  display: block;
  height: auto;
  max-width: 34ch;
  margin: 0 auto;
  text-align: center;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.45;
}

/* Uppy hides AddFiles-info via display:none on short dashboards; override it. */
#uppy .uppy-Dashboard-AddFiles-info { display: block; }

/* Hide trailing tiles that don't complete a row, so the responsive grid never
   shows a ragged partial row while more photos can still load. */
.tile--orphan { display: none; }

/* Video tile whose poster frame couldn't be generated (unsupported codec or
   >100 MB). A quiet dusk card so it still reads as an intentional video. */
.tile--noposter {
  background:
    radial-gradient(120% 120% at 50% 30%, var(--surface, #0f3222), var(--ground-deep, #001108));
}
.tile--noposter::after {
  content: "Video";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.6rem;
  text-align: center;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--muted, #d8d1bd);
}
