/* DeHardloopFotograaf — publieke voorpagina
 *
 * Vormgeving volgt het logo en de bestaande Pixieset-gallery: warm gebroken wit
 * met bijna-zwart, Raleway voor koppen en Lato voor tekst. Het logo heeft
 * precies één kleur — amber #fdba41 onder een zwart woordmerk — en die amber is
 * hier het accent. De foto's leveren verder alle kleur.
 */

:root {
  color-scheme: light;

  /* Overgenomen van gallery.deemedia.nl: warm gebroken wit met bijna-zwart. */
  --bg: #f6f6f3;
  --bg-raised: #ffffff;
  --bg-raised-2: #efefeb;
  --border: #e2e2dc;
  --border-strong: #cdcdc5;

  --text: #1e1e1e;
  --text-muted: #575757;
  --text-faint: #757574;

  /* Het amber uit logo.png, exact overgenomen. Net als in het logo staat er
   * bijna-zwarte tekst op: dat haalt 9,8:1. Let op — amber zelf haalt maar
   * 1,6:1 op deze achtergrond, dus alleen als vlak gebruiken, nooit als lijn
   * of tekst. Daarvoor is --accent-line, dezelfde tint maar donkerder. */
  --accent: #fdba41;
  --accent-ink: #1e1e1e;
  --accent-hover: #efa518;
  --accent-line: #9a6100;
  --accent-soft: rgba(253, 186, 65, 0.4);
  /* Het amber verdund tot een vlak waar tekst op kan: dezelfde tint als
   * --accent op wit, op 12%. Voor een blok dat eruit moet komen zonder dat het
   * een gekleurd vlak wordt — de zoekkaart. Bijna-zwarte tekst haalt hier
   * 15,6:1 en --text-muted 6,8:1; --text-faint zakt net onder de 4,5:1, dus
   * dat grijs hoort hier niet op. */
  --accent-tint: #fff7e8;

  /* Een hartje hoort rood te zijn: dat leest iedereen meteen als "bewaren".
   * Vast, niet uit het merkpalet, want het ligt op foto's van alle kleuren. */
  --hart: #e23b4e;
  --hart-donker: #c22b3d;

  --ok: #2f7d4f;
  /* Oranje, niet amber: anders is een waarschuwing niet te onderscheiden van
   * het merkaccent. */
  --warn: #9a4c07;
  --err: #b3261e;

  --radius: 2px;
  --radius-sm: 2px;
  --shadow: 0 14px 40px -20px rgba(30, 30, 30, 0.35);

  --max: 1200px;
  --font-kop: 'Raleway', ui-sans-serif, system-ui, 'Segoe UI', sans-serif;
  --font-tekst: 'Lato', ui-sans-serif, system-ui, 'Segoe UI', sans-serif;
}

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

html {
  -webkit-text-size-adjust: 100%;
  /* Ankerlinks (bv. stap 1 -> evenementen) glijden i.p.v. springen. */
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* De sticky header mag de aangesprongen sectie niet afdekken. */
[id] {
  scroll-margin-top: 96px;
}

body {
  overflow-x: clip;
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-tekst);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
  /* Niet naar het bureaublad te slepen, en op de telefoon geen "bewaar
   * afbeelding" bij lang vasthouden. Het menu bij de rechtermuisknop gaat er in
   * de layout bij (zie lib/html.js). */
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
  user-select: none;
}

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

/* Alleen waar echt aangewezen kan worden.
 *
 * Een telefoon houdt :hover na een tik vast tot je ergens anders tikt. Stond
 * deze regel buiten de mediaquery, dan bleef er na het aantikken van een link
 * een streep staan — ook onder een pijltje als ↗ of ↓, waar dat lelijk uitkomt.
 * En omdat de knoppen hun text-decoration juist binnen (hover: hover) uitzetten,
 * won de underline daar zelfs van de uitzondering. Zonder aanwijzer hoort er
 * simpelweg geen hoverstaat te bestaan. */
@media (hover: hover) {
  a:hover {
    text-decoration: underline;
  }
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-kop);
  font-weight: 700;
  line-height: 1.12;
  margin: 0;
  letter-spacing: -0.01em;
}

p {
  margin: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 700;
}

.skip-link:focus {
  left: 0;
}

:focus-visible {
  /* De donkere tint, niet het vlak-amber: een lijn van #fdba41 valt op dit
   * gebroken wit weg. */
  outline: 2px solid var(--accent-line);
  outline-offset: 3px;
}

/* ------------------------------------------------------------------- header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(246, 246, 243, 0.92);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}

/* Het logo links, de sociale kanalen rechts. De breedte en de marge zaten
 * eerst op .brand zelf: die link wás de rij. Nu er iets naast moet staan is dat
 * een rij eromheen geworden, anders zou het logo zich over de hele koptekst
 * uitrekken en de pictogrammen ertegenaan duwen. */
.site-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: var(--max);
  margin: 0 auto;
  padding: 0.85rem 1.5rem;
}

/* min-width: 0 — anders weigert deze cel te krimpen (een flexcel is standaard
 * nooit smaller dan zijn inhoud) en duwt het logo de pictogrammen ernaast van
 * de koptekst af zodra het krap wordt. */
.brand {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  min-width: 0;
}

.brand:hover {
  text-decoration: none;
}

.site-social {
  display: flex;
  align-items: center;
  gap: 0.15rem;
}

/* Alleen een pictogram, dus het raakvlak moet uit de opvulling komen: 40 px in
 * het vierkant, wat met de tussenruimte erbij op een vingertop uitkomt. Groter
 * zou de koptekst uitrekken, want die is precies zo hoog als het logo plus de
 * opvulling eromheen.
 *
 * De rand blijft weg tot de aanwijzer erop staat: twee omlijnde knoppen naast
 * een logo maken van de koptekst een werkbalk, en dit is een zijpaadje. */
.social-link {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: var(--text-faint);
  transition:
    color 0.16s ease,
    background 0.16s ease;
}

.social-link:hover {
  background: var(--bg-raised-2);
  color: var(--text);
}

.social-link svg {
  display: block;
  width: 20px;
  height: 20px;
}

/* logo-breed.png: het beeldmerk met het woordmerk ernaast, samengesteld uit
 * logo-nieuw.png (waar het woordmerk eronder staat). In een koptekst van één
 * regel hoog past de liggende versie, en dan is er ook geen losse tekst meer
 * naast nodig — die stond er alleen omdat het woordmerk in het beeld te klein
 * uitviel. De naam zit nu in de alt-tekst.
 *
 * Op breedte gemaat en niet op hoogte, net als .hero-logo img en .footer-mark.
 * Dat is hier het verschil tussen wel en niet in verhouding blijven: img heeft
 * hierboven max-width: 100% mee, en die knijpt de breedte af zodra de koptekst
 * te krap wordt. Stond de hoogte dan vast op 40px, dan bleef die 40px gewoon
 * staan en werd het logo platgedrukt. Nu volgt de hoogte de breedte, dus wat er
 * afgaat gaat er aan twee kanten af: het logo wordt kleiner, niet smaller.
 *
 * 210px is 40px hoog bij de verhouding 842:160 van het bestand. */
.brand-mark {
  width: 210px;
  height: auto;
  min-width: 0;
}

@media (max-width: 560px) {
  .site-header-inner {
    padding-inline: 1rem;
  }

  /* 179px is 34px hoog, zelfde verhouding. */
  .brand-mark {
    width: 179px;
  }

  .social-link {
    width: 36px;
    height: 36px;
  }

  .social-link svg {
    width: 18px;
    height: 18px;
  }
}

/* --------------------------------------------------------------------- hero */

.hero {
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}

