/* =========================================================================
   27 Moments — Gastenpagina (de POV-app)
   Vintage donkere kamer met crème papier. Mobiel eerst: gasten staan met
   een glas in de hand op het feest, niet achter een laptop.

   De pagina blijft volledig in de 27 Moments-huisstijl. Het koppel herken
   je aan de namen en de datum, niet aan een afwijkend kleurenpalet.
   ========================================================================= */

:root {
  /* 27 Moments-palet. De camerascherm-achtergrond is het diepe merkgroen:
     donker genoeg om beeld te laten spreken, zonder in zwart te vervallen. */
  --gast-diep: #3a4436;
  --gast-groen: #5a6850;
  --gast-inkt: #2c2c2b;
  --gast-papier: #f7f6f2;
  --gast-papier-warm: #e3eaca;
  --gast-zacht: #7c776f;
  --gast-lijn: #e2ded4;
  --gast-accent: #835fa5;
  --gast-lila: #c2b1d7;
  --gast-accent-tekst: #ffffff;
  --gast-fout: #a8412f;
  --gast-radius: 14px;
  --gast-display: "Pink Sunset", "Cooper Black", Georgia, serif;
  --gast-body: "apparat", "apparat-light", "Apparat", "Avenir Next", system-ui, sans-serif;

  /* DE STROOK DIE DE BROWSER OPEET. Een scherm hieronder staat op
     position:fixed; inset:0, en dat is op een telefoon de GROTE bak: de
     hoogte alsof de balken van de browser weggeschoven zijn. Staan die
     balken er wél, dan valt de onderste strook van dat scherm erachter —
     en daar wonen de sluiterknop en "Beelden versturen".

     Deze waarde is precies die strook: wat de browser ons geeft (100lvh)
     min wat de gast echt ziet (100dvh). Nul op een computer, nul in de app
     op het beginscherm, en precies de werkbalk hoog in een tabblad. Het
     BEELD mag er wél onderdoor lopen; de knoppen niet. */
  --gast-balkstrook: 0px;
}

/* De @supports is geen sierraad. Een eigen eigenschap wordt bij het inlezen
   NIET nagekeken: een oude browser slikt calc(100lvh - 100dvh) als tekst en
   struikelt er pas over op de plek waar we hem gebruiken — en daar valt dan
   de hele regel weg in plaats van terug te vallen op de regel erboven.
   lvh, svh en dvh kwamen samen binnen (Safari 15.4, Chrome 108), dus één
   test dekt ze alle drie.

   dvh en niet svh, en dat is een bewuste keuze: svh is de bak MET de balken
   en klopt dus alleen zolang die balken er staan. dvh is de bak van nu, dus
   de reservering is vanzelf nul zodra de balken wegschuiven. */
@supports (height: 100dvh) {
  :root { --gast-balkstrook: calc(100lvh - 100dvh); }
}

/* Het hidden-attribuut moet altijd winnen van display:flex/grid hieronder. */
[hidden] { display: none !important; }

/* DE KLEUR ACHTER DE STATUSBALK. Trekt een gast de pagina naar beneden, dan
   veert ze los van de bovenrand en zie je erachter de kleur van het CANVAS.
   Die kleur erft de browser van <html>, en <html> had er geen — dus kwam ze
   van de body, en dat is crème. Resultaat: een crème flits pal achter de
   batterij- en wifi-iconen, tegen een groene hero aan.

   Op <html> zetten is het hele antwoord. Het werkt in een tabblad én op het
   beginscherm, het heeft geen vast element nodig dat op iOS toch meeveert,
   en het hangt niet af van env(safe-area-inset-top) — die is in een tabblad
   namelijk gewoon 0.

   Gevolg dat je moet willen: ONDERaan veert het nu ook groen in plaats van
   crème. De voet is lichtgroen (--gast-papier-warm), dus dat staat beter dan
   wat er stond, maar het is een keuze en geen bijvangst.

   overscroll-behavior-y houdt de veerketen tegen; op Android zet het meteen
   ook pull-to-refresh uit. Dat is gewenst: een gast die halverwege een
   upload de pagina herlaadt, is een gast die zijn foto kwijt is. */
html { background: var(--gast-diep); }
html, body { overscroll-behavior-y: none; }

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

/* De pagina vult het scherm, met de voet onderaan in plaats van halverwege.
   Dat is het verschil tussen een webpagina en een app. 100dvh volgt de
   krimpende adresbalk op een telefoon; svh is het vangnet voor browsers die
   dvh nog niet kennen. */
