/* ==========================================================================
   Design tokens — palette is unchanged from the existing design system
   (2026-07-29 layout-spec). Everything below is a native-mobile-app pass on
   top of the same colors: elevation, motion, spacing and safe-area tokens,
   plus refined/added component rules. Every class name already referenced
   by the EJS views is preserved so no template needed to change to pick up
   the new look; a handful of flagship screens (app shell, timeline, media
   viewer, auth, settings) also got markup passes and use the newer classes
   noted inline.
   ========================================================================== */

:root {
  color-scheme: light;
  --navy: #2b3a52;
  --sky: #7bb8d4;
  --gold: #d4943a;
  --gold-dk: #b87a28;
  --green: #4e7c3a;
  --sand: #e8d5a3;
  --sand-lt: #f5edd6;
  --cream: #fdfaf3;
  --warm: #f0e8ce;
  --brown: #7a5230;
  --yellow: #f5c342;
  --yellow-lt: #fdf3cc;
  --red: #e96a6a;
  --purple: #c47fd4;

  --bg: #f2ede4;
  --border: rgba(43, 58, 82, 0.12);

  /* surfaces */
  --surface: #ffffff;
  --surface-2: var(--cream);
  --ink: var(--navy);
  --ink-soft: rgba(43, 58, 82, 0.64);
  --ink-faint: rgba(43, 58, 82, 0.42);

  /* elevation — soft, warm-tinted shadows instead of neutral grey */
  --shadow-xs: 0 1px 3px rgba(43, 58, 82, 0.07);
  --shadow-sm: 0 2px 10px rgba(43, 58, 82, 0.08);
  --shadow-md: 0 8px 24px rgba(43, 58, 82, 0.13);
  --shadow-lg: 0 18px 44px rgba(43, 58, 82, 0.2);
  --shadow-gold: 0 10px 22px rgba(212, 148, 58, 0.4);

  --radius-xs: 8px;
  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 22px;
  --radius-pill: 999px;

  --gap: 1rem;
  --tabbar-height: 62px;
  --header-height: 3.25rem;
  --sticky-bar-height: 4.5rem;

  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-fast: 120ms;
  --dur: 220ms;
}

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

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

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

body {
  margin: 0;
  font-family:
    'Inter',
    system-ui,
    -apple-system,
    'Segoe UI',
    Roboto,
    sans-serif;
  background: var(--bg);
  color: var(--ink);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--yellow);
  color: var(--brown);
}

img,
video {
  max-width: 100%;
}

:focus-visible {
  outline: 2.5px solid var(--gold);
  outline-offset: 2px;
  border-radius: 4px;
}

h1,
h2,
h3,
h4 {
  font-family: 'Nunito', sans-serif;
  font-weight: 900;
  letter-spacing: -0.5px;
  color: var(--navy);
}

h1 {
  font-size: clamp(1.8rem, 3vw, 2.4rem);
  margin-bottom: 1.25rem;
}

h3 {
  font-size: 1.15rem;
  margin-bottom: 0.5rem;
}

a {
  color: var(--navy);
}

hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 1.5rem 0;
}

small {
  color: var(--ink-soft);
}

/* ---- App brand mark (used in .brand, mobile header, auth screens) ---- */
.brand-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: 28%;
  background: var(--navy);
  color: var(--cream);
  line-height: 0;
}

.brand-logo svg {
  display: block;
}

/* ---- Topnav (desktop) ---- */
.topnav {
  /* Er hangen makkelijk 12+ losse links onder deze balk (zie partials/
     nav.ejs) — met de standaard flex-wrap:nowrap kunnen individuele
     flex-items niet verder krimpen dan hun eigen min-content-breedte, dus
     bij te weinig ruimte werd voorheen alleen de meerwoordige link ("Snel
     taggen") kapotgeknepen tot een tekst die middenin een woord afbrak,
     terwijl de rest van de rij niet netjes meeschoof. flex-wrap + expliciet
     flex-shrink:0 op de items laat de balk in plaats daarvan gewoon naar
     een tweede regel doorlopen, wat er bij smallere/desktop-site-breedtes
     opgeruimd uitziet i.p.v. verminkt. */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.25rem;
  padding: 0.85rem 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 20;
}

.topnav .brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  flex-shrink: 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 900;
  font-size: 1.2rem;
  margin-right: 0.5rem;
  text-decoration: none;
  color: var(--navy);
}

/* Signatuur-detail uit hetzelfde designsysteem als meesdegraaf.nl/
   juuldegraaf.nl: een gouden punt direct na de merknaam. Zit op
   .brand-name (niet op .brand zelf) omdat .brand een flex-container is
   (voor de logo-icoon + naam ernaast) — een ::after direct op een
   flex-container wordt zélf een flex-item en met align-items:center dan
   los als eigen doosje gecentreerd i.p.v. gewoon op de tekstbaseline mee te
   lopen, waardoor de punt boven de tekst leek te zweven. Binnen
   .brand-name (geen flex-context) staat de pseudo-content gewoon inline
   ná de naam, op dezelfde baseline. */
.topnav .brand-name::after {
  content: '.';
  color: var(--gold);
}

.topnav a {
  flex-shrink: 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.9rem;
  text-decoration: none;
  color: var(--navy);
  opacity: 0.7;
  transition: opacity var(--dur) var(--ease);
  white-space: nowrap;
}

.topnav a:hover,
.topnav a.active {
  opacity: 1;
}

/* ---- Desktop topnav: primary links + compact actions cluster ---- */
.topnav-links {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  margin-right: auto;
}

.topnav-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.topnav-icon-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  color: var(--navy);
  opacity: 0.75;
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: none;
  transition:
    background-color var(--dur) var(--ease),
    opacity var(--dur) var(--ease);
}

.topnav-icon-btn svg {
  width: 19px;
  height: 19px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.topnav-icon-btn:hover,
.topnav-icon-btn[aria-expanded='true'] {
  opacity: 1;
  background: rgba(43, 58, 82, 0.08);
}

.topnav-icon-btn .tab-badge {
  top: 1px;
  right: 1px;
}

.topnav-family-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  flex-shrink: 0;
  padding: 0.3rem 0.85rem 0.3rem 0.4rem;
  border-radius: var(--radius-pill);
  background: var(--sand-lt);
  color: var(--brown);
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--dur) var(--ease);
}

.topnav-family-btn:hover {
  background: var(--sand);
}

.topnav-family-btn svg {
  width: 13px;
  height: 13px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2.2;
  opacity: 0.6;
}

.topnav-more {
  position: relative;
  flex-shrink: 0;
}

.topnav-more-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 260px;
  max-height: 75vh;
  overflow-y: auto;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 0.6rem;
  z-index: 30;
  opacity: 0;
  transform: translateY(-6px) scale(0.98);
  transform-origin: top right;
  transition:
    opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease-spring);
  pointer-events: none;
}

.topnav-more-menu.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

/* Hergebruikt dezelfde .settings-group/.settings-list-markup als de
   mobiele "Meer"-sheet (partials/moreMenuContent.ejs) — hier compacter
   ingesteld voor een dropdown i.p.v. een volledig-schermbreed paneel. */
.topnav-more-menu .settings-group {
  margin-bottom: 0.6rem;
}

.topnav-more-menu .settings-group:last-child {
  margin-bottom: 0;
}

