/* ========================================
   Photo service - shared page shell
   Self-contained: reproduces the wedding site's palette, fonts, ivy header
   and grain as tokens of its own, but never imports from the static site's
   build output so the two stay decoupled. No third-party asset loads.
   Mobile-first, one-handed, in a dark room: guests arrive on phones.
   ======================================== */

:root {
  --color-primary: #a8d5a2;
  --color-primary-dark: #4a7c59;
  --color-primary-light: #c5e8c0;
  --color-background: #faf8f5;
  --color-text: #4a5568;
  --color-text-light: #6b7280;
  --color-white: #ffffff;
  --color-accent: #d4a574;
  --color-error: #b3695c;
  --color-border: rgba(74, 85, 104, 0.16);
  --color-chip: rgba(212, 165, 116, 0.16);
  /* Text laid on --color-primary-dark, which inverts between themes. */
  --color-on-primary: #ffffff;
  --color-on-primary-light: #2f5233;

  --header-gradient: linear-gradient(135deg, #3d5a3a 0%, #4a7c59 50%, #5a8a65 100%);
  --ivy-opacity: 0.12;

  /* Playfair and Lato cannot be fetched under `default-src 'self'` and are
     not self-hosted yet, so the fallbacks are the ones guests will actually
     see: the closest old-style serif and grotesque each platform ships. */
  --font-heading: "Playfair Display", "Iowan Old Style", "Palatino Linotype",
    Palatino, Georgia, serif;
  --font-body: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  --transition: all 0.3s ease;
}

/* Dark is declared twice on purpose: once for the phone's own setting, which
   is what nearly every guest will arrive with, and once for the explicit
   attribute the rest of the wedding site sets. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-primary: #7cb377;
    --color-primary-dark: #a8d5a2;
    --color-primary-light: #3d5a3a;
    --color-background: #1a1d1a;
    --color-text: #e5e7eb;
    --color-text-light: #9ca3af;
    --color-white: #242824;
    --color-error: #cf8a7d;
    --color-border: rgba(229, 231, 235, 0.13);
    --color-chip: rgba(212, 165, 116, 0.2);
    --color-on-primary: #16201a;
    --color-on-primary-light: #e5e7eb;
    --header-gradient: linear-gradient(135deg, #1a1d1a 0%, #2d3a2d 50%, #3d5a3a 100%);
    --ivy-opacity: 0.05;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 10px 18px rgba(0, 0, 0, 0.5);
  }
}

[data-theme="dark"] {
  --color-primary: #7cb377;
  --color-primary-dark: #a8d5a2;
  --color-primary-light: #3d5a3a;
  --color-background: #1a1d1a;
  --color-text: #e5e7eb;
  --color-text-light: #9ca3af;
  --color-white: #242824;
  --color-error: #cf8a7d;
  --color-border: rgba(229, 231, 235, 0.13);
  --color-chip: rgba(212, 165, 116, 0.2);
  --color-on-primary: #16201a;
  --color-on-primary-light: #e5e7eb;
  --header-gradient: linear-gradient(135deg, #1a1d1a 0%, #2d3a2d 50%, #3d5a3a 100%);
  --ivy-opacity: 0.05;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 10px 18px rgba(0, 0, 0, 0.5);
}

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

/* Several components below set `display`, which would otherwise outrank the
   browser's own rule for [hidden] and leave every "hidden" state on screen. */
[hidden] {
  display: none !important;
}

body {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  color: var(--color-text);
  background-color: var(--color-background);
  min-height: 100dvh;
  -webkit-text-size-adjust: 100%;
}

h1,
h2 {
  font-family: var(--font-heading);
  font-weight: 600;
  line-height: 1.25;
}

a {
  color: var(--color-primary-dark);
}

img {
  display: block;
  max-width: 100%;
}

/* The same fractal-noise grain the wedding site lays over every page. */
.grain {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 60;
  opacity: 0.035;
  /* Without an explicit tile size the SVG has no intrinsic dimensions and
     stretches to fill the element, which turns fine noise into huge blobs. */
  background-size: 180px 180px;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
}

/* ---------- Page header: the site's signature ---------- */

.page-header {
  position: relative;
  overflow: hidden;
  background: var(--header-gradient);
  color: #ffffff;
  padding: calc(26px + env(safe-area-inset-top)) 18px 22px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.page-header-tall {
  padding-top: calc(44px + env(safe-area-inset-top));
  padding-inline: 22px;
  padding-bottom: 24px;
}

/* Decorative ivy branches - the exact three from the wedding site. */
.page-header::before {
  content: "";
  position: absolute;
  inset: 0;
  opacity: var(--ivy-opacity);
  pointer-events: none;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 300'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='2'%3E%3Cpath d='M-10 300 Q30 250 25 200 Q20 150 40 100 Q60 50 50 0'/%3E%3Cpath d='M25 200 Q45 190 60 200'/%3E%3Cpath d='M40 100 Q60 95 70 105'/%3E%3Cpath d='M30 150 Q10 140 5 155'/%3E%3C/g%3E%3Cg fill='%23ffffff'%3E%3Cpath d='M60 200 Q75 185 70 170 Q60 175 55 190 Q50 180 40 185 Q50 195 60 200z'/%3E%3Cpath d='M70 105 Q90 95 85 75 Q70 85 68 100 Q60 90 50 95 Q62 105 70 105z'/%3E%3Cpath d='M5 155 Q-15 145 -20 160 Q-5 165 5 155 Q-5 170 0 180 Q10 170 5 155z'/%3E%3Cpath d='M50 250 Q65 235 60 220 Q50 225 48 240 Q40 230 30 235 Q42 245 50 250z'/%3E%3Cpath d='M45 50 Q60 35 55 20 Q45 25 43 40 Q35 30 25 35 Q37 45 45 50z'/%3E%3C/g%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 150 250'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='1.5'%3E%3Cpath d='M75 250 Q60 200 70 150 Q80 100 65 50 Q55 20 60 0'/%3E%3Cpath d='M70 150 Q50 145 40 155'/%3E%3Cpath d='M65 80 Q85 70 95 80'/%3E%3C/g%3E%3Cg fill='%23ffffff'%3E%3Cpath d='M40 155 Q25 145 20 160 Q35 165 40 155 Q30 170 35 180 Q45 168 40 155z'/%3E%3Cpath d='M95 80 Q110 70 105 55 Q92 65 95 80 Q105 90 100 100 Q90 88 95 80z'/%3E%3Cpath d='M72 200 Q85 185 80 170 Q70 178 72 190 Q62 182 55 188 Q65 198 72 200z'/%3E%3Cpath d='M58 30 Q45 20 40 35 Q52 40 58 30 Q50 45 55 52 Q62 42 58 30z'/%3E%3C/g%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 180 280'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='1.8'%3E%3Cpath d='M180 0 Q150 40 155 90 Q160 140 140 190 Q120 240 130 280'/%3E%3Cpath d='M155 90 Q135 85 125 95'/%3E%3Cpath d='M140 190 Q160 195 170 185'/%3E%3Cpath d='M148 140 Q128 150 120 140'/%3E%3C/g%3E%3Cg fill='%23ffffff'%3E%3Cpath d='M125 95 Q110 85 105 100 Q118 105 125 95 Q115 110 120 120 Q130 108 125 95z'/%3E%3Cpath d='M170 185 Q185 175 180 160 Q168 170 170 185 Q180 195 175 205 Q165 193 170 185z'/%3E%3Cpath d='M120 140 Q105 135 100 150 Q115 152 120 140 Q110 155 115 165 Q125 153 120 140z'/%3E%3Cpath d='M135 240 Q120 230 115 245 Q128 250 135 240 Q125 255 130 265 Q140 253 135 240z'/%3E%3Cpath d='M160 50 Q175 40 170 25 Q158 35 160 50 Q170 58 165 68 Q155 58 160 50z'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 250px 100%, 180px 85%, 220px 95%;
  background-repeat: no-repeat;
  background-position: left top, 55% top, right top;
}

.page-header > * {
  position: relative;
  z-index: 1;
}

.page-header h1 {
  font-size: 30px;
  letter-spacing: 0.5px;
}

.page-header-compact h1 {
  font-size: 21px;
}

.header-subtitle {
  font-size: 12.5px;
  opacity: 0.85;
  margin-top: 4px;
  letter-spacing: 2px;
  text-transform: uppercase;
}

.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.header-count {
  font-size: 12.5px;
  opacity: 0.85;
}

/* ---------- Pills on the gradient ---------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.11);
  color: #ffffff;
  font-family: inherit;
  font-size: 13px;
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition);
}

.pill-static {
  cursor: default;
  min-height: 0;
  margin-top: 16px;
}

.pill-dot {
  width: 7px;
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
  animation: pulse 2s infinite;
  flex: none;
}

/* ---------- Layout ---------- */

.container {
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding: 18px 18px 30px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.container-wide {
  max-width: 860px;
  padding: 14px 14px 28px;
  gap: 12px;
}

.card {
  background-color: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: 12px 14px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.field-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

.field-label .field-label-hint {
  font-weight: 400;
  color: var(--color-text-light);
}

/* 16px keeps iOS from zooming the whole page on focus. */
.form-input {
  height: 48px;
  width: 100%;
  border-radius: var(--radius-md);
  border: 1.5px solid var(--color-border);
  background: var(--color-white);
  color: var(--color-text);
  padding: 0 14px;
  font-size: 16px;
  font-family: inherit;
  box-shadow: var(--shadow-sm);
  transition: var(--transition);
}

.form-input:focus {
  outline: none;
  border-color: var(--color-primary-dark);
}

.form-input::placeholder {
  color: var(--color-text-light);
}

/* ---------- Challenge picker ----------
   One component, two jobs: the upload screen chooses a challenge with it and
   the gallery filters by one. Twenty-two labels written as sentences ruled
   out the scrolling chip row this replaces — collapsed it was fifteen screens
   wide, expanded it was taller than the page. */

.challenge-trigger {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
  padding: 11px 14px;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-text);
  font-family: inherit;
  font-size: 15px;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
  transition: var(--transition);
}

.challenge-trigger-value {
  flex: 1;
  min-width: 0;
}

.challenge-trigger-caret {
  flex: none;
  font-size: 13px;
  color: var(--color-text-light);
}

.challenge-trigger.has-challenge {
  border-color: var(--color-accent);
  background: var(--color-chip);
  font-weight: 700;
}

.challenge-trigger:focus-visible {
  outline: 2px solid var(--color-primary-dark);
  outline-offset: 2px;
}

/* ---------- The sheet ---------- */

.sheet {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
}

.sheet-open {
  display: flex;
}

.sheet-scrim {
  position: absolute;
  inset: 0;
  background: rgba(10, 14, 10, 0.45);
}

/* Held to the width of the page's own column: stretched across a desktop the
   rows put their label an inch away from their number and read as a table. */
.sheet-panel {
  position: relative;
  width: 100%;
  max-width: 640px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 84vh;
  background: var(--color-white);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.2);
  animation: sheet-up 0.25s ease;
}

.sheet-panel:focus {
  outline: none;
}

@keyframes sheet-up {
  from {
    opacity: 0;
    transform: translateY(60px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.sheet-handle {
  width: 38px;
  height: 4px;
  margin: 9px auto 0;
  border-radius: var(--radius-pill);
  background: var(--color-border);
}

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 10px 0 18px;
}

.sheet-title {
  font-family: var(--font-heading);
  font-size: 20px;
}

.sheet-close {
  width: 44px;
  height: 44px;
  flex: none;
  border: none;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-text-light);
  font-family: inherit;
  font-size: 17px;
  cursor: pointer;
}

.sheet-search {
  padding: 6px 16px 8px;
}

/* .form-input already carries the 16px that keeps iOS from zooming the page
   on focus, which would push the list the guest opened this to read. */
.sheet-search-input {
  height: 46px;
  box-shadow: none;
  background: var(--color-background);
}

.sheet-search-note {
  margin-top: 6px;
  font-size: 12px;
  color: var(--color-text-light);
}

.sheet-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 26px 20px;
  text-align: center;
}

.sheet-empty-title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 18px;
}

/* ---------- Rows ---------- */

.challenge-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 2px 12px calc(20px + env(safe-area-inset-bottom));
}