.hero-inner {
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(3rem, 8vw, 5.5rem) 1.5rem clamp(2.5rem, 6vw, 4rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.hero-logo {
  margin: 0;
}

.hero-logo img {
  width: clamp(168px, 22vw, 232px);
  height: auto;
}

.hero-tagline {
  margin-top: 1.9rem;
  font-family: var(--font-kop);
  font-weight: 600;
  font-size: clamp(1.15rem, 2.8vw, 1.6rem);
  letter-spacing: -0.01em;
  max-width: min(38ch, 100%);
  text-wrap: balance;
}

.hero-sub {
  margin-top: 0.75rem;
  color: var(--text-muted);
  font-weight: 300;
  max-width: min(46ch, 100%);
  text-wrap: pretty;
}

.hero-steps {
  list-style: none;
  margin: 2.6rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.7rem 2rem;
  font-size: 0.9rem;
  color: var(--text-muted);
  max-width: 100%;
}

@media (max-width: 560px) {
  .hero-steps {
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    gap: 0.65rem;
  }
}

.hero-steps li,
.hero-step-link {
  display: flex;
  align-items: center;
  /* 0.85rem i.p.v. 0.6rem: het spatie-tekstknoopje tussen bolletje en label is
   * vervangen door .hero-step-label, dus die breedte komt nu uit de gap. */
  gap: 0.85rem;
}

/* Amber bolletje met bijna-zwart cijfer: dezelfde verhouding als het logo. */
.hero-step-num {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  border: 1px solid var(--accent);
  font-family: var(--font-kop);
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--accent-ink);
}

/* ------------------------------------------- stap 1: link naar evenementen */

.hero-step-link {
  color: inherit;
  transition: color 0.2s ease;
}

/* Geen echte underline: die zou ook onder het bolletje doorlopen. In plaats
 * daarvan een streep die als achtergrond van het label van links inloopt. */
.hero-step-link .hero-step-label {
  background-image: linear-gradient(var(--accent-line), var(--accent-line));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 1px;
  transition: background-size 0.28s ease;
}

.hero-step-link .hero-step-num {
  transition:
    transform 0.2s ease,
    background-color 0.2s ease,
    border-color 0.2s ease,
    box-shadow 0.2s ease;
}

.hero-step-link:hover,
.hero-step-link:focus-visible {
  color: var(--text);
  /* De globale a:hover-underline uitzetten; de streep hierboven doet het werk. */
  text-decoration: none;
}

.hero-step-link:hover .hero-step-label,
.hero-step-link:focus-visible .hero-step-label {
  background-size: 100% 1px;
}

.hero-step-link:hover .hero-step-num,
.hero-step-link:focus-visible .hero-step-num {
  transform: scale(1.1);
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  box-shadow: 0 0 0 5px var(--accent-soft);
}

@media (prefers-reduced-motion: reduce) {
  .hero-step-link,
  .hero-step-link .hero-step-label,
  .hero-step-link .hero-step-num {
    transition: none;
  }

  .hero-step-link:hover .hero-step-num,
  .hero-step-link:focus-visible .hero-step-num {
    transform: none;
  }
}

/* ------------------------------------------------------------------ secties */

main {
  flex: 1;
}

.section {
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(2.75rem, 6vw, 4.5rem) 1.5rem;
}

.section-head {
  margin-bottom: 2rem;
  padding-bottom: 1.1rem;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.section-head h2 {
  min-width: 0;
  font-size: 0.86rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}

/* Het korte streepje onder een kopje komt van gallery.deemedia.nl; hier in het
 * amber van het logo. Puur decoratief, dus het lage contrast is geen bezwaar —
 * daarom ook 2px in plaats van 1px, anders valt het te veel weg. */
.section-head h2::after,
.search-card h2::after {
  content: '';
  display: block;
  width: 34px;
  height: 2px;
  margin-top: 0.7rem;
  background: var(--accent);
}

.section-head p {
  min-width: 0;
  color: var(--text-faint);
  font-size: 0.9rem;
  font-weight: 300;
}

/* Op een smal scherm past de <p> niet meer naast de kop en valt hij eronder.
 * Daardoor staat het amberen streepje niet langer onderaan het blok maar
 * middenin, en telt de padding die als ruimte ná dat streepje bedoeld was
 * gewoon op bij de marge eronder — samen ruim 3rem, wat als dubbele ruimte
 * leest. Hier dus alleen de marge. */
@media (max-width: 560px) {
  .section-head {
    padding-bottom: 0;
    margin-bottom: 1.5rem;
  }
}

/* ------------------------------------------------------- evenementenoverzicht */

.event-grid {
  display: grid;
  gap: 1.75rem 1.5rem;
  grid-template-columns: repeat(auto-fill, minmax(286px, 1fr));
}

.event-card {
  display: flex;
  flex-direction: column;
}

.event-card:hover {
  text-decoration: none;
}

.event-card-media {
  aspect-ratio: 3 / 2;
  background: var(--bg-raised-2);
  overflow: hidden;
  border-radius: var(--radius);
}

.event-card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.event-card:hover .event-card-media img {
  transform: scale(1.045);
}

.event-card-placeholder {
  width: 100%;
  height: 100%;
  background: repeating-linear-gradient(-45deg,
      #eeeee9,
      #eeeee9 12px,
      #e6e6e0 12px,
      #e6e6e0 24px);
}

.event-card-body {
  padding: 1.05rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  flex: 1;
}

.event-card-meta {
  order: -1;
  color: var(--text-faint);
  font-size: 0.76rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.13em;
}

.event-card-body h3 {
  font-size: 1.16rem;
  font-weight: 700;
}

.event-card-cta {
  margin-top: 0.55rem;
  font-family: var(--font-kop);
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-muted);
  transition: color 0.18s ease;
}

.event-card:hover .event-card-cta {
  color: var(--accent-line);
}

/* Een evenement dat is aangekondigd maar nog niet online staat.
 *
 * Geen anker, dus ook geen hover-gedrag: er valt hier niets te klikken en dat
 * hoort te voelen zoals het is. De kaart staat wel tussen de andere, dus hij
 * moet er wel bij horen en tegelijk duidelijk anders zijn. Vandaar gedempt in
 * plaats van weggestopt: de foto iets lichter, de tekst rustiger, en een label
 * dat zegt wat er aan de hand is. */
.event-card-soon {
  cursor: default;
}

.event-card-soon .event-card-media {
  position: relative;
}

.event-card-soon .event-card-media img {
  /* Lichter en minder verzadigd: te zien wat er komt, zonder te concurreren met
   * de evenementen waar je wél in kunt. */
  opacity: 0.72;
  filter: saturate(0.75);
}

.event-card-soon .event-card-body h3,
.event-card-soon .event-card-meta {
  color: var(--text-muted);
}

/* Het label op de foto. Vaste kleuren, want het ligt op een afbeelding en mag
 * dus niet met het thema meebewegen. Niet het merk-amber: dat is van de knoppen
 * waar je op moet klikken, en hier is dat juist niet zo. */
.event-card-badge {
  position: absolute;
  top: 0.7rem;
  left: 0.7rem;
  padding: 0.28rem 0.7rem;
  border-radius: 2px;
  background: rgba(30, 30, 30, 0.82);
  backdrop-filter: blur(4px);
  color: #f4f4f4;
  font-family: var(--font-kop);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.13em;
}

/* Geen pijltje en geen oplichten bij hover: dit is een mededeling, geen knop. */
.event-card-cta-soon {
  color: var(--text-faint);
  font-weight: 400;
  letter-spacing: 0.1em;
}

.empty-state {
  border: 1px solid var(--border);
  padding: 3.5rem 1.5rem;
  text-align: center;
  background: var(--bg-raised);
  border-radius: var(--radius);
}

.empty-state h3 {
  font-size: 1.15rem;
}

.empty-state p {
  margin-top: 0.6rem;
  color: var(--text-muted);
  font-weight: 300;
}

.empty-state .button {
  margin-top: 1.5rem;
}

/* ------------------------------------------------------------ evenementpagina */

.event-hero {
  position: relative;
  border-bottom: 1px solid var(--border);
  background: var(--bg-raised);
  overflow: hidden;
  /* De hele kop vermenigvuldigt met wat erachter ligt: dat is body, en die is
   * --bg (#f6f6f3). Vermenigvuldigen met bijna-wit haalt er maar een paar
   * procent af, dus dit is een subtiele verdonkering en geen ander beeld. Wil
   * je de foto zelf dieper maken, dan moet het naar .event-hero::after — daar
   * ligt de donkere verloop over de foto en bijt multiply wel. */
  mix-blend-mode: multiply;
}

.event-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: var(--cover);
  background-size: cover;
  /* De hero is een brede, lage band en de hoogte komt van de tekst, dus cover
   * snijdt verticaal bij. Op een derde van boven in plaats van in het midden:
   * daar staan de hardlopers, en bij het midden vielen de hoofden er vaak net
   * boven weg. Horizontaal blijft het gecentreerd — daar wordt nauwelijks
   * bijgesneden. */
  background-position: center 33%;
  opacity: 0.5;
}

.event-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
      rgba(20, 20, 18, 0.62),
      rgba(20, 20, 18, 0.88));
}

.event-hero {
  /* Licht op een verduisterde foto, net als de coverpagina's van de gallery. */
  --text: #ffffff;
  --text-muted: #e8e8e4;
  --text-faint: #cfcfc9;

  /* Nodig: het omzetten van de variabele alleen is niet genoeg. Kinderen erven
   * de al berekende kleur van body; door hier color te zetten erven ze wit. */
  color: var(--text);
}

.event-hero-inner {
  position: relative;
  z-index: 1;
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(1.4rem, 4vw, 2.25rem) 1.5rem clamp(2.25rem, 5vw, 3.25rem);
}

.back-link {
  display: inline-block;
  margin-bottom: 1.5rem;
  color: var(--text-faint);
  font-family: var(--font-kop);
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

.back-link:hover {
  color: var(--text);
  text-decoration: none;
}

.event-hero-meta {
  color: var(--text-faint);
  font-size: 0.78rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-bottom: 0.7rem;
}

.event-hero h1 {
  font-size: clamp(1.9rem, 5.5vw, 3.2rem);
}

.event-hero-description {
  margin-top: 1rem;
  color: var(--text-muted);
  font-weight: 300;
  max-width: min(60ch, 100%);
}

/* In de toelichting mag een link staan, bijvoorbeeld naar de fotograaf van de
 * afstand die ik zelf liep. Amber uit het logo: op de verduisterde cover is dat
 * ruim leesbaar en het is dezelfde kleur als de knop eronder, dus de link valt
 * op zonder dat er een tweede accent bij komt. Op de gewone achtergrond zou
 * amber juist onleesbaar zijn — vandaar dat deze regel bij de hero hoort en
 * niet bij links in het algemeen.
 *
 * De streep staat er meteen bij en niet pas bij hover: op een telefoon bestaat
 * hover niet, en ook daar moet te zien zijn dat er iets aan te tikken valt. */
.event-hero-description a {
  color: var(--accent);
  font-weight: 400;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--accent-soft);
  text-underline-offset: 3px;
}

@media (hover: hover) {
  .event-hero-description a:hover {
    color: var(--accent-hover);
    text-decoration-color: currentColor;
  }
}

/* De kop mag ruimer staan, maar het zoekveld moet in beeld blijven. Dat hangt
 * niet van de schermbreedte af maar van de hoogte: op een 1366x650-laptop is er
 * onder de zoekknop nu al maar zo'n 50px over, terwijl op 1440x900 ruim 300px
 * overblijft. Vandaar dat de ruimte met de hóógte meegroeit.
 *
 * Telefoons blijven hier vanzelf buiten: de voorkeurswaarde in de clamp is 4vw
 * en die ligt op een smal scherm onder het minimum, dus een hogere bovengrens
 * doet daar niets. Alleen brede schermen worden ruimer. */