.topnav-more-menu .settings-group-title {
  margin: 0 0.5rem 0.3rem;
}

.topnav-more-menu .settings-list {
  box-shadow: none;
  border-radius: 0;
  background: none;
}

.topnav-more-menu .settings-list li + li {
  border-top: none;
}

.topnav-more-menu .settings-row {
  padding: 0.5rem 0.6rem;
  font-size: 0.85rem;
  border-radius: var(--radius-sm);
  min-height: 0;
}

.topnav-more-menu .settings-row:hover {
  background: var(--sand-lt);
}

.topnav-more-menu .settings-row-icon {
  width: 28px;
  height: 28px;
}

.topnav-more-menu .settings-row-icon svg {
  width: 15px;
  height: 15px;
}

.topnav-more-menu .settings-row-chevron {
  display: none;
}

/* ---- Family switcher / mobile app header ---- */
/* Op desktop zit de familieswitcher + alle snelle acties nu al netjes in
   .topnav (zie partials/nav.ejs) — deze balk is dus alleen nog de mobiele
   app-header en blijft standaard verborgen; hieronder in de
   max-width:720px-media-query wordt hij weer getoond. */
.familybar {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 1.5rem;
  background: var(--sand-lt);
  border-bottom: 1px solid var(--border);
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
}

.familybar > a:first-child {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  color: var(--brown);
}

.familybar .switch-hint {
  margin-left: 0.5rem;
  font-weight: 600;
  font-size: 0.75rem;
  text-decoration: underline;
}

/* ---- Bottom tab bar (mobile) ---- */
.tabbar {
  display: none;
}

@media (max-width: 720px) {
  .topnav {
    display: none;
  }

  .tabbar {
    display: flex;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 20;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(16px) saturate(1.6);
    -webkit-backdrop-filter: blur(16px) saturate(1.6);
    box-shadow: 0 -1px 0 var(--border), 0 -8px 24px rgba(43, 58, 82, 0.1);
    padding-bottom: var(--safe-b);
  }

  .tabbar-group {
    display: flex;
    flex: 1;
    min-width: 0;
  }

  .tabbar a,
  .tabbar button {
    position: relative;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 3px;
    padding: 0.55rem 0.2rem 0.45rem;
    min-height: 44px;
    font-family: 'Nunito', sans-serif;
    font-weight: 700;
    font-size: 0.64rem;
    text-decoration: none;
    color: var(--ink-soft);
    background: none;
    border: none;
    cursor: pointer;
    transition:
      color var(--dur) var(--ease),
      transform var(--dur-fast) var(--ease);
  }

  .tabbar a:active:not(.tab-upload),
  .tabbar button:active {
    transform: scale(0.92);
  }

  .tabbar .tab-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 24px;
    border-radius: var(--radius-pill);
    transition: background-color var(--dur) var(--ease-spring);
  }

  .tabbar .tab-icon svg {
    width: 22px;
    height: 22px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .tabbar a.active {
    color: var(--gold-dk);
  }

  .tabbar a.active .tab-icon {
    background: var(--yellow-lt);
  }

  .tabbar a.active .tab-icon svg {
    stroke-width: 2.1;
  }

  .tabbar .tab-badge {
    position: absolute;
    top: 2px;
    right: 4px;
    min-width: 15px;
    height: 15px;
    padding: 0 3px;
    border-radius: var(--radius-pill);
    background: var(--red);
    color: #fff;
    font-size: 0.55rem;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.92);
  }

  .tabbar .tab-upload {
    flex: 0 0 auto;
    position: relative;
  }

  .tabbar .tab-upload .tab-icon {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background: linear-gradient(155deg, var(--gold) 0%, var(--gold-dk) 100%);
    color: #fff;
    margin-top: -24px;
    box-shadow:
      var(--shadow-gold),
      0 0 0 4px rgba(255, 255, 255, 0.92);
    transition: transform var(--dur-fast) var(--ease-spring);
  }

  .tabbar .tab-upload .tab-icon svg {
    width: 24px;
    height: 24px;
    stroke-width: 2.4;
  }

  .tabbar .tab-upload:active .tab-icon {
    transform: scale(0.9);
  }

  /* main.app-main (element+class) i.p.v. .app-main (class): moet zwaarder
     wegen dan de latere, ongeconditioneerde ".container { padding: ... }"
     verderop in dit bestand. Die shorthand-regel heeft anders exact
     dezelfde specificiteit en staat later in het bestand, en overschreef
     zo stilletjes elke padding-bottom die hier gezet werd — vandaar dat
     eerdere aanpassingen van deze waarde helemaal geen effect hadden. */
  main.app-main {
    /* Moet exact de werkelijke hoogte van .tabbar compenseren, en die is
       zelf niet vast: .tabbar telt env(safe-area-inset-bottom) óók bovenop
       de 64px (voor het gebaren-navigatiegebied/home-indicator op telefoons
       die dat hebben). */
    padding-bottom: calc(var(--tabbar-height) + var(--safe-b) + 1.25rem);
  }

  .familybar {
    display: flex;
    flex-wrap: wrap;
    padding: calc(0.6rem + var(--safe-t)) 1rem 0.6rem;
    gap: 0.4rem 0.75rem;
    position: sticky;
    top: 0;
    z-index: 15;
    background: rgba(245, 237, 214, 0.92);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
  }

  .familybar > a:first-child {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .timeline-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 0.3rem;
  }

  .media-nav {
    width: 38px;
    height: 38px;
    font-size: 1.3rem;
  }

  button:where(:not(.btn)) {
    min-height: 44px;
  }

  .calendar-nav-arrow {
    min-width: 44px;
    min-height: 44px;
  }
}

.container {
  max-width: 960px;
  margin: 0 auto;
  padding: 1.5rem 1.25rem;
}

@media (max-width: 720px) {
  .container {
    padding: 1.1rem 1rem;
  }
}

.inline-form {
  display: inline;
}

.error-page {
  text-align: center;
  padding: 3rem 1rem;
}

form.stacked {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  max-width: 420px;
  background: var(--surface);
  padding: 1.25rem;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  margin-bottom: 1.25rem;
}

.media-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1.25rem;
}

.media-actions form {
  margin: 0;
}

form.stacked label {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--navy);
}

/* Labels die een checkbox/radio omwikkelen (bv. "Kinderen taggen") zijn
   losse rijen, geen sectietitels — die moeten dus als flex-rij uitlijnen
   i.p.v. de standaard block-achtige label-styling hierboven. Puur-tekst
   labels (zonder input erin, bv. de "Kinderen taggen"-sectietitel) blijven
   ongemoeid. */
form.stacked label:has(input[type='checkbox']),
form.stacked label:has(input[type='radio']) {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 600;
  cursor: pointer;
}