.challenge-row {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  width: 100%;
  min-height: 48px;
  padding: 12px 13px;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-text);
  font-family: inherit;
  font-size: 15px;
  line-height: 1.4;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition);
}

.challenge-num {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-pill);
  background: var(--color-primary-light);
  color: var(--color-primary-dark);
  font-size: 12px;
  font-weight: 700;
}

/* The whole point of the row shape: flex: 1 with min-width: 0 lets the
   longest label — ninety-one characters — wrap onto three lines instead of
   sitting on one and pushing the document sideways, which is what the chips
   it replaces kept doing. */
.challenge-label {
  flex: 1;
  min-width: 0;
  padding-top: 2px;
}

.challenge-check {
  flex: none;
  padding-top: 2px;
  color: var(--color-accent);
  font-weight: 700;
  opacity: 0;
}

.challenge-count {
  flex: none;
  padding-top: 3px;
  color: var(--color-text-light);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}

.challenge-row[aria-selected="true"],
.challenge-row[aria-current="page"] {
  border-color: var(--color-accent);
  background: var(--color-chip);
  font-weight: 700;
}

.challenge-row[aria-selected="true"] .challenge-check {
  opacity: 1;
}

/* Gold is too light to carry white text: the same dark brown the viewer's
   download button uses sits on it at 7.4:1 instead of 2.1:1. */