/* Vaste waarden en geen clamp meer: bij 1440 breed is 4vw al 58px en dus hoger
 * dan elke bovengrens die je zou zetten, waardoor de voorkeurswaarde bindend
 * werd en verder verhogen niets meer deed.
 *
 * De breedte-eis staat erbij zodat een lange telefoon hier niet in valt: die
 * haalt de 760px hoogte wel, maar niet de 700px breedte. */
@media (min-width: 700px) and (min-height: 760px) {
  .event-hero-inner {
    padding-top: 4.5rem;
    padding-bottom: 5.75rem;
  }

  /* De kop blijft wel meeschalen met de breedte: op een smal maar hoog venster
   * zou een vaste 3.9rem de evenementnaam over twee regels breken. */
  .event-hero h1 {
    font-size: clamp(1.9rem, 5.5vw, 3.9rem);
  }
}

@media (min-width: 700px) and (min-height: 900px) {
  .event-hero-inner {
    padding-top: 6rem;
    padding-bottom: 7.5rem;
  }

  .event-hero h1 {
    font-size: clamp(1.9rem, 5.5vw, 4.4rem);
  }
}

/* Link naar het volledige Pixieset-album. Eigen regel in plaats van .button,
 * omdat die bij hover een lichte achtergrond onder witte tekst zet — hier op de
 * verduisterde cover dus onleesbaar. Deze vult juist met het merk-amber. */
/* De twee knoppen onder de evenementnaam. Naast elkaar, en op een smal scherm
 * onder elkaar met de volle breedte. */
.event-hero-acties {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem;
  margin-top: 1.6rem;
}

/* Dezelfde vorm voor allebei; het verschil zit in de vulling hieronder. */
.hero-knop {
  display: inline-flex;
  align-items: center;
  padding: 0.7rem 1.3rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-kop);
  font-size: 0.78rem;
  font-weight: 700;
  gap: 6px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    color 0.16s ease;
}

/* Zoeken is waarvoor de bezoeker komt, dus die knop is gevuld. Wit en niet
 * amber: op de verduisterde foto eronder springt wit er het duidelijkst uit,
 * en amber blijft daarmee voorbehouden aan het aanwijzen. */
.hero-knop-primair {
  background: #ffffff;
  border-color: #ffffff;
  color: #1e1e1e;
}

.album-link {
  border-color: rgba(255, 255, 255, 0.5);
  color: #ffffff;
}

/* Alleen waar echt aangewezen kan worden: op een telefoon blijft :hover na een
 * tik hangen en zou de knop verkeerd opgelicht blijven staan. */
@media (hover: hover) {
  .album-link:hover,
  .hero-knop-primair:hover {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-ink);
    text-decoration: none;
  }
}

@media (max-width: 560px) {
  .event-hero-acties {
    align-items: stretch;
  }

  .hero-knop {
    justify-content: center;
    flex: 1 1 100%;
  }
}

/* ------------------------------------------------------------------- zoeken */

/* De zoekkaart en het album eronder horen bij elkaar: het zijn de twee manieren
 * om je foto te vinden. Vandaar minder lucht onderaan dan .section geeft — die
 * 4,5rem is bedoeld tussen blokken die los van elkaar staan, en hier viel er een
 * gat tussen de kaart en "Alle foto's van dit evenement". Bovenaan blijft de
 * ruimte wél: daar komt de banner met de naam van het evenement vandaan. */
.search-section {
  padding-top: clamp(2rem, 5vw, 3rem);
  padding-bottom: clamp(1.6rem, 4vw, 2.4rem);
}

/* De zoekkaart is de hoofdhandeling van de evenementpagina, en dat mag je zien.
 *
 * Eerder was dit een wit vlak met een dun grijs randje, net als elk ander blok
 * op de pagina — en dus keek je er zo langs, precies bij het ene ding dat de
 * bezoeker komt doen. Nu draagt hij het amber van het logo:
 *
 *   - een dikke amberen rand bovenop, de kleur als vlak en niet als lijn (amber
 *     haalt maar 1,6:1 op dit wit, dus als lijn of tekst mag hij niet — zie de
 *     opmerking bij --accent);
 *   - het hele vlak in --accent-tint, hetzelfde amber verdund tot iets waar
 *     tekst op kan. Eerst was dit een verloop dat naar wit uitdoofde, maar dat
 *     gaf een zichtbare grens midden in de kaart en de bovenkant kleurde
 *     sterker dan nodig. Eén kleur is rustiger en zegt hetzelfde;
 *   - een zachte schaduw in de amber-lijnkleur, dezelfde als onder de grote
 *     knoppen, zodat de kaart van de achtergrond afkomt.
 *
 * De rand eromheen wordt amber-zacht in plaats van grijs. Dat is een vlakkleur
 * met doorzichtigheid, dus ook daar geldt de contrasteis niet: hij zegt niets
 * wat niet ook zonder kleur duidelijk is. */
.search-card {
  background: var(--accent-tint);
  border: 1px solid var(--accent-soft);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  box-shadow: 0 14px 34px -22px rgba(154, 97, 0, 0.5);
}

/* De kaart zelf verandert niet mee als je in het veld klikt: het veld krijgt de
 * amberen rand en de ring, en dat is waar het gebeurt. Een kaart die bij elke
 * klik van kleur wisselt of opzwelt trekt de aandacht juist weg van waar je aan
 * het typen bent. */

.search-card h2 {
  font-size: 0.86rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}

/* Het streepje onder de kop mag hier langer en dikker dan elders: op deze kaart
 * is het geen versiering bij een tussenkop maar de aankondiging van de
 * hoofdhandeling. */
.search-card h2::after {
  width: 56px;
  height: 3px;
}

.search-help {
  margin-top: 0.7rem;
  color: var(--text-muted);
  font-weight: 300;
}

.search-form {
  display: flex;
  gap: 0.6rem;
  margin-top: 1.5rem;
  flex-wrap: wrap;
}

/* Het veld staat nu op een licht amberen vlak, dus wit in plaats van --bg: zo
 * blijft te zien dat je hier moet typen. Het randje blijft grijs — zou het hier
 * al amber zijn, dan verschilt het niet meer van de rand die het bij focus
 * krijgt, en juist dat verschil is het teken dat je aan het typen bent. */
.search-form input {
  flex: 1 1 200px;
  min-width: 0;
  padding: 0.95rem 1.1rem;
  font-family: var(--font-kop);
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.search-form input::placeholder {
  color: var(--text-faint);
  font-weight: 400;
  letter-spacing: 0.02em;
}

.search-form input:focus {
  border-color: var(--accent-line);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* "620 van 635 foto's doorzoekbaar". Een tint donkerder dan het grijs dat
 * elders onder een blok staat: op --accent-tint haalt --text-faint geen 4,5:1
 * meer, en dit is kleine tekst in kapitalen. --text-muted haalt 6,8:1. */
.search-meta {
  margin-top: 1rem;
  font-size: 0.78rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

/* ------------------------------------------------------------------- buttons */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 0.85rem 1.5rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font-family: var(--font-kop);
  font-size: 0.82rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  cursor: pointer;
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    color 0.16s ease;
}

.button:hover:not(:disabled) {
  border-color: var(--text-faint);
  background: var(--bg-raised-2);
  text-decoration: none;
}

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

.button-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  padding-inline: 1.9rem;
}

.button-primary:hover:not(:disabled) {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  color: var(--accent-ink);
}

/* De hoofdactie van een pagina mag groter dan de rest, met een zachte schaduw
 * in de amber-lijnkleur zodat de knop van het vlak eronder afkomt. Moet ná
 * .button-primary staan: die zet padding-inline. */
.button-lg {
  padding: 1.05rem 2.2rem;
  font-size: 0.9rem;
  box-shadow: 0 10px 24px -14px rgba(154, 97, 0, 0.75);
}

.button-lg:hover:not(:disabled) {
  box-shadow: 0 12px 26px -14px rgba(154, 97, 0, 0.85);
}

.spinner {
  display: none;
  width: 14px;
  height: 14px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

.is-loading .spinner {
  display: block;
}

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

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

/* -------------------------------------------------------------- zoekresultaat */

.search-results {
  margin-top: 2rem;
}

.result-head {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  flex-wrap: wrap;
  margin-bottom: 1.35rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--border);
}

.result-head h3 {
  font-size: 0.86rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
}

.result-head .result-count {
  color: var(--text-faint);
  font-size: 0.86rem;
}

.result-grid {
  display: grid;
  gap: 1.25rem 1rem;
  /* Vier naast elkaar op een volle sectie (1200px min 2x1.5rem padding = 1152px
   * inhoud, met 16px ertussen): 240 is de kleinste maat waarbij er geen vijfde
   * kolom meer bij past. Het blijft auto-fill, dus op smallere schermen zakt het
   * vanzelf naar drie, twee en uiteindelijk een. Zowel de zoekuitslag als de
   * favorietenpagina gebruiken dit raster. */
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

.result-card {
  display: block;
  position: relative;
}

/* De kaart is een omhulling geworden: de link erin, het hartje erbovenop. Een
 * knop binnen een anker is geen geldige HTML, en een hartje dat de foto opent
 * in plaats van hem te bewaren is precies de verwarring die je niet wilt. */
.result-card-link {
  display: block;
  position: relative;
}

.result-card-link:hover {
  text-decoration: none;
}

.result-card img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: contain;
  background: var(--bg-raised-2);
  border-radius: var(--radius);
  transition: opacity 0.2s ease;
}

.result-card-link:hover img {
  opacity: 0.82;
}

/* Twee knoppen onder elke foto. Bestellen maakt in de galerij een lijst met
 * alléén deze foto, zodat niemand daar hoeft terug te navigeren naar een lijst
 * met alles erin. Downloaden geeft de foto direct. */
.kaart-acties {
  display: flex;
  gap: 0.4rem;
  padding-top: 0.6rem;
}

.kaart-actie {
  flex: 1 1 0;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* De knop is een flexcontainer, dus de spatie vóór het pijltje valt weg;
   * deze gap zet hem terug. In em, zodat hij meeschaalt met het lettertype. */
  gap: 0.45em;
  padding: 0.5rem 0.4rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font-family: var(--font-kop);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text);
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    color 0.16s ease;
}