form.stacked input:not([type='checkbox']):not([type='radio']),
form.stacked select,
form.stacked textarea {
  padding: 0.7rem 0.85rem;
  min-height: 46px;
  border: 1.5px solid var(--sand);
  border-radius: var(--radius-sm);
  font-size: 1rem;
  font-family: inherit;
  background: var(--cream);
  color: var(--ink);
  transition:
    border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

/* Checkboxes/radio's horen niet de tekstveld-styling hierboven te krijgen
   (padding/min-height 46px maakte er een enorm, van het label losstaand
   vierkant van) — gewoon een normale, iets grotere native checkbox. */
form.stacked input[type='checkbox'],
form.stacked input[type='radio'] {
  width: 20px;
  height: 20px;
  min-height: 0;
  flex-shrink: 0;
  accent-color: var(--gold);
}

form.stacked textarea {
  min-height: 90px;
}

form.stacked input:not([type='checkbox']):not([type='radio']):focus,
form.stacked select:focus,
form.stacked textarea:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 4px rgba(212, 148, 58, 0.16);
}

@media (max-width: 720px) {
  form.stacked > .btn,
  form.stacked > button.btn {
    align-self: stretch;
    text-align: center;
  }
}

.btn,
button:where(:not(.btn)) {
  transition:
    transform var(--dur-fast) var(--ease-spring),
    opacity var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease),
    background-color var(--dur) var(--ease);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  padding: 0.7rem 1.5rem;
  min-height: 46px;
  background: var(--navy);
  color: #fff;
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  text-decoration: none;
  font-size: 0.95rem;
  box-shadow: var(--shadow-sm);
}

@media (hover: hover) {
  .btn:hover {
    opacity: 0.92;
    box-shadow: var(--shadow-md);
  }
}

.btn:active {
  transform: scale(0.96);
}

.btn-gold {
  background: linear-gradient(155deg, var(--gold) 0%, var(--gold-dk) 100%);
  box-shadow: var(--shadow-gold);
}

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

.btn-danger {
  background: var(--red);
}

.btn-block {
  display: flex;
  width: 100%;
}

.btn-sm {
  padding: 0.5rem 1.1rem;
  min-height: 0;
  font-size: 0.85rem;
}

/* :where() geeft deze selector 0 specificiteit ondanks de :not() — daardoor
   verliest deze generieke "kale knop"-fallback altijd van elke component
   die zijn eigen knopklasse zet (.tile-reaction, .settings-row,
   .reaction-popover-emoji, .media-actionbar-btn, enz.), ook al staat die
   component-CSS eerder in dit bestand. Zonder :where() heeft
   "button:not(.btn)" specificiteit (0,1,1) — gelijk aan of hoger dan een
   los klasse-selector (0,1,0) — en wint hij soms alsnog van later
   gedefinieerde component-stijlen, wat meermaals per ongeluk een knop in
   een groot, romig standaardblokje veranderde i.p.v. het bedoelde
   subtiele uiterlijk. */
button:where(:not(.btn)) {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  padding: 0.45rem 0.95rem;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--sand);
  background: var(--cream);
  color: var(--navy);
  cursor: pointer;
}

button:where(:not(.btn)):active {
  transform: scale(0.95);
}

.timeline-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 0.5rem;
}

.timeline-grid figure {
  margin: 0;
  position: relative;
}

.timeline-grid figure > a {
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform var(--dur-fast) var(--ease);
}

.timeline-grid figure > a:active {
  transform: scale(0.94);
}

/* ---- Nog-te-bevestigen suggestie-badge op zoekresultaten (/search) ---- */
.suggestion-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.65rem;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--yellow);
  color: var(--brown);
  box-shadow: var(--shadow-xs);
}

/* Zelfde label, maar los van een foto-tegel gebruikt (bv. als voorbeeld in
   een uitlegtekst) — daar zou de absolute positionering hierboven t.o.v.
   de verkeerde voorouder positioneren. */
.suggestion-badge.inline {
  position: static;
  display: inline-block;
}

.favorite-badge {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(20, 26, 38, 0.45);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--yellow);
  font-size: 0.8rem;
  pointer-events: none;
}

.timeline-grid img,
.timeline-grid video {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radius);
  display: block;
  box-shadow: var(--shadow-sm);
}

.timeline-grid figure > a img,
.timeline-grid figure > a video {
  box-shadow: none;
}

/* ---- Media-detailweergave: swipe/pijltjes tussen foto's ---- */
.media-viewer {
  position: relative;
  margin: -1.1rem -1rem 1.25rem;
  touch-action: pan-y;
  background: #000;
}

@media (min-width: 721px) {
  .media-viewer {
    margin: 0 0 1.25rem;
    border-radius: var(--radius-lg);
    overflow: hidden;
  }
}

.media-viewer-media {
  width: 100%;
  max-height: 80vh;
  display: block;
  object-fit: contain;
  background: #000;
}

@media (min-width: 721px) {
  .media-viewer-media {
    border-radius: var(--radius-lg);
  }
}

.media-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(20, 26, 38, 0.5);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  font-size: 1.6rem;
  text-decoration: none;
  z-index: 2;
  transition: transform var(--dur-fast) var(--ease-spring);
}

.media-nav:active {
  transform: translateY(-50%) scale(0.88);
}

.media-nav-prev {
  left: 0.5rem;
}

.media-nav-next {
  right: 0.5rem;
}

.media-viewer-media[data-zoomable] {
  cursor: zoom-in;
}

body.media-viewer-open {
  overflow: hidden;
}

.media-viewer.fullscreen {
  position: fixed;
  inset: 0;
  z-index: 100;
  margin: 0;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
  overflow: hidden;
  padding-top: var(--safe-t);
  padding-bottom: var(--safe-b);
}

.media-viewer.fullscreen .media-viewer-media {
  width: 100%;
  height: 100%;
  max-height: 100vh;
  border-radius: 0;
  object-fit: contain;
  cursor: zoom-out;
  touch-action: none;
  transform-origin: center center;
  will-change: transform;
}

.media-viewer.fullscreen .media-nav {
  z-index: 101;
}

.thumbnail-pending {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius);
  background: linear-gradient(100deg, var(--warm) 30%, var(--sand-lt) 50%, var(--warm) 70%);
  background-size: 220% 100%;
  animation: shimmer 1.7s ease-in-out infinite;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.4rem;
  opacity: 0.75;
}

@keyframes shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

.timeline-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  margin-bottom: 1.25rem;
  font-size: 0.85rem;
}

.timeline-filters select,
.timeline-filters input[type='search'] {
  padding: 0.55rem 0.7rem;
  min-height: 42px;
  border: 1.5px solid var(--sand);
  border-radius: var(--radius-sm);
  background: var(--cream);
  font-family: inherit;
}

.timeline-filters label {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  white-space: nowrap;
}

/* ---- Uitklapbare filters ---- */
.timeline-filters-wrap {
  margin-bottom: 1.25rem;
}

.timeline-filters-wrap summary {
  cursor: pointer;
  list-style: none;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.9rem;
  padding: 0.65rem 1.1rem;
  background: var(--surface);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  transition: box-shadow var(--dur) var(--ease);
}

.timeline-filters-wrap summary::-webkit-details-marker {
  display: none;
}

.timeline-filters-wrap summary::before {
  content: '\1F50D';
}

.timeline-filters-wrap .filter-badge {
  background: var(--gold);
  color: #fff;
  font-size: 0.65rem;
  padding: 1px 8px;
  border-radius: var(--radius-pill);
}

.timeline-filters-wrap[open] summary {
  margin-bottom: 0.75rem;
  box-shadow: var(--shadow-md);
}

.timeline-filters-wrap .timeline-filters {
  margin-bottom: 0;
}