body {
  font-family: var(--gast-body);
  background: var(--gast-papier);
  color: var(--gast-inkt);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  min-height: 100svh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.omslag { max-width: 640px; width: 100%; margin: 0 auto; padding: 0 16px 30px; flex: 1; }

/* ------------------------------- Hero ---------------------------------- */

/* EFFEN, EN DEZELFDE KLEUR ALS DE BALK ERBOVEN. Hier stond een verloop met
   zijn middelpunt op 50% 0%. Daardoor was de bovenrand van de hero #5a6850
   in het midden en ~#475341 in de hoeken, terwijl de balk erboven #3a4436
   is: dat was de naad die je op een telefoon zag. Nu één kleur, en die staat
   op vier plekken gelijk:
     - <meta name="theme-color"> in sites/gasten/index.html
     - theme_color én background_color in functions/gasten/manifest.js
     - het canvas op <html> hierboven
     - .scherm, het cameravenster, verderop in dit bestand
   Wie deze kleur wijzigt, wijzigt die vier mee.

   env(safe-area-inset-top) is 0 in een tabblad van Safari. Start de pagina
   van het beginscherm (standalone, met status-bar-style black-translucent),
   dan tekent ze zelf ACHTER de batterij- en wifi-iconen en is die waarde 47
   tot 59px. Zonder deze calc begon de tekst gewoon onder de iconen. Het
   getal 22 mag je kiezen; de calc eromheen niet.

   Er stond hier ook een filmkorrel (.hero::after). Weg, en niet per ongeluk:
   er is om een EFFEN bovenkant gevraagd, en die korrel liep met inset:-50%
   door tot achter de statusbalk. Met hem vervallen overflow:hidden (dat
   sneed hem af) en .hero > * met z-index 1 (dat tilde de tekst erboven). */
.hero {
  position: relative;
  background: var(--gast-diep);
  color: var(--gast-papier);
  text-align: center;
  padding: calc(env(safe-area-inset-top, 0px) + 22px) 20px 22px;
}

/* De namen zijn nu de eerste en de grootste regel: er stond een merkregel en
   een aanhef boven, en die zijn eruit. Vandaar margin-top 0 — die 4px stond
   er alleen om de aanhef er niet tegenaan te laten plakken, en telde nu
   stilletjes bij de padding op. */
.hero h1 {
  font-family: var(--gast-display);
  font-weight: 400;
  font-size: clamp(27px, 7.5vw, 40px);
  line-height: 1.1;
  letter-spacing: 1px;
  margin: 0 0 6px;
}

.hero__datum { font-size: 12.5px; letter-spacing: 1.5px; text-transform: uppercase; opacity: 0.72; }

/* ------------------------------ Kaarten -------------------------------- */

.kaart {
  background: #fbfbf9;
  border: 1px solid var(--gast-lijn);
  border-radius: var(--gast-radius);
  padding: 16px 18px;
  margin: 14px 0;
  box-shadow: 0 2px 10px rgba(90, 104, 80, 0.05);
}

.kaart__kop { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.kaart h2 { font-family: var(--gast-display); font-weight: 400; letter-spacing: 1px; font-size: 18px; color: var(--gast-groen); margin-bottom: 5px; }
.uitleg { color: var(--gast-zacht); font-size: 13px; }
.telling { font-size: 12.5px; color: var(--gast-zacht); }

input[type="text"] {
  width: 100%;
  font: inherit;
  font-size: 16px;               /* 16px voorkomt inzoomen op iOS */
  padding: 10px 13px;
  border: 1.5px solid var(--gast-lijn);
  border-radius: 10px;
  background: var(--gast-papier);
  color: inherit;
}

input[type="text"]:focus-visible { outline: 2px solid var(--gast-accent); outline-offset: 1px; }

/* ------------------------------- Naam ----------------------------------
   Twee gedaanten. Het veld verschijnt alleen zolang we niemand kennen;
   daarna blijft er één smalle regel over. Vandaar dat er geen uitleg en
   geen bevestigingszin meer bij staan: het balkje ís de bevestiging. */

.naam-rij { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.naam-rij input[type="text"] { flex: 1; min-width: 0; }
/* stretch, want het veld is hoger dan de knop: naast elkaar viel dat verschil
   op als een te klein knopje naast een te hoog veld. */
.naam-rij .knop { flex: 0 0 auto; align-self: stretch; }

.naambalk {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 14px 0;
  padding: 10px 14px;
  border-radius: 999px;
  background: #fbfbf9;
  border: 1px solid var(--gast-lijn);
  font-size: 13.5px;
}

.naambalk__tekst { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--gast-zacht); }
.naambalk__tekst strong { color: var(--gast-inkt); font-weight: 600; }

.naambalk__knop {
  flex: 0 0 auto;
  font: inherit;
  font-size: 12.5px;
  padding: 6px 12px;
  min-height: 48px;      /* de norm uit de portaalstandaard, ook in een smal balkje */
  border-radius: 999px;
  border: 1px solid var(--gast-lijn);
  background: transparent;
  color: var(--gast-accent);
  cursor: pointer;
}

.naambalk__knop:focus-visible { outline: 2px solid var(--gast-accent); outline-offset: 2px; }

/* ------------------------------ Aanmelden ------------------------------
   Het e-mailadres voor de eerste selectie foto's. Zelfde twee gedaanten
   als de naam: het formulier tot de gast op de lijst staat, daarna alleen
   het smalle balkje (#aanmeld-balk hergebruikt .naambalk). */

.aanmeld-velden { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }

.kaart--aanmelden input[type="email"] {
  width: 100%;
  font: inherit;
  font-size: 16px;               /* 16px voorkomt inzoomen op iOS */
  padding: 10px 13px;
  border: 1.5px solid var(--gast-lijn);
  border-radius: 10px;
  background: var(--gast-papier);
  color: inherit;
}

.kaart--aanmelden input[type="email"]:focus-visible { outline: 2px solid var(--gast-accent); outline-offset: 1px; }

/* Twee losse toestemmingen onder elkaar: de voorwaarden (verplicht) en de
   marketingkeuze (nooit vooraf aangevinkt). Ze zien er hetzelfde uit, want
   geen van beide mag zich vermommen als kleine lettertjes. */
.aanmeld-akkoord {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  margin: 12px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--gast-zacht);
  cursor: pointer;
}

.aanmeld-akkoord + .aanmeld-akkoord { margin-top: 8px; }
.aanmeld-akkoord + .knop { margin-top: 12px; }

.aanmeld-akkoord input {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  margin-top: 1px;
  accent-color: var(--gast-accent);
}

.aanmeld-akkoord a { color: var(--gast-accent); }

/* Het honeypotveld: onzichtbaar voor mensen, onweerstaanbaar voor bots.
   Bewust niet display:none — sommige bots slaan verborgen velden over. */
.niet-invullen {
  position: absolute !important;
  left: -9999px !important;
  width: 1px !important;
  height: 1px !important;
  opacity: 0;
  pointer-events: none;
}

.voet__klein a { color: inherit; }

/* --------------------------- Audiogastenboek ---------------------------
   De enige donkere kaart op de pagina, met opzet: het audiogastenboek is
   het telefoontje in de hoek van de feestzaal, niet nog een formulier.
   Diep merkgroen zoals het camerascherm, de teller in dezelfde rode pil
   als de filmopname, zodat "er loopt een opname" overal dezelfde taal
   spreekt. */

.kaart--audio {
  background: radial-gradient(120% 130% at 50% 0%, var(--gast-groen) 0%, var(--gast-diep) 70%);
  border-color: var(--gast-diep);
  color: var(--gast-papier);
}

.kaart--audio h2 { color: var(--gast-papier-warm); }
.kaart--audio .uitleg { color: rgba(247, 246, 242, 0.72); }

/* De uitleg onder de kop is weg, dus hangt er naast de hoorn nog één regel.
   Die hoort op de hoogte van het rondje, niet bovenaan met acht pixels lucht
   eronder. */
.audio-kop { display: flex; gap: 14px; align-items: center; }
.audio-kop h2 { margin-bottom: 0; }
.audio-kop__tekst { min-width: 0; }

.audio-hoorn {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--gast-accent);
  color: var(--gast-accent-tekst);
  display: grid; place-items: center;
}