/* Bestellen is de stap die geld oplevert, dus die krijgt de accentkleur. */
.kaart-actie-koop {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

@media (hover: hover) {
  .kaart-actie:hover {
    border-color: var(--text-faint);
    background: var(--bg-raised-2);
    text-decoration: none;
  }

  .kaart-actie-koop:hover {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
    color: var(--accent-ink);
  }
}

/* "2 eerder" en "2 later" onder een treffer: de foto's ernaast erbij halen. Een
 * fotograaf schiet in reeksen, dus de deelnemer staat er vaak nog net op zonder
 * dat zijn nummer daar leesbaar was.
 *
 * Zelfde vorm als .kaart-actie maar rustiger: gestippelde rand, kleinere letter,
 * gedempte kleur. Bestellen en Download zijn de stappen die je wilt aanmoedigen;
 * dit is een hulpje ernaast en hoort er niet mee te wedijveren. */
.kaart-buren {
  display: flex;
  gap: 0.4rem;
  padding-top: 0.4rem;
}

.kaart-buur {
  flex: 1 1 0;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  padding: 0.4rem 0.35rem;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  /* Het is een <button>, dus achtergrond en aanwijzer moeten expliciet. */
  background: transparent;
  cursor: pointer;
  font-family: var(--font-kop);
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    color 0.16s ease;
}

/* display: inline-flex hierboven verslaat het display: none dat de browser aan
 * [hidden] hangt, dus expliciet. Anders blijft de knop staan aan het einde van
 * een galerij, waar er niets meer te halen is. */
.kaart-buur[hidden],
.kaart-buren[hidden] {
  display: none;
}

.kaart-buur:disabled {
  opacity: 0.5;
  cursor: default;
}

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

@media (hover: hover) {
  .kaart-buur:not(:disabled):hover {
    border-color: var(--text-faint);
    border-style: solid;
    background: var(--bg-raised-2);
    color: var(--text);
  }
}

@media (prefers-reduced-motion: reduce) {
  .kaart-buur {
    transition: none;
  }
}

/* Alleen te zien als er iets te melden is: dat de twee ernaast er al stonden, of
 * dat het ophalen mislukte. */
.kaart-buren-melding {
  margin: 0.35rem 0 0;
  color: var(--text-faint);
  font-size: 0.72rem;
  font-weight: 300;
  line-height: 1.35;
}

.kaart-buren-melding:empty {
  display: none;
}

/* Het labeltje op een foto die ernaast lag. Grijs en niet amber: op deze foto is
 * geen startnummer herkend, en het amber is van de echte treffers. Dat verschil
 * moet je in één blik zien, anders lijkt een buur een gevonden foto. */
/* Met beide klassen in de selector, want .result-tag staat verderop in dit
 * bestand: bij gelijk gewicht wint wie het laatst staat, en dan bleef het amber. */
.result-tag.result-tag-buur {
  background: rgba(30, 30, 30, 0.72);
  color: #f4f4f4;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* De downloadknop, even nadat de foto erin gevlogen is.
 *
 * Groen en niet amber: amber is op deze site het merkaccent en zegt "hier
 * klikken", terwijl dit juist zegt dat er niets meer te doen valt. Ná het
 * hover-blok hierboven, want de aanwijzer staat op dat moment nog op de knop en
 * die twee hebben evenveel gewicht — dan wint wie het laatst staat.
 *
 * Donkerder groen dan --ok: het opschrift is klein en in kapitalen, dus het
 * telt als gewone tekst en moet 4,5:1 halen. Op het lichtgroene vlak hieronder
 * komt --ok zelf niet verder dan 4,1:1; dit haalt 5,8:1.
 */
.kaart-actie.is-opgeslagen,
.kaart-actie.is-opgeslagen:hover {
  border-color: #256341;
  background: rgba(47, 125, 79, 0.1);
  color: #256341;
  animation: fav-klop 0.55s ease;
}

.result-tag {
  position: absolute;
  top: 0.55rem;
  left: 0.55rem;
  padding: 0.22rem 0.6rem;
  border-radius: 2px;
  /* Het gevonden startnummer is het belangrijkste label op de pagina, dus krijgt
   * het merk-amber met bijna-zwarte cijfers (9,8:1). Vaste kleuren: dit label
   * ligt op een foto, dus het mag niet met het thema meebewegen. */
  background: rgba(253, 186, 65, 0.94);
  backdrop-filter: blur(4px);
  color: #1e1e1e;
  font-family: var(--font-kop);
  font-size: 0.8rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

.result-empty {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2.75rem 1.5rem;
  text-align: center;
  background: var(--bg-raised);
}

.result-empty h3 {
  font-size: 1.1rem;
}

.result-empty p {
  margin-top: 0.75rem;
  color: var(--text-muted);
  font-weight: 300;
  max-width: min(54ch, 100%);
  margin-inline: auto;
}

.result-empty .button {
  margin-top: 1.5rem;
}

.result-maybe {
  margin-top: 2.5rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--border);
}

.result-maybe h4 {
  margin: 0 0 0.35rem;
  font-family: var(--font-kop);
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

.result-maybe p {
  color: var(--text-faint);
  font-size: 0.88rem;
  font-weight: 300;
  margin-bottom: 1.1rem;
}

/* De foto's waarop niets herkend is, onderaan de uitslag. Dichtgeklapt, want
 * het zijn er bij een groot evenement tientallen en ze mogen de eigen treffers
 * niet verdringen. */
.zonder-nummer {
  margin-top: 2.5rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--border);
}

/* Dit is de knop van het blok, dus hij moet er ook naar uitzien: een eigen
 * vlak met een rand, en boven en onder dezelfde ruimte. Eerder had de summary
 * helemaal geen padding en kwam de lucht erboven van de container, waardoor het
 * aanraakvlak scheef stond en nergens aan te zien was dat je erop kon klikken. */
.zonder-nummer > summary,
.album-blok > summary {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.1rem;
  /* Dezelfde vorm en dezelfde overgang als .button: dit is een knop, en de site
   * heeft er maar een soort van. */
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  font-family: var(--font-kop);
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  /* Het eigen driehoekje van de browser weg; hieronder komt er een eigen pijl. */
  list-style: none;
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    color 0.16s ease;
}

.zonder-nummer > summary::-webkit-details-marker,
.album-blok > summary::-webkit-details-marker {
  display: none;
}

/* De pijl rechts, die meedraait bij het openklappen: dat is het duidelijkste
 * teken dat er iets uit te klappen valt. */
.zonder-nummer > summary::after,
.album-blok > summary::after {
  content: '';
  margin-left: auto;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-0.15rem) rotate(45deg);
  transition: transform 0.16s ease;
}

.zonder-nummer[open] > summary::after,
.album-blok[open] > summary::after {
  transform: translateY(0.1rem) rotate(-135deg);
}

/* Alleen waar echt aangewezen kan worden: op een telefoon blijft :hover na een
 * tik hangen en zou de knop open of dicht dus verkeerd blijven oplichten. */
@media (hover: hover) {
  /* Woord voor woord wat .button:hover doet. */
  .zonder-nummer > summary:hover,
  .album-blok > summary:hover {
    border-color: var(--text-faint);
    background: var(--bg-raised-2);
  }

  /* Het telplaatje zou anders wegvallen tegen die grijze achtergrond. */
  .zonder-nummer > summary:hover .zonder-nummer-telling,
  .album-blok > summary:hover .album-telling {
    background: var(--bg-raised);
  }
}

.zonder-nummer > summary:focus-visible,
.album-blok > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .zonder-nummer > summary,
  .zonder-nummer > summary::after,
  .album-blok > summary,
  .album-blok > summary::after {
    transition: none;
  }
}

/* Het aantal als rustig plaatje ernaast, zodat meteen te zien is of het de
 * moeite is om open te klappen. */
.zonder-nummer-telling,
.album-telling {
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  background: var(--bg-raised-2);
  color: var(--text-muted);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  transition: background 0.16s ease;
}

.zonder-nummer-uitleg,
.zonder-nummer-rest,
.album-uitleg {
  color: var(--text-faint);
  font-size: 0.88rem;
  font-weight: 300;
  margin: 0.9rem 0 1.1rem;
}

/* Alle foto's van het evenement, in een eigen sectie onder het zoeken. De knop
 * van de uitklapper leent zijn opmaak van .zonder-nummer hierboven: de site
 * heeft maar een soort uitklapper. Wat hieronder staat is wat er verder bij
 * hoort. */
.album-section {
  padding-top: 0;
}

/* Zolang er niets gezocht is staat het uitslagvak er leeg tussen, en dan hoort
 * zijn marge er ook niet te zijn: anders zit er een dood gat tussen het
 * zoekvak en het album eronder. */
.search-results:empty {
  margin-top: 0;
}

.album-uitleg {
  max-width: 62ch;
}

/* Bij een groot evenement staan hier straks tweeduizend tegels in het document.
 * Het netwerk valt mee, want loading="lazy" haalt alleen op wat in beeld komt,
 * maar opmaken en tekenen doet de browser wel voor alles. content-visibility laat hem
 * alles buiten beeld overslaan, en met contain-intrinsic-size: auto onthoudt hij
 * de echte hoogte zodra een tegel een keer te zien was, zodat de scrollbalk niet
 * gaat springen. */
.album-blok .result-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 280px;
}

/* Hoeveel er staan en hoeveel er nog volgen. Bewust rustig: het verandert bij
 * elke pagina die erbij komt. */