/* ---- Maand-tijdlijn: tabs + hero-kaart per maand ---- */
.month-tabs {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  padding: 0.75rem 0;
  margin-bottom: 1.5rem;
  scrollbar-width: none;
}

.month-tabs::-webkit-scrollbar {
  display: none;
}

.month-tab {
  flex-shrink: 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  padding: 0.45rem 1.1rem;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--sand);
  background: var(--surface);
  color: var(--navy);
  text-decoration: none;
  scroll-snap-align: start;
  transition:
    transform var(--dur-fast) var(--ease-spring),
    background-color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
}

.month-tab:active {
  transform: scale(0.94);
}

.month-tab.active {
  border-color: var(--gold);
  background: var(--gold);
  color: #fff;
  box-shadow: var(--shadow-gold);
}

.month-section {
  margin-bottom: 2.5rem;
  scroll-margin-top: 4.5rem;
}

.month-hero-wrap {
  position: relative;
}

.month-hero {
  position: relative;
  display: block;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
  margin-bottom: 0.85rem;
  aspect-ratio: 4 / 3;
  transition: transform var(--dur-fast) var(--ease);
}

.month-hero:active {
  transform: scale(0.98);
}

.month-hero img,
.month-hero .thumbnail-pending {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
  display: block;
}

.month-hero-overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 3rem 1.25rem 1.1rem;
  background: linear-gradient(transparent, rgba(18, 23, 34, 0.8));
  color: #fff;
}

.month-hero-overlay h2 {
  color: #fff;
  font-size: 1.6rem;
  margin-bottom: 0.15rem;
}

.month-hero-overlay p {
  font-family: 'Nunito', sans-serif;
  font-weight: 600;
  font-size: 0.95rem;
  opacity: 0.92;
  margin: 0;
}

.month-hero-favorite {
  position: absolute;
  top: 0.85rem;
  right: 0.85rem;
  color: var(--yellow);
  font-size: 1.4rem;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}

.flash {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.85rem 1.1rem;
  border-radius: var(--radius-sm);
  border-left: 4px solid transparent;
  margin-bottom: 1rem;
  font-size: 0.9rem;
  box-shadow: var(--shadow-xs);
}

.flash.error {
  background: rgba(233, 106, 106, 0.13);
  color: #a83030;
  border-left-color: var(--red);
}

.flash.success {
  background: rgba(78, 124, 58, 0.13);
  color: #2d5c1a;
  border-left-color: var(--green);
}

.flash.warning {
  background: rgba(212, 148, 58, 0.13);
  color: #8a5a1a;
  border-left-color: var(--gold);
}

.flash.info {
  background: rgba(123, 184, 212, 0.18);
  color: #1f5a78;
  border-left-color: var(--sky);
}

.flash p {
  margin: 0;
}

.live-update-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.25rem 0.75rem;
  text-align: center;
}

.verify-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 1rem;
  margin: 0;
  padding: 0.75rem 1.25rem;
  border-radius: 0;
  border-left: none;
  text-align: center;
  box-shadow: none;
}

.verify-banner form {
  display: inline-flex;
  margin: 0;
}

.btn-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--navy);
  text-decoration: underline;
  cursor: pointer;
}

.member-list,
.child-list,
.activity-feed,
.notification-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.member-list li,
.child-list li,
.activity-item,
.notification-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem;
  padding: 0.85rem 1rem;
  margin-bottom: 0.55rem;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-xs);
  transition:
    box-shadow var(--dur) var(--ease),
    transform var(--dur-fast) var(--ease);
}

.member-list li > span,
.child-list li > span {
  overflow-wrap: anywhere;
}

/* ---- Tags/pills, reused for roles, emoji stamps, etc. ---- */
.tag {
  display: inline-block;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.7rem;
  padding: 3px 11px;
  border-radius: var(--radius-pill);
  background: var(--sand-lt);
  color: var(--brown);
}

/* ---- Avatars (initials, activity feed) ---- */
.avatar {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.9rem;
  color: #fff;
  box-shadow: var(--shadow-xs);
}

.avatar-sky {
  background: var(--sky);
}
.avatar-gold {
  background: var(--gold);
}
.avatar-green {
  background: var(--green);
}
.avatar-purple {
  background: var(--purple);
}
.avatar-red {
  background: var(--red);
}
.avatar-yellow {
  background: var(--yellow);
  color: var(--brown);
}
.avatar-brown {
  background: var(--brown);
}

/* ---- Activity feed ---- */
.activity-visits {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  padding: 0.25rem 0 1.25rem;
  -webkit-overflow-scrolling: touch;
}

.visit-avatar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  flex-shrink: 0;
}

.visit-avatar small {
  font-size: 0.7rem;
  opacity: 0.6;
  white-space: nowrap;
}

.activity-body {
  flex: 1;
  min-width: 0;
}

.activity-body p {
  margin: 0 0 2px;
  font-size: 0.9rem;
}

.activity-body small {
  opacity: 0.55;
  font-size: 0.75rem;
}

.activity-thumb {
  flex-shrink: 0;
  width: 52px;
  height: 52px;
}

.activity-thumb img,
.activity-thumb .thumbnail-pending {
  width: 52px;
  height: 52px;
  border-radius: var(--radius-sm);
  object-fit: cover;
}

/* ---- Kalender ---- */
.calendar-nav {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}

.calendar-nav h3 {
  margin: 0;
}

.calendar-nav-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  text-decoration: none;
  border-radius: var(--radius-pill);
  transition: background-color var(--dur) var(--ease);
}

.calendar-nav-arrow:active {
  background: var(--sand-lt);
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.4rem;
}

.calendar-weekday {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.75rem;
  text-align: center;
  opacity: 0.5;
  padding-bottom: 0.25rem;
}

.calendar-day {
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: var(--surface);
  text-decoration: none;
  color: var(--navy);
  box-shadow: var(--shadow-xs);
  transition: transform var(--dur-fast) var(--ease);
}

.calendar-day:active {
  transform: scale(0.92);
}

.calendar-day.empty {
  background: transparent;
  box-shadow: none;
}

.calendar-day.has-media {
  background: var(--sand-lt);
  font-weight: 700;
}

.calendar-day.is-today {
  border: 2px solid var(--gold);
}

.calendar-day-num {
  font-size: 0.9rem;
}

.calendar-day-count {
  font-size: 0.65rem;
  color: var(--gold);
  font-weight: 700;
}

/* ---- Selectie-checkbox op foto-tegels (kindherkenning trainen, filmbuilder) ---- */
.media-pick-checkbox {
  position: absolute;
  top: 6px;
  left: 6px;
  width: 26px;
  height: 26px;
  cursor: pointer;
}

/* ---- Infinite scroll: "meer laden"-sentinel onder een timeline-grid ---- */
.infinite-scroll-sentinel {
  text-align: center;
  padding: 1.25rem;
  color: var(--navy);
  opacity: 0.55;
  font-size: 0.85rem;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
}

/* ---- Vaste actiebalk onderaan (bv. "toevoegen aan album"-picker) — blijft
   bereikbaar ongeacht hoever je door een lange/infinite-scroll-lijst
   gescrold bent, i.p.v. een knop die pas na alle foto's komt. ---- */