.audio-hoorn svg { width: 21px; height: 21px; }

.audio-opname {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 14px;
}

.audio-knop {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font: inherit;
  font-size: 12px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  min-height: 48px;      /* de hoofdactie van deze kaart: even groot als .knop */
  padding: 10px 20px;
  border-radius: 999px;
  border: 1px solid rgba(247, 246, 242, 0.4);
  background: rgba(247, 246, 242, 0.08);
  color: var(--gast-papier);
  cursor: pointer;
}

.audio-knop:focus-visible { outline: 3px solid var(--gast-lila); outline-offset: 2px; }

.audio-knop__stip {
  flex: 0 0 auto;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--gast-fout);
}

/* Tijdens de opname: de stip wordt het bekende stopvierkant en de knop
   licht op, zodat je zonder lezen ziet dat er iets loopt. */
.audio-knop--bezig { background: var(--gast-papier); border-color: var(--gast-papier); color: var(--gast-diep); }
.audio-knop--bezig .audio-knop__stip { border-radius: 3px; }

/* De tikkende teller: zelfde rode pil met knipperende stip als bij het
   filmen (keyframes opname-knipper staan verderop bij de camera). */
.audio-teller {
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 14px;
  letter-spacing: 0.06em;
  padding: 5px 12px 5px 24px;
  border-radius: 999px;
  background: rgba(168, 65, 47, 0.92);
  color: #fff;
  position: relative;
}

.audio-teller::before {
  content: "";
  position: absolute;
  left: 10px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-radius: 50%;
  background: #fff;
  animation: opname-knipper 1s steps(1) infinite;
}

.audio-nakijk { margin-top: 14px; }
.audio-nakijk audio { width: 100%; margin: 10px 0 12px; }
.audio-knoppen { display: flex; gap: 8px; flex-wrap: wrap; }
.audio-knoppen .knop--stil { border-color: rgba(247, 246, 242, 0.35); }

/* De rustige uitleg als de micro niet mag of niet kan. Geen foutrood: een
   geweigerde micro is een keuze, geen ongeluk. */
.audio-melding {
  margin-top: 12px;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(247, 246, 242, 0.1);
  border: 1px solid rgba(247, 246, 242, 0.22);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--gast-papier-warm);
}

/* --------------------- Op het beginscherm zetten ----------------------- */

.kaart--install { border-color: var(--gast-lila); background: #faf8fc; }
.install-knoppen { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }

/* ------------------------------- Acties -------------------------------- */

.acties { display: grid; gap: 9px; margin: 16px 0 0; }

.actie {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  text-align: left;
  font: inherit;
  cursor: pointer;
  background: #fff;
  border: 1px solid var(--gast-lijn);
  border-radius: var(--gast-radius);
  padding: 13px 15px;
  color: inherit;
  transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

/* Terwijl de foto's klaargemaakt worden, staat de knop uit. Zonder deze regel
   zag je dat niet en tikte een gast dezelfde foto's een tweede keer bij.

   pointer-events uit is hier geen sierraad. CSS blokkeert :hover niet op een
   uitgeschakelde knop, dus zonder deze regel springt een gedempte knop nog
   altijd omhoog en krijgt hij de accentrand — precies het gebaar dat zegt
   "hier gebeurt iets". Op een telefoon blijft die stand na een tik bovendien
   plakken. Sinds de twee actieknoppen uit staan tot de scripts binnen zijn,
   ziet élke gast dat bij het openen van de pagina. */
.actie:disabled { opacity: 0.55; cursor: default; pointer-events: none; }

.actie:hover, .actie:focus-visible {
  border-color: var(--gast-accent);
  transform: translateY(-2px);
  box-shadow: 0 12px 26px rgba(43, 33, 26, 0.1);
  outline: none;
}

.actie__icoon {
  flex: 0 0 auto;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--gast-accent);
  color: var(--gast-accent-tekst);
}

.actie__icoon svg { width: 20px; height: 20px; }
.actie__tekst { display: block; }
.actie__tekst strong { display: block; font-size: 14.5px; margin-bottom: 1px; }
.actie__tekst span { font-size: 12.5px; color: var(--gast-zacht); }

/* -------------------------- Eigen bijdragen ----------------------------
   Bewust GEEN beelden. Wat bij het bruidspaar afgeleverd is, krijgt de gast
   niet meer te zien; wat overblijft is de stand in woorden. Het rooster met
   miniaturen dat hier stond, is daarom weg. */

.eigen-stand {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 14px;
}

.eigen-stand__regel {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--gast-inkt);
}

.eigen-stand__regel--leeg { color: var(--gast-zacht); }
.eigen-stand__regel--fout { color: var(--gast-fout); }

.eigen-stand__stip {
  flex: 0 0 auto;
  width: 8px; height: 8px;
  margin-top: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
}

.voetnoot {
  font-size: 12.5px;
  color: var(--gast-fout);
  background: #fbeeea;
  border: 1px solid #eccfc7;
  border-radius: 12px;
  padding: 12px 14px;
}

/* -------------------------------- Voet --------------------------------- */

.voet {
  text-align: center;
  padding: 18px 16px 24px;
  background: var(--gast-papier-warm);
  border-top: 1px solid var(--gast-lijn);
  font-size: 13px;
  color: var(--gast-zacht);
}

.voet__klein { font-size: 12px; margin-top: 4px; }

/* ------------------------------ Knoppen -------------------------------- */