.album-status {
  margin: 1.3rem 0 0;
  color: var(--text-faint);
  font-size: 0.85rem;
  font-weight: 300;
  text-align: center;
}

.album-status:empty {
  margin: 0;
}

.album-status.is-fout {
  color: rgb(248, 113, 113);
  font-weight: 400;
}

/* Het punt waarop de volgende pagina geladen wordt. Neemt zelf geen ruimte in;
 * de afstand tot het einde zit in de rootMargin van de IntersectionObserver. */
.album-sentinel {
  height: 1px;
}

.album-meer-rij {
  display: flex;
  justify-content: center;
  margin-top: 1.3rem;
}

/* .button zet zelf display: inline-flex, en dat verslaat het display: none dat
 * de browser aan [hidden] hangt, dus blijft de knop staan terwijl alles al
 * geladen is. Daarom expliciet, net als bij de andere blokken die zich verstoppen.
 * De rij eromheen valt mee weg, anders blijft er een lege marge onder het
 * raster hangen. */
.album-meer-rij .button[hidden] {
  display: none;
}

.album-meer-rij:has(> .button[hidden]) {
  display: none;
}

/* Alle gevonden foto's bij elkaar in een favorietenlijst in de galerij. Staat
 * boven het raster en is de belangrijkste vervolgstap na een geslaagde
 * zoekopdracht, dus als opvallende banner: amber vlak met een dikke amber lijn
 * links, tekst links en de grote knop rechts.
 *
 * Onder de vouw neemt .favorite-float het over: dezelfde knop, zwevend
 * onderaan het scherm. */
.result-favorite {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.1rem 1.75rem;
  margin: 0 0 1.9rem;
  padding: 1.35rem 1.5rem;
  border: 1px solid var(--accent-soft);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius-sm);
  background: rgba(253, 186, 65, 0.1);
  text-align: left;
}

.result-favorite-text {
  flex: 1 1 26ch;
}

/* Geen klein kapitaaltjes-kopje zoals de andere sectiekoppen: dit is een
 * uitnodiging, geen tussenkop, en mag dus gewoon leesbaar groot. */
.result-favorite h4 {
  margin: 0 0 0.2rem;
  font-family: var(--font-kop);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.result-favorite p {
  color: var(--text-muted);
  font-size: 0.9rem;
  font-weight: 300;
  margin: 0;
  max-width: min(62ch, 100%);
}

.result-favorite .button {
  flex: none;
}

@media (max-width: 560px) {
  .result-favorite {
    padding: 1.2rem 1.15rem;
  }

  .result-favorite .button {
    width: 100%;
  }
}

/* Dezelfde knop als in de banner, zwevend onderaan het scherm. De banner staat
 * boven het raster en is na een paar rijen foto's uit beeld; zonder deze knop
 * scrolt bijna niemand nog terug.
 *
 * Alleen de knop, geen tekst en geen vlak eromheen: de hele banner onderaan
 * vastzetten nam op een telefoon een derde van het scherm in beslag. Rechts
 * uitgelijnd op een breed scherm, over de volle breedte op een smal — daar is
 * onderaan de duimzone.
 *
 * position: fixed en geen sticky: de knop hoort aan het scherm vast te zitten,
 * niet aan een plek in de uitslag. Wanneer hij te zien is regelt volgZwever()
 * in app.js. */
.favorite-float {
  position: fixed;
  right: 1.5rem;
  /* Onderaan een telefoon zit de streep voor het thuisgebaar; env() houdt de
   * knop daarboven. */
  bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  z-index: 15;
  display: flex;
  /* Onzichtbaar én onaanklikbaar zolang de banner zelf in beeld is. Niet met
   * display: none, want dan valt er niets te animeren; visibility haalt hem ook
   * uit de tab-volgorde en bij de schermlezer weg. */
  visibility: hidden;
  opacity: 0;
  transform: translateY(0.5rem);
  transition:
    opacity 0.18s ease,
    transform 0.18s ease,
    visibility 0.18s;
}

.favorite-float.is-visible {
  visibility: visible;
  opacity: 1;
  transform: none;
}

/* Een zwaardere schaduw dan .button-lg: deze knop ligt over de foto's heen en
 * moet daar los van komen. */
.favorite-float .button {
  box-shadow: 0 10px 30px -12px rgba(30, 30, 30, 0.55);
}

@media (max-width: 560px) {
  .favorite-float {
    left: 1rem;
    right: 1rem;
  }

  .favorite-float .button {
    width: 100%;
  }
}

/* Delen van de zoekuitslag. Bewust géén amber en geen merkkleuren van de
 * platforms: de fotolijst-banner hierboven is de hoofdactie en die is amber, en
 * de logokleuren van WhatsApp, Instagram en Facebook halen op deze achtergrond
 * bij lange na niet de contrasteis voor tekst. Vandaar dezelfde rustige
 * knoppen als de rest van de site, met dezelfde tussenkop als "Mogelijk ook van
 * jou". */
.result-share {
  margin-top: 2.5rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--border);
}

.result-share h4 {
  margin: 0 0 0.35rem;
  font-family: var(--font-kop);
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

.result-share p {
  color: var(--text-faint);
  font-size: 0.88rem;
  font-weight: 300;
  margin: 0 0 1.1rem;
  max-width: min(62ch, 100%);
}

.share-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

/* Kleiner dan een gewone knop: het zijn er vijf naast elkaar en ze zijn
 * secundair aan de fotolijst-knop. */
.share-buttons .button {
  flex: none;
  padding: 0.7rem 1.15rem;
  font-size: 0.75rem;
}

/* De terugkoppeling na kopiëren, en de uitleg bij Instagram.
 *
 * Als gewone grijze regel viel dit weg tegen de uitleg boven de knoppen — even
 * klein, even licht, even grijs — en dan zie je niet dat je klik iets deed.
 * Daarom een eigen blokje: witte kaart met een gekleurde lijn links, een icoon
 * en een vette aanhef. Tot er iets te melden is staat het op display:none, dus
 * het neemt geen ruimte in beslag. */
.result-share .share-note {
  display: none;
  align-items: flex-start;
  gap: 0.6rem;
  margin: 1.1rem 0 0;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
  color: var(--text);
  font-size: 0.88rem;
  font-weight: 400;
}

.result-share .share-note.is-visible {
  display: flex;
}

.result-share .share-note strong {
  font-weight: 700;
}

/* Het icoon staat in een rondje van de statuskleur, met het teken erin in de
 * kaartkleur. Eén variabele (--note-kleur) bedient zowel dit rondje als de lijn
 * links, zodat een status op één plek gezet wordt. Vaste maat en lijnhoogte,
 * want een ✓ en een ! zijn niet even hoog. */
.share-note-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.05rem;
  border-radius: 50%;
  background: var(--note-kleur, var(--border-strong));
  color: var(--bg-raised);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
}

.share-note-body {
  min-width: 0;
}

/* De link zelf als er niets te kopiëren viel. Mag afbreken waar het moet,
 * anders duwt een lange URL het blokje uit de kolom. */
.share-note-url {
  display: block;
  margin-top: 0.45rem;
  font-family: ui-monospace, 'SFMono-Regular', 'Consolas', monospace;
  font-size: 0.82rem;
  color: var(--text-muted);
  overflow-wrap: anywhere;
  user-select: all;
}

/* Geslaagd: groen. Mislukt: rood. Alleen als lijn en als rondje, niet als
 * tekst — de tekst blijft --text, dat leest het rustigst. */
.result-share .share-note.soort-ok {
  --note-kleur: var(--ok);
  border-left-color: var(--ok);
}

.result-share .share-note.soort-fout {
  --note-kleur: var(--err);
  border-left-color: var(--err);
}

/* Twee keer dezelfde knop moet ook te zien zijn: het blokje licht kort op. In
 * de eigen statuskleur, niet in amber — anders ziet een foutmelding er tijdens
 * de animatie oranje uit. De klasse wordt er in app.js af- en weer op gezet
 * zodat de animatie opnieuw begint. Kent een browser color-mix niet, dan valt
 * alleen dit oplichten weg. */
.result-share .share-note.is-nieuw {
  animation: share-note-oplichten 0.75s ease-out;
}

@keyframes share-note-oplichten {
  from {
    background: color-mix(
      in srgb,
      var(--note-kleur, var(--accent)) 18%,
      var(--bg-raised)
    );
  }
  to {
    background: var(--bg-raised);
  }
}

@media (prefers-reduced-motion: reduce) {
  .result-share .share-note.is-nieuw {
    animation: none;
  }
}

@media (max-width: 420px) {
  /* Op een smal scherm passen er twee per regel; even breed leest rustiger dan
   * knoppen die op woordlengte uitlijnen. */
  .share-buttons .button {
    flex: 1 1 calc(50% - 0.3rem);
  }
}

/* De albumlink staat onder elk resultaat, zodat je altijd door kunt naar de
 * rest van de foto's. Gecentreerd, want het is een afsluitende actie en geen
 * onderdeel van de grid erboven. */
.result-album {
  margin-top: 2.5rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--border);
  text-align: center;
}

.result-album p {
  color: var(--text-muted);
  font-size: 0.9rem;
  font-weight: 300;
  margin: 0 auto 1.1rem;
  max-width: min(48ch, 100%);
}

.notice {
  border-radius: var(--radius-sm);
  padding: 0.85rem 1.1rem;
  margin-bottom: 1.2rem;
  border: 1px solid var(--border-strong);
  background: var(--bg-raised-2);
  font-size: 0.92rem;
}

.notice-error {
  border-color: rgba(248, 113, 113, 0.45);
  background: rgba(248, 113, 113, 0.09);
}

.notice-success {
  border-color: rgba(74, 222, 128, 0.4);
  background: rgba(74, 222, 128, 0.09);
}