.sticky-submit-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 25;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1.5rem;
  padding-bottom: calc(0.85rem + var(--safe-b));
  background: rgba(253, 250, 243, 0.95);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--border);
  box-shadow: 0 -4px 20px rgba(43, 58, 82, 0.1);
}

.sticky-submit-bar-spacer {
  height: var(--sticky-bar-height);
}

@media (max-width: 720px) {
  .sticky-submit-bar {
    /* Boven de vaste .tabbar onderaan blijven staan, niet erdoorheen. */
    bottom: calc(var(--tabbar-height) + var(--safe-b));
    padding-bottom: 0.85rem;
  }

  .sticky-submit-bar-spacer {
    height: calc(var(--sticky-bar-height) + var(--tabbar-height) + var(--safe-b));
  }
}

/* ---- Storiesbalk met 1-seconde-films, boven de tijdlijn ---- */
.reel-stories {
  display: flex;
  gap: 1.1rem;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0.25rem 0 1.25rem;
  margin-bottom: 0.5rem;
}

.reel-story {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
  width: 72px;
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease);
}

.reel-story:active {
  transform: scale(0.93);
}

.reel-story-thumb {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--warm);
  border: 3px solid var(--gold);
  font-size: 1.4rem;
  box-shadow: var(--shadow-xs);
}

.reel-story.seen .reel-story-thumb {
  border-color: var(--border);
}

.reel-story-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.reel-story small {
  font-size: 0.7rem;
  text-align: center;
  color: var(--navy);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* ---- Filmtegel tussen foto's/video's op de tijdlijn ---- */
.reel-tile {
  position: relative;
  display: block;
}

.reel-tile-badge {
  position: absolute;
  bottom: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(43, 58, 82, 0.65);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
}

/* ---- Meldingen ---- */
.notification-item.unread {
  border-left: 3px solid var(--gold);
}

.notification-thumb {
  flex-shrink: 0;
}

.notification-body {
  flex: 1;
  min-width: 0;
}

.notification-body p {
  margin: 0 0 2px;
  font-size: 0.9rem;
  font-weight: 600;
}

.notification-item:not(.unread) .notification-body p {
  font-weight: 400;
  opacity: 0.65;
}

.notification-body small {
  opacity: 0.55;
  font-size: 0.75rem;
}

.notification-item form {
  margin: 0;
  flex-shrink: 0;
}

/* ---- Upload-formulier: drag & drop, mobiel-vriendelijk ---- */
.upload-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 560px;
}

.upload-dropzone {
  position: relative;
}

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

.upload-dropzone-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  text-align: center;
  padding: 3.25rem 1.5rem;
  border: 2px dashed var(--sand);
  border-radius: var(--radius-lg);
  background: var(--cream);
  cursor: pointer;
  transition:
    border-color var(--dur) var(--ease),
    background-color var(--dur) var(--ease),
    transform var(--dur-fast) var(--ease);
}

@media (hover: hover) {
  .upload-dropzone-label:hover {
    border-color: var(--gold);
  }
}

.upload-dropzone-label:active {
  transform: scale(0.99);
}

.upload-input:focus-visible + .upload-dropzone-label {
  border-color: var(--gold);
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.upload-dropzone.drag-active .upload-dropzone-label {
  border-color: var(--gold);
  background: var(--sand-lt);
}

.upload-dropzone-icon {
  font-size: 2.6rem;
}

.upload-dropzone-label strong {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--navy);
}

.upload-dropzone-hint {
  font-size: 0.85rem;
  opacity: 0.6;
}

.upload-summary {
  margin: 0;
  font-size: 0.85rem;
  opacity: 0.7;
}

.upload-filelist {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.upload-filelist li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.55rem 0.8rem;
  background: var(--surface);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-xs);
}

.upload-file-thumb {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--warm);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
}

.upload-file-info {
  flex: 1;
  min-width: 0;
  font-size: 0.85rem;
}

.upload-file-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.upload-file-size {
  opacity: 0.55;
  font-size: 0.75rem;
}

button.upload-file-remove {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: 50%;
  border: none;
  background: var(--sand-lt);
  color: var(--brown);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.upload-submit {
  align-self: flex-start;
}

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

@media (max-width: 720px) {
  .upload-dropzone-label {
    padding: 2.5rem 1rem;
  }

  .upload-submit {
    align-self: stretch;
    text-align: center;
  }
}

/* ---- Gezichtsherkenning-suggesties ---- */
.face-suggestions {
  margin-bottom: 1.25rem;
}

.face-suggestion {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  padding: 0.75rem 1rem;
  margin-bottom: 0.5rem;
  background: var(--yellow-lt);
  border: 1.5px solid var(--yellow);
  border-radius: var(--radius);
}

.face-suggestion-crop {
  flex-shrink: 0;
  width: 72px;
  height: 72px;
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--yellow);
  object-fit: cover;
}

.face-reassign-select {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  padding: 0.4rem 0.9rem;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--sand);
  background: var(--cream);
  color: var(--navy);
  cursor: pointer;
}

/* Hoe zeker het systeem is van een suggestie ("82% match") — de score komt
   uit MediaFaceDetection.confidenceScore (1 - afstand tot het dichtstbij-
   zijnde gezichtsprofiel), berekend op het moment van suggereren. */
.face-match-score {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.75rem;
  color: var(--brown);
}

/* ---- Trainen: kandidaat-gezichten (/people/:id/train, /children/:id/train) ---- */
.face-candidate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.face-candidate-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem;
  background: var(--yellow-lt);
  border: 1.5px solid var(--yellow);
  border-radius: var(--radius-sm);
}

.face-candidate-crop-slot {
  width: 96px;
  height: 96px;
}

.face-candidate-crop {
  width: 96px;
  height: 96px;
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--yellow);
  object-fit: cover;
}

.face-candidate-actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.3rem;
  width: 100%;
}

.face-candidate-actions .btn,
.face-candidate-actions button,
.face-candidate-actions select {
  font-size: 0.85rem;
  padding: 0.4rem 0.6rem;
}

.face-candidate-crop-slot {
  cursor: zoom-in;
}

/* Gelijkenis-score t.o.v. deze persoon ("82%") — alleen zichtbaar zodra de
   pool al op gelijkenis herrangschikt is (zie personTrainingService/
   childTrainingService.listCandidates), dus niet bij een net toegevoegd,
   nog ongetraind kind/familielid. */
.face-candidate-score {
  position: absolute;
  top: 6px;
  right: 6px;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.65rem;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--navy);
  color: var(--cream);
}

/* "Getrainde foto's"-pagina: markeert een training-sample die opvallend
   afwijkt van de rest van hetzelfde profiel (findOutlierKeys) -- puur een
   signaal om te bekijken, geen automatische afkeuring. */
.face-candidate-outlier-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.65rem;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--red);
  color: #fff;
}

/* ---- Foto-lightbox (volledige foto bekijken vanuit een uitsnede) ----
   Zelfde patroon als .age-compare-modal (children/list.ejs), maar zonder
   navigatie tussen meerdere foto's -- hier gaat het altijd om precies 1
   foto per keer openen. */
body.photo-lightbox-open {
  overflow: hidden;
}

.photo-lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

.photo-lightbox[hidden] {
  display: none;
}

.photo-lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 24, 34, 0.78);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.photo-lightbox.is-visible .photo-lightbox-backdrop {
  opacity: 1;
}