/* min-height plus inline-flex, niet inline-block: met alleen de padding kwam
   deze knop op 41 px uit en dat is te klein voor een telefoon in een
   feestzaal, waar met één hand getikt wordt. */
.knop {
  font: inherit;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  min-height: 48px;
  padding: 10px 20px;
  border-radius: 999px;
  border: 1px solid var(--gast-lijn);
  background: #fff;
  color: var(--gast-inkt);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  text-decoration: none;   /* de klasse hangt ook aan een <a> op het foutscherm */
}

/* De uitgang op het foutscherm van gasten.js: die volgt daar rechtstreeks op
   de uitleg en zou er anders tegenaan plakken. */
.kaart .uitleg + .knop { margin-top: 14px; }

.knop--vol { background: var(--gast-accent); border-color: var(--gast-accent); color: var(--gast-accent-tekst); }
.knop--stil { background: transparent; border-color: rgba(255, 255, 255, 0.28); color: inherit; }
.knop:disabled { opacity: 0.5; cursor: default; }
.knop:focus-visible { outline: 2px solid var(--gast-accent); outline-offset: 2px; }

/* ============================= Schermen ================================
   De camera en de uploadcontrole draaien fullscreen: op een feest wil je
   geen halve pagina zien.

   Ze komen met een korte vervaging in beeld in plaats van er in één beeldje
   te staan; dat harde omschakelen las als haperen. gasten.js zet daarvoor
   eerst hidden af en pas in het volgende beeldje de klasse erbij. */

/* HET SLOT ONDER EEN OPEN SCHERM. Dit stond als style.overflow op de body in
   gasten.js, en dat is op een telefoon niet genoeg: de body is er niet de
   scroller, dus de pagina eronder veerde nog gewoon na onder je vinger. En
   elke veeg is ook het gebaar waarmee Safari zijn balken weer uitklapt —
   precies wat we niet willen terwijl er een camera openstaat.

   Het slot hangt daarom aan <html>, als klasse, zodat de regels hier bij
   elkaar staan in plaats van half in JS. gasten.js zet en haalt hem in
   openScherm() en sluitScherm(). */
html.scherm-op, html.scherm-op body {
  overflow: hidden;
  overscroll-behavior: none;
}

.scherm {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--gast-diep);
  font-size: 14px;
  color: var(--gast-papier);
  display: flex;
  flex-direction: column;
  padding: max(10px, env(safe-area-inset-top)) 12px max(12px, env(safe-area-inset-bottom));
  opacity: 0;
  transform: scale(0.985);
  transition: opacity 0.18s ease, transform 0.18s ease;
}

.scherm--open { opacity: 1; transform: none; }

/* Het camerascherm krijgt bij het openen zelf de focus (tabindex="-1"), zodat
   een bluetooth-sluiterknopje afdrukt in plaats van de camera te sluiten. Dat
   is programmatische focus op een vlak dat het hele scherm vult; een rand
   eromheen zou eruitzien als een fout. De knoppen erin houden hun rand. */
.scherm:focus { outline: none; }

.scherm__balk { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 2px 10px; }
.scherm__titel { font-size: 14px; letter-spacing: 0.12em; text-transform: uppercase; opacity: 0.8; }
.balkknoppen { display: flex; gap: 8px; }

.rondknop {
  width: 48px; height: 48px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.06);
  color: var(--gast-papier);
  display: grid; place-items: center;
  cursor: pointer;
}

.rondknop svg { width: 20px; height: 20px; }
.rondknop--leeg { border-color: transparent; background: none; cursor: default; }
.rondknop:focus-visible { outline: 2px solid var(--gast-accent); outline-offset: 2px; }

/* De flits staat aan: het knopje licht mee op, zodat je zonder te kijken
   weet dat de volgende foto licht krijgt. */
.rondknop--aan { background: var(--gast-papier); border-color: var(--gast-papier); color: var(--gast-groen); }

.opnametijd {
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 14px;
  letter-spacing: 0.06em;
  padding: 5px 12px 5px 24px;
  border-radius: 999px;
  /* 0,96 in plaats van 0,92 houdt de rode pil egaal in plaats van licht
     doorschijnend boven een fel beeld; de schaduw geeft hem een rand.
     Alleen hier: .audio-teller hierboven ziet er hetzelfde uit maar staat op
     de crème pagina, waar niets doorschijnt. */
  background: rgba(168, 65, 47, 0.96);
  box-shadow: 0 2px 10px rgba(12, 16, 10, 0.45);
  color: #fff;
  position: relative;
}

.opnametijd::before {
  content: "";
  position: absolute;
  left: 10px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-radius: 50%;
  background: #fff;
  animation: opname-knipper 1s steps(1) infinite;
}

@keyframes opname-knipper { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0.25; } }

.zoeker {
  flex: 1;
  min-height: 0;
  position: relative;
  display: grid;
  place-items: center;
  background: #000;
  border-radius: 14px;
  overflow: hidden;
}

/* ===================== Camerascherm: zoeker vult alles ==================
   Het beeld is het onderwerp, dus dat krijgt het volledige scherm. De balk
   bovenaan en de bediening onderaan liggen erover, en ze dragen hun EIGEN
   achtergrond — er ligt GEEN verloop meer over het beeld.

   WAAROM DAT WEG MOEST, met de meting erbij (390x844): het verloop bovenaan
   was 78px, dat onderaan 230px, samen 308 van de 844 = 36,5% van het kader.
   En daarvan was 126,5px EFFEN 72% donker, want dat onderste verloop had een
   stop op 55%. Op het beginscherm, met de veilige zones erbij, loopt dat op
   tot 45%. Een gast die zijn foto beoordeelde keek dus over ruim een derde
   van het beeld naar een gewassen kleur. De pillen hieronder dekken 6,6%.

   DE REGEL DIE HIERBIJ HOORT: geen backdrop-filter op iets dat over de
   zoeker ligt. Die dwingt de browser het bewegende beeld eronder bij ELK
   beeldje opnieuw te vervagen; de kop van js/camera.js verbiedt het al.
   Dekking komt van alfa, niet van vervaging. (Het terugvalveld verderop mag
   het wél: toonTerugval() zet de zoeker eerst stil.)

   EN DE TWEEDE REGEL: het verloop weghalen en de knoppen hun eigen mat geven
   zijn twee helften van ÉÉN wijziging. Doe je alleen het eerste, dan is een
   witte sluitknop op een witte muur 1,0:1 en is de camera onbruikbaar. */