/* Oranje in plaats van amber, zodat een waarschuwing niet op het merkaccent
 * lijkt. */
.notice-warning {
  border-color: rgba(251, 146, 60, 0.5);
  background: rgba(251, 146, 60, 0.1);
}

.notice-info {
  border-color: var(--border-strong);
  background: var(--bg-raised-2);
  color: var(--text-muted);
}

/* -------------------------------------------------------------------- footer */

.site-footer {
  border-top: 1px solid var(--border);
  padding: 2.5rem 1.5rem 3rem;
  text-align: center;
  color: var(--text-faint);
  font-size: 0.82rem;
  font-weight: 300;
}

.footer-mark {
  width: 52px;
  height: auto;
  margin: 0 auto 1.35rem;
  opacity: 0.45;
}

.site-footer a {
  color: var(--text-muted);
}

.footer-note {
  margin-top: 0.4rem;
  color: #8d8d8a;
}

/* De regel over privacy is een hele zin en geen los woord; op een breed scherm
   zou hij anders over de volle 1200 px lopen. */
.footer-note {
  max-width: 46rem;
  margin-inline: auto;
}

/* ---------------------------------------------------------- tekstpagina */

/* Lopende tekst in plaats van kaarten: de privacyverklaring. Smaller dan de
   rest van de site, want een regel van 1200 px leest niet, en met de afstanden
   er expliciet in — `p` heeft bovenaan dit bestand `margin: 0`. */
.tekstpagina {
  max-width: 46rem;
  margin: 0 auto;
}

.tekstpagina-kop {
  margin-bottom: 2.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--border);
}

.tekstpagina-kop h1 {
  margin-bottom: 0.6rem;
  font-size: clamp(1.75rem, 5vw, 2.25rem);
}

.tekstpagina-intro {
  color: var(--text-muted);
  font-size: 1.05rem;
}

.tekstpagina h2 {
  margin-top: 2.75rem;
  margin-bottom: 0.9rem;
  font-size: 1.15rem;
}

.tekstpagina p,
.tekstpagina li {
  color: var(--text-muted);
}

.tekstpagina p + p,
.tekstpagina ul + p,
.tekstpagina p + ul {
  margin-top: 1rem;
}

.tekstpagina ul {
  margin: 0;
  padding-left: 1.25rem;
  list-style: disc;
}

.tekstpagina li + li {
  margin-top: 0.65rem;
}

.tekstpagina strong {
  color: var(--text);
  font-weight: 700;
}

/* De opslagsleutels bij naam, zodat te zien is dat ze letterlijk zo in de
   browser staan. break-all omdat ze op een smal scherm langer zijn dan de
   regel. */
.tekstpagina code {
  padding: 0.1em 0.35em;
  border-radius: var(--radius-sm);
  background: var(--bg-raised-2);
  color: var(--text);
  font-size: 0.9em;
  word-break: break-all;
}

/* In lopende tekst is de streep het enige waaraan een link te herkennen is, dus
   die staat er altijd onder en niet pas bij hover zoals elders op de site. */
.tekstpagina a {
  text-decoration: underline;
}

.tekstpagina-datum {
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
  color: var(--text-faint);
  font-size: 0.85rem;
}

/* ------------------------------------------------------------------ 404/fout */

.page-error {
  display: grid;
  place-items: center;
}

.error-wrap {
  text-align: center;
  padding: 4rem 1.5rem;
}

.error-wrap h1 {
  font-size: 3.5rem;
  letter-spacing: 0.02em;
}

.error-wrap p {
  margin: 0.9rem 0 2rem;
  color: var(--text-muted);
  font-weight: 300;
}

/* --------------------------------------------------------------- voortgang */

.progress {
  height: 5px;
  border-radius: 999px;
  background: var(--bg-raised-2);
  overflow: hidden;
  border: 1px solid var(--border);
}

.progress-bar {
  height: 100%;
  background: var(--accent);
  transition: width 0.35s ease;
}
/* ------------------------------------------------------------- favorieten */

/* Het hartje en de sociale pictogrammen staan samen rechts in de koptekst. Een
 * rij eromheen, want zonder die rij zou space-between ze uit elkaar duwen. */
.site-header-acties {
  display: flex;
  align-items: center;
  gap: 0.15rem;
}

/* Zelfde raakvlak als een sociaal pictogram, maar met het getal ernaast: dit is
 * geen zijpaadje maar de weg naar wat de bezoeker aan het verzamelen is. */
/* Een echte knop en geen pictogram tussen de andere: dit is de weg naar wat de
 * bezoeker aan het verzamelen is, en dat viel als kaal hartje tussen Instagram
 * en Facebook niet op. Vandaar de rand, het woord erbij en de teller erin. */
.fav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  height: 40px;
  padding: 0 0.85rem;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text);
  font-family: var(--font-kop);
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  white-space: nowrap;
  transition:
    color 0.16s ease,
    background 0.16s ease,
    border-color 0.16s ease,
    transform 0.16s ease;
}

.fav-link:hover {
  background: var(--bg-raised-2);
  border-color: var(--text-faint);
  color: var(--text);
  text-decoration: none;
}

.fav-link svg {
  display: block;
  width: 18px;
  height: 18px;
  transition:
    fill 0.16s ease,
    stroke 0.16s ease;
}

/* Staat er iets in, dan is het hartje gevuld en rood: dan zie je dat zonder het
 * getal te hoeven lezen. */
.fav-link.heeft-favorieten svg {
  fill: var(--hart);
  stroke: var(--hart);
}

.fav-link:hover svg {
  fill: var(--hart);
  stroke: var(--hart);
}

/* Eén klop als er een foto aankomt. */
.fav-link.klopt {
  animation: fav-klop 0.55s ease;
}

@keyframes fav-klop {
  0% { transform: scale(1); }
  30% { transform: scale(1.16); }
  55% { transform: scale(0.97); }
  100% { transform: scale(1); }
}

/* Het getal ligt over de rechterbovenhoek van het hartje. Vaste kleuren en geen
 * var(--accent-ink): dit plakje is klein, en dan telt alleen leesbaarheid. */
/* Het getal schuift bij het optellen en aftrekken, dus het plakje knipt af wat
 * er buiten valt: het oude cijfer glijdt eruit terwijl het nieuwe binnenkomt. */
.fav-count {
  position: relative;
  overflow: hidden;
  min-width: 19px;
  padding: 0 5px;
  border-radius: 10px;
  background: var(--accent);
  color: #1e1e1e;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  line-height: 19px;
  text-align: center;
}

/* Het nieuwe cijfer staat in de tekststroom en bepaalt dus de breedte van het
 * plakje; het oude ligt er los overheen en telt daar niet in mee. */
.fav-count-cijfer {
  display: block;
}

.fav-count-oud {
  position: absolute;
  inset: 0;
  display: block;
  text-align: center;
}

/* Het hartje op een foto. Rechtsboven, tegenover het startnummer linksboven.
 * Een donkere schaduw eronder, want het ligt op een foto en die kan alle kanten
 * op qua helderheid. */
.fav-knop {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(30, 30, 30, 0.35);
  backdrop-filter: blur(4px);
  color: #ffffff;
  cursor: pointer;
  transition:
    background 0.16s ease,
    color 0.16s ease,
    transform 0.16s ease;
}

.fav-knop svg {
  display: block;
  width: 20px;
  height: 20px;
}

.fav-knop.is-aan {
  background: rgba(255, 255, 255, 0.94);
  color: var(--hart);
}

.fav-knop.is-aan svg {
  fill: currentColor;
}

/* Alleen op een apparaat met een echte muisaanwijzer.
 *
 * Een telefoon houdt :hover na een tik vast tot je ergens anders tikt. Zonder
 * deze grens bleef het hartje daardoor rood en gevuld nadat je een foto júist
 * uit je favorieten had gehaald: het zag eruit alsof de tik niets had gedaan,
 * of erger, alsof hij nog steeds bewaard was. Met (hover: hover) bestaan deze
 * regels op een touchscreen niet en toont .is-aan alleen wat er echt bewaard is.
 */
@media (hover: hover) {
  /* Bij het aanwijzen wordt het hartje rood en vult het zich: zo zie je vooraf
   * wat de klik gaat doen, in plaats van alleen een kringetje dat oplicht. */
  .fav-knop:hover {
    background: rgba(255, 255, 255, 0.94);
    color: var(--hart);
    transform: scale(1.08);
  }

  .fav-knop:hover svg {
    fill: currentColor;
  }

  /* Staat hij al aan, dan gaat het aanwijzen de andere kant op: dieper rood,
   * want de klik haalt hem er juist uit. */
  .fav-knop.is-aan:hover {
    color: var(--hart-donker);
  }
}

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

@media (prefers-reduced-motion: reduce) {
  .fav-knop {
    transition: none;
  }
}

@media (prefers-reduced-motion: reduce) and (hover: hover) {
  .fav-knop:hover {
    transform: none;
  }
}

/* ------------------------------------------------------ /favorieten */

.fav-page {
  max-width: var(--max);
  margin: 0 auto;
}

.fav-page-head {
  margin-bottom: 2rem;
}

.fav-page-head h1 {
  margin-bottom: 0.5rem;
}

.fav-page-intro {
  max-width: 44rem;
  color: var(--text-muted);
}

.fav-status {
  margin-bottom: 1.5rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid #e0b4b4;
  border-radius: var(--radius);
  background: #fbf1f1;
  color: #8a2b2b;
}

/* Geen fout maar een mededeling — "bijgewerkt met de galerij". Hetzelfde
   amberen vlak met de dikke linkerrand als de andere aanwijzingen op de site,
   zodat het als bericht leest en niet als storing. */
.fav-status.is-melding {
  border-color: var(--accent-soft);
  border-left: 4px solid var(--accent);
  background: rgba(253, 186, 65, 0.1);
  color: var(--text-muted);
}