.photo-lightbox-content {
  position: relative;
  z-index: 1;
  max-width: 90vw;
  max-height: 90vh;
  opacity: 0;
  transform: scale(0.96);
  transition:
    opacity 0.2s ease,
    transform 0.2s ease;
}

.photo-lightbox.is-visible .photo-lightbox-content {
  opacity: 1;
  transform: scale(1);
}

.photo-lightbox-content img {
  display: block;
  max-width: 90vw;
  max-height: 90vh;
  border-radius: var(--radius);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
}

.photo-lightbox-close {
  position: absolute;
  top: -0.75rem;
  right: -0.75rem;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: var(--sand-lt);
  color: var(--navy);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

/* ---- Snelle tagger (/tagger) ---- */
.tagger-progress {
  font-weight: 700;
  color: var(--brown);
}

.tagger-presence {
  font-size: 0.85rem;
  color: #1f5a78;
  margin-top: -0.5rem;
}

.tagger-card {
  background: var(--cream);
  border: 1.5px solid var(--sand);
  border-radius: var(--radius-lg);
  padding: 0.75rem;
  margin-bottom: 1rem;
}

.tagger-photo {
  display: block;
  width: 100%;
  max-height: 60vh;
  object-fit: contain;
  border-radius: var(--radius-sm);
  background: var(--navy);
}

.tagger-children {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.child-tag-btn {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 1rem;
  padding: 0.65rem 1.3rem;
  border-radius: var(--radius-pill);
  border: 2px solid var(--sand);
  background: var(--cream);
  color: var(--navy);
  cursor: pointer;
  transition:
    transform var(--dur-fast) var(--ease-spring),
    background-color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
}

.child-tag-btn:active {
  transform: scale(0.94);
}

.child-tag-btn.suggested {
  border-color: var(--yellow);
}

.child-tag-btn.active {
  background: var(--navy);
  border-color: var(--navy);
  color: #fff;
}

/* ---- Andere familieleden in de tagger: bewust kleiner/rustiger dan de
   kind-knoppen hierboven — kinderen blijven de primaire workflow. ---- */
.tagger-section-label {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.8rem;
  color: var(--brown);
  margin: 0 0 0.4rem;
}

.tagger-people {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1.25rem;
}

.person-tag-btn {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  padding: 0.5rem 1rem;
  border-radius: var(--radius-pill);
  border: 2px solid var(--sand);
  background: var(--cream);
  color: var(--navy);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-spring);
}

.person-tag-btn:active {
  transform: scale(0.94);
}

.person-tag-btn.suggested {
  border-color: var(--yellow);
}

.person-tag-btn.active {
  background: var(--brown);
  border-color: var(--brown);
  color: #fff;
}

.tagger-actions {
  display: flex;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.tagger-actions button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.tagger-hint {
  font-size: 0.85rem;
  color: var(--brown);
}

.tagger-empty {
  text-align: center;
  padding: 3rem 1rem;
}

/* ---- Vergelijk op leeftijd (kinderenpagina) ---- */
.age-compare {
  margin-bottom: 1.75rem;
}

.age-compare-title {
  margin-bottom: 0.6rem;
}

.age-compare-strip {
  display: flex;
  gap: 0.9rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  padding: 0.25rem 0.25rem 1rem;
  margin: 0 -0.25rem;
}

.age-compare-card {
  flex-shrink: 0;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  min-width: 168px;
  background: var(--surface);
  border: 1.5px solid var(--sand);
  border-radius: var(--radius-lg);
  padding: 0.9rem 0.75rem 1rem;
  box-shadow: var(--shadow-sm);
  transition:
    transform var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

.age-compare-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.age-compare-label {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.8rem;
  padding: 0.35rem 1rem;
  border-radius: var(--radius-pill);
  background: var(--gold);
  color: #fff;
  border: none;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-spring);
}

.age-compare-label:active {
  transform: scale(0.94);
}

@media (hover: hover) {
  .age-compare-label:hover {
    filter: brightness(1.06);
  }
}

.age-compare-photos {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: center;
}

.age-compare-photo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  width: 68px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
}

.age-compare-photo img {
  width: 68px;
  height: 68px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  border: 2px solid var(--sand-lt);
  transition: border-color var(--dur) var(--ease);
}

.age-compare-photo:hover img {
  border-color: var(--gold);
}

.age-compare-child-name {
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--navy);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

body.age-compare-open {
  overflow: hidden;
}

.age-compare-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1rem;
}

/* Een class-selector met `display` heeft dezelfde specificiteit als de
   standaard-`[hidden] { display: none }` van de browser, en auteur-CSS wint
   dan altijd van die UA-regel — zonder deze regel bleef de modal dus een
   onzichtbare, volledig-scherm laag die alle klikken/scrollen op de hele
   pagina onderschepte, óók terwijl het hidden-attribuut nog stond. */
.age-compare-modal[hidden] {
  display: none;
}

.age-compare-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 24, 34, 0.78);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}

.age-compare-modal.is-visible .age-compare-modal-backdrop {
  opacity: 1;
}

.age-compare-modal-content {
  position: relative;
  z-index: 1;
  max-width: 720px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--cream);
  border-radius: var(--radius-lg);
  padding: 2rem 1.5rem 1.75rem;
  text-align: center;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: scale(0.96);
  transition:
    opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}

.age-compare-modal.is-visible .age-compare-modal-content {
  opacity: 1;
  transform: scale(1);
}

.age-compare-modal-close {
  position: absolute;
  top: 0.75rem;
  right: 0.85rem;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: var(--sand-lt);
  color: var(--navy);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

.age-compare-modal-age {
  font-size: clamp(1.3rem, 3vw, 1.7rem);
  margin: 0 0 1.25rem;
}

.age-compare-modal-photos {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  justify-content: center;
}

.age-compare-modal-figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  width: 220px;
}

.age-compare-modal-figure img {
  width: 220px;
  height: 220px;
  border-radius: var(--radius);
  object-fit: cover;
  box-shadow: var(--shadow-md);
}

.age-compare-modal-figure figcaption {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  color: var(--navy);
}

.age-compare-modal-nav {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: rgba(43, 58, 82, 0.55);
  color: #fff;
  font-size: 1.6rem;
  cursor: pointer;
  z-index: 1;
  /* Standaard onzichtbaar en niet-klikbaar: zonder dit blijven de pijlen
     zichtbaar "hangen" terwijl de achtergrond/inhoud al wegfadet bij het
     sluiten (die fade duurt 200ms, zie children-compare.js), want zonder
     eigen transition sprongen ze in één keer van zichtbaar naar weg. */
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease);
}

.age-compare-modal.is-visible .age-compare-modal-nav {
  opacity: 1;
  pointer-events: auto;
}

.age-compare-modal.is-visible .age-compare-modal-nav:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

@media (max-width: 640px) {
  .age-compare-modal {
    padding: 0.5rem;
  }

  .age-compare-modal-nav {
    width: 38px;
    height: 38px;
    font-size: 1.3rem;
  }

  .age-compare-modal-figure,
  .age-compare-modal-figure img {
    width: 150px;
    height: 150px;
  }
}

/* ==========================================================================
   New native-feeling components — settings list, chips, cards, media action
   bar, reaction row, album grid, auth shell. Used by the redesigned
   screens; kept scoped so they don't clash with the shared rules above.
   ========================================================================== */