.scherm--camera { padding: 0; }

.scherm--camera .zoeker {
  position: absolute;
  inset: 0;
  border-radius: 0;
  background: #000;
  z-index: 0;
}

/* In de zoeker valt niets te scrollen, dus mag een veeg daar de pagina niet
   meer raken. Bewust op de zoeker en niet op het hele camerascherm: de
   browser snijdt touch-action door over de hele keten, en het terugvalveld
   erboven moet wél bereikbaar blijven. */
.scherm--camera .zoeker { touch-action: none; }

/* Het beeld komt pas in zicht als er echt een beeldje in staat. Zonder dit
   zag je eerst een zwart vlak en dan een sprong — precies het hikje bij het
   openen van de camera. camera.js zet de klasse zodra de stream loopt. */
.zoeker__beeld {
  position: absolute;
  inset: 0;
  line-height: 0;
  opacity: 0;
  transition: opacity 0.22s ease;
}

.zoeker--klaar .zoeker__beeld { opacity: 1; }

.zoeker__beeld video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;           /* vult het scherm; de foto krijgt dezelfde uitsnede */
  display: block;
}

/* Zwevende bediening ------------------------------------------------------ */

.scherm__balk--zwevend {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  /* Boven, rechts, onder, links. In staande stand zijn links en rechts nul;
     in LIGGENDE stand schuiven de inkeping en de home-indicator naar de
     zijkant, en dan kwam de sluitknop onder de inkeping te liggen. */
  padding: max(10px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) 20px max(12px, env(safe-area-inset-left));
}

.camera-onder {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  /* HIER WOONT ALLES WAT EEN GAST INDRUKT: de lenzen 0,5x/1x/2x, het
     schuifje Foto/Filmpje, de sluiterknop van 74px en de bevestigingskaart
     die camera.js hier vooraan inschuift. Het BEELD loopt bewust door tot
     de echte onderrand — dat is wat schermvullend betekent — maar deze rij
     moet boven de werkbalk van de browser blijven staan.

     Vandaar --gast-balkstrook erbij. Nul op een computer en in de app op
     het beginscherm, ~50px in een tabblad van Safari. En links en rechts de
     inkeping ontwijken, voor de liggende stand. */
  padding: 18px 12px max(12px, env(safe-area-inset-bottom));
  padding-bottom: calc(max(12px, env(safe-area-inset-bottom)) + var(--gast-balkstrook));
  padding-left: max(12px, env(safe-area-inset-left));
  padding-right: max(12px, env(safe-area-inset-right));
}

/* ============== De balken zijn geen knoppen ==========================
   Deze twee dozen liggen met z-index 2 over de zoeker en zijn breed en hoog:
   samen eten ze op een iPhone bijna een derde van het beeld. Nu er tikken en
   vegen op de zoeker gebeuren, zou een tik daar niets doen terwijl de gast er
   gewoon beeld ziet — en dan begrijpt hij niet waarom scherpstellen soms wel
   en soms niet aankomt.

   pointer-events uit op de dozen en op hun lege omhulsels, en weer aan op de
   echte knoppen: de lege ruimte laat de tik door naar de zoeker, de knoppen
   vangen hem nog steeds zelf. .zoomrij, .belichtrij, .standen en
   .scherm__voet staan in de eerste lijst omdat het volle-breedte dozen zijn
   met hun inhoud in het midden — hun lege helften blokkeerden net zo goed.

   .pov-bevestiging en .pov-melding staan er BEWUST niet bij. Dat zijn geen
   knoppen maar volle-breedte meldingen over de zoeker — precies het soort doos
   waarvoor deze regelset bestaat. De knop "Toch niet" erin wordt al gedekt
   door .camera-onder button, en pointer-events: auto op een kind werkt gewoon
   onder een ouder op none. Stonden ze er wel bij, dan was er na elke foto een
   paar seconden een dode strook van 361x61 midden over het beeld — juist als
   een gast herkadert voor de volgende foto.

   LET OP bij het toevoegen van een nieuw kind: zonder een regel in de tweede
   lijst is het onaanraakbaar. */
.scherm--camera .scherm__balk--zwevend,
.scherm--camera .scherm__balk--zwevend .balkknoppen,
.scherm--camera .camera-onder,
.scherm--camera .zoomrij,
.scherm--camera .belichtrij,
.scherm--camera .standen,
.scherm--camera .scherm__voet {
  pointer-events: none;
}

.scherm--camera .scherm__balk--zwevend button,
.scherm--camera .opnametijd,
.scherm--camera .camera-onder button,
.scherm--camera .camera-onder input,
.scherm--camera .camera-onder label {
  pointer-events: auto;
}

/* ==================== Tikken en vegen in de zoeker ====================
   Eén vlak in de zoeker met twee bewoners: het kadertje van een tik en het
   zonnetje van een veeg. Het hangt in de ZOEKER en niet in .zoeker__beeld,
   want dat laatste staat op opacity 0 tot het beeld loopt en draagt in
   selfiestand scaleX(-1) — dan zou het kadertje aan de verkeerde kant van het
   scherm staan.

   Alles hier is pointer-events: none. Deze laag toont alleen; de gebaren
   worden op de zoeker zelf afgehandeld. */
.pov-gebaar {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
}

/* Het zonnetje van een veeg: een baantje van 118px met een bol die met de
   vinger meeloopt, en het getal ernaast. */