.challenge-row[aria-selected="true"] .challenge-num,
.challenge-row[aria-current="page"] .challenge-num {
  background: var(--color-accent);
  color: #2d2417;
}

.challenge-row:focus-visible {
  outline: 2px solid var(--color-primary-dark);
  outline-offset: 2px;
}

/* ---------- The gallery's filter bar ---------- */

.filter-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.filter-trigger {
  width: auto;
  min-height: 44px;
  border-radius: var(--radius-pill);
  padding: 0 16px;
  font-size: 13.5px;
  font-weight: 700;
}

/* Says which filter is on, and is itself the way out of it. */
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border: 1.5px solid var(--color-accent);
  border-radius: var(--radius-pill);
  background: var(--color-chip);
  color: var(--color-text);
  font-size: 13.5px;
  font-weight: 700;
  text-decoration: none;
}

.filter-chip-num {
  flex: none;
  color: var(--color-accent);
}

.filter-chip-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- Buttons ---------- */

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 54px;
  padding: 0 20px;
  font-family: inherit;
  font-size: 16.5px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-align: center;
  text-decoration: none;
  color: var(--color-on-primary);
  background-color: var(--color-primary-dark);
  border: none;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  cursor: pointer;
  transition: var(--transition);
}

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

.btn-secondary {
  min-height: 48px;
  font-size: 15px;
  color: var(--color-text);
  background: transparent;
  border: 1.5px solid var(--color-border);
  box-shadow: none;
}