/* ---- Grouped settings/menu list ("Meer", Instellingen) ---- */
.settings-group {
  margin-bottom: 1.5rem;
}

.settings-group-title {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
  margin: 0 0.25rem 0.5rem;
}

.settings-list {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.settings-list li + li {
  border-top: 1px solid var(--border);
}

.settings-row {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.9rem 1.1rem;
  text-decoration: none;
  color: var(--ink);
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.95rem;
  min-height: 30px;
  background: none;
  border: none;
  width: 100%;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}

.settings-row:active {
  background: var(--sand-lt);
}

.settings-row-icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-sm);
  background: var(--sand-lt);
  color: var(--brown);
}

.settings-row-icon svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.settings-row-label {
  flex: 1;
  min-width: 0;
}

.settings-row-meta {
  flex-shrink: 0;
  font-weight: 600;
  font-size: 0.8rem;
  color: var(--ink-faint);
}

.settings-row-chevron {
  flex-shrink: 0;
  color: var(--ink-faint);
  display: inline-flex;
}

.settings-row-chevron svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.settings-row.danger {
  color: var(--red);
}

.settings-row.danger .settings-row-icon {
  background: rgba(233, 106, 106, 0.14);
  color: var(--red);
}

/* ---- Album grid (native "Albums" tab look) ---- */
.album-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
}

@media (min-width: 560px) {
  .album-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.album-card {
  display: block;
  text-decoration: none;
  color: var(--ink);
  transition: transform var(--dur-fast) var(--ease);
}

.album-card:active {
  transform: scale(0.97);
}

.album-card-cover {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-lg);
  background: linear-gradient(150deg, var(--sand) 0%, var(--warm) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-sm);
  margin-bottom: 0.55rem;
  overflow: hidden;
}

.album-card-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.album-card-cover svg {
  width: 34%;
  height: 34%;
  stroke: var(--brown);
  fill: none;
  stroke-width: 1.5;
  opacity: 0.65;
}

.album-card-title {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.album-card-meta {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.75rem;
  color: var(--ink-faint);
}

/* ---- Media detail action bar + reaction chips ---- */
.media-actionbar {
  display: flex;
  gap: 0.5rem;
  margin: 0 0 1.25rem;
}

.media-actionbar form {
  margin: 0;
}

.media-actionbar-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  padding: 0.55rem 1rem;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--sand);
  background: var(--surface);
  color: var(--navy);
  cursor: pointer;
  text-decoration: none;
  box-shadow: var(--shadow-xs);
  transition: transform var(--dur-fast) var(--ease-spring);
}

.media-actionbar-btn:active {
  transform: scale(0.94);
}

.media-actionbar-btn svg {
  width: 17px;
  height: 17px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.media-actionbar-btn.is-active {
  background: var(--yellow-lt);
  border-color: var(--yellow);
  color: var(--brown);
}

.media-actionbar-btn.is-active svg {
  fill: var(--gold);
  stroke: var(--gold-dk);
}

.media-actionbar-btn.danger {
  color: var(--red);
  border-color: rgba(233, 106, 106, 0.4);
}

.reaction-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.85rem;
}

.reaction-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-pill);
  background: var(--sand-lt);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--brown);
}

.reaction-picker {
  display: flex;
  gap: 0.4rem;
  margin: 0 0 1.5rem;
}

.reaction-picker button {
  font-size: 1.2rem;
  width: 46px;
  height: 46px;
  padding: 0;
  border-radius: 50%;
  transition: transform var(--dur-fast) var(--ease-spring);
}

.reaction-picker button:active {
  transform: scale(0.85);
}

/* ---- Snel reageren rechtstreeks vanaf een tegel (tijdlijn/zoeken/
   suggesties, overal waar partials/timelineGridItems.ejs gebruikt wordt) —
   een badge op de tegel + een centrale popover met de 5 emoji, zodat
   reageren niet meer vereist dat je eerst de foto opent. ---- */
/* "button.tile-reaction" (element+klasse) i.p.v. ".tile-reaction" alleen:
   moet minstens even zwaar wegen als de generieke "button:not(.btn)"-regel
   verderop in dit bestand (die ook min-height:44px zet op mobiel) — anders
   wint die generieke resetstijl alsnog en werd dit een groot, romig blok
   zonder het bedoelde subtiele, doorschijnende badge-uiterlijk. Zelfde
   klasse bug als eerder bij .more-sheet-handle. */
button.tile-reaction {
  position: absolute;
  bottom: 6px;
  right: 6px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 22px;
  height: 22px;
  min-height: 0;
  padding: 0 6px;
  border-radius: var(--radius-pill);
  border: none;
  background: rgba(20, 26, 38, 0.4);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  color: #fff;
  font-family: 'Nunito', sans-serif;
  font-size: 0.68rem;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  opacity: 0.85;
  transition:
    transform var(--dur-fast) var(--ease-spring),
    background-color var(--dur) var(--ease),
    opacity var(--dur) var(--ease);
}

button.tile-reaction:active {
  transform: scale(0.88);
  opacity: 1;
}

.tile-reaction svg {
  width: 12px;
  height: 12px;
  stroke: #fff;
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

button.tile-reaction.is-mine {
  background: var(--gold);
  opacity: 1;
}

.tile-reaction-emoji {
  font-size: 0.78rem;
}

button.tile-reaction.tile-reaction--hero {
  bottom: 0.85rem;
  right: 0.85rem;
  height: 30px;
  min-width: 30px;
  padding: 0 0.6rem;
  font-size: 0.78rem;
}

.tile-reaction--hero svg {
  width: 15px;
  height: 15px;
}

.tile-reaction--hero .tile-reaction-emoji {
  font-size: 0.95rem;
}

.reaction-popover {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0 1rem 2rem;
}

.reaction-popover[hidden] {
  display: none;
}

@media (max-width: 720px) {
  .reaction-popover {
    padding-bottom: calc(var(--tabbar-height) + var(--safe-b) + 1rem);
  }
}

.reaction-popover-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 24, 34, 0.4);
  opacity: 0;
  border: none;
  padding: 0;
  transition: opacity var(--dur) var(--ease);
}

.reaction-popover.is-open .reaction-popover-backdrop {
  opacity: 1;
}

.reaction-popover-panel {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 0.4rem;
  background: var(--surface);
  border-radius: var(--radius-pill);
  padding: 0.55rem 0.65rem;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(10px) scale(0.94);
  transition:
    opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease-spring);
}

.reaction-popover.is-open .reaction-popover-panel {
  opacity: 1;
  transform: translateY(0) scale(1);
}

button.reaction-popover-emoji {
  width: 50px;
  height: 50px;
  min-height: 0;
  padding: 0;
  border-radius: 50%;
  border: none;
  background: var(--cream);
  font-size: 1.55rem;
  line-height: 1;
  cursor: pointer;
  transition:
    transform var(--dur-fast) var(--ease-spring),
    background-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

button.reaction-popover-emoji:active {
  transform: scale(0.85);
}

button.reaction-popover-emoji.is-active {
  background: var(--yellow-lt);
  box-shadow: 0 0 0 2px var(--gold) inset;
}

.comment-list {
  list-style: none;
  padding: 0;
  margin: 0 0 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.comment-list li {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-xs);
  padding: 0.75rem 1rem;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}

.comment-list p {
  margin: 0 0 2px;
}

/* ---- Auth screens: branded, centered onboarding shell ---- */
.auth-shell {
  max-width: 380px;
  margin: 0 auto;
  padding-top: calc(var(--safe-t) + clamp(1rem, 6vh, 3rem));
}

.auth-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.6rem;
  margin-bottom: 2rem;
}