/* MET EEN EIGEN CAPSULE, om dezelfde reden als de knoppen: dit zweeft over
   een LEVEND beeld, en tegen een witte kerkmuur of een bruidsjurk was een
   goudkleurig zonnetje op een crème spoor 1,68:1 — je zag het niet. Dit is
   het enige wat een gast tijdens de veeg terugkoppelt, dus het moet leesbaar
   zijn op elk beeld.

   Nagerekend op 0,82: het goud komt op 5,42:1 tegen de capsule en het spoor
   op 5,58:1; de capsule zelf staat op 9,10:1 tegen wit. Op 0,62 was het goud
   nog 2,75:1 — onder de 3:1 die een grafisch bedieningselement nodig heeft. */
.pov-zon {
  position: absolute;
  width: 34px;
  height: 118px;
  margin: -59px 0 0 -17px;
  border-radius: 999px;
  background: rgba(28, 34, 26, 0.82);
  box-shadow: 0 2px 12px rgba(12, 16, 10, 0.45);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.pov-zon.aan { opacity: 1; }
.pov-zon--vast { transition: none; }

/* Het spoor waarlangs de bol loopt. */
.pov-zon::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 12px;
  bottom: 12px;
  width: 2px;
  margin-left: -1px;
  border-radius: 2px;
  background: rgba(247, 246, 242, 0.75);
}

.pov-zon__bol {
  position: absolute;
  left: 50%;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  color: #f2c14e;
  display: grid;
  place-items: center;
  filter: drop-shadow(0 1px 3px rgba(12, 16, 10, 0.7));
}

.pov-zon__bol svg { width: 24px; height: 24px; }

/* Het cijfer staat BUITEN de capsule, dus het draagt zijn eigen chipje. */
.pov-zon__cijfer {
  position: absolute;
  left: 50%;
  top: -26px;
  transform: translateX(-50%);
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(28, 34, 26, 0.78);
  box-shadow: 0 2px 10px rgba(12, 16, 10, 0.45);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--gast-papier);
  white-space: nowrap;
}

/* ------------------------- Het schuifje ------------------------------
   De weg naar de belichting voor wie niet veegt: met een toetsenbord, met
   VoiceOver, of gewoon omdat een schuifje duidelijker is. 44px hoog — de
   ondergrens voor een vinger — en het staat IN .camera-onder en niet over
   het beeld. */
/* MET EEN EIGEN MAT, net als .standen. Zonder was dit het enige nieuwe
   bedieningselement dat kaal over het levende beeld hing: tegen een witte
   kerkmuur of een bruidsjurk gemeten kwam het spoor op 1,04:1 en het cijfer
   op 1,08:1 — letterlijk onzichtbaar, terwijl de tabel in
   docs/gastenpagina.md 4,5:1 voor tekst eist. Op deze vulling is het cijfer
   7,9:1. */
.belichtrij {
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(300px, 100%);
  margin: 0 auto 8px;
  padding: 4px 14px;
  border-radius: 999px;
  background: rgba(28, 34, 26, 0.78);
  box-shadow: 0 2px 12px rgba(12, 16, 10, 0.45);
}

.belichtrij__zon { flex: 0 0 auto; color: #f2c14e; display: grid; place-items: center; }
.belichtrij__zon svg { width: 20px; height: 20px; filter: drop-shadow(0 1px 3px rgba(12, 16, 10, 0.7)); }

.belichtschuif {
  flex: 1;
  min-width: 0;
  height: 44px;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
}

.belichtschuif::-webkit-slider-runnable-track { height: 3px; border-radius: 3px; background: rgba(247, 246, 242, 0.75); }
.belichtschuif::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 26px; height: 26px; margin-top: -11.5px;
  border-radius: 50%; background: var(--gast-papier); border: 2px solid #f2c14e;
  box-shadow: 0 2px 8px rgba(12, 16, 10, 0.5);
}
.belichtschuif::-moz-range-track { height: 3px; border-radius: 3px; background: rgba(247, 246, 242, 0.75); }
.belichtschuif::-moz-range-thumb { width: 26px; height: 26px; border-radius: 50%; background: var(--gast-papier); border: 2px solid #f2c14e; }
.belichtschuif:focus-visible { outline: 3px solid var(--gast-lila); outline-offset: 2px; }

/* De weg terug. Klein maar met een echt tikdoel van 44px hoog, want hij staat
   naast een schuifje dat een gast met een duim bedient. */
.belichtrij__nul {
  flex: 0 0 auto;
  min-width: 30px;
  height: 44px;
  padding: 0 6px;
  border: 0;
  background: none;
  color: rgba(247, 246, 242, 0.86);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}

.belichtrij__nul:focus-visible { outline: 3px solid var(--gast-lila); outline-offset: 2px; border-radius: 8px; }

.belichtrij__waarde {
  flex: 0 0 42px;
  text-align: right;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  color: var(--gast-papier);
  text-shadow: 0 1px 3px rgba(12, 16, 10, 0.8);
}

/* IN LIGGENDE STAND PAST DE RIJ ER NIET BIJ. .camera-onder is aan bottom: 0
   verankerd en groeit dus omhoog; de open belichtrij maakt hem 51px hoger.
   Nagemeten op 844x320 (een iPhone in liggende stand): met de rij open
   overlapt de bediening de bovenbalk met 39px, en zodra de bevestigingskaart
   erbij komt staat de knop "Toch niet" met zijn bovenrand van het scherm af.
   Dat is de enige weg terug na een foto die een gast niet wou versturen.

   Onder deze grens verdwijnt de rij dus, en camera.js verbergt de knop mee —
   een knop die een rij opent die er niet is, is erger dan geen knop. De VEEG
   over de zoeker blijft daar gewoon werken, dus de belichting zelf gaat niet
   verloren. */
@media (max-height: 460px) {
  .belichtrij { display: none !important; }
}

/* ============ De bediening draagt haar eigen achtergrond ==============
   Wat wegviel met de verlopen, komt hier terug: per knop een matte pil. De
   dekking is uitgerekend op het SLECHTSTE geval — een knop pal op een witte
   muur. Een pictogram in --gast-papier op rgba(28,34,26,0.72) over wit geeft
   5,95:1; op een gewone zaalmuur 10,8:1 en in een donkere zaal 17,9:1. Met
   het oude vlak van 6% wit was dat op een witte muur 1,00:1 — letterlijk
   niets, en zelfs mét het oude verloop haalde de sluitknop maar ~1,9:1 op de
   plek waar hij echt staat.

   De schaduw is geen sier: die geeft de pil een rand op een fel beeld, waar
   een lichte rand in het niets oplost.

   Op .scherm--camera gehangen en niet op .rondknop zelf, want dezelfde
   klasse hangt ook in de uploadcontrole, en die is crème met zwarte inkt. */
.scherm--camera .rondknop {
  border-color: rgba(255, 255, 255, 0.42);
  background: rgba(28, 34, 26, 0.72);
  box-shadow: 0 2px 10px rgba(12, 16, 10, 0.45);
}

/* De regel hierboven weegt zwaarder dan .rondknop--aan en zou hem anders
   overrulen — vandaar deze. Een WITTE knop op een WITTE muur is als vorm
   verdwenen, dus de rand wordt donker in plaats van papier: 0,55 geeft
   3,93:1 tegen wit, ruim boven de 3:1 die een bedieningselement nodig heeft.
   Het pictogram zelf (groen op papier, 5,50:1) hangt niet van de achtergrond
   af. */
.scherm--camera .rondknop--aan {
  background: var(--gast-papier);
  border-color: rgba(28, 34, 26, 0.55);
  color: var(--gast-groen);
}

/* En de lege plaatshouder blijft leeg. Hij staat vandaag alleen in de
   uploadcontrole, maar de regel hierboven zou hem een pil geven zodra iemand
   er een in de camerabalk zet. */
.scherm--camera .rondknop--leeg {
  background: none;
  border-color: transparent;
  box-shadow: none;
}

/* Lenskeuze: 0,5× / 1× / 2× zoals in de camera-app van de telefoon. */
.zoomrij {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin-bottom: 10px;
}

.zoomknop {
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  min-width: 42px;
  height: 42px;
  padding: 0 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.34);
  background: rgba(28, 34, 26, 0.72);
  color: var(--gast-papier);
  cursor: pointer;
  /* GEEN backdrop-filter. Deze stond er nog als enige over, terwijl de kop
     van js/camera.js hem al verbiedt: hij dwingt de browser het bewegende
     zoekerbeeld eronder bij elk beeldje opnieuw te vervagen. Wat hij deed —
     leesbaar blijven op een fel beeld — doet de dekking hierboven beter en
     gratis. Op 0,5 zonder verloop was het label 2,97:1, onder de ondergrens;
     op 0,72 is het 5,94:1. */
  box-shadow: 0 2px 10px rgba(12, 16, 10, 0.45);
}