/* Terwijl de foto's opgehaald worden.
 *
 * Zonder dit staat er tussen het openen van de pagina en het antwoord van de
 * server een leeg vlak, en juist op het moment dat het lang duurt — na het
 * invullen van een adres, want dan wordt de galerij bij Pixieset nagelezen —
 * lijkt het alsof er niets gebeurt. */
.fav-laden {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 2rem 0;
  color: var(--text-muted);
  font-size: 0.95rem;
}

.fav-laden[hidden] {
  display: none;
}

.fav-laden-ring {
  flex: none;
  width: 18px;
  height: 18px;
  border: 2px solid var(--border-strong);
  border-top-color: var(--accent-line);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

/* Het voorschrift bovenaan zet elke animatie zo goed als stil, dus een ring
   die niet draait zou hier alleen maar op een storing lijken. De regel ernaast
   zegt hetzelfde in woorden en blijft staan. */
@media (prefers-reduced-motion: reduce) {
  .fav-laden-ring {
    display: none;
  }
}

.fav-evenement + .fav-evenement {
  margin-top: 3rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--border);
}

/* De naam links, de knop rechts; op een smal scherm onder elkaar met de knop
 * over de volle breedte, want daar is hij de hoofdhandeling. */
.fav-evenement-kop {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.35rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--border);
}

/* De vraag om het e-mailadres, bovenaan /favorieten zolang er geen is.
 *
 * Het amberen vlak met de dikke linkerrand van de andere aanwijzingen op de
 * site: dit is geen storing en geen voorwaarde, maar iets wat de bezoeker beter
 * wél kan doen. */
.fav-adres {
  margin-bottom: 2rem;
  padding: 1.35rem 1.5rem;
  border: 1px solid rgba(253, 186, 65, 0.55);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  background: rgba(253, 186, 65, 0.1);
}

.fav-adres[hidden] {
  display: none;
}

.fav-adres h2 {
  margin-bottom: 0.55rem;
  font-size: 1.05rem;
}

.fav-adres > p {
  color: var(--text-muted);
  font-size: 0.95rem;
}

/* Veld en knop naast elkaar; op een smal scherm onder elkaar met allebei de
   volle breedte, want daar is de knop de hoofdhandeling. */
.fav-adres-form {
  display: flex;
  gap: 0.6rem;
  margin-top: 1.1rem;
  flex-wrap: wrap;
}

.fav-adres-veld {
  flex: 1 1 16rem;
  min-width: 0;
  padding: 0.8rem 1rem;
  font-family: var(--font-tekst);
  font-size: 1rem;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.fav-adres-veld:focus {
  border-color: var(--accent-line);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.fav-adres-fout {
  margin-top: 0.7rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid #e0b4b4;
  border-radius: var(--radius-sm);
  background: #fbf1f1;
  color: #8a2b2b;
  font-size: 0.88rem;
}

.fav-adres-fout[hidden] {
  display: none;
}

.fav-adres-klein {
  margin-top: 0.85rem;
  color: var(--text-faint);
  font-size: 0.82rem;
}

/* Onderstreept, net als in het venster: in een grijze kleine regel is de streep
   het enige waaraan de link te zien is. */
.fav-adres-klein a {
  text-decoration: underline;
}

/* Hetzelfde blok, maar voor wie zijn adres al ingevuld heeft. Geen amber:
   dat vlak vraagt om iets, en hier valt niets te doen — het staat er om te
   laten zien wat er bekend is en om het weer weg te kunnen halen. Een rustige
   kaart dus, zodat het niet elke keer om aandacht schreeuwt. */
.fav-adres-bekend {
  border: 1px solid var(--border);
  border-left: 4px solid var(--border-strong);
  background: var(--bg-raised);
}

/* De twee knoppen naast elkaar; op een smal scherm onder elkaar, net als het
   formulier hierboven. */
.fav-adres-acties {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.1rem;
}

@media (max-width: 560px) {
  .fav-adres-form .button {
    width: 100%;
  }

  .fav-adres-acties .button {
    width: 100%;
  }
}

/* Wat er met de foto's mag, één keer bovenaan de pagina. Bij elk evenement
 * herhalen zou van een mededeling een muur maken.
 *
 * STAAT NU UIT. Alleen deze ene regel; de tekst zelf staat gewoon nog in de
 * pagina (renderFavorietenPage() in lib/routes/public.js en de PHP-tegenhanger
 * in php/httpdocs/favorieten.php). Haal `display: none` hieronder weg en het
 * blok is terug zoals het was. */
.fav-voorwaarden {
  display: none;

  margin-bottom: 2rem;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised-2);
}

.fav-voorwaarden h2 {
  font-size: 1rem;
  margin-bottom: 1.15rem;
}

/* De stappen binnen het kader iets krapper dan op de voorpagina: daar staat het
 * blok op zichzelf, hier boven een lijst met foto's. */
.fav-voorwaarden .hartjes-stappen {
  gap: 1.1rem;
}

.fav-voorwaarden .hartjes-icoon {
  width: 34px;
  height: 34px;
  font-size: 0.9rem;
}

.fav-voorwaarden .hartjes-stappen p {
  font-size: 0.88rem;
}

.fav-evenement-kop h2 {
  font-size: 1.15rem;
}

.fav-evenement-meta {
  margin-top: 0.2rem;
  color: var(--text-faint);
  font-size: 0.9rem;
}

/* De knop naar de galerij, met eronder op wiens naam de lijst komt te staan.
   Rechts uitgelijnd, want de knop staat rechts in de kop; op een smal scherm
   valt hij onder de titel en gaat hij over de volle breedte, want daar is hij
   de hoofdhandeling. */
.fav-evenement-actie {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.45rem;
}

/* Bijwerken naast openen: de tweede knop is de bijzaak, dus links van de
   hoofdknop en zonder accentkleur. */
.fav-evenement-knoppen {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Bezig: de knop blijft staan waar hij stond, maar is niet meer aan te klikken. */
.fav-evenement-knoppen .button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.fav-evenement-adres {
  color: var(--text-faint);
  font-size: 0.82rem;
  text-align: right;
}

/* Wat het nalezen bij dít evenement opleverde. Onder de knop waarop geklikt is,
   in de amberkleur van de andere aanwijzingen — het is een mededeling, geen
   fout. */
.fav-evenement-melding {
  color: var(--accent-line);
  font-size: 0.82rem;
  font-weight: 700;
  text-align: right;
}

.fav-evenement-melding[hidden] {
  display: none;
}

.fav-evenement-adres strong {
  color: var(--text-muted);
  font-weight: 700;
  overflow-wrap: anywhere;
}

/* Een knop die eruitziet als een link: het gaat om een klein bijzaakje naast
   de hoofdknop, maar het ís een handeling op deze pagina en geen adres. */
.linkknop {
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-muted);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  cursor: pointer;
}

.linkknop:hover {
  color: var(--text);
}

@media (max-width: 560px) {
  .fav-evenement-actie {
    width: 100%;
    align-items: stretch;
  }

  /* Allebei de knoppen over de volle breedte, met de hoofdknop bovenaan: dat is
     waar de duim het eerst komt. */
  .fav-evenement-knoppen {
    flex-direction: column-reverse;
  }

  .fav-evenement-adres,
  .fav-evenement-melding {
    text-align: left;
  }
}

@media (max-width: 560px) {
  /* Een pil, dus geen vaste breedte: het hartje en de teller bepalen hem. Wel
     iets lager, net als de andere knoppen in de koptekst. */
  .fav-link {
    height: 36px;
  }

  .fav-link svg {
    width: 17px;
    height: 17px;
  }
}

/* ----------------------------------------- het venster om het e-mailadres */

/* Eén veld over de pagina heen, vlak voordat de lijst in de galerij gezet
   wordt. Boven het fotovenster in de stapeling: staan ze allebei open, dan
   hoort dit venster voorop en gaat het met Escape ook als eerste dicht. */
.mailvenster {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: grid;
  place-items: center;
  padding: 1.5rem 1rem;
}

.mailvenster[hidden] {
  display: none;
}

.mailvenster-achtergrond {
  position: absolute;
  inset: 0;
  background: rgba(20, 20, 20, 0.7);
}

.mailvenster-doos {
  position: relative;
  width: min(30rem, 100%);
  max-height: calc(100dvh - 3rem);
  overflow-y: auto;
  padding: 1.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  box-shadow: var(--shadow);
}

.mailvenster-doos h2 {
  margin-bottom: 0.6rem;
  font-size: 1.2rem;
}

.mailvenster-uitleg {
  color: var(--text-muted);
  font-size: 0.95rem;
}

.mailvenster-label {
  display: block;
  margin-top: 1.35rem;
  margin-bottom: 0.4rem;
  font-family: var(--font-kop);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-muted);
}

/* Dezelfde vorm als het startnummerveld op de voorpagina, maar zonder de grote
   letters: een adres is geen getal van vier cijfers en moet gewoon te lezen
   zijn terwijl je het intikt. */