.btn-small {
  width: auto;
  min-height: 44px;
  padding: 0 14px;
  font-size: 13px;
  box-shadow: none;
}

.btn-icon {
  width: 44px;
  min-height: 44px;
  padding: 0;
  font-size: 16px;
  flex: none;
}

.btn-danger {
  color: var(--color-error);
  background: transparent;
  border: 1.5px solid var(--color-error);
  box-shadow: none;
}

.btn-retry {
  color: var(--color-primary-dark);
  background: transparent;
  border: 1.5px solid var(--color-primary-dark);
  box-shadow: none;
}

/* ---------- Notices ---------- */

.notice {
  font-size: 12px;
  line-height: 1.55;
  color: var(--color-text-light);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
}

.notice strong {
  color: var(--color-text);
}

.alert {
  border-radius: var(--radius-md);
  border: 1.5px solid var(--color-accent);
  background: var(--color-chip);
  padding: 12px 14px;
  font-size: 13.5px;
}

.alert-error {
  border-color: var(--color-error);
  background: transparent;
  color: var(--color-error);
}

.alert-success {
  border: none;
  background: var(--color-primary-light);
  color: var(--color-on-primary-light);
  padding: 15px;
  text-align: center;
  font-size: 14.5px;
  font-weight: 700;
  animation: rise 0.4s ease;
}