.zoomknop[aria-checked="true"] {
  background: var(--gast-papier);
  color: var(--gast-groen);
  /* Donkere haarrand in plaats van papier: zonder verloop is een witte pil
     op een witte muur geen vorm meer. 0,55 geeft 3,93:1 tegen wit. */
  border-color: rgba(28, 34, 26, 0.55);
}

.zoomknop:focus-visible { outline: 3px solid var(--gast-lila); outline-offset: 2px; }

/* ---------------------- Foto of filmpje -------------------------------
   Hetzelfde schuifje als in de camera-app van de telefoon, zodat niemand
   hoeft uit te zoeken waar het filmen zit. */

.standen {
  display: flex;
  gap: 4px;
  justify-content: center;
  margin: 4px auto 6px;
  padding: 4px;
  border-radius: 999px;
  /* 0,78 en niet 0,55: dit schuifje lag tot nu toe halverwege het onderste
     verloop mee te liften. Ter hoogte van de pil had dat verloop nog 0,486
     dekking, samen ~0,77. Precies dat cijfer zit nu in de pil zelf, zodat er
     niets verandert aan hoe het eruitziet — alleen aan waar de donkerte
     vandaan komt. Op 0,55 zou het inactieve label op 2,56:1 blijven steken. */
  background: rgba(28, 34, 26, 0.78);
  box-shadow: 0 2px 12px rgba(12, 16, 10, 0.45);
  width: fit-content;
}

.standknop {
  font: inherit;
  font-size: 12.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  min-height: 48px;
  padding: 0 18px;
  border-radius: 999px;
  border: 0;
  background: transparent;
  /* 0,86 op de pil van 0,78 geeft 5,93:1. Met 0,72 was het 5,42:1 en dat mag
     ook, maar FILMPJE is de knop die een gast moet kunnen lezen terwijl er
     iemand voor zijn lens danst. */
  color: rgba(247, 246, 242, 0.86);
  cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease;
}

.standknop[aria-checked="true"] { background: var(--gast-papier); color: var(--gast-groen); font-weight: 600; }
.standknop:focus-visible { outline: 3px solid var(--gast-lila); outline-offset: 2px; }

/* ------------------------------ Sluiter -------------------------------- */

.scherm__voet { padding: 8px 0 4px; display: grid; place-items: center; gap: 10px; }
.scherm__knoppen { display: flex; gap: 10px; justify-content: center; }
/* flex-basis auto, niet 0: met twee gelijke helften viel "Beelden versturen"
   op een telefoon over twee regels. Nu krijgt de langste knop de ruimte die
   haar tekst vraagt en vullen ze samen de rij. */
.scherm__knoppen .knop { flex: 1 1 auto; max-width: 220px; }

.sluiter {
  width: 74px; height: 74px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.92);
  /* De sluiter was drie keer wit: een witte ring, een witte schijf, en een
     DOORZICHTIGE spleet van 5px ertussen. Op een witte muur is dat zonder
     verloop 1,00:1 — de grootste knop van het scherm verdwijnt gewoon. De
     spleet wordt daarom donker: 0,62 geeft 4,59:1 tussen de schijf en de
     spleet en 4,49:1 tussen de ring en de spleet. In een donkere zaal valt
     die spleet samen met het beeld en verandert er niets.

     In de stand Filmpje krimpt de schijf naar 30px en komt er meer van die
     donkere spleet in beeld. Dat is gewenst: een rood vierkant op een
     donkere ring is dezelfde taal als elke camera-app. */
  background: rgba(20, 26, 18, 0.62);
  box-shadow: 0 0 0 1.5px rgba(20, 26, 18, 0.6), 0 8px 22px rgba(12, 16, 10, 0.45);
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
}