.mailvenster-veld {
  width: 100%;
  padding: 0.85rem 1rem;
  font-family: var(--font-tekst);
  font-size: 1.05rem;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.mailvenster-veld:focus {
  border-color: var(--accent-line);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.mailvenster-fout {
  margin-top: 0.7rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid #e0b4b4;
  border-radius: var(--radius-sm);
  background: #fbf1f1;
  color: #8a2b2b;
  font-size: 0.88rem;
}

.mailvenster-fout[hidden] {
  display: none;
}

.mailvenster-klein {
  margin-top: 0.9rem;
  color: var(--text-faint);
  font-size: 0.82rem;
}

/* Onderstreept, niet pas bij hover zoals elders: in een grijze regel van 0,82rem
   is de streep het enige waaraan de link te zien is. */
.mailvenster-klein a {
  text-decoration: underline;
}

/* De hoofdknop rechts, zoals overal: dat is de kant waar de duim eindigt. */
.mailvenster-knoppen {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  margin-top: 1.5rem;
  flex-wrap: wrap;
}

@media (max-width: 460px) {
  .mailvenster-doos {
    padding: 1.35rem 1.15rem;
  }

  .mailvenster-knoppen {
    flex-direction: column-reverse;
  }

  .mailvenster-knoppen .button {
    width: 100%;
  }
}

/* ------------------------------------------------- de foto in het groot */

/* Eén foto over de pagina heen, met het hartje erbij. De bezoeker blijft dus op
 * onze site om te kiezen; naar de galerij gaat hij pas als hij wil bestellen. */
.fotovenster {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 1.5rem 1rem;
}

.fotovenster[hidden] {
  display: none;
}

.fotovenster-achtergrond {
  position: absolute;
  inset: 0;
  background: rgba(20, 20, 20, 0.88);
}

/* Achter het venster mag de pagina niet meescrollen: dan verdwijnt de foto
 * onder je vinger vandaan terwijl je hem bekijkt. */
body.heeft-fotovenster {
  overflow: hidden;
}

.fotovenster-doos {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
  max-width: min(1100px, 94vw);
}

/* Een houder die om de foto heen krimpt, zodat de pijlen aan de rand van het
 * beeld staan en niet aan de rand van het scherm. */
.fotovenster-beeldhouder {
  position: relative;
  display: flex;
  max-width: 100%;
}

.fotovenster-beeld {
  display: block;
  max-width: 100%;
  /* Ruimte laten voor de balk eronder, ook op een liggend telefoonscherm. */
  max-height: min(76vh, 76dvh);
  object-fit: contain;
  border-radius: var(--radius);
  background: #111111;
}

/* Terwijl de grote variant onderweg is.
 *
 * De foto's komen van Pixieset en dat duurt soms merkbaar lang. De browser
 * blijft in die tussentijd de vórige foto tonen, dus zonder teken van leven
 * lijkt het alsof de klik niet aankwam en wisselt het beeld ineens veel later.
 * Deze laag legt zich over dat oude beeld heen: gedempt, met de ring erop.
 *
 * pointer-events uit, zodat de pijlen eronder gewoon aanklikbaar blijven —
 * doorbladeren hoeft niet te wachten tot de vorige foto binnen is. */
.fotovenster-laden {
  position: absolute;
  inset: 0;
  display: none;
  place-items: center;
  gap: 0.6rem;
  border-radius: var(--radius);
  background: rgba(17, 17, 17, 0.45);
  color: #ffffff;
  pointer-events: none;
  /* Pas na een korte stilte in beeld: een foto die er al bijna is verdient
   * geen ring die even opflitst. */
  animation: fotovenster-laden-erbij 0.18s ease 0.22s both;
}

.fotovenster-beeldhouder.is-laden .fotovenster-laden {
  display: grid;
}

/* Bij het ópenen van het venster staat er nog geen foto onder en is de img nul
 * pixels groot; dan houdt de houder zelf een vlak open zodat de ring ergens
 * staat. Bij doorbladeren blijft de vorige foto staan en gebeurt dit niet. */
.fotovenster-beeldhouder.is-leeg {
  min-width: min(320px, 78vw);
  min-height: min(220px, 42vh);
  border-radius: var(--radius);
  background: #111111;
}

@keyframes fotovenster-laden-erbij {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.fotovenster-laden-ring {
  width: 30px;
  height: 30px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-top-color: #ffffff;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

/* Het voorschrift bovenaan zet elke animatie zo goed als stil, dus een ring die
   niet draait zou hier alleen maar op een storing lijken. Dan liever in
   woorden, net als bij de lijst met favorieten. */
.fotovenster-laden-tekst {
  display: none;
  font-size: 0.9rem;
}

@media (prefers-reduced-motion: reduce) {
  .fotovenster-laden-ring {
    display: none;
  }

  .fotovenster-laden-tekst {
    display: block;
  }
}

/* De pijlen liggen over de foto, verticaal in het midden. Ze verdwijnen aan het
 * begin en het eind van de reeks: een pijl die niets doet is een pijl waar je
 * op blijft klikken. */
.fotovenster-pijl {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(20, 20, 20, 0.5);
  backdrop-filter: blur(4px);
  color: #ffffff;
  cursor: pointer;
  transition: background 0.16s ease;
}

.fotovenster-pijl[hidden] {
  display: none;
}

.fotovenster-pijl:hover {
  background: rgba(20, 20, 20, 0.78);
}

.fotovenster-pijl svg {
  display: block;
  width: 22px;
  height: 22px;
}

.fotovenster-vorige {
  left: 0.6rem;
}

.fotovenster-volgende {
  right: 0.6rem;
}

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

.fotovenster-balk {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* Bestellen en downloaden, subtiel naast het hartje: dezelfde pilvorm maar
 * omlijnd in plaats van gevuld, zodat het hartje de hoofdhandeling blijft en
 * deze twee er rustig naast staan. */
.fotovenster-actie {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 0.95rem;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 999px;
  color: #ffffff;
  font-family: var(--font-kop);
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  white-space: nowrap;
  transition:
    background 0.16s ease,
    border-color 0.16s ease;
}

@media (hover: hover) {
  .fotovenster-actie:hover {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.55);
    text-decoration: none;
  }
}

/* Dezelfde melding in de balk van het fotovenster. Lichter groen: die balk ligt
   op een bijna-zwarte achtergrond, en --ok zou daar wegvallen. */
.fotovenster-actie.is-opgeslagen,
.fotovenster-actie.is-opgeslagen:hover {
  border-color: rgba(126, 214, 160, 0.75);
  background: rgba(47, 125, 79, 0.35);
  color: #d9f5e5;
  animation: fav-klop 0.55s ease;
}

.fotovenster-actie:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
}

.fotovenster-teller {
  color: rgba(255, 255, 255, 0.7);
  font-family: var(--font-kop);
  font-size: 0.74rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
}

/* Het hartje uit het raster, maar dan als knop met tekst: in het venster is er
 * ruimte voor, en dan hoeft niemand te raden wat het pictogram doet. */
.fotovenster-hart {
  position: static;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  width: auto;
  height: 40px;
  padding: 0 1rem;
  border-radius: 999px;
  font-family: var(--font-kop);
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.fotovenster-hart:hover {
  transform: none;
}

/* In het venster staat het hartje op een donkere achtergrond en niet op een
 * foto, dus daar mag het gewoon rood zijn in plaats van wit-op-rood. */
.fotovenster-hart {
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
}

.fotovenster-hart:hover,
.fotovenster-hart.is-aan {
  background: rgba(255, 255, 255, 0.94);
  color: var(--hart);
}

.fotovenster-sluit {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
  cursor: pointer;
  transition: background 0.16s ease;
}

.fotovenster-sluit:hover {
  background: rgba(255, 255, 255, 0.26);
}

.fotovenster-sluit svg {
  display: block;
  width: 18px;
  height: 18px;
}

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

@media (max-width: 560px) {
  .fotovenster {
    padding: 0.75rem;
  }

  .fotovenster-balk {
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.4rem;
  }
}

/* ---------------------------------------------- uitleg over de hartjes */

/* Drie stappen naast elkaar op de voorpagina. Het eerste bolletje is het hartje
 * zelf en niet het cijfer 1: dat is waar de bezoeker straks naar zoekt. */
.hartjes-stappen {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.hartjes-stappen li {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  align-items: center;
  gap: 0.35rem 0.9rem;
}

/* Het bolletje staat midden naast de tekst, ongeacht of die twee of drie
 * regels lang is. Met align-self: start hing hij bij de langere teksten aan de
 * bovenkant en leken de drie stappen niet op één lijn te staan. */
.hartjes-icoon {
  grid-row: span 2;
  align-self: center;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font-kop);
  font-size: 1.05rem;
  font-weight: 700;
}

.hartjes-icoon svg {
  display: block;
  width: 22px;
  height: 22px;
  fill: currentColor;
}

/* Het eerste bolletje is het hartje zelf, en dat hoort rood te zijn: hetzelfde
 * hartje dat de bezoeker straks op de foto's aanklikt. Een rood hartje op het
 * amber van de andere twee is niet te lezen, dus dit bolletje krijgt een zacht
 * rode vulling met een dunne rand eromheen. */
.hartjes-icoon--hart {
  background: rgba(226, 59, 78, 0.12);
  box-shadow: inset 0 0 0 1px rgba(226, 59, 78, 0.3);
  color: var(--hart);
}

.hartjes-stappen h3 {
  align-self: end;
  font-size: 0.95rem;
}

.hartjes-stappen p {
  align-self: start;
  color: var(--text-muted);
  font-size: 0.94rem;
}

/* ------------------------------------------------- de foto die wegvliegt */

/* De kopie van de foto die naar het hartje in de koptekst schuift. Los van de
 * pagina, en niet aan te klikken: hij is er alleen om te laten zien wáár de
 * foto heen gaat. */
.fav-vlucht {
  position: fixed;
  z-index: 200;
  margin: 0;
  object-fit: contain;
  border-radius: 2px;
  box-shadow: 0 12px 30px -12px rgba(20, 20, 20, 0.6);
  pointer-events: none;
}

@media (max-width: 560px) {
  /* Op een telefoon is er geen ruimte voor het woord naast het hartje; het
     pictogram en de teller blijven staan. */
  .fav-link-tekst {
    display: none;
  }

  .fav-link {
    gap: 0.4rem;
    padding: 0 0.7rem;
  }

  .fotovenster-pijl {
    width: 40px;
    height: 40px;
  }

  .fotovenster-vorige {
    left: 0.35rem;
  }

  .fotovenster-volgende {
    right: 0.35rem;
  }
}