.text-muted {
  color: var(--color-text-light);
  font-size: 12.5px;
}

/* ---------- Spinner ---------- */

.spinner {
  display: inline-block;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-pill);
  border: 2.5px solid var(--color-primary-dark);
  border-top-color: transparent;
  animation: spin 0.9s linear infinite;
  flex: none;
}

.spinner-small {
  width: 16px;
  height: 16px;
  border-width: 2px;
  border-color: var(--color-accent);
  border-top-color: transparent;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.3;
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* A guest who asked their phone for less motion gets less motion. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- Full-screen photo viewer ----------
   Shared by the guest gallery and the moderation console. */


.lightbox {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(8, 11, 8, 0.96);
  animation: rise 0.25s ease;
  overflow: hidden;
  overscroll-behavior: contain;
}

.lightbox[hidden] {
  display: none;
}

.lightbox-image,
.lightbox-video,
.lightbox-follow {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #080b08;
}

.lightbox-follow {
  z-index: 1;
  pointer-events: none;
}

.lightbox.is-gesturing .lightbox-image,
.lightbox.is-gesturing .lightbox-video,
.lightbox.is-gesturing .lightbox-follow {
  will-change: transform, opacity;
}

.lightbox-top {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: calc(10px + env(safe-area-inset-top)) 12px 30px;
  background: linear-gradient(rgba(8, 11, 8, 0.65), transparent);
}

.lightbox-count {
  color: rgba(255, 255, 255, 0.7);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}

.lightbox-btn {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: rgba(8, 11, 8, 0.4);
  color: #ffffff;
  font-family: inherit;
  font-size: 17px;
  cursor: pointer;
  flex: none;
}

.lightbox-prev,
.lightbox-next {
  position: absolute;
  z-index: 2;
  top: 50%;
  transform: translateY(-50%);
  font-size: 18px;
}

.lightbox-prev {
  left: 8px;
}

.lightbox-next {
  right: 8px;
}

.lightbox-bottom {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 34px 14px calc(16px + env(safe-area-inset-bottom));
  background: linear-gradient(transparent, rgba(8, 11, 8, 0.75));
}

.lightbox-meta {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.lightbox-author {
  color: #ffffff;
  font-size: 15px;
  font-weight: 700;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

.lightbox-challenge {
  align-self: flex-start;
  max-width: 100%;
  font-size: 11px;
  color: #f3e3cd;
  background: rgba(212, 165, 116, 0.3);
  border: 1px solid rgba(212, 165, 116, 0.55);
  border-radius: var(--radius-pill);
  padding: 3px 10px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lightbox-slot {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
}

.lightbox-download,
.lightbox-action {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 48px;
  padding: 0 20px;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
  color: #2d2417;
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
  border: none;
  font-family: inherit;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
}

/* The console's action is a decision, not a download: it carries the colour
   of what it does so a tired thumb cannot mistake one for the other. */
.lightbox-action-remove {
  background: var(--color-error);
  color: #ffffff;
}

.lightbox-action-restore {
  background: var(--color-primary);
  color: #16201a;
}

/* ---------- Wider screens ----------
   The phone is the real case; a desktop is where the photos get looked at
   again afterwards, so the page grows rather than stretching. */

@media (min-width: 720px) {
  .page-header {
    padding: 40px 32px 30px;
  }

  .page-header-tall {
    padding: 56px 32px 34px;
  }

  .page-header > * {
    max-width: 1160px;
    margin-inline: auto;
  }
}