.sluiter span {
  width: 58px; height: 58px;
  border-radius: 50%;
  background: var(--gast-papier);
  display: block;
  transition: transform 0.16s ease, background 0.16s ease, border-radius 0.16s ease, width 0.16s ease, height 0.16s ease;
}

.sluiter:active span { transform: scale(0.86); }
.sluiter:focus-visible { outline: 3px solid var(--gast-accent); outline-offset: 3px; }

/* In de stand Filmpje wordt de stip rood, en tijdens de opname een vierkant
   — dezelfde taal als elke camera-app. */
.sluiter--video span { background: var(--gast-fout); }
.sluiter--bezig span { width: 30px; height: 30px; border-radius: 8px; background: var(--gast-fout); }

.terugval {
  position: absolute;
  inset: auto 12px 22%;
  z-index: 3;
  text-align: center;
  padding: 18px;
  display: grid;
  gap: 12px;
  place-items: center;
  background: rgba(28, 34, 26, 0.82);
  border-radius: var(--gast-radius);
  backdrop-filter: blur(6px);
}

/* De melding staat sinds kort IN dit veld (ze lag eerst los over de zoeker).
   De pilvorm van .pov-melding hoort bij dat losse plekje: hier is het veld
   zelf al de omkadering, dus een kader in een kader hoeft niet. */
.terugval .pov-melding {
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  /* De schaduw die .pov-melding van camera.js meekrijgt hoort bij de losse
     pil in de onderrij, niet hier: in dit veld zou hij als een rechthoekige
     slagschaduw rond een kale alinea blijven staan. */
  box-shadow: none;
}

/* --------------------------- Uploadcontrole ---------------------------- */

/* DE UPLOADCONTROLE KRIJGT DE BAK DIE DE GAST ECHT ZIET. Hier zit onderin
   een scrollende lijst met "Beelden versturen" eronder, en die stond op een
   iPhone permanent achter de werkbalk van Safari: je kon eindeloos verder
   scrollen en de knop bleef half weg. inset:0 geeft namelijk de grote bak.

   Twee regels, en de volgorde is de truc: een browser die dvh niet kent
   gooit de tweede weg en houdt svh; een browser die het wel kent neemt de
   laatste. Andersom zetten zou de goede waarde overschrijven. Met height
   erbij telt bottom uit inset:0 niet meer mee, dus de bak stopt netjes boven
   de balk. Het CAMERAscherm doet dit bewust NIET: daar mag het beeld juist
   tot achter de balken doorlopen. */
.scherm--vel { height: 100svh; }
.scherm--vel { height: 100dvh; }

.scherm--vel { background: var(--gast-papier); color: var(--gast-inkt); }
.scherm--vel .scherm__balk { border-bottom: 1px solid var(--gast-lijn); }
.scherm--vel .rondknop { border-color: var(--gast-lijn); background: #fff; color: var(--gast-inkt); }
.scherm--vel .knop--stil { border-color: var(--gast-lijn); color: var(--gast-inkt); }
.scherm--vel input[type="text"] { background: #fff; }

/* overscroll-behavior: zonder dit springt een veeg die het einde van de
   fotolijst raakt door naar de pagina eronder. Dat doorschieten is een van
   de dingen waaraan je merkt dat je in een webpagina zit en niet in een app. */
.vel-inhoud { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 14px 4px 10px; display: grid; gap: 14px; align-content: start; }

.upload-rooster { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; }
.upload-item { position: relative; margin: 0; }
.upload-item img, .upload-item video { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 12px; display: block; background: var(--gast-papier-warm); }
.upload-item__type { position: absolute; top: 6px; left: 6px; background: rgba(58, 68, 54, 0.78); color: #fff; font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; padding: 3px 7px; border-radius: 999px; }

/* Het kruisje was 24 px: het kleinste tikdoel van de app, op een miniatuur
   waar een misser meteen de verkeerde foto weghaalt. */
.upload-weg {
  position: absolute; top: 6px; right: 6px;
  width: 32px; height: 32px; border-radius: 50%;
  border: 0; background: rgba(58, 68, 54, 0.82); color: #fff;
  cursor: pointer; font-size: 18px; line-height: 1;
}

.upload-weg:hover { background: var(--gast-fout); }

/* ------------------------------- Toosten ------------------------------- */

.toosten { position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 80; display: grid; gap: 8px; width: min(420px, calc(100vw - 28px)); }

/* Staat er een scherm open, dan ligt een toost in dezelfde dode strook als
   de sluiterknop. Alleen dán tillen we hem op: op de gewone pagina mag een
   gast wél scrollen, en dan zijn die balken vaak al weg. */
html.scherm-op .toosten { bottom: calc(18px + var(--gast-balkstrook)); }

.toost {
  background: var(--gast-groen);
  color: var(--gast-papier);
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 14px;
  box-shadow: 0 12px 30px rgba(28, 22, 19, 0.3);
  animation: toost-in 0.22s ease;
}

.toost--fout { background: var(--gast-fout); }

@keyframes toost-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

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

/* ------------------------------ Breder --------------------------------- */

@media (min-width: 700px) {
  .acties { grid-template-columns: repeat(2, 1fr); }
  .actie { flex-direction: column; align-items: flex-start; gap: 12px; }
  /* :not(.scherm--camera) en dat is een reparatie: deze verkorte regel staat
     300 regels ná .scherm--camera { padding: 0 }, weegt even zwaar en won
     dus. Vanaf 700px kreeg het camerascherm daardoor alsnog 22px padding,
     en omdat de zoeker absoluut ligt, krimpt hij dan mee — met een
     hertekening van het WebGL-doek als gevolg. Op een iPad zichtbaar als
     een flits in de zoeker. */
  .scherm:not(.scherm--camera) { padding: 18px 22px; }
  .zoeker { border-radius: 18px; }
}