.auth-header .brand-logo {
  width: 64px;
  height: 64px;
  border-radius: 22px;
  box-shadow: var(--shadow-md);
}

.auth-header h1 {
  margin: 0;
  font-size: 1.5rem;
}

.auth-header p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

.auth-shell form.stacked {
  max-width: none;
  box-shadow: var(--shadow-md);
}

.auth-links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
}

/* ---- Section headers used on flagship screens ---- */
.page-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.1rem;
}

.page-title-row h1 {
  margin: 0;
}

/* ---- "Meer"-tabblad als toggelbaar bottom sheet i.p.v. alleen een losse
   pagina: tikken op de tab opent een overlay-paneel, nogmaals tikken (of de
   achtergrond/handle) sluit hem weer — /more blijft daarnaast als volwaardige
   pagina bestaan (progressive enhancement: werkt ook zonder JS). ---- */
.more-sheet {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.more-sheet[hidden] {
  display: none;
}

.more-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 24, 34, 0.5);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
  border: none;
  padding: 0;
}

.more-sheet.is-open .more-sheet-backdrop {
  opacity: 1;
}

.more-sheet-panel {
  position: relative;
  width: 100%;
  max-width: 560px;
  max-height: 82vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--bg);
  border-radius: 26px 26px 0 0;
  padding: 0.5rem 1.1rem calc(1.5rem + var(--safe-b));
  box-shadow: var(--shadow-lg);
  transform: translateY(100%);
  transition: transform var(--dur) var(--ease-spring);
}

.more-sheet.is-open .more-sheet-panel {
  transform: translateY(0);
}

/* Specificiteit (element+klasse) moet minstens gelijk zijn aan de generieke
   "button:not(.btn)"-regel verderop in dit bestand — anders wint die
   generieke knopstyling (padding/min-height:44px/rand/achtergrond) alsnog
   van deze regel ondanks dat hij later in het bestand staat, en werd deze
   sluitknop een groot, leeg pilvormig blok zonder zichtbaar icoon. */
button.more-sheet-handle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  min-height: 0;
  border-radius: 50%;
  background: var(--sand-lt);
  border: none;
  margin: 0.7rem auto 1rem;
  padding: 0;
  color: var(--brown);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-spring);
}

button.more-sheet-handle:active {
  transform: scale(0.9);
}

.more-sheet-handle svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2.4;
  stroke-linecap: round;
}

body.more-sheet-open {
  overflow: hidden;
}

/* ---- Empty states ---- */
.empty-state {
  text-align: center;
  padding: 3rem 1.25rem;
  color: var(--ink-soft);
}

.empty-state-icon {
  font-size: 2.4rem;
  margin-bottom: 0.5rem;
  display: block;
}

/* ---- Verjaardagsbanner: subtiele viering bovenaan de tijdlijn als een
   kind vandaag jarig is (mediaController.timeline berekent dit puur uit de
   al opgehaalde kinderenlijst, geen extra query). Bewust rustig gehouden —
   een licht wapperend vlaggenlijntje en een zachtjes wiebelend taartje,
   geen volledige-schermbrede confetti-explosie. Respecteert de globale
   prefers-reduced-motion-regel bovenaan dit bestand. ---- */
.birthday-banner {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: linear-gradient(150deg, var(--yellow-lt) 0%, var(--sand-lt) 100%);
  padding: 1.85rem 1.25rem 1.15rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--shadow-sm);
  text-align: center;
}

.birthday-flags {
  position: absolute;
  top: 0;
  left: 0.75rem;
  right: 0.75rem;
  display: flex;
  justify-content: space-between;
}

.birthday-flags span {
  width: 0;
  height: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-top: 13px solid var(--gold);
  transform-origin: top center;
  animation: birthday-flag-sway 2.6s ease-in-out infinite;
}

.birthday-flags span:nth-child(2n) {
  border-top-color: var(--sky);
  animation-delay: 0.15s;
}

.birthday-flags span:nth-child(3n) {
  border-top-color: var(--purple);
  animation-delay: 0.3s;
}

.birthday-flags span:nth-child(4n) {
  border-top-color: var(--green);
  animation-delay: 0.45s;
}

.birthday-flags span:nth-child(5n) {
  border-top-color: var(--red);
  animation-delay: 0.6s;
}

@keyframes birthday-flag-sway {
  0%,
  100% {
    transform: rotate(-6deg);
  }
  50% {
    transform: rotate(6deg);
  }
}

.birthday-banner-icon {
  display: inline-block;
  font-size: 1.9rem;
  animation: birthday-icon-bounce 1.8s ease-in-out infinite;
}

@keyframes birthday-icon-bounce {
  0%,
  100% {
    transform: translateY(0) rotate(0deg);
  }
  50% {
    transform: translateY(-4px) rotate(-6deg);
  }
}

.birthday-banner p {
  margin: 0.4rem 0 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 1.05rem;
  color: var(--brown);
}

/* ---- Seizoensbanner (kerst/oud&nieuw/pasen) — zelfde opzet/animatie als
   .birthday-banner hierboven (deelt .birthday-flags en .birthday-banner-
   icon), alleen de kleurthema's per feest verschillen. Bepaald puur op
   datum in utils/seasonalEvents.js, geen instelbare kalender. ---- */
.seasonal-banner {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  padding: 1.85rem 1.25rem 1.15rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--shadow-sm);
  text-align: center;
}

.seasonal-banner p {
  margin: 0.4rem 0 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 1.05rem;
  color: var(--brown);
}

.seasonal-banner--christmas {
  background: linear-gradient(150deg, #fdeceb 0%, var(--cream) 100%);
}

.seasonal-banner--christmas .birthday-flags span {
  border-top-color: var(--red);
}

.seasonal-banner--christmas .birthday-flags span:nth-child(2n) {
  border-top-color: var(--green);
}

.seasonal-banner--christmas .birthday-flags span:nth-child(3n) {
  border-top-color: var(--gold);
}

.seasonal-banner--newyear {
  background: linear-gradient(150deg, var(--yellow-lt) 0%, #f3ecfb 100%);
}

.seasonal-banner--newyear .birthday-flags span {
  border-top-color: var(--purple);
}

.seasonal-banner--newyear .birthday-flags span:nth-child(2n) {
  border-top-color: var(--gold);
}

.seasonal-banner--newyear .birthday-flags span:nth-child(3n) {
  border-top-color: var(--sky);
}

.seasonal-banner--easter {
  background: linear-gradient(150deg, #eef7e5 0%, var(--yellow-lt) 100%);
}

.seasonal-banner--easter .birthday-flags span {
  border-top-color: var(--green);
}

.seasonal-banner--easter .birthday-flags span:nth-child(2n) {
  border-top-color: var(--sky);
}

.seasonal-banner--easter .birthday-flags span:nth-child(3n) {
  border-top-color: var(--yellow);
}
