/* Hotel Modern */
/* ── ../base/icons.css ── */
[class*="icon-"] {
    display: inline-block;
    mask-position: center;
    mask-size: cover;
    width: 1.5rem;
    height: 1.5rem;
}

.icon-close {
    mask-image: url(../../images/uikit-icons/close-15b2ed35fd5b392564d057667b0b9a0d.svg?vsn=d);
    width: 2.5rem;
    height: 2.5rem;
    position: absolute;
    top: 1rem;
    right: 1rem;
}

/* .icon-edit {
    mask-image: url(../../images/icon-edit-fd09267ba8328d6780bec4bad30f42d1.svg?vsn=d);
} */

.icon-edit {
    mask-image: url(../../images/uikit-icons/pencil-a0bc4622f024e5d0b964c0d88bc3a04e.svg?vsn=d);
}

/* .icon-trash {
  mask-image: url(../../images/icon-trash-5a2dc75422c229cda91d96d4758be924.svg?vsn=d);
} */

.icon-trash {
    mask-image: url(../../images/uikit-icons/trash-42b373e524cc75a4a5eaccf616d1974a.svg?vsn=d);
}

/* .icon-add {
  mask-image: url(../../images/icon-add-3b9ea3724a7707ccf99c25589622820a.svg?vsn=d);
} */

.icon-add {
    mask-image: url(../../images/uikit-icons/plus-circle-acba33e1739f4298501db3a8d3cf6c83.svg?vsn=d);
}

/* .icon-settings {
  mask-image: url(../../images/icon-settings-f41e5d259a8561a05713d3c74390bedf.svg?vsn=d);
} */

.icon-settings {
    mask-image: url(../../images/uikit-icons/cog-edf071e7a29c25f2ee97474ddee12ed0.svg?vsn=d);
}

.icon-dragdrop {
    mask-image: url(../../images/icon-dragdrop-eac16b5ae81d834c5d8f2aac330f27ef.svg?vsn=d);
}

/* .icon-map {
  mask-image: url(../../images/icon-map-a3e9a06707253aac9279437ab990fb7a.svg?vsn=d);
} */

.icon-map {
    mask-image: url(../../images/uikit-icons/folder-c1bdadcaaac975a8c14db5f6120a4a3c.svg?vsn=d);
}

.icon-save {
    mask-image: url(../../images/icon-save-53b1307ab9c827ff2685248b8a3ab2d1.svg?vsn=d);
}

/* .icon-upload {
  mask-image: url(../../images/icon-upload-141b0aa8044c1cc4b6a418e26bd81f24.svg?vsn=d);
} */

.icon-upload {
    mask-image: url(../../images/uikit-icons/upload-8c078b22af3d4d23552826ec3c9a4923.svg?vsn=d);
}

/* .icon-doc {
  mask-image: url(../../images/icon-doc-5b0508dd4595138627e3b54883b561c8.svg?vsn=d);
} */

.icon-doc {
    mask-image: url(../../images/uikit-icons/file-text-fd66c2dbd2c21d23068256aee20a9fcf.svg?vsn=d);
}

.icon-bulb {
    mask-image: url(../../images/icon-bulb-2f170032e8ea753b9a3929b78dc0debe.svg?vsn=d);
}

/* .icon-search {
  mask-image: url(../../images/icon-search-12450b69ebb01960f770962c89fba581.svg?vsn=d);
} */

.icon-search {
    mask-image: url(../../images/uikit-icons/search-331276ff568e5255f0c27f7401a42f83.svg?vsn=d);
}

.icon-pdf {
    mask-image: url(../../images/icon-pdf-05ccda42ed8dc274fb510f8421d02134.svg?vsn=d);
}

.icon-download {
    mask-image: url(../../images/icon-download-8728065eb51f5de15f128f65e0de4986.svg?vsn=d);
}

.icon-word {
    mask-image: url(../../images/icon-word-17fc9b590088d67983e1210df173fd91.svg?vsn=d);
}

.icon-spreadsheet {
    mask-image: url(../../images/icon-spreadsheet-b363c0ef1f72ee5ff3062c13d83cb582.svg?vsn=d);
}

.icon-presentation {
    mask-image: url(../../images/icon-presentation-4217e1e655f25fa4c45ee7f744b5b230.svg?vsn=d);
}

.icon-text {
    mask-image: url(../../images/icon-text-e43aaf1d6a12f4f7d5c0afccb72b51da.svg?vsn=d);
}

.icon-reset {
    mask-image: url(../../images/icon-reset-ec17cab7f8c7d0cba241e36a0d40f935.svg?vsn=d);
}

.icon-select {
    mask-image: url(../../images/icon-select-a258b1a1ca4ebe4a81f981f91cbd7b39.svg?vsn=d);
}

.icon-login {
    /* mask-image: url(../../images/icon-login-97c2c046b1b87e9622c7d2cd887e4a3d.svg?vsn=d); */
    mask-image: url(../../images/uikit-icons/sign-in-85bf50b9030faa00e8e9cfae39c43182.svg?vsn=d);
}

.icon-logout {
    /* mask-image: url(../../images/icon-login-97c2c046b1b87e9622c7d2cd887e4a3d.svg?vsn=d); */
    mask-image: url(../../images/uikit-icons/sign-out-5221d406d0ae5dd6bb5c97f85002f3b0.svg?vsn=d);
}

.icon-next,
.icon-prev {
    mask-image: url(../../images/icon-next-d5ebb7b1c570bf649b9c09682e3768cd.svg?vsn=d);
    width: 2.5rem;
    height: 2.5rem;
    position: absolute;
    top: 1rem;
    right: 1rem;
    background-color: #f7f7f7;
}

.icon-prev {
    mask-image: url(../../images/icon-prev-c2469870f4488bbe0c0f17969bda1692.svg?vsn=d);
}

.icon-facebook {
    /*mask-image: url(../../images/icon-facebook-0ec646bda14f7391ead677a4d864bb23.svg?vsn=d);*/
    mask-image: url(../../images/uikit-icons/facebook-faf81578aab860cc839780e031819bb7.svg?vsn=d);

    width: 2.5rem;
    height: 2.5rem;
    background-color: #f7f7f7;
    margin-right: 1rem;
}

.icon-instagram {
    /*mask-image: url(../../images/icon-instagram-d2205c5220672c44939b0e0261b04689.svg?vsn=d);*/
    mask-image: url(../../images/uikit-icons/instagram-a62c55f9512c8858f79a4fe9d946fb82.svg?vsn=d);

    width: 2.375rem;
    height: 2.375rem;
    background-color: #f7f7f7;
    transform: translateY(-0.0625rem);
}

.icon-bluesky {
    mask-image: url(../../images/uikit-icons/bluesky-36625b6d441269ec82248849b8efbbf0.svg?vsn=d);

    width: 2.5rem;
    height: 2.5rem;
    background-color: #f7f7f7;
}

.icon-menu {
    mask-image: url(../../images/uikit-icons/menu-dff723e996096ef0d5f09ed62bab789e.svg?vsn=d);
    width: 2.5rem;
    height: 2.5rem;
    position: absolute;
    top: 1rem;
    right: 1rem;
    z-index: 999;
}

.icon-vimeo {
    mask-image: url(../../images/icon-vimeo-1da8e35599fcd666f0392d3022a87b4f.svg?vsn=d);
    width: 2.5rem;
    height: 2.5rem;
    background-color: #f7f7f7;
}

.admin.actions .icon-close,
.modal-overlay .icon-close {
    position: static;
    width: 1.25rem;
    height: 1.25rem;
}

.icon-pay {
    mask-image: url(../../images/uikit-icons/bag-d5e2f52e4196be07c9e1fbb5bcec2b5b.svg?vsn=d);
    background-color: #fff;
}

.icon-card {
    mask-image: url(../../images/uikit-icons/credit-card-ab63a111102f56a79a129ce677ae163f.svg?vsn=d);
    background-color: #fff;
}

.icon-linkedin {
    mask-image: url(../../images/uikit-icons/linkedin-64b5270df41884fdf2d2807d1cbe0a3d.svg?vsn=d);
    background-color: #333;
}

.icon-tickets {
    mask-image: url(../../images/icon-tickets-74d316fe32e223ad34fa2f6f4cd05040.svg?vsn=d);
    background-color: currentColor;
}

/* Het kaartje/label uit de UIkit-set. Staat naast een kaartjeslink; de mask
   neemt de kleur van de tekst eromheen over. */
.icon-tag {
    mask-image: url(../../images/uikit-icons/tag-ea7b096d08dd553fcb78eda39b74c503.svg?vsn=d);
    background-color: currentColor;
}

.icon-envelope {
    mask-image: url(../../images/icon-envelope-f5c82d1cca610c68d9b2464df63d6a8a.svg?vsn=d);
}

.icon-home {
    mask-image: url(../../images/icon-home-adf455e2cb70b317d350127b93c87422.svg?vsn=d);
}

@media (width > 48rem) {
    .icon-menu {
        display: none;
    }
}


/* ── ../base/reset.css ── */
html,
body {
    width: 100%;
    min-height: 100%;
    padding: 0;
    margin: 0;
}

html {
    scrollbar-gutter: stable;
}

/* Basis fade-in.

   Alleen `opacity`, geen `transform`. Hier stond een `translateY(8px)` erbij, en
   dat brak `position: fixed` op elke pagina: zolang `<html>` een transform draagt
   is hij zélf de houder van alles wat fixed staat, en dan hangt zo'n element aan
   het document in plaats van aan het venster — het scrolt dus mee. Duurde maar
   0,2s, maar precies in de 0,2s waarin een pagina binnenkomt. */
html {
    animation: pageLoad 0.2s ease-out;
}

@keyframes pageLoad {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

/* Layout stability */
img,
video,
iframe {
    max-width: 100%;
    height: auto;
}

/* Smooth font rendering */
body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body * {
    box-sizing: border-box;
}

ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

a {
    text-decoration: none;
    color: currentColor;
}

img {
    max-width: 100%;
    height: auto;
}

p {
    margin: 1.25rem 0;
    line-height: 1.8;
}

button {
    background-color: transparent;
    border: none;
    outline: none;
    cursor: pointer;
    font-size: 1rem;
}

/* Verwijderknoppen waren links (`<a href="#" phx-click>`), en zijn nu echte
   knoppen: een handeling is geen adres, en een link naar `#` is voor een
   schermlezer en voor het toetsenbord iets anders dan hij doet. Een `<button>`
   krijgt van de browser een eigen letter, kleur en binnenruimte, waar een
   `<a>` die van zijn omgeving erft. Deze regel geeft zo'n knop dezelfde
   uitgangspositie als de link die hij was. `:where` houdt de specificiteit op
   nul: elke eigen regel van een tenant wint. Alleen met de class `als-link`,
   zodat knoppen die altijd al knop waren niet veranderen. */
:where(button.als-link) {
    font: inherit;
    color: inherit;
    letter-spacing: inherit;
    line-height: inherit;
    text-transform: inherit;
    text-align: inherit;
    padding: 0;
    margin: 0;
    background: none;
    border: 0;
}

figure {
    margin: 0;
    padding: 0;
}

blockquote {
    margin: 0;
}

/* `bestand_kiezen/1` (CoreComponents): het bestandsveld van de browser
   ("Choose file") onzichtbaar, maar wel bereikbaar met Tab; het label eromheen
   met de eigen knop opent de keuze. Hier en niet in drop.css, omdat elke
   tenant dit bestand laadt. */
.bestand-kiezen {
    position: relative;
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    cursor: pointer;
}

.bestand-kiezen-veld {
    position: absolute;
    width: 0.0625rem;
    height: 0.0625rem;
    opacity: 0;
    overflow: hidden;
    clip-path: inset(50%);
}

.bestand-kiezen-veld:focus-visible + .bestand-kiezen-knop {
    outline: 0.125rem solid currentColor;
    outline-offset: 0.125rem;
}


/* ── ../base/base.css ── */
html {
  scroll-behavior: auto;
}

body.no-scroll {
  overflow-y: hidden;
}

.outer {
  width: 100%;
  min-height: 100vh;
}

.inner {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: relative;
}

main.main {
  flex-grow: 1;
}

.wrap {
  max-width: 80rem;
  margin: auto;
  width: 100%;
}

.footer-inner {
  padding: 2rem;
  text-align: center;
}

#back-to-top {
  display: none;
  padding: 2rem 0;
}

#back-to-top.visible {
  display: flex;
  justify-content: center;
  align-items: center;
}

#back-to-top button {
  font-size: 1.125rem;
  text-decoration: underline;
}

strong + p {
  margin-top: 0;
}

.body-no-scroll {
  overflow-y: hidden;
}

.hidden {
  display: none !important;
}

@media (width < 80rem) {
  .index,
  header.header .header-inner,
  .home-productions > h2,
  .home-productions ul.cards {
    padding-left: 1rem;
    padding-right: 1rem;
  }
}

a {
  color: currentColor;
}

/* ── De gevel van een video ──────────────────────────────────────────────

   Wat er staat vóór er iets speelt: een beeld met een afspeelteken, waar de
   speler pas bij een klik in komt (VideoPoster in assets/js/hooks.js). Een
   iframe van Vimeo, YouTube of Bunny is geen plaatje maar een programma, en
   drie video's onder een voorstelling waren dus drie programma's die begonnen
   te werken zodra de pagina laadde.

   Staat hier en niet in een tenantbestand: dit is dezelfde gevel op de
   voorstellingspagina en op de film-tv index, en base.css importeert elke
   tenant. De film-tv-kaart heeft zijn eigen, specifiekere regels in
   <tenant>/base/film-tv.css; die blijven winnen.

   De maat komt van de tenant, want die had hem al voor de speler die hier
   stond: elk vel dat `.video-players iframe` een kader gaf, geeft nu ook
   `.bunny-poster-card` datzelfde kader. */

.bunny-poster-card {
  position: relative;
  display: block;
  background: #000;
  overflow: hidden;
}

/* De speler die er na de klik in komt vult de gevel, en erft niet nog eens de
   marge die de tenant aan `.video-players iframe` gaf — die zit al op het
   kader eromheen. */
.bunny-poster-card > iframe {
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  border: 0;
}

/* ── Vergroten ───────────────────────────────────────────────────────────

   Onze eigen knop voor volledig scherm, rechtsboven op het kader. De spelers
   hebben er zelf een, maar die is van hun balk afhankelijk: in de smalle kolom
   van een kamer is de speler 23.5rem breed, en dan is het pictogram van Bunny
   nauwelijks te raken en laat Vimeo het weg. Deze houdt altijd dezelfde maat.

   Hij staat er pas als de speler geladen is (`hidden` gaat er in de hook af);
   op een stilstaand beeld valt niets te vergroten. */
.video-vergroot {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  border-radius: 0.25rem;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  cursor: pointer;
}

.video-vergroot:hover,
.video-vergroot:focus-visible {
  background: rgba(0, 0, 0, 0.8);
}

/* `display: grid` hierboven wint het van de standaardregel van de browser voor
   `[hidden]`, en dan staat de knop er al op het stilstaande beeld — waar niets
   te vergroten valt. Vandaar deze regel erbij. */
.video-vergroot[hidden] {
  display: none;
}

/* Op volledig scherm vult het kader het scherm: de 16/9 die het in de pagina
   draagt zou er anders een balk omheen leggen op elk ander schermformaat. */
.bunny-poster-card:fullscreen {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  background: #000;
}

.bunny-poster-card:fullscreen > iframe {
  width: 100%;
  height: 100%;
}

.bunny-poster {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  border: 0;
  background: #000;
  position: relative;
  cursor: pointer;
}

/* `contain` en niet `cover`: het kader is liggend en een film hoeft dat niet te
   zijn. De trailer van Oer en andere tijden is 480x848, en met `cover` werd die
   op breedte volgeschaald en boven- en onderaan afgesneden — je zag het midden
   van een staand beeld. Nu staat het hele beeld erin, met zwart ernaast, en dat
   is ook precies wat de speler ná de klik laat zien: die legt een staande film
   net zo goed op zijn zwarte ondergrond. Wat je vóór de klik ziet is dus wat je
   krijgt.

   Voor een liggende bron van 16:9 — dat is verreweg het meeste — maakt het
   verschil niets uit: dan vult het beeld het kader precies. */
.bunny-poster > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Het bewegende lusje ligt óver de still in plaats van in de plaats ervan, en
   draagt `loading="lazy"` in de HTML. Dat is de hele afweging en geen detail:
   zo'n lusje is ruim een halve MB tegen ongeveer 40 kB voor een still. Nu
   staat de still er meteen en haalt de browser het lusje op zodra het kader in
   beeld komt. */
.bunny-poster > .bunny-poster-beweegt {
  position: absolute;
  inset: 0;
}

/* Wie beweging heeft afgezet krijgt de still. Het lusje wordt dan nog wel
   opgehaald — een `<img>` die je in CSS verbergt haalt de browser toch op —
   maar dat is een enkele bezoeker, en de rest van de pagina hangt er niet van
   af. */
@media (prefers-reduced-motion: reduce) {
  .bunny-poster > .bunny-poster-beweegt {
    display: none;
  }
}

/* Een schijf met een driehoek: het teken dat zegt dat hier film onder zit. De
   driehoek is getekend en geen letter — ▶ (U+25B6) is op de meeste systemen
   een kleuren-emoji, en dan staat er een oranje blokje in de schijf. */
.bunny-poster .play-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.5rem;
  height: 4.5rem;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  transition: background 0.15s, transform 0.15s;
}

/* Iets naar rechts: een driehoek weegt aan zijn platte kant, dus het
   meetkundige midden ligt links van het optische. */
.bunny-poster .play-icon::before {
  content: "";
  width: 0;
  height: 0;
  margin-left: 0.35rem;
  border-style: solid;
  border-width: 0.75rem 0 0.75rem 1.25rem;
  border-color: transparent transparent transparent currentColor;
}

.bunny-poster:hover .play-icon,
.bunny-poster:focus-visible .play-icon {
  background: rgba(0, 0, 0, 0.75);
  transform: translate(-50%, -50%) scale(1.05);
}

/* Zonder tenantregel toch een kader: 16:9 is de maat van vrijwel al het
   materiaal, en zonder hoogte klapt een gevel zonder still dicht tot een
   streep. Elke tenant die `.video-players iframe` al een eigen maat gaf,
   overschrijft dit hieronder in zijn eigen bestand. */
.video-players .bunny-poster-card {
  width: 100%;
  aspect-ratio: 16 / 9;
}

/* De rij fondsenlogo's — onder een voorstelling en op een over-ons-pagina,
   want dat is dezelfde rij. Zonder maat staat elk logo op zijn eigen
   bestandsformaat in de pagina: een svg zonder breedte vult de hele kolom, en
   drie fondsen onder elkaar zijn dan een scherm vol. Een fonds is een
   voetnoot en geen beeld, dus een rij kleine logo's.

   De hoogte is de maat en de breedte volgt: zo wegen een staand logo (het
   AFK) en een liggend (Stichting Melanie) even zwaar. `object-fit` erbij
   omdat niet elk logo een eigen formaat meebrengt — dat van Melanie heeft
   alleen een viewBox, en zonder vaste hoogte meet de browser hem op nul.
   Een tenant die de fondsen groter of anders wil, overschrijft dit in zijn
   eigen bestand; die worden ná dit bestand geladen. */
.logos ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem;
}

.logos li {
  margin: 0;
}

.logos img {
  height: 3.5rem;
  width: auto;
  max-width: 100%;
  object-fit: contain;
}


/* ── ../base/flatpickr.css ── */
.flatpickr-calendar{background:transparent;opacity:0;display:none;text-align:center;visibility:hidden;padding:0;-webkit-animation:none;animation:none;direction:ltr;border:0;font-size:14px;line-height:24px;border-radius:5px;position:absolute;width:307.875px;-webkit-box-sizing:border-box;box-sizing:border-box;-ms-touch-action:manipulation;touch-action:manipulation;background:#fff;-webkit-box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08);box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08)}.flatpickr-calendar.open,.flatpickr-calendar.inline{opacity:1;max-height:640px;visibility:visible}.flatpickr-calendar.open{display:inline-block;z-index:99999}.flatpickr-calendar.animate.open{-webkit-animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1);animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1)}.flatpickr-calendar.inline{display:block;position:relative;top:2px}.flatpickr-calendar.static{position:absolute;top:calc(100% + 2px)}.flatpickr-calendar.static.open{z-index:999;display:block}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+1) .flatpickr-day.inRange:nth-child(7n+7){-webkit-box-shadow:none !important;box-shadow:none !important}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1){-webkit-box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6;box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6}.flatpickr-calendar .hasWeeks .dayContainer,.flatpickr-calendar .hasTime .dayContainer{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.flatpickr-calendar .hasWeeks .dayContainer{border-left:0}.flatpickr-calendar.hasTime .flatpickr-time{height:40px;border-top:1px solid #e6e6e6}.flatpickr-calendar.noCalendar.hasTime .flatpickr-time{height:auto}.flatpickr-calendar:before,.flatpickr-calendar:after{position:absolute;display:block;pointer-events:none;border:solid transparent;content:'';height:0;width:0;left:22px}.flatpickr-calendar.rightMost:before,.flatpickr-calendar.arrowRight:before,.flatpickr-calendar.rightMost:after,.flatpickr-calendar.arrowRight:after{left:auto;right:22px}.flatpickr-calendar.arrowCenter:before,.flatpickr-calendar.arrowCenter:after{left:50%;right:50%}.flatpickr-calendar:before{border-width:5px;margin:0 -5px}.flatpickr-calendar:after{border-width:4px;margin:0 -4px}.flatpickr-calendar.arrowTop:before,.flatpickr-calendar.arrowTop:after{bottom:100%}.flatpickr-calendar.arrowTop:before{border-bottom-color:#e6e6e6}.flatpickr-calendar.arrowTop:after{border-bottom-color:#fff}.flatpickr-calendar.arrowBottom:before,.flatpickr-calendar.arrowBottom:after{top:100%}.flatpickr-calendar.arrowBottom:before{border-top-color:#e6e6e6}.flatpickr-calendar.arrowBottom:after{border-top-color:#fff}.flatpickr-calendar:focus{outline:0}.flatpickr-wrapper{position:relative;display:inline-block}.flatpickr-months{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flatpickr-months .flatpickr-month{background:transparent;color:rgba(0,0,0,0.9);fill:rgba(0,0,0,0.9);height:34px;line-height:1;text-align:center;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}.flatpickr-months .flatpickr-prev-month,.flatpickr-months .flatpickr-next-month{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-decoration:none;cursor:pointer;position:absolute;top:0;height:34px;padding:10px;z-index:3;color:rgba(0,0,0,0.9);fill:rgba(0,0,0,0.9)}.flatpickr-months .flatpickr-prev-month.flatpickr-disabled,.flatpickr-months .flatpickr-next-month.flatpickr-disabled{display:none}.flatpickr-months .flatpickr-prev-month i,.flatpickr-months .flatpickr-next-month i{position:relative}.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month,.flatpickr-months .flatpickr-next-month.flatpickr-prev-month{/*
      /*rtl:begin:ignore*/left:0/*
      /*rtl:end:ignore*/}/*
      /*rtl:begin:ignore*/
/*
      /*rtl:end:ignore*/
.flatpickr-months .flatpickr-prev-month.flatpickr-next-month,.flatpickr-months .flatpickr-next-month.flatpickr-next-month{/*
      /*rtl:begin:ignore*/right:0/*
      /*rtl:end:ignore*/}/*
      /*rtl:begin:ignore*/
/*
      /*rtl:end:ignore*/
.flatpickr-months .flatpickr-prev-month:hover,.flatpickr-months .flatpickr-next-month:hover{color:#959ea9}.flatpickr-months .flatpickr-prev-month:hover svg,.flatpickr-months .flatpickr-next-month:hover svg{fill:#f64747}.flatpickr-months .flatpickr-prev-month svg,.flatpickr-months .flatpickr-next-month svg{width:14px;height:14px}.flatpickr-months .flatpickr-prev-month svg path,.flatpickr-months .flatpickr-next-month svg path{-webkit-transition:fill .1s;transition:fill .1s;fill:inherit}.numInputWrapper{position:relative;height:auto}.numInputWrapper input,.numInputWrapper span{display:inline-block}.numInputWrapper input{width:100%}.numInputWrapper input::-ms-clear{display:none}.numInputWrapper input::-webkit-outer-spin-button,.numInputWrapper input::-webkit-inner-spin-button{margin:0;-webkit-appearance:none}.numInputWrapper span{position:absolute;right:0;width:14px;padding:0 4px 0 2px;height:50%;line-height:50%;opacity:0;cursor:pointer;border:1px solid rgba(57,57,57,0.15);-webkit-box-sizing:border-box;box-sizing:border-box}.numInputWrapper span:hover{background:rgba(0,0,0,0.1)}.numInputWrapper span:active{background:rgba(0,0,0,0.2)}.numInputWrapper span:after{display:block;content:"";position:absolute}.numInputWrapper span.arrowUp{top:0;border-bottom:0}.numInputWrapper span.arrowUp:after{border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:4px solid rgba(57,57,57,0.6);top:26%}.numInputWrapper span.arrowDown{top:50%}.numInputWrapper span.arrowDown:after{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid rgba(57,57,57,0.6);top:40%}.numInputWrapper span svg{width:inherit;height:auto}.numInputWrapper span svg path{fill:rgba(0,0,0,0.5)}.numInputWrapper:hover{background:rgba(0,0,0,0.05)}.numInputWrapper:hover span{opacity:1}.flatpickr-current-month{font-size:135%;line-height:inherit;font-weight:300;color:inherit;position:absolute;width:75%;left:12.5%;padding:7.48px 0 0 0;line-height:1;height:34px;display:inline-block;text-align:center;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.flatpickr-current-month span.cur-month{font-family:inherit;font-weight:700;color:inherit;display:inline-block;margin-left:.5ch;padding:0}.flatpickr-current-month span.cur-month:hover{background:rgba(0,0,0,0.05)}.flatpickr-current-month .numInputWrapper{width:6ch;width:7ch\0;display:inline-block}.flatpickr-current-month .numInputWrapper span.arrowUp:after{border-bottom-color:rgba(0,0,0,0.9)}.flatpickr-current-month .numInputWrapper span.arrowDown:after{border-top-color:rgba(0,0,0,0.9)}.flatpickr-current-month input.cur-year{background:transparent;-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;cursor:text;padding:0 0 0 .5ch;margin:0;display:inline-block;font-size:inherit;font-family:inherit;font-weight:300;line-height:inherit;height:auto;border:0;border-radius:0;vertical-align:initial;-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.flatpickr-current-month input.cur-year:focus{outline:0}.flatpickr-current-month input.cur-year[disabled],.flatpickr-current-month input.cur-year[disabled]:hover{font-size:100%;color:rgba(0,0,0,0.5);background:transparent;pointer-events:none}.flatpickr-current-month .flatpickr-monthDropdown-months{appearance:menulist;background:transparent;border:none;border-radius:0;box-sizing:border-box;color:inherit;cursor:pointer;font-size:inherit;font-family:inherit;font-weight:300;height:auto;line-height:inherit;margin:-1px 0 0 0;outline:none;padding:0 0 0 .5ch;position:relative;vertical-align:initial;-webkit-box-sizing:border-box;-webkit-appearance:menulist;-moz-appearance:menulist;width:auto}.flatpickr-current-month .flatpickr-monthDropdown-months:focus,.flatpickr-current-month .flatpickr-monthDropdown-months:active{outline:none}.flatpickr-current-month .flatpickr-monthDropdown-months:hover{background:rgba(0,0,0,0.05)}.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month{background-color:transparent;outline:none;padding:0}.flatpickr-weekdays{background:transparent;text-align:center;overflow:hidden;width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:28px}.flatpickr-weekdays .flatpickr-weekdaycontainer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}span.flatpickr-weekday{cursor:default;font-size:90%;background:transparent;color:rgba(0,0,0,0.54);line-height:1;margin:0;text-align:center;display:block;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;font-weight:bolder}.dayContainer,.flatpickr-weeks{padding:1px 0 0 0}.flatpickr-days{position:relative;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;width:307.875px}.flatpickr-days:focus{outline:0}.dayContainer{padding:0;outline:0;text-align:left;width:307.875px;min-width:307.875px;max-width:307.875px;-webkit-box-sizing:border-box;box-sizing:border-box;display:inline-block;display:-ms-flexbox;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-wrap:wrap;-ms-flex-pack:justify;-webkit-justify-content:space-around;justify-content:space-around;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}.dayContainer + .dayContainer{-webkit-box-shadow:-1px 0 0 #e6e6e6;box-shadow:-1px 0 0 #e6e6e6}.flatpickr-day{background:none;border:1px solid transparent;border-radius:150px;-webkit-box-sizing:border-box;box-sizing:border-box;color:#393939;cursor:pointer;font-weight:400;width:14.2857143%;-webkit-flex-basis:14.2857143%;-ms-flex-preferred-size:14.2857143%;flex-basis:14.2857143%;max-width:39px;height:39px;line-height:39px;margin:0;display:inline-block;position:relative;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flatpickr-day.inRange,.flatpickr-day.prevMonthDay.inRange,.flatpickr-day.nextMonthDay.inRange,.flatpickr-day.today.inRange,.flatpickr-day.prevMonthDay.today.inRange,.flatpickr-day.nextMonthDay.today.inRange,.flatpickr-day:hover,.flatpickr-day.prevMonthDay:hover,.flatpickr-day.nextMonthDay:hover,.flatpickr-day:focus,.flatpickr-day.prevMonthDay:focus,.flatpickr-day.nextMonthDay:focus{cursor:pointer;outline:0;background:#e6e6e6;border-color:#e6e6e6}.flatpickr-day.today{border-color:#959ea9}.flatpickr-day.today:hover,.flatpickr-day.today:focus{border-color:#959ea9;background:#959ea9;color:#fff}.flatpickr-day.selected,.flatpickr-day.startRange,.flatpickr-day.endRange,.flatpickr-day.selected.inRange,.flatpickr-day.startRange.inRange,.flatpickr-day.endRange.inRange,.flatpickr-day.selected:focus,.flatpickr-day.startRange:focus,.flatpickr-day.endRange:focus,.flatpickr-day.selected:hover,.flatpickr-day.startRange:hover,.flatpickr-day.endRange:hover,.flatpickr-day.selected.prevMonthDay,.flatpickr-day.startRange.prevMonthDay,.flatpickr-day.endRange.prevMonthDay,.flatpickr-day.selected.nextMonthDay,.flatpickr-day.startRange.nextMonthDay,.flatpickr-day.endRange.nextMonthDay{background:#569ff7;-webkit-box-shadow:none;box-shadow:none;color:#fff;border-color:#569ff7}.flatpickr-day.selected.startRange,.flatpickr-day.startRange.startRange,.flatpickr-day.endRange.startRange{border-radius:50px 0 0 50px}.flatpickr-day.selected.endRange,.flatpickr-day.startRange.endRange,.flatpickr-day.endRange.endRange{border-radius:0 50px 50px 0}.flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n+1)),.flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n+1)),.flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n+1)){-webkit-box-shadow:-10px 0 0 #569ff7;box-shadow:-10px 0 0 #569ff7}.flatpickr-day.selected.startRange.endRange,.flatpickr-day.startRange.startRange.endRange,.flatpickr-day.endRange.startRange.endRange{border-radius:50px}.flatpickr-day.inRange{border-radius:0;-webkit-box-shadow:-5px 0 0 #e6e6e6,5px 0 0 #e6e6e6;box-shadow:-5px 0 0 #e6e6e6,5px 0 0 #e6e6e6}.flatpickr-day.flatpickr-disabled,.flatpickr-day.flatpickr-disabled:hover,.flatpickr-day.prevMonthDay,.flatpickr-day.nextMonthDay,.flatpickr-day.notAllowed,.flatpickr-day.notAllowed.prevMonthDay,.flatpickr-day.notAllowed.nextMonthDay{color:rgba(57,57,57,0.3);background:transparent;border-color:transparent;cursor:default}.flatpickr-day.flatpickr-disabled,.flatpickr-day.flatpickr-disabled:hover{cursor:not-allowed;color:rgba(57,57,57,0.1)}.flatpickr-day.week.selected{border-radius:0;-webkit-box-shadow:-5px 0 0 #569ff7,5px 0 0 #569ff7;box-shadow:-5px 0 0 #569ff7,5px 0 0 #569ff7}.flatpickr-day.hidden{visibility:hidden}.rangeMode .flatpickr-day{margin-top:1px}.flatpickr-weekwrapper{float:left}.flatpickr-weekwrapper .flatpickr-weeks{padding:0 12px;-webkit-box-shadow:1px 0 0 #e6e6e6;box-shadow:1px 0 0 #e6e6e6}.flatpickr-weekwrapper .flatpickr-weekday{float:none;width:100%;line-height:28px}.flatpickr-weekwrapper span.flatpickr-day,.flatpickr-weekwrapper span.flatpickr-day:hover{display:block;width:100%;max-width:none;color:rgba(57,57,57,0.3);background:transparent;cursor:default;border:none}.flatpickr-innerContainer{display:block;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden}.flatpickr-rContainer{display:inline-block;padding:0;-webkit-box-sizing:border-box;box-sizing:border-box}.flatpickr-time{text-align:center;outline:0;display:block;height:0;line-height:40px;max-height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flatpickr-time:after{content:"";display:table;clear:both}.flatpickr-time .numInputWrapper{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;width:40%;height:40px;float:left}.flatpickr-time .numInputWrapper span.arrowUp:after{border-bottom-color:#393939}.flatpickr-time .numInputWrapper span.arrowDown:after{border-top-color:#393939}.flatpickr-time.hasSeconds .numInputWrapper{width:26%}.flatpickr-time.time24hr .numInputWrapper{width:49%}.flatpickr-time input{background:transparent;-webkit-box-shadow:none;box-shadow:none;border:0;border-radius:0;text-align:center;margin:0;padding:0;height:inherit;line-height:inherit;color:#393939;font-size:14px;position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.flatpickr-time input.flatpickr-hour{font-weight:bold}.flatpickr-time input.flatpickr-minute,.flatpickr-time input.flatpickr-second{font-weight:400}.flatpickr-time input:focus{outline:0;border:0}.flatpickr-time .flatpickr-time-separator,.flatpickr-time .flatpickr-am-pm{height:inherit;float:left;line-height:inherit;color:#393939;font-weight:bold;width:2%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.flatpickr-time .flatpickr-am-pm{outline:0;width:18%;cursor:pointer;text-align:center;font-weight:400}.flatpickr-time input:hover,.flatpickr-time .flatpickr-am-pm:hover,.flatpickr-time input:focus,.flatpickr-time .flatpickr-am-pm:focus{background:#eee}.flatpickr-input[readonly]{cursor:pointer}@-webkit-keyframes fpFadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes fpFadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}

/* ── ../base/image-library-modal.css ── */
/* ── brandpunt.css ── */
/* De brandpuntkiezer (KaapkunstvlijtWeb.BrandpuntKiezer).
   Geïmporteerd via base/image-library-modal.css, dat elke tenant al laadt.
   Het venster staat in een portal onder <body>, dus deze regels hangen niet
   aan een formulier of aan de beeldbank. Systeemkleuren (Canvas, CanvasText)
   zodat het venster in elk beheer leesbaar is zonder een eigen palet. */

.brandpunt-open {
  font: inherit;
  font-size: 0.875rem;
  padding: 0.25rem 0;
  border: 0;
  background: none;
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
}

.brandpunt-laag {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: grid;
  place-items: center;
  padding: 1rem;
}

.brandpunt-achtergrond {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
}

.brandpunt-venster {
  position: relative;
  width: min(64rem, 100%);
  max-height: calc(100vh - 2rem);
  overflow: auto;
  padding: 1.25rem;
  background: Canvas;
  color: CanvasText;
  border-radius: 0.5rem;
  box-shadow: 0 0.5rem 2rem rgba(0, 0, 0, 0.3);
}

.brandpunt-venster header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.brandpunt-venster h2 {
  margin: 0;
  font-size: 1.25rem;
}

.brandpunt-sluit {
  font-size: 1.5rem;
  line-height: 1;
  padding: 0.25rem 0.5rem;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}

.brandpunt-uitleg {
  margin: 0.5rem 0 1rem;
  font-size: 0.9rem;
}

.brandpunt-werk {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: 1.25rem;
  align-items: start;
}

/* De knop krimpt om de foto heen, zodat een klik op de knop ook een klik op
   de foto is: de hook rekent in procenten van het beeld zelf. Geen
   object-fit hier, anders klopt die rekensom niet meer. `fit-content` met
   een `max-width` houdt de knop zo breed als de foto, maar nooit breder dan
   zijn kolom. */
.brandpunt-foto {
  position: relative;
  display: block;
  width: fit-content;
  max-width: 100%;
  justify-self: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: crosshair;
  line-height: 0;
}

.brandpunt-foto img {
  display: block;
  max-width: 100%;
  max-height: 60vh;
  width: auto;
  height: auto;
}

.brandpunt-foto:focus-visible {
  outline: 0.2rem solid Highlight;
  outline-offset: 0.2rem;
}

.brandpunt-stip {
  display: none;
  position: absolute;
  left: var(--bx);
  top: var(--by);
  width: 1.25rem;
  height: 1.25rem;
  margin: -0.625rem 0 0 -0.625rem;
  border: 0.2rem solid #fff;
  border-radius: 50%;
  box-shadow: 0 0 0 0.125rem rgba(0, 0, 0, 0.7);
  pointer-events: none;
}

.heeft-punt .brandpunt-stip {
  display: block;
}

.brandpunt-voorbeelden {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
  align-items: start;
}

.brandpunt-voorbeelden li {
  display: grid;
  align-content: start;
  gap: 0.25rem;
  font-size: 0.8rem;
}

/* `--verhouding` zet de component; een staand voorbeeld wordt niet hoger dan
   11rem, een liggend vult de kolom. */
.brandpunt-kader {
  width: min(100%, calc(11rem * var(--verhouding, 1)));
  overflow: hidden;
  background: rgba(127, 127, 127, 0.2);
}

.brandpunt-kader img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--brandpunt, 50% 50%);
}

.brandpunt-venster footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1rem;
}

.brandpunt-stand {
  margin: 0 auto 0 0;
  font-size: 0.9rem;
}

.brandpunt-wis,
.brandpunt-klaar {
  font: inherit;
  padding: 0.4rem 0.9rem;
  border: 0.0625rem solid currentColor;
  border-radius: 0.25rem;
  background: none;
  color: inherit;
  cursor: pointer;
}

.brandpunt-klaar {
  background: CanvasText;
  color: Canvas;
}

@media (max-width: 48rem) {
  .brandpunt-werk {
    grid-template-columns: 1fr;
  }
}



.modal-overlay,
.gallery-upload {
  border-top: none !important;
  position: fixed;
  width: 100vw;
  height: 100vh;
  top: 0;
  left: 0;
  z-index: 1000;
  padding: 2rem 2rem 0 2rem;
  box-shadow: 0 0 2rem rgba(0, 0, 0, 0.15);
  inset: 0;
  overflow-y: auto;
}

.modal-overlay header button.button {
  position: fixed;
  left: 80%;
  top: unset;
  bottom: 2rem;
  z-index: 1000;
}

/* Uploadblokken van de bibliotheken staan standaard uit. Ze bevatten zelf een
   `<form>`, en op de meeste schermen wordt de bibliotheek gerenderd bínnen een
   nog openstaand formulier; genest gooit de browser de binnenste weg en
   verstuurt de knop het formulier eromheen.

   Een scherm dat zijn modal buiten dat formulier tekent, zet het blok aan
   (`allow_uploads={true}` op het component). Zo volgen de overige schermen één
   één, zonder dat er ondertussen een knop staat die stilletjes het verkeerde
   doet. */
.upload-section {
  display: none;
}

.upload-section.upload-enabled {
  display: block;
}

.modal-content {
  position: relative;
  max-width: 90rem;
  margin: auto;
}

/* De voet van het videovenster: de stand links, de klaar-knop rechts. Plakt
   onderaan, want de lijst erboven kan lang zijn en dan moet die knop niet
   onder in de scroll verdwijnen — hij is het antwoord op "en nu?". */
.video-bibliotheek-voet {
    position: sticky;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    margin-top: 1.5rem;
    padding: 1rem 0;
    background: inherit;
}

.video-bibliotheek-stand {
    margin: 0;
    font-size: 0.875rem;
}

/* De kop van een bibliotheekvenster: titel links, kruisje rechts, op één regel.
   Alleen de eigen kop van het venster — de bibliotheek zelf heeft er binnenin
   nog een (`.image-library-header`) met het zoekveld erin, en die moet blijven
   zoals hij is. Vandaar de kindselectors. */
.modal-overlay > .wrap > header,
.modal-overlay > .modal-content > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

/* Het kruisje van dat venster. De kleur staat hier omdat een pictogram een
   masker is: het is precies zo zichtbaar als zijn achtergrondkleur.
   `base/admin-delfts-blauw.css` zet elk pictogram in een modal op wit
   (`.modal-overlay [class*="icon-"]`) én de modal zelf ook — op elke tenant
   behalve Hotel Modern, dat zijn eigen inktregel heeft, was dit kruisje dus wit
   op wit. Met `currentColor` volgt het de kop ernaast en klopt het overal. */
.modal-overlay > .wrap > header > .icon-close,
.modal-overlay > .modal-content > header > .icon-close {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  background-color: currentColor;
  opacity: 0.6;
  transition: opacity 0.15s ease;
}

.modal-overlay > .wrap > header > .icon-close:hover,
.modal-overlay > .modal-content > header > .icon-close:focus-visible {
  opacity: 1;
}

.image-options .button,
.document-options .button,
.gallery-actions .button,
.modal-actions .button {
  position: static;
  transform: translateX(0);
  margin-bottom: 0.5rem;
}

.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  border: 0.25rem solid #fff;
  background-color: #fff;
}

form#production-form {
  position: relative;
}

.image-grid .image-thumbnail {
  border-radius: 0.5rem 0.5rem 0 0;
}

.image-grid .image-thumbnail img {
  height: 20rem;
  object-fit: cover;
  width: 100%;
}

.image-grid .image-item,
.document-grid .document-item {
  position: relative;
  overflow: hidden;
  border: 0.25rem solid #fff;
  border-radius: 0.25rem;
  transition: transform 0.5s;
}

.image-grid .image-item.selected,
.image-grid .image-item.gallery-selected {
  transform: scale(1.025);
  box-shadow: 0 0 1rem rgba(0, 0, 0, 0.25);
  transition: transform 0.5s ease-out;
}

.image-grid .image-item img:focus-visible {
  opacity: 0.925;
  scale: 0.9;
}

.document-grid .document-item {
  transition: all 0.5s;
}

@media (hover: hover) {
  .image-grid .image-item img:hover,
  .document-grid .document-item:hover {
    cursor: pointer;
    opacity: 0.85;
    scale: 1.0125;
    transition: all 0.3s;
  }

  .document-grid .document-item:hover {
    box-shadow: 0 0 1rem rgba(0, 0, 0, 0.25);
  }
}

.image-grid .image-item .image-info,
.image-grid .image-item .image-actions {
  padding: 1rem;
}

.image-library-header {
  padding: 1rem 0 2rem;
}

p.image-alt-text {
  display: flex;
  text-align: center;
}

p.image-alt-text span {
  margin-right: 0.25rem;
}

.image-library .gallery-selection-info {
  padding: 0.5rem;
  border-radius: 0.25rem;
  margin-top: 3rem;
  text-align: center;
}

/* De bibliotheek kan meters lang zijn. Stonden de knoppen onderaan, dan moest
   wie boven in de lijst een foto aanklikte eerst helemaal naar beneden scrollen
   om die keuze te bevestigen. Ze liggen nu onderin het venster, boven de foto's,
   met een dekkende achtergrond zodat er niets doorheen schuift. */
.image-library-footer.actions {
  position: sticky;
  bottom: 0;
  z-index: 3;
  display: flex;
  /* `footer.actions` is elders een zwevend balkje met `width: fit-content`;
     hier moet de balk over de volle breedte van de bibliotheek liggen. */
  width: auto;
  gap: 1rem;
  padding: 1.25rem 0;
  border-top: 0.0625rem solid rgba(0, 0, 0, 0.1);
  justify-content: center;
  margin-top: 2rem;
  background: var(--admin-white, #fff);
}

.image-library-footer.actions .button {
  transform: translateX(0);
}

.admin section.gallery-upload {
  margin: 0;
  padding-top: 8rem;
}

.admin section.gallery-upload .wrap {
  background-color: rgba(255, 255, 255, 0.5);
  padding: 3rem;
}

.admin section.gallery-upload .wrap .drop {
  display: grid;
  grid-template-columns: 1fr 2fr;
}

.admin section.gallery-upload .wrap .drop span {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgb(255 152 0 / 30%);
  height: 12rem;
  width: 100%;
  border-radius: 0.5rem;
}

#gallery-upload-section > div > ul.entry-list {
  margin: 4rem 0 2rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 1rem;
  padding: 3rem 1rem;
  border: 0.0625rem solid #999;
  border-radius: 0.0625rem;
}

#gallery-upload-section > div > ul.entry-list li {
  height: 100%;
}

.selection-indicator {
  position: absolute;
  top: 0.375rem;
  right: 0.375rem;
  /* background: #3b82f6; */
  color: white;
  border-radius: 50%;
  width: 1.5rem;
  height: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.125rem;
}

/* ── Zoeken ──────────────────────────────────────────────────────────

   Eén regel met een streep eronder, geen invulvak. Het zoekveld stond als
   formulierveld aangekleed — vol kader, ruime binnenmarge en het vergrootglas
   van 2,25rem half over de rechterrand geschoven — terwijl er hier niets in te
   vullen valt: je typt en het raster reageert meteen. De streep zegt dat
   genoeg, en het pictogram staat links, waar je begint te lezen.

   De lange selector hieronder is nodig, niet sierlijk. `base/form.css` geeft
   elke `input` een placeholder van 1,125rem met 0,25rem letterspatiëring (dat
   was de uitgerekte "z o e k  f o t o's") en witte tekstkleur, en
   `base/admin-delfts-blauw.css` legt daar met `.index.admin.wrap
   input[type="text"]` het blauwe kader overheen. Die laatste weegt vier
   klassen; de importvolgorde verschilt per tenant, dus om er overal bovenuit te
   komen moet deze er vijf hebben. */

.modal-overlay header .search-section {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  max-width: 26rem;
  margin: 1.5rem 0 2rem;
  padding-bottom: 0.35rem;
  border-bottom: 0.0625rem solid currentColor;
  opacity: 0.75;
  transition: opacity 0.15s ease;
}

/* Focus zit in de streep, niet in een kader eromheen: hij wordt voller en
   dikker. De binnenmarge krimpt met de dikte mee, anders springt de regel een
   pixel omhoog zodra je erin klikt. */
.modal-overlay header .search-section:focus-within {
  opacity: 1;
  padding-bottom: 0.2875rem;
  border-bottom-width: 0.125rem;
}

.modal-overlay .image-library .image-library-header .search-section input.library-search {
  flex: 1;
  min-width: 0;
  width: auto;
  padding: 0.35rem 0;
  margin: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font-size: 0.95rem;
  letter-spacing: normal;
}

/* Twee lagen focusversiering wegnemen: `base/form.css` legt er een grijze
   outline omheen en `base/admin-delfts-blauw.css` daar nog een blauwe
   box-shadow overheen. Samen tekenden ze precies het kader dat we hierboven
   net hadden weggehaald. De focus blijft zichtbaar in de streep eronder. */
.modal-overlay
  .image-library
  .image-library-header
  .search-section
  input.library-search:focus {
  outline: none;
  box-shadow: none;
}

.modal-overlay
  .image-library
  .image-library-header
  .search-section
  input.library-search::placeholder {
  padding: 0;
  color: inherit;
  opacity: 0.6;
  font-size: 0.95rem;
  letter-spacing: normal;
  text-transform: none;
}

.modal-overlay header h4 {
  font-size: 1.125rem;
  letter-spacing: 0.125rem;
  color: var(--color-red);
  display: none;
}

/* Links van het veld in plaats van eroverheen: de flexvolgorde draait het om,
   zodat de markup (eerst de input, dan het icoon) ongemoeid blijft. */
.modal-overlay header .icon-search {
  order: -1;
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  transform: none;
  background-color: currentColor;
}

/* ── Wat er onder een miniatuur staat ────────────────────────────────
   Drie regels met drie rollen, en die moeten uit elkaar te houden zijn:
   de fotograaf (credit), waar de foto hangt (gebruik) en wat erop staat
   (alt-tekst). Ze verschillen in gewicht, niet in kleurtje. */

.image-grid .image-item .image-credit {
  font-weight: 600;
}

.image-grid .image-item .image-credit.missing {
  font-weight: 400;
  opacity: 0.55;
}

/* Het gebruik is een vindmiddel, geen inhoud: kleiner, en het mag niet over
   twee regels uitlopen op een kaart die al vol staat. */
.image-grid .image-item .image-usage {
  font-size: 0.8rem;
  opacity: 0.7;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.image-grid .image-item .image-alt-text {
  font-style: italic;
  opacity: 0.8;
}
/* ── De bibliotheek als fotowand ─────────────────────────────────────

   Het uiterlijk van de kaarten staat in base/gallery.css, gedeeld met de
   sorteerbare galerij van het productieformulier: het zijn twee schermen met
   dezelfde inhoud, dus ze horen er hetzelfde uit te zien. Hier blijft alleen
   staan wat de bibliotheek eigen is — het wegnemen van de witte omlijsting
   waarin de grid vroeger was gevat. */

.image-grid.masonry {
  border: none;
}

.image-grid.masonry .image-item {
  border: none;
  overflow: visible;
}

/* ── Credits in bulk ─────────────────────────────────────────────────

   Een fotograaf schiet zelden één foto: de credits komen in series binnen, en
   dan is één naam op een hele selectie zetten het verschil tussen een handeling
   en een middag klikken. Vandaar het filter op wat nog leeg is, het aanvinken
   in de beheerstand, en de balk onderaan. */

.library-filter {
  margin: 0 0 1rem;
}

.library-filter-toggle {
  padding: 0.3rem 0.7rem;
  border: 0.0625rem solid currentColor;
  border-radius: 1rem;
  background: none;
  color: inherit;
  font-size: 0.8rem;
  font-variant: all-small-caps;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.15s ease;
}

.library-filter-toggle:hover,
.library-filter-toggle.on {
  opacity: 1;
}

/* Aangevinkt staat hetzelfde in beeld als gekozen in de andere standen: één
   taal voor "deze bedoel ik". */
.image-grid .image-item.bulk-selected {
  transform: scale(1.025);
  box-shadow: 0 0 1rem rgba(0, 0, 0, 0.25);
}

.bulk-credit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

.bulk-credit-count {
  font-variant: all-small-caps;
  white-space: nowrap;
}

.bulk-credit input {
  width: 18rem;
  margin: 0;
}

.bulk-notice,
.bulk-credit button:not(.button) {
  margin: 0;
  background: none;
  border: none;
  color: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  opacity: 0.7;
}

/* ── Placeholders ────────────────────────────────────────────────────

   `base/form.css` geeft elke placeholder 1,125rem met 0,25rem letterspatiëring
   en een eigen binnenmarge. Dat is gemaakt voor de grote velden van een
   invulformulier; in de kleine velden van de bibliotheek schreeuwt het harder
   dan de ingevulde tekst zelf. Hier dus mee in de pas met de invoer, en
   gedempt — een placeholder is een aanwijzing, geen inhoud. */

.image-library ::placeholder,
.modal-overlay .bulk-credit ::placeholder {
  padding: 0;
  font-size: inherit;
  letter-spacing: normal;
  text-transform: none;
  color: inherit;
  opacity: 0.45;
}

/* De miniatuur is een knop (kiezen met het toetsenbord) en geen klikbare
   `div` meer; zonder deze regel kreeg hij de binnenruimte, rand en achtergrond
   van een browserknop. */
.image-grid button.image-thumbnail {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.image-grid button.image-thumbnail:disabled {
  cursor: default;
}

/* De documentbibliotheek: de titel is de knop waarmee je kiest, en zijn
   `::after` legt een klikvlak over de hele kaart (die staat op
   `position: relative`). De beheerknoppen liggen erboven. */
.document-grid .document-kies {
  /* `.document-item button` (base/documents.css) is bedoeld voor de
     beheerknoppen en maakt elke knop een flexblok; de titel hoort in de regel. */
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-align: inherit;
  cursor: pointer;
}

.document-grid .document-kies::after {
  content: "";
  position: absolute;
  inset: 0;
}

.document-grid .document-item .document-actions {
  position: relative;
  z-index: 1;
}


/* ── ../base/img-panel.css ── */
.img-panel {
    background-color: #ccc;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: flex-end;
    position: relative;
    object-fit: cover;
    object-position: top;
    aspect-ratio: 9/10;
}

.img-panel figure {
    position: relative;
    width: 100%;
    height: 100%;
}

.img-panel img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top;
}

.img-panel .panel {
    position: absolute;
    padding: clamp(1.5rem, 1.368rem + 0.702vw, 2rem)
        clamp(1.5rem, 1.368rem + 0.702vw, 2rem)
        clamp(2rem, 1.842rem + 0.842vw, 2.6rem)
        clamp(1.5rem, 1.368rem + 0.702vw, 2rem);
    width: clamp(17rem, 12.423rem + 19.531vw, 30rem);
    transform: translateY(clamp(4rem, 3.474rem + 2.807vw, 6rem));
    line-height: 1.2;
}

.img-panel .panel header {
    font-size: clamp(1.4rem, calc(1.2909rem + 0.5455vw), 1.7rem);
    margin: 0.5rem 0;
}

.img-panel .panel p {
    margin: 0.25rem 0;
}

.img-panel p.caption {
    margin: 0;
    visibility: hidden;
    height: 0;
}

.img-panel .panel a {
    text-decoration: underline;
}

.brochures-list .img-panel img {
    object-position: initial;
}

@media (width >= 48rem) {
    .img-panel {
        aspect-ratio: 8/6;
    }
}

@media (width >= 60rem) {
    .img-panel {
        aspect-ratio: 16/9;
    }
}

@media (width < 90rem) {
    .img-panel .panel {
        margin-right: 1rem;
    }
}


/* ── ../base/admin.css ── */
.admin.actions {
  display: flex;
  flex-wrap: wrap;
}

/* Banners-repeater is standaard verborgen. Tenants die banners gebruiken
   (bv. servaes) zetten hem weer aan via base/cta-banners.css, dat ná dit
   bestand geïmporteerd wordt. */
.banners-fieldset {
  display: none;
}

.index.admin:last-child {
  margin-bottom: 6rem;
}

.index.admin.wrap:last-child {
  margin-bottom: 0;
}

header .admin.actions {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 4;
  /* padding: 1rem; */
  justify-content: center;
}

.pages-table table {
  width: 100%;
  border-collapse: collapse;
  margin: 2rem 0;
  background-color: #fff;
}

.pages-table table thead tr {
  border-bottom: 0.0625rem solid #333;
  padding: 2rem;
}

.pages-table table thead tr th {
  padding: 1rem;
  text-align: left;
}

.pages-table table tbody tr td {
  padding: 1rem;
}

.ql-editor p,
.ql-editor ol,
.ql-editor ul,
.ql-editor pre,
.ql-editor blockquote,
.ql-editor h1,
.ql-editor h2,
.ql-editor h3,
.ql-editor h4,
.ql-editor h5,
.ql-editor h6 {
  margin: 1rem 0 !important;
}

section.index.productions header .admin {
  padding: 2rem 0;
}

.document-upload-section.publicity {
  display: none;
}

@media (width >= 48rem) {
  section.index.productions header .admin .button:not(:last-of-type),
  section.production-detail header .admin.actions .button,
  section.index.agenda-items header .admin.actions .button:not(:last-of-type),
  footer .actions .button:not(:last-of-type),
  .button:not(:last-of-type),
  button.button:not(:last-of-type),
  /* `:last-of-type` telt per element: een Bewerken-link naast een
     verwijderknop (`button`) is de laatste `a` en viel zo buiten de regel.
     Even zwaar als de regel erboven, zodat een tenant die zelf een marge op
     zijn knoppen zet nog steeds wint. */
  .button:not(:last-child):where(:has(~ button)) {
    margin-right: 1rem;
  }
}

@media (width < 48rem) {
  a.logout-link,
  .button.admin {
    position: static;
    transform: translateX(-5rem);
  }
}

/* Achtergrondkleur veld: standaard verborgen, alleen zichtbaar bij zusjesvandijk */
div:has(> .input-background-color) {
  display: none;
}

/* ── Fondsen bij een productie ─────────────────────────────────────────────
   Het keuzeraster hoort bij het productieformulier, dus staat het hier: dit
   bestand laadt elke tenant. Het stond eerder in een los
   base/funder-selector.css dat maar vijf van de achttien tenants
   importeerden; bij de rest viel het blok uit elkaar tot losse vinkjes met
   logo's op ware grootte ertussen.

   Het logo krijgt een vak van een vaste maat en gaat daar met `object-fit`
   in: staande logo's (het AFK) en liggende (Stichting Melanie) laten zich
   dan geen van beide oprekken. Een vak en geen losse maxima, omdat niet elk
   logo een eigen formaat meebrengt — dat van Melanie heeft alleen een
   viewBox, en die meet de browser zonder vak op nul. */
.funder-selector {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  gap: 1rem;
  background-color: #fff;
  padding: 1rem;
}

.funder-selector label {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  padding: 0.5rem;
  border-radius: 0.25rem;
  aspect-ratio: 1;
  margin-bottom: 0;
  background-color: #f7f7f7;
}

.funder-selector label.is-selected {
  background-color: #e8f5e9;
}

/* Het vinkje is een plaatje van de stand, niet de knop: de klik zit op het
   label eromheen. Zonder dit vangt het vakje zijn eigen klik op en gaat hij
   langs LiveView heen. */
.funder-selector input {
  width: 20%;
  pointer-events: none;
}

.funder-selector img {
  width: 70%;
  height: 7rem;
  object-fit: contain;
}

.funder-selector span {
  align-self: flex-end;
  display: inline-block;
  padding: 1rem;
  font-size: 0.875rem;
  text-transform: lowercase;
  letter-spacing: 0;
}

/* Sorteerbare funders */
.funder-sortable {
  list-style: none;
  padding: 0;
  margin: 0;
}

.funder-sort-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.25rem;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: grab;
}

.funder-sort-item:active {
  cursor: grabbing;
}

.funder-order-hint {
  margin: 0.75rem 0 0.5rem;
  font-size: 0.85rem;
  opacity: 0.7;
}

.funder-sort-item img {
  height: 1.5rem;
  width: auto;
}

.funder-sort-item .drag-handle {
  color: #999;
  font-size: 1rem;
  user-select: none;
}

.funder-sort-item.sortable-ghost {
  opacity: 0.4;
  background: #e8f5e9;
}

.funder-sort-item.sortable-chosen {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.location-mode-toggle {
  display: none;
}

/* Uitleg bij een veld waarvan het effect elders op de site zichtbaar wordt */
.field-note {
  font-size: 0.875rem;
  line-height: 1.5;
  color: #334155;
  background: #f1f5f9;
  border-left: 3px solid #94a3b8;
  padding: 0.75rem 1rem;
  border-radius: 0 0.375rem 0.375rem 0;
  margin: 0 0 1rem;
}

/* Wie zit er nog meer op deze pagina */
.editors-indicator {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.875rem;
  color: #92400e;
  background: #fffbeb;
  border: 1px solid #fcd34d;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  margin-bottom: 1rem;
}

.editors-indicator svg {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
}

/* Admin kijkt mee terwijl iemand anders bewerkt (read-only) */
.lock-observer {
  background: #fffbeb;
  border: 1px solid #fcd34d;
  border-left: 4px solid #f59e0b;
  color: #78350f;
  padding: 1rem 1.5rem;
  border-radius: 0.5rem;
  margin-bottom: 1.5rem;
}

.lock-observer p {
  margin: 0 0 0.5rem;
}

.lock-observer .lock-observer-caveat {
  font-size: 0.875rem;
  opacity: 0.85;
}

/* Wachtkamer: iemand anders heeft het slot, wij schuiven vanzelf door */
.lock-waiting {
  background: #f8fafc;
  border: 1px solid #cbd5e1;
  border-left: 0.25rem solid #64748b;
  color: #1e293b;
  padding: 1.5rem 1.75rem;
  border-radius: 0.5rem;
  margin-bottom: 1.5rem;
  max-width: 44rem;
}

.lock-waiting h3 {
  margin: 0 0 0.75rem;
  font-size: 1.125rem;
}

.lock-waiting p {
  margin: 0 0 0.75rem;
  line-height: 1.5;
}

.lock-waiting .lock-waiting-caveat {
  font-size: 0.875rem;
  opacity: 0.75;
}

/* Het slot was losgelaten wegens stilte en is inmiddels overgenomen */
.lock-lost {
  background: #fef2f2;
  border: 1px solid #fca5a5;
  border-left: 0.25rem solid #dc2626;
  color: #7f1d1d;
  padding: 1rem 1.5rem;
  border-radius: 0.5rem;
  margin-bottom: 1.5rem;
}

.lock-lost p {
  margin: 0 0 0.5rem;
}

.lock-lost .lock-lost-caveat {
  font-size: 0.875rem;
  opacity: 0.85;
}

/* De inerte form is niet interactief; toon dat ook visueel */
form[inert] {
  opacity: 0.7;
  filter: grayscale(0.3);
}

.form-validation-error {
  background: #fef2f2;
  border: 1px solid #fca5a5;
  border-left: 4px solid #ef4444;
  color: #991b1b;
  padding: 1rem 1.5rem;
  border-radius: 0.5rem;
  margin-bottom: 1.5rem;
  font-weight: 500;
}

/* Admin-only pricing block op publieke orderpagina */
section.ticketing.order.wrap form .admin-pricing {
  border: 0.0625rem dashed #999;
  border-radius: 0.375rem;
  padding: 0.75rem 1rem;
  margin: 1rem 0;
  background: rgba(0, 0, 0, 0.03);
}

section.ticketing.order.wrap form .admin-pricing legend {
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0 0.5rem;
  color: #555;
}

section.ticketing.order.wrap form .admin-pricing label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
  margin-bottom: 0;
  cursor: pointer;
  font-size: 0.95rem;
  font-weight: 500;
  font-family: inherit;
  text-transform: none;
  letter-spacing: normal;
  color: inherit;
}

section.ticketing.order.wrap form .admin-pricing input[type="radio"] {
  display: inline-block;
  width: auto;
  margin: 0;
  padding: 0;
  accent-color: #003078;
  flex-shrink: 0;
}

section.ticketing.order.wrap form .admin-pricing span {
  flex: 1;
}

/* Order type-badges in /admin/ticket-orders */
.order-type-badge {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-radius: 0.25rem;
  vertical-align: middle;
}

.order-type-discount_20 {
  background: #fef3c7;
  color: #92400e;
}

.order-type-free {
  background: #d1fae5;
  color: #065f46;
}

/* Andere prijzen bij een kaartverkoopmoment (CJP, student, tot 30) */
.ticket-form__prices {
  margin: 0 0 1rem;
  padding: 0;
  border: 0;
}

.ticket-form__prices legend {
  margin-bottom: 0.25rem;
  padding: 0;
  font-weight: 600;
}

.ticket-form__prices > p {
  margin: 0 0 0.75rem;
  font-size: 0.875rem;
}

.ticket-form__prices ol {
  display: grid;
  gap: 0.75rem;
  margin: 0 0 0.75rem;
  padding: 0;
  list-style: none;
}

.ticket-form__prices li {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 0.5rem 1rem;
  align-items: end;
  padding-bottom: 0.75rem;
  border-bottom: 0.0625rem solid rgba(0, 0, 0, 0.1);
}

.ticket-form__prices .ticket-form__price-note {
  grid-column: 1 / -1;
}

.ticket-form__prices li > button {
  justify-self: start;
}

/* Soorten kaarten onder het aantal, als een bestelling er meer heeft */
.order-kinds {
  display: block;
  font-size: 0.8rem;
  opacity: 0.75;
  white-space: nowrap;
}

.ticket-order-summary__breakdown {
  font-size: 0.85rem;
  color: #555;
  margin-top: 0.25rem;
}

/* Wachtlijst onder de bestellingen */
.ticket-waitlist {
  margin-top: 3rem;
}

.ticket-waitlist > p {
  max-width: 40rem;
}

/* ============================================================
   Veld-help (?) + sticky user-badge
   ============================================================ */

.help-tip {
  display: inline-block;
  box-sizing: border-box;
  width: 1.2rem;
  height: 1.2rem;
  padding: 0;
  margin: 0 0 0 0.4rem;
  border-radius: 50%;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  font-size: 0.7rem;
  font-weight: bold;
  line-height: calc(
    1.2rem - 2px
  ); /* hoogte minus 2× border, centreert ? verticaal */
  text-align: center;
  opacity: 0.5;
  cursor: pointer;
  vertical-align: middle;
  flex: 0 0 auto; /* niet krimpen binnen flex-parents */
  transition:
    opacity 0.15s,
    background-color 0.15s;
}

.help-tip:hover,
.help-tip:focus {
  opacity: 1;
  background: rgba(0, 0, 0, 0.05);
  outline: none;
}

/* Velden waarbij het label nu in een <header> staat zodat het ?-knopje
   netjes inline naast het labeltext leeft. De <.input> zelf rendert een
   (lege) <label> die we hier verbergen om dubbele witruimte te voorkomen. */
.field-with-help > div > label:empty {
  display: none;
}

.user-badge {
  position: fixed;
  top: 1.2rem;
  right: 0.8rem;
  z-index: 1000;
  padding: 0.2rem 0.6rem;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 500;
  border-radius: 999px;
  letter-spacing: 0.02em;
  pointer-events: none;
  user-select: none;
  opacity: 0.7;
  transition: opacity 0.2s;
}

.user-badge:hover {
  opacity: 1;
}

/* driver.js close-knop herstel — onze globale button-reset (background:
   transparent, border:none) sloopt de standaardweergave anders. */
.driver-popover-close-btn {
  cursor: pointer !important;
  font-size: 1.5rem !important;
  line-height: 1 !important;
  color: #444 !important;
  background: transparent !important;
  border: none !important;
  padding: 0 0.4rem !important;
}

.driver-popover-close-btn:hover {
  color: #000 !important;
}

.admin section.afterpage-link {
  padding: 2rem 1.25rem 4rem;
  background-color: #f0d5cc;
  border-left: 0.25rem solid #c44b2b;
  border-radius: 0 0.5rem 0.5rem 0;
  margin: 3rem 0;
}

.admin section.afterpage-link header {
  margin-bottom: 0.5rem;
}

.admin section.afterpage-link header p {
  margin: 0 0 0.5rem;
  font-size: 0.875rem;
}

/* ── Een veldkop met een knop ernaast ────────────────────────────────

   Voor een veld dat je op twee manieren kunt invullen: met de hand, of door
   iets te kiezen dat er al is. De knop hoort bij het veld en niet naast het
   formulier, dus het is een tekstknop en geen `.button`. */

.index.admin.wrap .veldkop {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.index.admin.wrap .veldkop label {
  margin-bottom: 0;
}

.index.admin.wrap .veldknop {
  padding: 0;
  background: none;
  border: none;
  color: var(--admin-blue, #1a4d8f);
  font-size: 0.75rem;
  text-decoration: underline;
  cursor: pointer;
}

.index.admin.wrap .veldknop:hover,
.index.admin.wrap .veldknop:focus-visible {
  color: var(--admin-blue-dark, #003078);
}

/* ── De lijst met video's die al op onze speler staan ─────────────────

   Bij Bunny is een video een GUID die op zoveel plekken mag staan als je
   wilt. Wie hetzelfde bestand twee keer uploadt krijgt dus geen tweede plek
   maar een tweede kopie — dubbele opslag, dubbele verwerking. Deze lijst is
   het alternatief, en staat op elk scherm waar een video gekozen wordt: de
   bioscoop van Hotel Modern en het productieformulier. */

.index.admin.wrap .video-bibliotheek {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

/* Het kaartje zelf houdt zijn witte bodem, nu het venster eronder grijs is.
   De ronding staat hier én op de knop: de knop draagt de rand, het kaartje het
   wit, en zonder dezelfde straal piepen er witte hoeken achter de rand uit. */
.index.admin.wrap .video-bibliotheek li {
  background: var(--admin-white, #fff);
  border-radius: var(--admin-radius, 0.375rem);
}

.index.admin.wrap .video-bibliotheek button {
  display: block;
  width: 100%;
  padding: 0;
  text-align: left;
  background: none;
  border: 0.0625rem solid var(--admin-blue-border, #b8d0eb);
  border-radius: var(--admin-radius, 0.375rem);
  overflow: hidden;
  cursor: pointer;
}

.index.admin.wrap .video-bibliotheek button:hover,
.index.admin.wrap .video-bibliotheek button:focus-visible {
  border-color: var(--admin-blue, #1a4d8f);
  background: var(--admin-blue-light, #e8f0fb);
}

.index.admin.wrap .video-bibliotheek img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: #111;
}

.index.admin.wrap .video-bibliotheek-naam {
  display: block;
  padding: 0.5rem 0.6rem 0;
  font-weight: 600;
}

.index.admin.wrap .video-bibliotheek-herkomst {
  display: block;
  padding: 0.15rem 0.6rem 0.6rem;
  color: var(--admin-text-light, #4a5568);
  font-size: 0.8rem;
  font-variant: all-small-caps;
}

/* Twee groepen in dezelfde bak: wat er los ligt en wat al ergens hangt. De
   kop is klein — hij ordent, hij kondigt niet aan. */
.index.admin.wrap .video-bibliotheek-kop {
  margin: 1.5rem 0 0;
  font-size: 0.85rem;
  font-variant: all-small-caps;
  letter-spacing: 0.05em;
  color: var(--admin-text-light, #4a5568);
}

.index.admin.wrap .video-bibliotheek-kop:first-of-type {
  margin-top: 1rem;
}

/* Twee soorten kaartjes staan er wél maar zijn niet te kiezen: een video die
   Bunny nog verwerkt (kiezen levert een leeg kaartje op) en de video die al op
   dit kaartje staat (kiezen doet niets). Allebei zichtbaar, want weglaten is
   niet te onderscheiden van "hij is er niet" — en dat is precies de conclusie
   die we willen voorkomen. Grijs en zonder aanwijzer, zodat het te zien is
   voordat je klikt; de reden staat eronder. */
.index.admin.wrap .video-bibliotheek button[disabled] {
  cursor: default;
  opacity: 0.55;
  border-style: dashed;
}

.index.admin.wrap .video-bibliotheek button[disabled]:hover,
.index.admin.wrap .video-bibliotheek button[disabled]:focus-visible {
  border-color: var(--admin-blue-border, #b8d0eb);
  background: none;
}

/* Bunny gaf geen antwoord: de lijst is dan niet compleet, en dat mag de
   redactie weten voordat ze concludeert dat hun upload weg is. */
.index.admin.wrap .video-bibliotheek-waarschuwing {
  margin: 1rem 0 0;
  padding: 0.6rem 0.75rem;
  border-left: 0.1875rem solid var(--admin-warning, #c47f00);
  background: var(--admin-warning-light, #fdf6e6);
  color: var(--admin-text, #2d3748);
  font-size: 0.9rem;
}

/* Niets te kiezen: zeg dat, in plaats van een leeg vak. */
.index.admin.wrap .video-bibliotheek-leeg {
  margin: 1rem 0 0;
  color: var(--admin-text-light, #4a5568);
  font-style: italic;
}

/* ── De kaartenbak ────────────────────────────────────────────────────

   Een lijst waarin elk item een kaartje is met een greep over de volle
   bovenrand. Begon in de bioscoop van Hotel Modern (/admin/media/bioscoop)
   en staat nu ook bij de video's van een productie, dus staat het hier: dit
   bestand importeert elke tenant, base/media-room-admin.css niet.

   Wat de kaartjes vervangen: een rij vakken over de volle breedte, waar de
   volgorde alleen te zien was door te tellen en de sleepgreep het woordje
   "Versleep" was — een tekstje dat eruitziet als een bijschrift. De greep is
   nu de hele bovenrand, en `.drag-handle` is precies wat SortableJS pakt
   (assets/js/sortable_hooks.js).

   De kleuren komen uit base/admin-delfts-blauw.css. Zeven tenants importeren
   dat thema niet, dus draagt elke variabele hier zijn eigen terugval. */

.index.admin.wrap .media-cards {
  list-style: none;
  margin: 1.5rem 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
}

.index.admin.wrap .media-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "grip"
    "velden";
  align-content: start;
  background: var(--admin-white, #ffffff);
  border: 0.0625rem solid var(--admin-blue-border, #b8d0eb);
  border-radius: var(--admin-radius, 0.375rem);
  overflow: hidden;
}

/* Niets in de bak: zeg dat, in plaats van een gat tussen de kop en de knop. */
.index.admin.wrap .media-cards-leeg {
  margin: 1.5rem 0;
  color: var(--admin-text-light, #4a5568);
  font-style: italic;
}

/* ── De greep ───────────────────────────────────────────────────────── */

/* Ribbels, een handje en het woord erbij: drie keer hetzelfde zeggen is hier
   geen ruis maar het punt — dit is de plek waar de oude opmaak op faalde. */
.index.admin.wrap .media-card-grip {
  grid-area: grip;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  background-color: var(--admin-blue-light, #e8f0fb);
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(0, 48, 120, 0.14) 0,
    rgba(0, 48, 120, 0.14) 0.0625rem,
    transparent 0.0625rem,
    transparent 0.25rem
  );
  background-position: right 5.5rem center;
  background-repeat: no-repeat;
  background-size: 2.5rem 0.8125rem;
  border-bottom: 0.0625rem solid var(--admin-blue-border, #b8d0eb);
  color: var(--admin-blue-dark, #003078);
  font-size: 0.8rem;
  cursor: grab;
  user-select: none;
}

.index.admin.wrap .media-card-grip:active {
  cursor: grabbing;
}

.index.admin.wrap .media-card-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.5rem;
  padding: 0 0.35rem;
  border-radius: 50%;
  background: var(--admin-blue-dark, #003078);
  color: var(--admin-white, #ffffff);
  font-weight: 700;
}

.index.admin.wrap .media-card-grip .icon-dragdrop {
  width: 1rem;
  height: 1rem;
  background-color: currentColor;
}

.index.admin.wrap .media-card-grip-label {
  font-variant: all-small-caps;
  letter-spacing: 0.02em;
}

/* Verwijderen hangt in dezelfde balk, rechts. Kleurt pas rood als je erheen
   gaat: het is een uitweg, geen aanbod. */
.index.admin.wrap .media-card-delete {
  position: absolute;
  top: 0.5rem;
  right: 0.75rem;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.4rem;
  background: none;
  border: none;
  color: var(--admin-text-light, #4a5568);
  font-size: 0.8rem;
  font-variant: all-small-caps;
  line-height: 1.5rem;
  cursor: pointer;
}

.index.admin.wrap .media-card-delete:hover,
.index.admin.wrap .media-card-delete:focus-visible {
  color: var(--admin-danger, #c53030);
}

.index.admin.wrap .media-card-delete .icon-trash {
  width: 0.9rem;
  height: 0.9rem;
  background-color: currentColor;
}

/* ── De velden ──────────────────────────────────────────────────────── */

.index.admin.wrap .media-card-velden {
  grid-area: velden;
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.index.admin.wrap .media-card-velden .field {
  margin: 0;
}

.index.admin.wrap .media-card-velden label {
  display: block;
  margin-bottom: 0.2rem;
  font-size: 0.75rem;
  color: var(--admin-text-light, #4a5568);
}

.index.admin.wrap .media-card-velden input[type="text"] {
  width: 100%;
}

/* De keuzeknoppen dragen hun eigen label; dat mag geen blokje worden zoals de
   labels hierboven. */
.index.admin.wrap .media-card-velden .video-type-toggle label {
  display: inline-block;
  margin: 0;
  font-size: 0.75rem;
  color: inherit;
}

/* Het sleepvak mag niet met de velden mee uitrekken: het hoort onderaan het
   kaartje te liggen, ook als de buurman hoger is. */
.index.admin.wrap .media-card-velden .bunny-upload {
  margin-top: auto;
}

/* ── Slepen ─────────────────────────────────────────────────────────── */

/* Alleen binnen de kaartenbak: `.sortable-ghost` en `.sortable-chosen` zijn
   de klassen van élke sorteerlijst in de admin (zie BASE_OPTIONS in
   assets/js/sortable_hooks.js), en de galerij en de persknipsels hebben hun
   eigen uiterlijk. */
.index.admin.wrap .media-cards .sortable-ghost {
  opacity: 0.4;
}

.index.admin.wrap .media-cards .sortable-chosen {
  box-shadow: 0 0.25rem 0.75rem rgba(0, 48, 120, 0.25);
}

/* ── Smallere schermen ──────────────────────────────────────────────── */

/* Onder de 64rem is een halve kolom te smal voor een kaartje met een
   keuzerij, een codeveld en een sleepvak: dan liever één per rij. */
@media (width < 64rem) {
  .index.admin.wrap .media-cards {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ── De sprongbalk boven het voorstellingsformulier ──────────────────────────

   Tien plekken in een formulier van vijfendertig secties. Hij blijft bovenin
   staan terwijl je scrolt, en de plek waar je bent staat aan.

   Eerst stond hij er dun en in kleinkapitalen bij, en dat viel nauwelijks op:
   hij las als een bijschrift boven het formulier in plaats van als iets waar je
   op kunt klikken. Nu is het een band met een eigen grond, in gewone letters,
   en de plek waar je bent is een wit plaatje in die band. */

/* Eén getal voor twee dingen: hoe ver een sectie onder de bovenrand parkeert
   als je erheen springt, én de lijn waarboven de hook een sectie als "hier ben
   je" telt. Stonden die apart, dan liepen ze uiteen en zette de balk na een
   sprong de sectie erbóven aan — precies de fout die dit voorkomt. De hook
   leest hem uit (`--sprong-marge` in hooks.js).

   Ruimer sinds de balk een vaste band over de volle breedte is: hij is nu
   ongeveer 3,4rem hoog, en een kop die er net onder parkeert plakt eraan
   vast. */
.index.admin.wrap {
  --sprong-marge: 5.5rem;
}

/* De balk staat vast bovenin het venster en ligt dus over de bovenkant van het
   werkblad heen. Alleen op schermen die hem hebben. */
.index.admin.wrap:has(.form-sprongbalk) {
  margin-top: 4.5rem;
}

/* Hij stond als een licht plaatje binnen het werkblad: de breedte van de kaart,
   lichtblauw op wit, letters van 0,875rem in de serif van de tenant. Dat is de
   letter van de site — mooi voor een lap tekst, bescheiden voor de enige
   navigatie van een formulier van negenduizend pixels hoog. Je keek eroverheen.

   Nu is het een band over de volle breedte van het venster, met een eigen
   donkere grond, in een schreefloze letter. Dat laatste is het halve verschil:
   een serif kan dit wel dragen, maar niet op deze maat — Noto Serif heeft 400
   en 700 en verder niets, dus "dikker" houdt daar op. Een schreefloze letter
   maakt bovendien meteen duidelijk wat dit is: geen tekst van de site maar het
   gereedschap eromheen. Dezelfde scheiding die elk besturingssysteem maakt.

   Vast en niet plakkend: hij hoort altijd te staan, ook bovenaan de pagina. Het
   werkblad schuift er met een bovenmarge onderuit (zie `--sprong-marge`
   hierboven). */
.form-sprongbalk {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 900;
  background-color: var(--admin-blue-dark, #003078);
  box-shadow: 0 0.125rem 0.75rem rgba(0, 0, 0, 0.25);
  /* De letter van het gereedschap, niet die van de site. Geen bestand erbij:
     dit is wat het scherm zelf al heeft. */
  font-family:
    system-ui,
    -apple-system,
    "Segoe UI",
    Roboto,
    "Helvetica Neue",
    Arial,
    sans-serif;
  font-size: 1rem;
  line-height: 1;
}

/* De grond loopt van rand tot rand, de namen niet: die staan op dezelfde
   kantlijn als het werkblad eronder. Zelfde maximumbreedte en zelfde zijmarge
   als `.index.admin.wrap`, zodat "Titel" recht boven de titel van de pagina
   staat en niet ergens links in het niets.

   `min-height` en `align-items: stretch` horen bij elkaar. De band was drie rem
   hoog met een raakvlak van twee: een halve rem dood gebied boven en onder elke
   naam, en dát is waardoor je het gevoel kreeg te moeten richten. Nu is elke
   naam zo hoog als de band. */
.form-sprongbalk-binnen {
  display: flex;
  align-items: stretch;
  gap: 1rem;
  /* Dezelfde doos als het werkblad: `.inner.wrap` is tachtig rem breed met
     anderhalve rem opvulling, en de kaart daarbinnen nog eens twee rem. Samen
     drieënhalve rem, en dan valt de kantlijn van de balk samen met die van de
     kaart — breed, waar de doos gecentreerd staat, én smal, waar hij de volle
     breedte neemt. */
  max-width: 80rem;
  min-height: 3.5rem;
  margin: 0 auto;
  padding: 0 3.5rem;
}

/* De negatieve marge vangt de zijruimte van de eerste naam op: zonder dat
   begint "Titel" 0,7rem rechts van de kantlijn van het werkblad, en dat zie
   je. Rechts hetzelfde, voor de laatste uitgang. */
/* Altijd één regel, en hij schuift opzij als hij niet past. Niet omdat
   afbreken lelijk is, maar omdat het het raakvlak sloopt: in een flexdoos die
   mag afbreken wordt een regel zo hoog als zijn inhoud, en dan rekt een naam
   niet meer op tot de hoogte van de band. Precies die halve rem dood gebied
   boven en onder was het "even richten"-gevoel. */
.form-sprongbalk-sprongen {
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  overflow-x: auto;
  margin-left: -0.5rem;
  scrollbar-width: none;
}

.form-sprongbalk-sprongen::-webkit-scrollbar {
  display: none;
}

/* De uitgangen: weg van deze pagina, en dus gescheiden van de sprongen
   ernaast, die erop blijven. De sitekop draagt ze niet meer (zie onderaan). */
.form-sprongbalk-uit {
  display: flex;
  align-items: stretch;
  margin-left: auto;
  margin-right: -0.5rem;
}

/* De omslachtige selector is nodig, niet netjes bedoeld. De algemene linkregel
   van het beheerthema staat op `.index.admin.wrap a[href]:not(.button)` — vijf
   klassen — en die won van een kale `.form-sprongbalk a`: de links kwamen
   daardoor in het middenblauw van een gewone link op deze donkere band te
   staan (nauwelijks te lezen), en hun maat viel terug op 0,875rem. Dit is
   dezelfde vorm met de band erbij, en dat is er één meer. */
.index.admin.wrap .form-sprongbalk a[href]:not(.button) {
  display: flex;
  align-items: center;
  /* Krap gezet, en dat mag: het raakvlak zit in de hoogte, niet in de zijkant.
     Dertien namen plus drie uitgangen moeten samen binnen de tachtig rem van
     het werkblad passen; ruimer opgezet schoof "Status" over de rand. */
  padding: 0 0.5rem;
  color: rgba(255, 255, 255, 0.78);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition:
    color 0.15s ease,
    background-color 0.15s ease;
}

.index.admin.wrap .form-sprongbalk a[href]:not(.button):hover,
.index.admin.wrap .form-sprongbalk a[href]:not(.button):focus-visible {
  color: #fff;
  background-color: rgba(255, 255, 255, 0.14);
  text-decoration: none;
}

.index.admin.wrap .form-sprongbalk a[href]:not(.button):focus-visible {
  outline: 0.125rem solid #fff;
  outline-offset: -0.125rem;
}

/* Waar je bent: het plaatje keert om. Een wit vlak van de volle bandhoogte —
   op een armlengte afstand het enige lichte blok in de band, en het leest als
   het tabblad dat openligt. */
.index.admin.wrap .form-sprongbalk a[href]:not(.button).hier {
  color: var(--admin-blue-dark, #003078);
  background-color: var(--admin-white, #fff);
  font-weight: 700;
}

/* De uitgangen staan een tint terug en een maat kleiner: ze horen bij de band,
   maar het zijn niet de sprongen waar de balk voor bestaat. Het scheelt ook de
   ruimte die de sprongen nodig hebben. */
.index.admin.wrap .form-sprongbalk-uit a[href]:not(.button) {
  padding: 0 0.5rem;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.875rem;
  font-weight: 500;
}

.index.admin.wrap .form-sprongbalk-uit a[href]:not(.button):hover {
  color: #fff;
}

/* Het pictogram op de maat van de letter ernaast, en in diezelfde kleur: een
   masker is precies zo zichtbaar als zijn achtergrondkleur, en het beheer zet
   ze standaard op wit (gezet voor donkere knoppen) én op anderhalve rem. Naast
   een regel van 0,875rem is dat een blok. */
.index.admin.wrap .form-sprongbalk-uit [class*="icon-"] {
  width: 1rem;
  height: 1rem;
  background-color: currentColor;
}

/* Een naam breekt nooit in tweeën, en hij krimpt niet: dan wordt de rij smal
   genoeg om te schuiven in plaats van onleesbaar. */
.index.admin.wrap .form-sprongbalk a[href]:not(.button) {
  flex: none;
  white-space: nowrap;
}

/* Op een smal scherm is de zijruimte van het werkblad kleiner; de balk volgt.
   De uitgangen schuiven niet mee met de rij ernaast — die moet je altijd
   kunnen vinden. */
@media (width < 60rem) {
  .form-sprongbalk-binnen {
    gap: 0.5rem;
    padding: 0 1rem;
  }

  .form-sprongbalk-sprongen {
    margin-left: 0;
  }
}

/* ── De kop van de site op een beheerscherm ──────────────────────────────────

   De balk staat vast bovenin het venster en ligt dus over de kop van de site
   heen: de naam van de site, het menu en de uitloglink verdwenen er half
   onder. Die kop hoort hier ook niet — je bewerkt de site, je bezoekt hem niet.

   Alleen op schermen die zo'n balk hebben: een beheerscherm zonder balk zou
   anders helemaal geen uitgang meer overhouden. Wat de kop droeg staat rechts
   in de band terug, inclusief het uitloggen (zie `production_live/form.ex`). */
/* Met `!important`, en dat is hier het eerlijke antwoord in plaats van een
   trucje. Elke tenant zet zijn eigen kop op `display` met een selector die
   zwaarder weegt dan deze — bij Hotel Modern is dat
   `body.hotelmodern:not(:has(.hm-stage)) .header` — en er zijn er zestien. Ze
   allemaal overtreffen zou een selector opleveren die niemand meer kan lezen,
   en de uitspraak is simpel: op een scherm met deze balk hoort die kop er niet
   te staan. */
body:has(.form-sprongbalk) .header {
  display: none !important;
}

/* Het naambordje staat vast in de rechterbovenhoek en zou nu in de band
   liggen, over de uitgangen heen. Het zakt eronder. */
body:has(.form-sprongbalk) .user-badge {
  top: 4.2rem;
}

/* ── De bordjes naar de site ─────────────────────────────────────────────────

   Twee wegen naar buiten: de voorpagina, en de lijst waar deze voorstelling in
   staat. Ze stonden even in de sprongbalk, en dat klopte niet: die balk gaat
   over déze pagina — waar sta ik, waar kan ik heen binnen dit formulier — en
   deze twee wijzen de deur uit.

   Dus hangen ze erbuiten, boven de kaart, precies op de plek waar het menu van
   de site stond voordat de balk die kop verving. Bij Hotel Modern is dat
   letterlijk de gang: kop en voet liggen daar buiten de kaart op de foto (zie
   hotelmodern/components/admin.css), en een bordje aan de muur is hoe die site
   zelf naar een andere kamer wijst.

   Boven de kaart en niet in de kantlijn ernaast: hoe breed die kantlijn is
   hangt van het venster af, en een bordje dat op een laptop half over het
   werkblad valt is geen bordje meer. */
.beheer-bordjes {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.6rem;
  max-width: 80rem;
  margin: 0 auto;
  /* Dezelfde kantlijn als de kaart. Twee rem en niet drieënhalve, anders dan
     bij de balk: die staat vast in het venster en moet de zijruimte van
     `.inner.wrap` zelf meerekenen, terwijl dit erbinnen staat en hem dus al
     heeft. */
  padding: 0 2rem;
}

/* Onder de vaste band, en de kaart sluit er strak op aan. De marge die de kaart
   anders zelf neemt (zie `.index.admin.wrap:has(.form-sprongbalk)`) verhuist
   hierheen: de bordjes zijn nu het eerste wat er staat. */
body:has(.form-sprongbalk) .beheer-bordjes {
  margin-top: 4.75rem;
}

.beheer-bordjes + .index.admin.wrap {
  margin-top: 0.75rem;
}

.beheer-bordje {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.9rem;
  background: var(--admin-white, #ffffff);
  border: 0.0625rem solid var(--admin-blue-border, #b8d0eb);
  border-radius: var(--admin-radius, 0.375rem);
  box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.12);
  color: var(--admin-blue-dark, #003078);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease;
}

/* Een bordje dat je aanwijst komt een haartje van de muur. */
.beheer-bordje:hover,
.beheer-bordje:focus-visible {
  transform: translateY(-0.0625rem);
  box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.18);
  text-decoration: none;
}

/* In de hoek, onder elkaar — zoals ze in een kamer hangen — zodra er kantlijn
   genoeg is om ze aan op te hangen.

   Die grens is te rekenen en niet gekozen: het werkblad is tachtig rem breed en
   staat midden in het venster, dus de kantlijn ernaast is (100vw - 80rem) / 2.
   Het breedste bordje is negenenhalve rem en wil anderhalve rem van de rand
   blijven, dus er moet elf rem naast passen: 100vw >= 80rem + 22rem. Daaronder
   zou een bordje over het formulier heen hangen, en dan blijven ze staan waar
   ze stonden — boven de kaart, naast elkaar, waar ze nooit iets afdekken.

   Onder de sprongbalk (die staat op 900) en onder de vensters (1000), maar
   boven het werkblad: ze hangen aan de muur, niet op het bureau. En onder het
   naambordje in de hoek, dat op 4,2rem staat. */
@media (width >= 102rem) {
  .beheer-bordjes {
    position: fixed;
    top: 6.5rem;
    right: 1.5rem;
    z-index: 800;
    flex-direction: column;
    align-items: flex-end;
    gap: 1rem;
    max-width: none;
    margin: 0;
    padding: 0;
  }

  /* De bordjes staan niet meer in de rij, dus de ruimte die zij onder de balk
     hielden, houdt de kaart weer zelf. */
  body:has(.form-sprongbalk) .beheer-bordjes {
    margin-top: 0;
  }

  .beheer-bordjes + .index.admin.wrap {
    margin-top: 4.5rem;
  }
}

/* De balk staat óver de kop van de sectie waar je heen springt; deze marge
   houdt die kop vrij. Ruimer dan de balk hoog is, zodat er lucht boven staat. */
.sprongdoel {
  scroll-margin-top: var(--sprong-marge, 4.5rem);
}

/* ── Een veldgroep die dichtgeklapt staat ────────────────────────────────────

   Voor velden die er wél moeten zijn maar bij vrijwel elke invulbeurt leeg
   blijven — de plek van de scèneknop is de eerste. Zo'n groep opengeslagen in
   het formulier zetten kost twee dingen tegelijk: schermhoogte, en aandacht
   van een redacteur die zich afvraagt of hij hier iets moet invullen.

   Hij hoort binnen het paneel waar hij bij hoort, onder de hoofdhandeling, met
   een lijn ertussen: dan leest hij als "en verder, als je het nodig hebt" en
   niet als een tweede veld. */
.index.admin.wrap .veldgroep-inklap {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 0.0625rem solid var(--admin-blue-border, #b8d0eb);
}

/* Onderin een paneel sluit de groep het af en hoort er niets achter. Staat er
   wél iets onder — het persbericht onder Pers heeft de contactvelden achter
   zich — dan moet die ruimte er wel zijn: dichtgeklapt is de groep één regel,
   en zonder lucht eronder leest hij als het opschrift van het veld erna. */
.index.admin.wrap .veldgroep-inklap:not(:last-child) {
  margin-bottom: 2rem;
}

/* Het driehoekje van de browser staat links buiten de tekst en verschilt per
   browser; dit is er één die overal hetzelfde staat en meedraait. */
.index.admin.wrap .veldgroep-inklap > summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--admin-blue-dark, #003078);
  font-weight: 600;
  font-size: 0.9rem;
  list-style: none;
  cursor: pointer;
}

.index.admin.wrap .veldgroep-inklap > summary::-webkit-details-marker {
  display: none;
}

.index.admin.wrap .veldgroep-inklap > summary::before {
  content: "▸";
  font-size: 0.85em;
  line-height: 1;
  transition: transform 0.15s ease;
}

.index.admin.wrap .veldgroep-inklap[open] > summary::before {
  transform: rotate(90deg);
}

.index.admin.wrap .veldgroep-inklap > summary:focus-visible {
  outline: 0.125rem solid currentColor;
  outline-offset: 0.25rem;
}

/* De uitleg pas ná het openen, en in de toon van een onderschrift: wie de
   groep dichtlaat hoeft hem niet te lezen. */
.index.admin.wrap .veldgroep-inklap > .hint {
  margin: 0.75rem 0 0;
  color: var(--admin-text-light, #5a6b82);
  font-size: 0.85rem;
}

/* ── Velden naast elkaar ─────────────────────────────────────────────────────

   Drie getallen van hooguit vijf tekens hoeven geen drie volle regels: naast
   elkaar zijn ze samen één ding om in te vullen. `minmax(0, 1fr)` omdat een
   invoerveld anders zijn eigen standaardbreedte als ondergrens neemt en de rij
   uit het paneel duwt. Zodra een kolom onder de twaalf rem zou komen breekt de
   rij vanzelf: een getalveld dat smaller is dan zijn eigen label leest niemand
   meer. */
.index.admin.wrap .veldgroep-rij {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 0.75rem 1rem;
  margin-top: 0.75rem;
}

.index.admin.wrap .veldgroep-rij > div {
  min-width: 0;
}

/* ── De recensies van een voorstelling ───────────────────────────────────────

   Een lijst regels, met de recensie die je bewerkt als werkblad over die lijst
   heen. Waarom dat zo is, staat bij de sectie zelf in
   `production_live/form.ex`; hier staat alleen hoe het eruitziet.

   De kleuren komen uit base/admin-delfts-blauw.css. Zeven tenants importeren
   dat thema niet, dus draagt elke variabele hier zijn eigen terugval. */

.index.admin.wrap .press-items-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.index.admin.wrap .press-item-form {
  margin: 0;
  padding: 0;
  border: none;
  background: none;
}

/* De regel zelf: greep, de tekst als knop, wat eraan hangt, en de uitweg. */
.index.admin.wrap .press-regel {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.375rem 0.75rem;
  background: var(--admin-white, #ffffff);
  border: 0.0625rem solid var(--admin-blue-border, #b8d0eb);
  border-radius: var(--admin-radius, 0.375rem);
  transition: border-color 0.15s ease;
}

.index.admin.wrap .press-regel:hover {
  border-color: var(--admin-blue-dark, #003078);
}

.index.admin.wrap .press-regel .drag-handle {
  flex: none;
  opacity: 0.45;
}

.index.admin.wrap .press-regel .drag-handle:hover {
  opacity: 1;
}

/* De hele regel is de knop die hem opent: een apart potloodje ernaast zou een
   tweede plek zijn om te mikken voor dezelfde handeling. */
.index.admin.wrap .press-regel-open {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.4rem 0;
  background: none;
  border: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.index.admin.wrap .press-medium {
  flex: none;
  max-width: 14rem;
  overflow: hidden;
  color: var(--admin-blue-dark, #003078);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Het fragment neemt wat overblijft en kapt af op de breedte die er is. Op één
   regel, want twee regels zouden de lijst weer laten ademen als kaarten. */
.index.admin.wrap .press-fragment {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  color: var(--admin-text-light, #4a5568);
  font-size: 0.9rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Nog niets ingevuld: wél te lezen, maar herkenbaar als een gat en niet als
   een medium dat "Nieuwe recensie" heet. */
.index.admin.wrap .press-medium.leeg,
.index.admin.wrap .press-fragment.leeg {
  font-style: italic;
  opacity: 0.6;
}

.index.admin.wrap .press-tekens {
  flex: none;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--admin-text-light, #4a5568);
}

.index.admin.wrap .press-tekens .icon-pdf {
  width: 1rem;
  height: 1rem;
  background-color: currentColor;
  opacity: 0.7;
}

.index.admin.wrap .press-teken {
  font-size: 1rem;
  line-height: 1;
  opacity: 0.7;
}

/* Verwijderen is een uitweg en geen hoofdhandeling: het pictogram alleen, in
   de hoek. De naam staat in `aria-label` en `title`. Als knop in de huisstijl
   was het een blauw blok dat meer aandacht trok dan de recensie ernaast. */
.index.admin.wrap .press-regel-weg {
  flex: none;
  display: flex;
  align-items: center;
  margin: 0;
  padding: 0.3rem;
  background: none;
  border: none;
  border-radius: var(--admin-radius, 0.375rem);
  color: var(--admin-text-light, #4a5568);
  cursor: pointer;
}

.index.admin.wrap .press-regel-weg .icon-trash {
  width: 1.1rem;
  height: 1.1rem;
  background-color: currentColor;
  opacity: 0.4;
  transition: opacity 0.15s ease;
}

.index.admin.wrap .press-regel-weg:hover .icon-trash,
.index.admin.wrap .press-regel-weg:focus-visible .icon-trash {
  opacity: 1;
}

/* ── Het werkblad ──────────────────────────────────────────────────────── */

/* Dicht is `display: none` en niet weg uit de DOM: de velden moeten blijven
   meesturen (zie de sectie in form.ex). */
.index.admin.wrap .press-werkblad {
  display: none;
}

.index.admin.wrap .press-item-form.open > .press-werkblad {
  display: block;
}

/* Boven de sprongbalk (900) en onder de bibliotheekvensters (1000): die laatste
   open je vanuit dit werkblad, dus die horen erover te komen. */
.index.admin.wrap .press-werkblad-doek {
  position: fixed;
  inset: 0;
  z-index: 950;
  background: rgba(0, 20, 50, 0.45);
}

.index.admin.wrap .press-werkblad-kaart {
  position: fixed;
  z-index: 960;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  width: min(52rem, calc(100vw - 3rem));
  max-height: calc(100vh - 3rem);
  background: var(--admin-white, #ffffff);
  border-radius: var(--admin-radius, 0.375rem);
  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.3);
}

.index.admin.wrap .press-werkblad-kaart > header {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-bottom: 0.0625rem solid var(--admin-blue-border, #b8d0eb);
}

.index.admin.wrap .press-werkblad-kaart > header h3 {
  margin: 0;
  color: var(--admin-blue-dark, #003078);
  font-size: 1.05rem;
}

/* Welk medium het is, staat al in de kop van de kaart; hier is het de bevestiging
   dat je de goede regel te pakken hebt, niet de titel zelf. */
.index.admin.wrap .press-werkblad-medium {
  color: var(--admin-text-light, #4a5568);
  font-weight: 400;
}

/* `base/icons.css` zet dit kruisje in de hoek van het venster (`position:
   absolute`), gezet voor de lichtbak. Hier staat het in een kop die zelf al een
   rij is, dus mag de flex het plaatsen — net als in de bibliotheekvensters. */
.index.admin.wrap .press-werkblad-kaart > header .icon-close {
  flex: none;
  position: static;
  width: 1.5rem;
  height: 1.5rem;
  background-color: currentColor;
  border: none;
  opacity: 0.6;
  cursor: pointer;
}

.index.admin.wrap .press-werkblad-kaart > header .icon-close:hover,
.index.admin.wrap .press-werkblad-kaart > header .icon-close:focus-visible {
  opacity: 1;
}

/* Alleen de velden scrollen. Kop en voet blijven staan, zodat de opslaanknop
   ook bij een lange samenvatting in beeld is. */
.index.admin.wrap .press-werkblad-velden {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 1.25rem;
}

.index.admin.wrap .press-werkblad-velden .form-field {
  margin-bottom: 1.25rem;
}

/* Krant en datum horen bij elkaar en zijn allebei kort: naast elkaar lezen ze
   als één bronvermelding in plaats van als twee losse vragen. Onder de 14rem
   per veld gaan ze onder elkaar staan — smaller dan dat is een krantennaam in
   het veld niet meer te overzien. */
.index.admin.wrap .press-werkblad-velden .form-field-paar {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1rem;
}

.index.admin.wrap .press-werkblad-velden .form-field-paar > .form-field {
  flex: 1 1 14rem;
}

/* Eén tree lager dan de kop van de kaart erboven, net als elders in het
   beheer: dit zijn veldlabels, geen sectiekoppen. */
.index.admin.wrap .press-werkblad-velden .form-field > label {
  display: block;
  margin-bottom: 0.35rem;
  color: var(--admin-text, #1a1a2e);
  font-weight: 500;
  font-size: 0.8125rem;
}

.index.admin.wrap .press-werkblad-velden textarea,
.index.admin.wrap .press-werkblad-velden input[type="text"],
.index.admin.wrap .press-werkblad-velden input[type="url"] {
  width: 100%;
}

.index.admin.wrap .press-werkblad-velden .document-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* Wat er nog ontbreekt voordat deze recensie bewaard kan worden. Tussen de kop
   en de velden, zodat het het eerste is wat je leest als het werkblad opengaat. */
.index.admin.wrap .press-werkblad-fout {
  margin: 0;
  padding: 0.75rem 1.25rem;
  background: #fdecea;
  border-bottom: 0.0625rem solid #f2c4bf;
  color: #8a1c12;
  font-size: 0.9375rem;
  line-height: 1.4;
}

/* Na opslaan vanuit het werkblad blijf je in het formulier; deze regel boven de
   lijst zegt dat het gelukt is. Een flash zou hier niet verschijnen. */
.index.admin.wrap .press-opgeslagen {
  margin: 0 0 0.75rem;
  padding: 0.5rem 0.75rem;
  background: #e8f3ea;
  border-left: 0.25rem solid #2f7d45;
  color: #1f4d2b;
  font-size: 0.9375rem;
}

/* Het gekoppelde document. base/documents.css kleedt `.selected-document` en
   `.current-document` aan als kaart uit de documentbibliotheek: alles onder
   elkaar, met vier rem binnenruimte onderaan. In het werkblad is het één regel
   onder de twee knoppen: pictogram, titel, kruisje. */
.index.admin.wrap .press-werkblad-velden .selected-document,
.index.admin.wrap .press-werkblad-velden .current-document {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 0.625rem;
  margin-top: 0.75rem;
  padding: 0.625rem 0.75rem;
  border: 0.0625rem solid rgba(0, 0, 0, 0.12);
  border-radius: 0.25rem;
  background: rgba(0, 0, 0, 0.03);
  box-shadow: none;
}

.index.admin.wrap .press-werkblad-velden .selected-document [class*="icon-"],
.index.admin.wrap .press-werkblad-velden .current-document [class*="icon-"] {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
}

.index.admin.wrap .press-werkblad-velden .selected-document > span:not([class]),
.index.admin.wrap .press-werkblad-velden .current-document > span:not([class]) {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}

.index.admin.wrap .press-werkblad-velden .selected-document > button {
  position: static;
  flex: none;
  margin: 0 0 0 auto;
}

.index.admin.wrap .press-werkblad-voet {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  padding: 1rem 1.25rem;
  border-top: 0.0625rem solid var(--admin-blue-border, #b8d0eb);
  background: var(--admin-blue-light, #e8f0fb);
  border-radius: 0 0 var(--admin-radius, 0.375rem) var(--admin-radius, 0.375rem);
}

.index.admin.wrap .press-werkblad-stappen,
.index.admin.wrap .press-werkblad-klaar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.index.admin.wrap .press-werkblad-voet .button {
  margin: 0;
}

/* Aan het begin of het eind van de lijst: de knop blijft staan, zodat de rij
   niet verspringt, maar hij doet niets meer. */
.index.admin.wrap .press-werkblad-stappen .button[disabled] {
  opacity: 0.35;
  cursor: default;
}

/* Op een smal scherm is het werkblad het scherm, en gaan de twee rijen knoppen
   onder elkaar staan. */
@media (width < 40rem) {
  .index.admin.wrap .press-werkblad-kaart {
    width: 100vw;
    max-height: 100vh;
    height: 100vh;
    border-radius: 0;
  }

  .index.admin.wrap .press-werkblad-voet {
    flex-direction: column-reverse;
    align-items: stretch;
    border-radius: 0;
  }

  .index.admin.wrap .press-werkblad-stappen,
  .index.admin.wrap .press-werkblad-klaar {
    justify-content: space-between;
  }
}

/* ── De hoofdstukken van een lang beheerformulier ────────────────────────────

   Het voorstellingsformulier heeft achtentwintig secties en tien onderwerpen.
   De koppen van die secties stonden allemaal op dezelfde maat, hetzelfde
   gewicht en dezelfde kleur, dus je zag nergens waar het ene onderwerp ophield
   en het volgende begon: één lange band van gelijke blokken. De sprongbalk
   bovenaan nóémde de indeling wel, maar op de pagina stond er niets tegenover.

   Dit is die naam, op de plek waar de balk heen springt. Groter dan een
   sectiekop en met een lijn die doorloopt tot de kantlijn — een lijn kost geen
   inkt en zegt "hier begint iets nieuws" duidelijker dan alleen witruimte.

   De trap is nu drie treden diep: hoofdstuk (1,5rem), sectiekop (1,0625rem,
   base/admin-delfts-blauw.css) en veldlabel (0,8125rem). Hij stond op één. */
.index.admin.wrap .form-hoofdstuk {
  display: flex;
  align-items: center;
  gap: 1rem;
  /* Ruim boven, krap onder: de kop hoort bij wat eronder komt, niet bij wat
     erboven staat. Zonder dat verschil zweeft hij tussen twee hoofdstukken in
     en moet je lezen waar hij bij hoort. */
  margin: 3.5rem 0 1rem;
  color: var(--admin-blue-dark, #003078);
  /* Aangedikt: de serif van een tenant heeft 400 en 700 en verder niets, dus
     voorbij 700 kan een kop alleen nog in maat groeien. Anderhalve rem las nog
     als een zware alinea; op 1,75 is het een kop. */
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1.2;
}

/* Het eerste hoofdstuk staat direct onder de sprongbalk; daar hoort die drie
   en een halve rem lucht niet. */
.index.admin.wrap .form-hoofdstuk:first-of-type {
  margin-top: 1rem;
}

.index.admin.wrap .form-hoofdstuk::after {
  content: "";
  flex: 1 1 auto;
  height: 0.125rem;
  background: var(--admin-blue-border, #b8d0eb);
}

/* Zodra een formulier hoofdstukken heeft, is de streep boven elke sectie
   dubbelop. Er staat er al een bij de hoofdstukkop, en achtentwintig strepen
   van hetzelfde gewicht zijn nou juist het gebrek aan onderscheid dat die
   koppen moeten oplossen: alles even belangrijk is hetzelfde als niets
   belangrijk. Binnen een hoofdstuk scheidt witruimte, en waar een sectie een
   paneel is, doet dat paneel het al.

   Met `:has()` zodat het beperkt blijft tot schermen die hoofdstukken hebben.
   Op de andere beheerschermen is die streep voorlopig het enige dat de secties
   uit elkaar houdt, en die halen we er niet onderuit zolang ze daar geen
   koppen voor terugkrijgen. */
.index.admin.wrap:has(.form-hoofdstuk) section,
.index.admin.wrap:has(.form-hoofdstuk) .thumbnail {
  border-top: none;
}

/* Wat direct onder een hoofdstukkop staat, hoort erbij. De ruimte die bij die
   weggehaalde streep hoorde — anderhalve rem opvulling plus tweeënhalve rem
   marge — zette er vijf rem tussen, en dan zweeft de kop los boven zijn eigen
   eerste sectie. Panelen houden hun binnenruimte: die staat in
   base/admin-delfts-blauw.css, dat ná dit bestand geladen wordt en bij gelijke
   zwaarte dus wint. */
.index.admin.wrap .form-hoofdstuk + section,
.index.admin.wrap .form-hoofdstuk + div,
.index.admin.wrap .form-hoofdstuk + .thumbnail {
  margin-top: 0;
  padding-top: 0;
}

/* ── De staat van een voorstelling ───────────────────────────────────────────

   Concept, gepubliceerd of gearchiveerd is de schakelaar met de meeste
   gevolgen op het hele formulier — hij bepaalt of het ding op de site staat —
   en hij zag eruit als alles eromheen: drie radiootjes op een rij in het
   achtentwintigste blauwe blok.

   Nu is het een keuze uit drie kaarten, en de gekozen kaart draagt de kleur van
   die staat. Dat zijn de kleuren die dit beheer elders al gebruikt: oker voor
   een waarschuwing (er ontbreekt iets, er is niets stuk), groen voor goed, en
   gedempt grijs voor wat opzij is gezet. Zo lees je van een meter afstand waar
   een voorstelling staat, zonder te hoeven zien welk rondje aan is. */
.index.admin.wrap .status-keuze {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.index.admin.wrap .status-optie {
  flex: 1 1 13rem;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0.1rem 0.6rem;
  margin: 0;
  padding: 0.9rem 1rem;
  background: var(--admin-white, #ffffff);
  /* Twee keer een zestiende in plaats van één: de gekozen kaart verandert
     straks alleen van kleur, niet van maat — anders verspringt de rij bij elke
     klik. */
  border: 0.125rem solid var(--admin-blue-border, #b8d0eb);
  border-radius: var(--admin-radius, 0.375rem);
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    background-color 0.15s ease;
}

.index.admin.wrap .status-optie:hover {
  border-color: var(--admin-blue-dark, #003078);
}

.index.admin.wrap .status-optie .input-radio {
  grid-row: 1 / span 2;
  width: auto;
  min-width: 0;
  margin: 0;
}

.index.admin.wrap .status-naam {
  color: var(--admin-text, #1a1a2e);
  font-weight: 700;
  font-size: 0.95rem;
}

.index.admin.wrap .status-uitleg {
  grid-column: 2;
  color: var(--admin-text-light, #4a5568);
  font-size: 0.8125rem;
}

/* De gekozen staat, in zijn eigen kleur. `:has()` omdat het rondje binnen het
   label staat: de kaart kleurt mee met wat erin aangevinkt is, zonder dat er
   een klasse van de server bij hoeft. */
.index.admin.wrap .status-optie.is-draft:has(input:checked) {
  border-color: var(--admin-warning, #c47f00);
  background: var(--admin-warning-light, #fdf6e6);
}

.index.admin.wrap .status-optie.is-draft:has(input:checked) .status-naam {
  color: var(--admin-warning, #c47f00);
}

.index.admin.wrap .status-optie.is-published:has(input:checked) {
  border-color: var(--admin-success, #276749);
  background: #eef6f1;
}

.index.admin.wrap .status-optie.is-published:has(input:checked) .status-naam {
  color: var(--admin-success, #276749);
}

.index.admin.wrap .status-optie.is-archived:has(input:checked) {
  border-color: var(--admin-text-light, #4a5568);
  background: #f3f4f6;
}

.index.admin.wrap .status-optie.is-archived:has(input:checked) .status-naam {
  color: var(--admin-text-light, #4a5568);
}

/* ── Blauw betekent weer iets ────────────────────────────────────────────────

   Elk uploadveld zat in een lichtblauw paneel, maar Titel, Ondertitel en
   Tagline zweefden er los tussen: het paneel volgde dus het sóórt veld en niet
   de betekenis. En omdat datzelfde blauw ook de koptekst, de knoppen en de
   randen droeg, zei het nergens meer iets.

   De panelen worden wit met een rand. Ze houden hun grens — je ziet nog steeds
   waar een veld begint en ophoudt — maar het gevulde blauw is nu van de
   knoppen alleen, en dan betekent het "hier kun je op drukken".

   Alleen op schermen mét hoofdstukken, net als de weggehaalde sectiestreep
   hierboven: daar dragen de koppen de indeling. De andere beheerschermen
   houden hun blauwe vlakken tot ze diezelfde koppen krijgen. */
.index.admin.wrap:has(.form-hoofdstuk) .thumbnail,
.index.admin.wrap:has(.form-hoofdstuk) .document-upload-section,
.index.admin.wrap:has(.form-hoofdstuk) .audio-upload-zone,
.index.admin.wrap:has(.form-hoofdstuk) section.checkbox-fields {
  background: var(--admin-white, #ffffff);
}

/* De statussectie krijgt helemaal geen vak meer: de drie kaarten erin hebben
   hun eigen rand, en een vak om drie vakken heen is een doos in een doos. */
.index.admin.wrap:has(.form-hoofdstuk) section.status-section {
  background: none;
  border: none;
  padding: 0;
}

/* --- Zoekresultaten in het speelbeurtformulier ---------------------------- */
/* Productie en locatie kies je uit een lijst die onder het zoekveld opengaat.
   Dat waren kale `div`'s met een klik erop: niet met het toetsenbord te
   bereiken, en voor een schermlezer geen keuze. Nu een lijst met knoppen, die
   er precies zo uitzien als die regels: gewone tekst, over de volle breedte. */
.production-results button,
.location-results button {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-align: left;
  cursor: pointer;
}

.production-results button:hover,
.production-results button:focus-visible,
.location-results button:hover,
.location-results button:focus-visible {
  text-decoration: underline;
}

/* De onzichtbare "verder"-knop die enter zijn betekenis teruggeeft. Niet
   display:none — een verborgen knop doet niet mee aan impliciet verzenden.
   Hier en niet in form.css: niet elke tenant laadt dat bestand, en daar stond
   hij als plat streepje boven de vraag. */
.wizard .wizard-default-submit {
  position: absolute;
  width: 0.0625rem;
  height: 0.0625rem;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
}

/* ── Het afrondscherm, na het aanmaken ──────────────────────────────────────
   Drie wegen (publiceren, verder bewerken, terug) en daaronder de site zelf in
   een iframe. De iframe krijgt een vaste hoogte: hij is een venster op de
   pagina, en scrolt zelf. */
.afronden-keuzes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
}

.afronden-uitleg {
  margin-top: 0.75rem;
  opacity: 0.7;
}

.voorvertoning {
  margin-top: 2.5rem;
}

/* Boven het venster: de kop, de twee keuzes (wat, en op welk scherm) en de
   weg naar een eigen tabblad. Elke keuze is een rij aaneengesloten knoppen;
   de ingedrukte is gevuld. */
.voorvertoning-balk {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  margin-bottom: 0.75rem;
}

.voorvertoning-balk h3 {
  margin: 0;
}

.voorvertoning-keuze {
  display: inline-flex;
}

.voorvertoning-keuze button {
  margin: 0;
  padding: 0.4rem 0.9rem;
  border: 0.0625rem solid currentColor;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.875rem;
  line-height: 1.2;
  cursor: pointer;
}

.voorvertoning-keuze button + button {
  margin-left: -0.0625rem;
}

.voorvertoning-keuze button[aria-pressed="true"] {
  background: #111;
  border-color: #111;
  color: #fff;
}

.voorvertoning-keuze button:focus-visible {
  outline: 0.125rem solid #ffbf00;
  outline-offset: 0.125rem;
  position: relative;
}

.voorvertoning-los {
  margin-left: auto;
  font-size: 0.875rem;
}

/* Het venster heeft een vaste hoogte en de site scrolt erin. De iframe krijgt
   van de hook de breedte van het gekozen apparaat en wordt verkleind tot hij
   past; een telefoon past meestal op ware grootte, en staat dan in het midden
   op een grijze tafel. */
.voorvertoning-venster {
  position: relative;
  height: calc(100vh - 12rem);
  min-height: 28rem;
  overflow: hidden;
  border: 0.0625rem solid rgba(0, 0, 0, 0.2);
  background: #e6e6e6;
}

.voorvertoning-venster iframe {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
  border: 0;
  background: #fff;
  transform-origin: 0 0;
}

.voorvertoning-venster:not([data-apparaat="scherm"]) iframe {
  box-shadow: 0 0 1.5rem rgba(0, 0, 0, 0.15);
}

/* Naast "Productie opslaan": waarom de voorvertoning er even niet is. */
.voorvertoning-wacht {
  font-size: 0.875rem;
  opacity: 0.7;
}

/* Bovenaan het formulier, na "Verder bewerken": het concept bestaat al, dit is
   aanvullen en geen nieuw begin. */
.aanvul-melding {
  margin-bottom: 1.5rem;
  padding: 0.75rem 1rem;
  border-left: 0.25rem solid currentColor;
  background: rgba(0, 0, 0, 0.04);
}


/* ── ../base/admin-delfts-blauw.css ── */
/* ===== Delfts Blauw Admin Thema ===== */
/* Gedeeld admin-thema. Tenants importeren dit via hun app.css ná base/admin.css
   en vóór ./components/admin.css, zodat tenant-overrides bovenop blijven werken. */

:root {
  --admin-blue-dark: #003078;
  --admin-blue: #1a4d8f;
  --admin-blue-light: #e8f0fb;
  --admin-blue-border: #b8d0eb;
  --admin-white: #ffffff;
  --admin-text: #1a1a2e;
  --admin-text-light: #4a5568;
  --admin-danger: #c53030;
  --admin-success: #276749;
  /* Een waarschuwing is geen fout: er is niets stuk, er ontbreekt iets.
     Vandaar oker naast het rood van --admin-danger. */
  /* De bodem van een paneel binnen een venster: net genoeg grijs om witte
     kaartjes erop te laten staan. */
  --admin-paneel: #f7f7f7;
  --admin-warning: #c47f00;
  --admin-warning-light: #fdf6e6;
  --admin-radius: 6px;
}

/* Container */
.index.admin.wrap {
  max-width: 80rem;
  margin: 2rem auto;
  padding: 2.5rem 2rem;
  background: var(--admin-white);
  border: 0.0625rem solid var(--admin-blue-border);
  border-radius: var(--admin-radius);
  box-shadow: 0 0.0625rem 4px rgba(0, 48, 120, 0.08);
}

.index.admin.wrap > header {
  border-bottom: 2px solid var(--admin-blue-dark);
  padding-bottom: 1.25rem;
  margin-bottom: 2rem;
}

.index.admin.wrap > header h2 {
  color: var(--admin-blue-dark);
  font-size: 1.5rem;
  margin: 0 0 0.25rem;
}

.index.admin.wrap > header p {
  color: var(--admin-text-light);
  font-size: 0.9rem;
  margin: 0;
}

section.gallery-upload {
  background-color: var(--admin-blue-light);
}

/* Form secties */
/* .index.admin.wrap section {
  margin-bottom: 1.5rem;
} */

/* De middelste tree van de trap: boven staat de hoofdstukkop (1,5rem, zie
   base/admin.css), hieronder het veldlabel (0,8125rem). Deze stond op 0,95rem
   en het label op 0,875rem — anderhalve pixel verschil, dus in de praktijk
   geen verschil. Een sectiekop moet je kunnen overslaan met je ogen; dat kan
   alleen als hij een maat groter is dan wat eronder hangt. */
.index.admin.wrap section > header {
  color: var(--admin-blue-dark);
  font-weight: 600;
  font-size: 1.0625rem;
  margin-bottom: 0.75rem;
}

/* Labels: de onderste tree. Kleiner dan de sectiekop erboven, en in de
   tekstkleur en niet in het blauw — blauw is in dit beheer de kleur van koppen
   en van knoppen, en een label is geen van beide. */
.index.admin.wrap label {
  color: var(--admin-text);
  font-size: 0.8125rem;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
}

.index.admin.wrap label span {
  display: inline-block;
  padding: 0 0.25rem;
}

/* Inputs */
.index.admin.wrap input[type="text"],
.index.admin.wrap input[type="email"],
.index.admin.wrap input[type="number"],
.index.admin.wrap input[type="url"],
.index.admin.wrap input[type="tel"],
.index.admin.wrap input[type="password"],
.index.admin.wrap textarea,
.index.admin.wrap select {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 0.0625rem solid var(--admin-blue-border);
  border-radius: var(--admin-radius);
  background: var(--admin-white);
  color: var(--admin-text);
  font-size: 0.9rem;
  transition: border-color 0.15s ease;
}

.index.admin.wrap input:focus,
.index.admin.wrap textarea:focus,
.index.admin.wrap select:focus {
  outline: none;
  border-color: var(--admin-blue);
  box-shadow: 0 0 0 3px rgba(26, 77, 143, 0.12);
}

/* Checkboxes / radios — overschrijft de globale form.css regels die de wrapper-divs
   een vaste breedte geven en de input-radio op 2rem breed zetten. */
.index.admin.wrap section.checkbox-fields,
.index.admin.wrap section.status-section {
  background: var(--admin-blue-light);
  border: 0.0625rem solid var(--admin-blue-border);
  border-radius: var(--admin-radius);
  padding: 1rem 1.25rem;
  margin: 1.5rem 0;
}

.index.admin.wrap section.checkbox-fields > header,
.index.admin.wrap section.status-section > header {
  color: var(--admin-blue-dark);
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: normal;
  margin-bottom: 0.75rem;
}

/* Deelregel boven de site-vinkjes: vertelt welke andere sites meeveranderen.
   Staat tussen de kop en de vinkjes, dus iets kleiner en rustiger dan de kop —
   het is een mededeling, geen waarschuwing. */
.index.admin.wrap section.checkbox-fields .sharing-notice {
  margin: -0.25rem 0 0.75rem;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--admin-blue-dark);
  opacity: 0.85;
}

.index.admin.wrap section.checkbox-fields .checkboxes,
.index.admin.wrap section.status-section .rbtns-body {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  padding: 0;
  border: none;
}

.index.admin.wrap section.checkbox-fields .checkboxes > div,
.index.admin.wrap section.status-section .rbtns-body > div {
  display: flex;
  align-items: center;
  width: auto;
  margin: 0;
}

.index.admin.wrap .label-radio {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
}

.index.admin.wrap .label-radio input {
  width: auto;
}

.index.admin.wrap input[type="checkbox"].input-radio,
.index.admin.wrap input[type="radio"].input-radio,
.index.admin.wrap
  section.checkbox-fields
  .checkboxes
  .label-radio
  input.input-radio,
.index.admin.wrap section.status-section .rbtns-body div input.input-radio {
  width: 1rem;
  height: 1rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  accent-color: var(--admin-blue);
  flex-shrink: 0;
}

/* Uploadvelden: één doos voor elk bestand dat je meegeeft.

   Het veld 'Uitgelichte afbeelding' was het enige dat zich als paneel liet
   zien: een lichtblauw vlak met een donkerblauwe kop, waardoor je in één
   oogopslag ziet waar het veld begint en ophoudt. Alle andere uploads —
   flyer, titellogo, scèneknop, documenten, geluid — kregen dezelfde behandeling
   en staan daarom hieronder in dezelfde regel. Nieuwe uploadvelden schrijf je
   met `.thumbnail` (beeld) of voeg je hier toe. */
.index.admin.wrap .thumbnail,
.index.admin.wrap .document-upload-section,
.index.admin.wrap .audio-upload-zone {
  background: var(--admin-blue-light);
  border: 0.0625rem solid var(--admin-blue-border);
  border-radius: var(--admin-radius);
  padding: 1.25rem;
  margin-bottom: 1.5rem;
}

/* Een uploadveld draagt zijn naam in een `header` of, bij het geluidsvak, in
   een `label`. Alle drie zijn ze een sectiekop en horen ze dus op de middelste
   tree te staan, niet op die van een veldlabel. */
.index.admin.wrap .thumbnail > header,
.index.admin.wrap .document-upload-section > header,
.index.admin.wrap .audio-upload-zone > label {
  display: block;
  color: var(--admin-blue-dark);
  font-weight: 600;
  font-size: 1.0625rem;
  margin-bottom: 0.75rem;
}

/* De uitleg onder een kop hoort bij de kop, maar hoeft niet te schreeuwen. */
.index.admin.wrap .thumbnail > header p,
.index.admin.wrap .document-upload-section > header p {
  color: var(--admin-text-light);
  font-weight: 400;
  font-size: 0.85rem;
  margin: 0.25rem 0 0;
}

.index.admin.wrap .thumbnail img {
  max-width: 100%;
  height: auto;
  border-radius: var(--admin-radius);
  margin-top: 0.75rem;
}

.index.admin.wrap .drop {
  border: 2px dashed var(--admin-blue-border);
  border-radius: var(--admin-radius);
  padding: 1.5rem;
  text-align: center;
  background: var(--admin-white);
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    background 0.15s ease;
}

.index.admin.wrap .drop:hover {
  border-color: var(--admin-blue);
  background: rgba(26, 77, 143, 0.03);
}

.index.admin.wrap .drop span {
  color: var(--admin-text-light);
  font-size: 0.85rem;
}

/* De eigen knop van een bestandsveld (`bestand_kiezen/1`) is een span in de
   sleepzone; de regel hierboven maakt elke span daar klein en grijs. */
.index.admin.wrap .drop .bestand-kiezen-knop,
.index.admin.wrap .bestand-kiezen-knop {
  padding: 0.65rem 1.25rem;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--admin-blue-dark);
  text-decoration: none;
}

/* Upload progress */
.index.admin.wrap .entry {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 0.75rem;
  padding: 0.5rem;
  background: var(--admin-white);
  border: 0.0625rem solid var(--admin-blue-border);
  border-radius: var(--admin-radius);
}

.index.admin.wrap .entry .progress {
  flex: 1;
}

.index.admin.wrap .entry .bar {
  height: 6px;
  background: var(--admin-blue-light);
  border-radius: 3px;
  overflow: hidden;
}

.index.admin.wrap .entry .bar span {
  display: block;
  height: 100%;
  background: var(--admin-blue);
  border-radius: 3px;
  transition: width 0.2s ease;
}

.index.admin.wrap .entry img {
  width: 4rem;
  height: 4rem;
  object-fit: cover;
  border-radius: var(--admin-radius);
}

.index.admin.wrap .entry button {
  background: none;
  border: none;
  color: var(--admin-danger);
  font-size: 1.25rem;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}

/* De voorbeeldkaart van een foto die net gesleept is.
   De regels hierboven maken van `.entry` één regel — pictogram, balk, kruisje
   naast elkaar. Voor een document klopt dat: daar is de bestandsnaam de inhoud.
   Bij een foto is de fóto de inhoud, en die stond als duimnagel van 4rem
   bijgesneden in een vak van 20rem hoog, met de balk ernaast. Vandaar hier een
   kaart: de foto vult hem, de voortgang staat eronder, het kruisje in de hoek. */
.index.admin.wrap .thumbnail .entry {
  position: relative;
  flex-direction: column;
  align-items: stretch;
  gap: 0.5rem;
  margin-top: 0;
  padding: 0.75rem;
}

/* Alle drie de kaarten van een uploadveld tonen hun foto op dezelfde manier:
   vullend, niet bijgesneden. De marge hoort hier niet — de ruimte tussen de
   dingen in de kaart komt van de gap. */
.index.admin.wrap .thumbnail .entry img,
.index.admin.wrap .thumbnail .current-image img,
.index.admin.wrap .thumbnail .selected-image img {
  flex: 1;
  min-height: 0;
  width: 100%;
  height: auto;
  margin-top: 0;
  object-fit: contain;
}

/* Percentage en balk blijven naast elkaar, maar nemen alleen de hoogte die ze
   nodig hebben — anders eet de balk de ruimte van de foto op. */
.index.admin.wrap .thumbnail .entry .progress {
  flex: none;
  margin-bottom: 0;
}

/* Afbreken hoort bij de kaart, niet in de rij ernaast. Het schijfje eronder
   houdt het kruisje leesbaar, ook op een donkere foto. */
.index.admin.wrap .thumbnail .entry > button {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  line-height: 1;
}

.index.admin.wrap .thumbnail .entry > button:hover {
  background: #fff;
}

/* Quill editor */
.index.admin.wrap .ql-toolbar {
  border-color: var(--admin-blue-border) !important;
  border-radius: var(--admin-radius) var(--admin-radius) 0 0;
  background: var(--admin-blue-light);
}

.index.admin.wrap .ql-container {
  border-color: var(--admin-blue-border) !important;
  border-radius: 0 0 var(--admin-radius) var(--admin-radius);
  background: var(--admin-white);
  min-height: 10rem;
}

/* Footer / Acties */
.index.admin.wrap footer.actions {
  margin: 2rem 0rem;
  padding: 1.5rem;
  border: 0.0625rem solid var(--admin-blue-border);
  display: flex;
  align-items: center;
  gap: 1rem;
}

.index.admin.wrap footer.actions .button,
.index.admin.wrap button.button {
  background-color: var(--admin-blue-dark);
  color: var(--admin-white);
  font-size: 0.9rem;
  font-weight: 500;
  padding: 0.65rem 1.75rem;
  border: none;
  border-radius: var(--admin-radius);
  cursor: pointer;
  transition: background-color 0.15s ease;
  min-height: 0;
}

.index.admin.wrap footer.actions .button:hover,
.index.admin.wrap button.button:hover {
  background-color: var(--admin-blue);
}

/* ── De rang van een knop ────────────────────────────────────────────────────

   Het voorstellingsformulier telde negenentwintig knoppen, en alle
   negenentwintig waren hetzelfde marineblauwe blok — vijf ervan over de volle
   breedte. Het luidste ding op het scherm was daarmee "Beheer bibliotheek", een
   zijdeur die je zelden nodig hebt, en "Productie opslaan" schreeuwde even hard
   als "Verwijderen". Alles even belangrijk is hetzelfde als niets belangrijk.

   Drie rangen, en ze staan hier bij elkaar zodat een scherm ze kiest in plaats
   van ze zelf te tekenen:

     gevuld      — de handeling waar het scherm voor bestaat. Eén per scherm,
                   en in een venster één per venster.
     omlijnd     — de gewone handelingen: kiezen, uploaden, toevoegen.
     `.uitweg`   — weghalen, afbreken, de zijdeur. Tekst met een pictogram,
                   verder niets.

   Omlijnd doet zijn rand met een `inset box-shadow` en niet met `border`: de
   gevulde knop hierboven staat op `border: none`, en een echte rand zou de knop
   dus groter maken dan zijn buurman. Een rij met twee rangen ernaast elkaar
   moet op één lijn blijven staan. */
/* `.back` staat er als vaste klant bij: dat is de link die elk beheerscherm
   onderaan heeft, en teruggaan is nooit de handeling waar een scherm voor
   bestaat. Naast "Productie opslaan" stonden er zo twee even luide knoppen. */
.index.admin.wrap .button.secondary,
.index.admin.wrap button.button.secondary,
.index.admin.wrap a.button.secondary,
.index.admin.wrap a.button.back {
  background-color: var(--admin-white);
  color: var(--admin-blue-dark);
  box-shadow: inset 0 0 0 0.0625rem var(--admin-blue-dark);
}

/* De maat van een knop staat op `button.button` en gold dus niet voor een
   link die zich als knop voordoet: "Afterpagina bewerken" en "Back" kregen wel
   de rand van hun rang, maar niet de ruimte eromheen — onderstreepte tekst in
   een krap doosje. Alleen de links die hierboven een rang hebben gekregen, en
   niet elke `a.button` in het beheer: die staan op tientallen schermen die
   hier niet in beeld zijn. */
.index.admin.wrap a.button.secondary,
.index.admin.wrap a.button.back {
  padding: 0.65rem 1.75rem;
  border: none;
  border-radius: var(--admin-radius);
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: none;
}

.index.admin.wrap .button.secondary:hover,
.index.admin.wrap button.button.secondary:hover,
.index.admin.wrap a.button.secondary:hover,
.index.admin.wrap a.button.back:hover {
  background-color: var(--admin-blue-light);
}

/* Een pictogram is een masker en dus precies zo zichtbaar als zijn
   achtergrondkleur. Het beheer zet ze allemaal op wit (zie "Admin iconen"
   verderop), gezet voor donkere knoppen; op een omlijnde knop is dat wit op
   wit. Met `currentColor` volgt het pictogram de letter ernaast. */
.index.admin.wrap .button.secondary [class*="icon-"],
.index.admin.wrap .button.back [class*="icon-"] {
  background-color: currentColor;
}

/* De uitweg. Geen knopvlak: dit zijn handelingen die er moeten zijn maar niet
   om aandacht vragen — een `Verwijderen` onder een foto hoort niet even hard te
   roepen als het opslaan van de hele voorstelling. Dezelfde vorm die de
   prullenbak in een recensieregel al had. */
.index.admin.wrap .uitweg {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  padding: 0.35rem 0;
  background: none;
  border: none;
  color: var(--admin-text-light);
  font-size: 0.8125rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
}

.index.admin.wrap .uitweg [class*="icon-"] {
  width: 1rem;
  height: 1rem;
  background-color: currentColor;
  opacity: 0.7;
}

.index.admin.wrap .uitweg:hover,
.index.admin.wrap .uitweg:focus-visible {
  color: var(--admin-blue-dark);
  text-decoration: underline;
}

.index.admin.wrap .uitweg:hover [class*="icon-"] {
  opacity: 1;
}

/* Terug link */
.index.admin.wrap a[href]:not(.button) {
  color: var(--admin-blue);
  text-decoration: none;
  font-size: 0.875rem;
}

.index.admin.wrap a[href]:not(.button):hover {
  text-decoration: underline;
}

/* Flash berichten */
.index.admin.wrap .flash-info {
  background: var(--admin-blue-light);
  border: 0.0625rem solid var(--admin-blue-border);
  color: var(--admin-blue-dark);
  padding: 0.75rem 1rem;
  border-radius: var(--admin-radius);
  margin-bottom: 1.5rem;
}

.index.admin.wrap .flash-error {
  background: #fef2f2;
  border: 0.0625rem solid #fecaca;
  color: var(--admin-danger);
  padding: 0.75rem 1rem;
  border-radius: var(--admin-radius);
  margin-bottom: 1.5rem;
}

/* Admin tabel (index pagina's) */
.index.admin.wrap .pages-table table {
  width: 100%;
  border-collapse: collapse;
  background: var(--admin-white);
}

.index.admin.wrap .pages-table table thead tr {
  border-bottom: 2px solid var(--admin-blue-dark);
}

.index.admin.wrap .pages-table table thead tr th {
  padding: 0.75rem 1rem;
  text-align: left;
  color: var(--admin-blue-dark);
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.index.admin.wrap .pages-table table tbody tr {
  border-bottom: 0.0625rem solid var(--admin-blue-light);
}

.index.admin.wrap .pages-table table tbody tr:hover {
  background: var(--admin-blue-light);
}

.index.admin.wrap .pages-table table tbody tr td {
  padding: 0.75rem 1rem;
  font-size: 0.9rem;
}

/* Admin iconen: wit op donkere knoppen */
.index.admin [class*="icon-"] {
  background-color: #fff;
}

.tooltip span.icon-edit {
  background-color: #999 !important;
}

/* Admin knoppen en links: neutrale kleuren */
.index.admin .logout-link,
.index.admin a.logout-link {
  color: #000;
}

.index.admin .admin.actions .button {
  background-color: #000;
  color: #fff;
}

.index.admin .admin.actions .button span[class*="icon-"],
.modal-overlay,
.modal-overlay [class*="icon-"] {
  background-color: #fff;
}

/* Het vlak binnen een bibliotheekvenster. Grijs, zodat de witte kaartjes erop
   staan in plaats van erin te verdwijnen: wit op wit laat een raster in elkaar
   overlopen, en de koppen erboven dragen dan het hele onderscheid. */
.modal-overlay .wrap {
  padding: 4rem 2rem;
  background: var(--admin-paneel, #f7f7f7);
}

.index.admin .admin.actions .button:hover {
  background-color: #333;
}

/* ANBI documenten sectie */
.index.admin.wrap .anbi-documents-section {
  border: 0.0625rem solid var(--admin-blue-border);
  border-radius: var(--admin-radius);
  padding: 1rem 1.25rem 1.25rem;
  background: var(--admin-white);
}

.index.admin.wrap .anbi-document-category {
  margin-bottom: 1.5rem;
  padding-bottom: 1.25rem;
  border-bottom: 0.0625rem dashed var(--admin-blue-border);
}

.index.admin.wrap .anbi-document-category:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

.index.admin.wrap .anbi-document-category h4 {
  color: var(--admin-blue-dark);
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 0.75rem;
}

.index.admin.wrap .sortable-anbi-docs {
  list-style: none;
  padding: 0;
  margin: 0 0 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.index.admin.wrap .sortable-anbi-docs .existing-document {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.5rem 0.75rem;
  background: var(--admin-blue-light);
  border: 0.0625rem solid var(--admin-blue-border);
  border-radius: var(--admin-radius);
}

.index.admin.wrap .sortable-anbi-docs .drag-handle {
  cursor: grab;
  color: var(--admin-text-light);
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.index.admin.wrap .sortable-anbi-docs .drag-handle:active {
  cursor: grabbing;
}

.index.admin.wrap .sortable-anbi-docs .existing-document a {
  color: var(--admin-blue-dark);
  text-decoration: none;
  font-weight: 500;
  flex-shrink: 0;
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.index.admin.wrap .sortable-anbi-docs .existing-document a:hover {
  text-decoration: underline;
}

.index.admin.wrap .sortable-anbi-docs .existing-document input[type="text"] {
  flex: 1;
  margin: 0;
  padding: 0.4rem 0.6rem;
  font-size: 0.85rem;
}

.index.admin.wrap .sortable-anbi-docs .existing-document button {
  flex-shrink: 0;
  background: transparent;
  color: var(--admin-danger);
  border: 0.0625rem solid var(--admin-danger);
  padding: 0.35rem 0.65rem;
  font-size: 0.8rem;
  border-radius: var(--admin-radius);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.index.admin.wrap .sortable-anbi-docs .existing-document button:hover {
  background: var(--admin-danger);
  color: var(--admin-white);
}

.index.admin.wrap .sortable-anbi-docs .sortable-ghost {
  opacity: 0.4;
}

.index.admin.wrap .sortable-anbi-docs .sortable-chosen {
  background: var(--admin-blue-border);
}

.index.admin.wrap .anbi-document-category .drop {
  border: 0.125rem dashed var(--admin-blue-border);
  border-radius: var(--admin-radius);
  padding: 0.75rem 1rem;
  background: var(--admin-blue-light);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.85rem;
  color: var(--admin-text-light);
}

.index.admin.wrap .anbi-document-category .entry {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.5rem;
  padding: 0.4rem 0.75rem;
  background: var(--admin-blue-light);
  border-radius: var(--admin-radius);
  font-size: 0.85rem;
}

.index.admin.wrap .anbi-document-category .entry .progress {
  flex: 1;
}

.index.admin.wrap .anbi-document-category .entry .progress .bar {
  height: 0.375rem;
  background: var(--admin-blue-border);
  border-radius: 0.25rem;
  overflow: hidden;
}

.index.admin.wrap .anbi-document-category .entry .progress .bar span {
  display: block;
  height: 100%;
  background: var(--admin-blue);
  transition: width 0.15s linear;
}

/* Responsive */
@media (max-width: 48rem) {
  .index.admin.wrap {
    margin: 1rem;
    padding: 1.5rem 1rem;
  }

  .index.admin.wrap .sortable-anbi-docs .existing-document {
    flex-wrap: wrap;
  }

  .index.admin.wrap .sortable-anbi-docs .existing-document input[type="text"] {
    flex-basis: 100%;
  }
}

/* Aanvangstijd in het agendaformulier: de gekozen tijd (`.active`) valt op,
   de rest is een omlijnde knop. Met `:where` zo zwak mogelijk, zodat een
   tenant met eigen regels voor `.time-buttons` (feikeshuis, allesvdk, …)
   die gewoon houdt.

   Dezelfde knoppen voor de keuze "Bestaande locatie" / "Vrije tekst". Die
   staat in base/admin.css standaard uit; een tenant zet hem aan met
   `.location-mode-toggle { display: flex }`. */
:where(.index.admin.wrap) .time-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

:where(.index.admin.wrap) .location-mode-toggle {
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

:where(.index.admin.wrap) .time-buttons button,
:where(.index.admin.wrap) .location-mode-toggle button {
  padding: 0.5rem 1rem;
  border: 0.0625rem solid var(--admin-blue-border);
  border-radius: var(--admin-radius);
  background: var(--admin-white);
  color: var(--admin-blue-dark);
  cursor: pointer;
}

:where(.index.admin.wrap) .time-buttons button:hover,
:where(.index.admin.wrap) .location-mode-toggle button:hover {
  border-color: var(--admin-blue);
  background: var(--admin-blue-light);
}

:where(.index.admin.wrap) .time-buttons button.active,
:where(.index.admin.wrap) .location-mode-toggle button.active {
  border-color: var(--admin-blue-dark);
  background: var(--admin-blue-dark);
  color: var(--admin-white);
  font-weight: 600;
}


/* ── ../base/media-room-admin.css ── */
/* De beheerschermen van de mediakamers (/admin/media/...).

   De kaartenbak zelf staat niet meer hier maar in base/admin.css: dezelfde
   kaartjes met dezelfde greep staan inmiddels ook bij de video's van een
   productie, en dat formulier is van elke tenant. Wat hier overblijft is wat
   alleen een kamer heeft — de kop met de knop naar het doek, de poster naast
   de velden, de opname van de hoorspelkamer, en de balk onderin.

   Bouwt op het gedeelde admin-thema (base/admin-delfts-blauw.css) en gebruikt
   diens variabelen; alles staat onder `.media-room`, zodat het nergens anders
   op het platform doorwerkt. */

/* ── De kop ──────────────────────────────────────────────────────── */

.index.admin.wrap.media-room .media-room-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.index.admin.wrap.media-room .media-room-intro {
    margin: 0.35rem 0 0;
    max-width: 42rem;
    color: var(--admin-text-light);
}

/* ── De sleepzone erboven ────────────────────────────────────────── */

.index.admin.wrap.media-room .media-room-upload {
    margin: 1.5rem 0;
}

.index.admin.wrap.media-room .media-room-upload .hint {
    margin: 0 0 0.75rem;
    color: var(--admin-text-light);
}

.index.admin.wrap.media-room .media-room-upload-entry {
    display: flex;
    align-items: flex-end;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
    padding: 0.75rem;
    background: var(--admin-blue-light);
    border-radius: var(--admin-radius);
}

/* ── Het kaartje met een poster ──────────────────────────────────── */

/* Het gedeelde kaartje is één kolom: greep boven, velden eronder. Hier komt
   de poster erbij, en die hoort ernaast. Op een kaart van een halve
   schermbreedte is dat de enige indeling waarin de poster groot genoeg blijft
   om de film aan te herkennen én de titel op één regel past. */
.index.admin.wrap.media-room .media-card {
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    grid-template-areas:
        "grip grip"
        "poster velden";
}

/* De poster vult de linkerkolom, dus houdt de rechterkolom links geen
   padding over. */
.index.admin.wrap.media-room .media-card-velden {
    padding-left: 0;
}

/* ── De poster ───────────────────────────────────────────────────── */

.index.admin.wrap.media-room .media-card-poster {
    grid-area: poster;
    padding: 0.75rem;
}

/* 16:9, net als op het doek: zo zie je hier hetzelfde beeld als de bezoeker,
   inclusief wat er links en rechts afvalt. */
.index.admin.wrap.media-room .media-card-poster img {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: 0.2rem;
    background: #111;
}

.index.admin.wrap.media-room .media-card-poster-leeg {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 0.0625rem dashed var(--admin-blue-border);
    border-radius: 0.2rem;
    color: var(--admin-text-light);
    font-size: 0.8rem;
}

.index.admin.wrap.media-room .media-card-poster-acties {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.5rem;
}

/* ── De opname (hoorspelkamer) ───────────────────────────────────── */

.index.admin.wrap.media-room .media-card-opname audio {
    display: block;
    width: 100%;
}

.index.admin.wrap.media-room .media-card-opname-regel {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 0.4rem;
    font-size: 0.8rem;
}

/* De bestandsnaam mag de kaart niet oprekken; hij staat er ter herkenning. */
.index.admin.wrap.media-room .media-card-opname-regel a {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.index.admin.wrap.media-room .media-card-opname-leeg {
    margin: 0;
    color: var(--admin-text-light);
    font-style: italic;
}

/* Een kaartje zonder opname heeft niets in het midden; zonder dit zakt het
   naast zijn buren in elkaar. */
.index.admin.wrap.media-room .media-card:has(.media-card-opname-leeg) .media-card-velden {
    justify-content: space-between;
}

/* ── Onderaan ────────────────────────────────────────────────────── */

.index.admin.wrap.media-room .media-room-empty {
    margin: 2rem 0;
    color: var(--admin-text-light);
    font-style: italic;
}

/* Blijft in beeld: met dertien kaartjes staat "Opslaan" anders een halve
   pagina onder de kaart waar je net in typte, en daar gaat werk verloren. */
.index.admin.wrap.media-room .media-room-balk {
    position: sticky;
    bottom: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin: 0 -2rem -2.5rem;
    padding: 1rem 2rem;
    background: var(--admin-white);
    border-top: 0.0625rem solid var(--admin-blue-border);
}

/* ── De verwijzing in het paginaformulier ────────────────────────── */

.index.admin.wrap .media-room-verwijzing {
    margin: 0;
    color: var(--admin-text-light);
}

/* ── Smallere schermen ───────────────────────────────────────────── */

/* De bak gaat al naar één kolom in base/admin.css. Hier hoort alleen wat met
   de poster te maken heeft: onder de 64rem is een halve kolom te smal voor
   poster náást velden, dus gaat de poster erboven. */
@media (width < 64rem) {
    .index.admin.wrap.media-room .media-card {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "grip"
            "poster"
            "velden";
    }

    .index.admin.wrap.media-room .media-card-velden {
        padding: 0 0.75rem 0.75rem;
    }
}


/* ── ../base/pages-index.css ── */
/* ============================================================
   Pages Index – admin overzicht van pagina's
   Tabel, badges, statuslabels en tenant-switcher.
   ============================================================ */

/* --- Waarschuwing duplicaten --- */
.pages-table .alert-warning {
    background: #fff3cd;
    border: 0.0625rem solid #ffeaa7;
    padding: 1rem;
    margin: 1rem 0;
    border-radius: 0.25rem;
}

/* --- Tabel --- */
.pages-table table {
    width: 100%;
    border-collapse: collapse;
}

.pages-table tr.duplicate {
    background: #fff3cd;
}

.pages-table tbody tr {
    border-bottom: 0.0625rem solid #eee;
}

/* --- Badges (homepage, duplicate) --- */
.badge--homepage {
    background: #17a2b8;
    color: white;
    padding: 0.2rem 0.5rem;
    border-radius: 0.1875rem;
    font-size: 0.8rem;
    margin-left: 0.5rem;
}

.badge--duplicate {
    background: #dc3545;
    color: white;
    padding: 0.2rem 0.5rem;
    border-radius: 0.1875rem;
    font-size: 0.8rem;
    margin-left: 0.5rem;
}

/* Een concept staat in de lijst van de beheerder, maar nergens anders. Grijs en
   niet rood: het is geen fout, het is nog niet af. */
.badge--concept {
    background: #6c757d;
    color: white;
    padding: 0.2rem 0.5rem;
    border-radius: 0.1875rem;
    font-size: 0.8rem;
    margin-left: 0.5rem;
    vertical-align: middle;
}

/* --- Status active/inactive --- */
.status--active {
    color: #28a745;
}

.status--inactive {
    color: #dc3545;
}

/* --- Section-tags (Producties, Agenda, Nieuws) --- */
.pages-table td.sections {
    font-size: 0.9rem;
}

.section-tag {
    background: #e9ecef;
    padding: 0.2rem 0.4rem;
    border-radius: 0.1875rem;
    margin-right: 0.3rem;
}

/* --- Datum kolom --- */
.pages-table td.created {
    color: #666;
    font-size: 0.9rem;
}

/* --- Acties cel --- */
.pages-table td.actions-cell .actions-row {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.pages-table .action-link {
    font-size: 0.8rem;
    padding: 0.3rem 0.6rem;
}

.pages-table .btn-deactivate {
    font-size: 0.8rem;
    padding: 0.3rem 0.6rem;
    background: #ffc107;
    border-color: #ffc107;
}

.pages-table .btn-activate {
    font-size: 0.8rem;
    padding: 0.3rem 0.6rem;
    background: #28a745;
    border-color: #28a745;
}

.pages-table .btn-delete {
    font-size: 0.8rem;
    padding: 0.3rem 0.6rem;
    background: #dc3545;
    border-color: #dc3545;
    color: white;
}

/* --- Tenant switcher --- */
.tenant-switcher {
    margin-top: 3rem;
    padding: 1rem;
    background: #f8f9fa;
    border-radius: 0.25rem;
}

.tenant-switcher__options {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin-top: 1rem;
}

.tenant-switcher__current {
    padding: 0.5rem 1rem;
    background: #007bff;
    color: white;
    border-radius: 0.25rem;
}

.tenant-switcher__link {
    padding: 0.5rem 1rem;
    background: #6c757d;
    color: white;
    text-decoration: none;
    border-radius: 0.25rem;
}


/* ── ../base/form.css ── */
.form-container {
    position: relative;
    max-width: 60rem;
    padding: clamp(1rem, 0.1429rem + 4.2857vw, 4rem);
    z-index: 10001;
    box-shadow: 0 0 2rem rgba(0, 0, 0, 0.25);
}

.form-container .button {
    position: relative;
    margin-top: 4rem;
    font-size: 1.125rem;
    border-width: 0.25rem;
}

.form-container h3 {
    margin-bottom: 0;
}

.form-container form {
    margin-top: 3rem;
}

label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: 500;
    letter-spacing: 0.0625rem;
    font-size: 0.9375rem;
}

input,
textarea {
    display: block;
    border: none;
    outline: none;
}

input {
    padding: 0.75rem 0.25rem;
    /* width: clamp(15rem, 13.684rem + 7.018vw, 20rem); */
    width: 20.5rem;
    border-radius: 0.25rem;
}

::placeholder {
    color: var(--color-blue);
    text-transform: lowercase;
    font-size: 1.125rem;
    letter-spacing: 0.25rem;
    padding: 1rem 0 0 0.5rem;
}

input,
textarea {
    margin-bottom: 1rem;
    color: #f7f7f7;
    padding-left: 0.5rem;
}

/* Radio/checkbox horen niet onder de bare-`input` width/display/padding-regels
   hierboven — anders worden ze uitgerekt tot 20.5rem en op een eigen regel
   gezet. Reset ze terug naar inline native gedrag. Lokale overrides
   (zoals .input-radio, .video-type-toggle) winnen op specificiteit. */
input[type="radio"],
input[type="checkbox"] {
    width: auto;
    display: inline-block;
    padding: 0;
    margin: 0 0.375rem 0 0;
    vertical-align: middle;
}

textarea {
    width: clamp(18.75rem, 12.632rem + 32.632vw, 42rem);
    height: 12.5rem;
    border-radius: 0.5rem;
}

form > div > div {
    padding: 1rem 1rem 1rem 0;
}

form > div > div:not(:first-of-type) {
    border-top: 0.0625rem solid rgba(255, 255, 255, 0.2);
}

form .thumbnail,
.admin section {
    margin: 2.5rem 0;
    padding-top: 1.5rem;
    border-top: 0.0625rem solid rgba(0, 0, 0, 0.1);
}

input:focus,
textarea:focus,
select:focus {
    outline: 0.125rem solid rgba(0, 0, 0, 0.15);
    outline-offset: 0.125rem;
}

form .thumbnail header,
form .document-upload-section header,
section.gallery-section header,
section.makers header,
section.checkbox-fields header,
section.status-section header,
.admin section header {
    margin-bottom: 0.5rem;
    font-weight: 500;
    letter-spacing: 0.0625rem;
    font-size: 0.9375rem;
}

form .thumbnail section.input,
form .document-upload-section section.input {
    /* Eén hoogte voor de vakken van een uploadveld: kiezen, slepen, en wat er
       nu ligt. Die hoogte stond eerder als `height: 20rem` op de voorbeeldkaart
       alleen — die kaart bepaalde daarmee de hoogte van de hele rij en de rest
       rekte mee, dus zonder kaart was het veld ineens veel lager. Nu staat hij
       één keer en houden de vakken zich er alle drie aan. */
    --uploadvak-hoogte: 16rem;
    width: 100%;
    /* Links gelijk met de kop van het veld: de vakken stonden 2rem naar binnen
       terwijl de kop en het streepje dat niet deden. De onderrand van 2.5rem
       komt van `.admin section` — dat is de ruimte tússen twee secties, en
       binnen dit paneel is het een lap leegte onder de vakken. */
    padding: 1.5rem 0 0;
    margin-bottom: 0;
}

form .thumbnail > * {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

form .thumbnail .drop,
form .thumbnail .entry,
form .thumbnail .current-image,
form .thumbnail .selected-image,
form .document-upload-section .drop,
form .document-upload-section .entry {
    min-height: var(--uploadvak-hoogte, 16rem);
}

/* De knoppen vullen hun kolom en beginnen bovenaan, zodat die kolom een kolom
   is en geen zwevend paar in het midden. De onderlinge ruimte komt van de gap;
   de marge die de knoppen zelf meebrengen zou er anders bovenop komen. */
form .thumbnail .image-options,
form .document-upload-section .image-options {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0.5rem;
}

form .thumbnail .image-options .button,
form .document-upload-section .image-options .button {
    /* `base/button.css` geeft elke knop 1.25rem rechts en de bibliotheekknoppen
       0.5rem onder, voor knoppen die op een rij staan. Hier staan ze onder
       elkaar in een kolom met een eigen gap; die marges maken de knoppen dan
       ongelijk breed en zetten er dubbele ruimte tussen. */
    margin: 0;
}

form .thumbnail .drop {
    padding: 0 1rem;
}

form .thumbnail .drop input {
    padding-top: 0;
}

form .thumbnail label {
    line-height: 1.25;
}

select.select {
    padding: 0.75rem 2.5rem 0.75rem 1rem;
    width: clamp(16rem, 12.842rem + 16.842vw, 28rem);
    border-radius: 0.125rem;
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23333' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    font-family: inherit;
    font-size: 0.9375rem;
    letter-spacing: 0.0625rem;
    text-transform: none;
}

select.select::-webkit-scrollbar {
    width: 0.5rem;
}

select.select::-webkit-scrollbar-track {
    background: transparent;
}

select.select::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.2);
    border-radius: 0.25rem;
}

form .thumbnail img {
    object-fit: contain;
    border: 0.25rem solid #fff;
    box-shadow: 0 0 2rem rgba(0, 0, 0, 0.15);
}

.current-image,
form .thumbnail .selected-image {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    gap: 0.5rem;
    padding: 1rem;
    border-radius: 0.5rem;
    border: 0.125rem solid #ccc;
}

/* Het kopje van zo'n kaart is een label, geen titel: even groot als de kop van
   het veld eromheen. Uit `base/documents.css` komt 1.35rem, wat klopt boven een
   documentenlijst maar niet in een vak van deze maat. */
form .thumbnail .selected-image h4,
form .thumbnail .current-image > header {
    margin: 0;
    font-weight: 500;
    font-size: 0.9375rem;
    letter-spacing: 0.0625rem;
}

form .thumbnail .selected-image p {
    margin: 0;
    font-size: 0.875rem;
}

/* Verwijderen is een uitweg, geen hoofdhandeling: zo breed als het woord. */
form .thumbnail .selected-image button {
    align-self: flex-start;
}

/* De foto vult de kaart en wordt niet bijgesneden: je kijkt naar wat je koos,
   niet naar het midden ervan. `min-height: 0` omdat een flex-item anders niet
   kleiner wil worden dan zijn eigen inhoud. */
form .thumbnail .current-image img,
form .thumbnail .selected-image img {
    flex: 1;
    min-height: 0;
    width: 100%;
    object-fit: contain;
}

.tenant-selector {
    padding: 3rem;
}

.tenant-selector .checkbox-group {
    display: flex;
}

.tenant-selector .checkbox-group .checkbox-item {
    display: inline-flex;
    margin: 1rem 0;
}

.tenant-selector .checkbox-group .checkbox-item input {
    width: 1.5rem;
}

.tenant-selector .checkbox-group .checkbox-item span {
    display: inline-block;
    margin-right: 2rem;
}

.input-group {
    display: flex;
}

.input-group {
    justify-content: space-between;
}

.checkbox-fields .checkbox-item {
    display: inline-flex;
    margin: 1rem 0;
}

.checkbox-fields .checkbox-item input {
    width: 1.5rem;
}

.checkbox-fields .checkbox-item span {
    display: inline-block;
    margin-right: 2rem;
}

section.checkbox-fields,
section.status-section {
    margin: 1.5rem 0;
    padding: 1.5rem 0;
}

section.checkbox-fields header {
    letter-spacing: 0.125rem;
}

section.checkbox-fields header p,
form header p,
.social-media-main label {
    margin: 0.25rem 0;
    font-size: 0.9375rem;
    font-style: italic;
    font-weight: normal;
    padding: 0;
    opacity: 0.9;
    line-height: 1.4;
    letter-spacing: normal;
}

form header p span {
    font-style: normal;
    font-size: 1.5rem;
}

section.checkbox-fields .checkboxes {
    padding: 1.5rem 1rem;
    display: flex;
    flex-wrap: wrap;
    border: 0.0625rem dotted #fff;
    border-radius: 0.25rem;
}

section.checkbox-fields .checkboxes div,
section.status-section .rbtns-body div {
    display: flex;
    width: clamp(8rem, 6.947rem + 5.614vw, 12rem);
    margin: 0.5rem 0.5rem 0 0;
}

section.status-section .rbtns-body div {
    width: 33.333%;
}

section.checkbox-fields .checkboxes .label-radio,
section.status-section .rbtns-body,
section.status-section .rbtns-body label {
    display: flex;
}

section#english-fields-production {
    padding: 3rem clamp(1rem, 0.539rem + 2.456vw, 2.75rem);
    position: relative;
}

.form-download-link,
.form-slug,
.form-input-order {
    display: none;
}

input[type="file" i] {
    font-size: 0.875rem;
}

section.status-section .rbtns-body label {
    align-items: center;
}

section.status-section .rbtns-body {
    padding: 2rem 1rem;
}

section.checkbox-fields .checkboxes .label-radio input.input-radio,
section.status-section .rbtns-body div input.input-radio {
    min-width: 0;
    width: 2rem;
    height: 1rem;
}

label.radio-option input {
    margin-top: 1rem;
}

input[type="file"]::file-selector-button {
    display: ruby-text;
    font-size: 0.875rem;
    transition: color 1s;
    cursor: pointer;
}

.gallery-item-controls > input.caption-input {
    width: 16rem;
    height: 2rem;
    margin: 0.25rem 0 0 0.25rem;
}

section.video-urls > div {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
    gap: 2rem;
    padding: 1.5rem;
}

section.funding .funding-main,
section.social-media .social-media-main {
    padding: 2rem;
}

section.funding .funding-main p {
    margin: 0;
    line-height: 1;
}

.location .location-selector {
    position: relative;
}

.location .location-selector .actions {
    position: absolute;
    right: 1rem;
    top: 4rem;
}

.popup {
    position: absolute;
    left: 50%;
    top: 50%;
    background-color: #fff265;
    color: #333;
    border: 0.5rem solid;
    transform: translate(-50%, -50%);
    transition: all 0.5s;
    font-size: 1.5rem;
    opacity: 0;
}

.fade-out {
    opacity: 0;
    transition: opacity 1s ease-out;
}

.form-group:not(:first-of-type) {
    margin: 1rem 0 2rem;
}

.form-group:first-of-type {
    margin-bottom: 2rem;
}

.form-group label {
    width: 18.75rem;
    display: flex;
    /* justify-content: space-between;
    align-items: center; */
    flex-direction: column;
}

.maker-selector,
.production-selector,
.location-selector,
section.start-time .time-buttons {
    padding: 2rem;
}

section.makers .maker-input {
    position: relative;
    width: fit-content;
}

section.makers span.icon-search {
    background-color: #333;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    right: 1rem;
}

.production-selector .search-input {
    border-bottom: none;
    background-color: #fff;
    width: fit-content;
    padding: 0 .75rem;
}

.production-selector .search-input input {
    background-color: #fff;
}

.form-group label[for="message"] {
    width: clamp(23rem, 21rem + 10vw, 30rem);
}

span.error {
    font-size: 0.875rem;
    font-family: var(--font-thin);
    font-style: italic;
    letter-spacing: 0.0625rem;
}

.spinner {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    border-top-color: #fff;
    animation: spin 1s ease-in-out infinite;
    margin-right: 0.5rem;
}

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

.btn-submit.submitting {
    opacity: 0.8;
    cursor: not-allowed;
}

.checkboxes {
    padding: 2rem 1rem;
    display: flex;
}

.checkboxes div {
    display: flex;
    width: clamp(8rem, 6.947rem + 5.614vw, 12rem);
}

.checkboxes .label-radio {
    display: flex;
}

section.checkboxes {
    margin: 1.5rem 0;
}

section.checkboxes header p {
    margin: 0 0 0.125rem 0;
}

.checkboxes .label-radio input.input-radio {
    min-width: 0;
    width: 2rem;
}

section.press-items-section > .button {
    margin: 1.5rem 0 0;
}

ul.press-items-list:not(:has(li)) {
    display: none;
}

@media (width >= 48rem) {
    form .thumbnail section.input,
    form .document-upload-section section.input {
        display: grid;
        grid-template-columns: 2fr 3fr 2fr;
        /* Eén vaste rijhoogte in plaats van "zo hoog als het langste vak".
           Dat laatste laat de hoogte van het veld afhangen van het formaat van
           de foto die je toevallig koos: een staande plaat maakte er een toren
           van. En omdat de hoogte dan pas achteraf vastligt, weet een foto in
           zo'n vak niet waar hij zich naar moet schikken en gaat hij op ware
           grootte staan. */
        grid-auto-rows: var(--uploadvak-hoogte, 16rem);
        justify-content: space-between;
        align-items: stretch;
        gap: 2rem;
        margin-top: 0;
    }

    /* Drie kolommen zijn er alleen als er ook een bibliotheekknop staat:
       kiezen, slepen, en wat er nu ligt. Een veld dat alleen uploadt (titellogo,
       scèneknop, een plaat per taal) houdt er twee over, anders staat de
       sleepzone in de smalle kolom die voor de knoppen bedoeld was. */
    form .thumbnail section.input:not(:has(.image-options)) {
        grid-template-columns: 3fr 2fr;
    }

}

.honeypot {
    display: none;
}

/* De video's van een productie staan sinds 7 sep 2026 in de gedeelde
   kaartenbak (`.media-cards` in base/admin.css), niet meer in een eigen rij
   vakken. Wat hieronder overblijft is de keuzerij Vimeo/YouTube/Bunny, want
   die staat op elk scherm waar een video gekozen wordt. */

/* Radio toggle buttons for video type */
.video-type-toggle {
    display: flex;
    gap: 0;
}

.video-type-toggle input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.video-type-toggle label {
    cursor: pointer;
    padding: 0.35rem 0.75rem;
    border: 0.0625rem solid;
    font-size: 0.8rem;
    transition: background 0.15s, color 0.15s;
    user-select: none;
}

.video-type-toggle label:first-of-type {
    border-right: none;
}

.video-type-toggle input[type="radio"]:checked + label {
    background-color: rgba(0, 0, 0, 0.12);
    font-weight: bold;
}

.video-item-actions {
    display: flex;
    gap: 1.25rem;
    align-items: center;
    margin-top: 1.25rem;
}

/* ============================================ TICKETING — onmiskenbare form-errors
   Globaal voor alle tenants die de bestelpagina (section.ticketing.order.wrap)
   tonen. Tenants kunnen de kleur overschrijven via --form-error-color /
   --form-error-bg op een hogere specificity-regel. */

section.ticketing.order.wrap form {
    --form-error-color: #b3261e;
    --form-error-bg: #fdecec;
}

/* foutmelding-blok (Phoenix's <.error> rendert .text-rose-600) */
section.ticketing.order.wrap form .text-rose-600,
section.ticketing.order.wrap form p.text-rose-600,
section.ticketing.order.wrap form [class*="text-rose"] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.5rem 0 0;
    padding: 0.625rem 0.875rem;
    background-color: var(--form-error-bg);
    border-left: 0.375rem solid var(--form-error-color);
    color: var(--form-error-color);
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.4;
    border-radius: 0 0.125rem 0.125rem 0;
    text-transform: none;
}

section.ticketing.order.wrap form .text-rose-600::before {
    content: "⚠";
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.375rem;
    height: 1.375rem;
    color: var(--form-error-color);
    font-size: 1.125rem;
    font-weight: 700;
}

section.ticketing.order.wrap form .text-rose-600 .hero-exclamation-circle-mini,
section.ticketing.order.wrap form .text-rose-600 svg {
    display: none;
}

/* invalid veld */
section.ticketing.order.wrap form input[aria-invalid="true"],
section.ticketing.order.wrap form select[aria-invalid="true"],
section.ticketing.order.wrap form textarea[aria-invalid="true"],
section.ticketing.order.wrap form input.border-rose-400,
section.ticketing.order.wrap form select.border-rose-400,
section.ticketing.order.wrap form textarea.border-rose-400 {
    border-color: var(--form-error-color);
    border-width: 0.125rem;
    box-shadow: 0 0 0 0.1875rem rgba(179, 38, 30, 0.18);
    background-color: rgba(179, 38, 30, 0.05);
}

/* label van invalid veld kleurt mee + ⚠ */
section.ticketing.order.wrap form div:has(> input[aria-invalid="true"]) > label,
section.ticketing.order.wrap form div:has(> select[aria-invalid="true"]) > label,
section.ticketing.order.wrap form div:has(> textarea[aria-invalid="true"]) > label {
    color: var(--form-error-color);
    font-weight: 700;
}

section.ticketing.order.wrap form div:has(> input[aria-invalid="true"]) > label::before,
section.ticketing.order.wrap form div:has(> select[aria-invalid="true"]) > label::before,
section.ticketing.order.wrap form div:has(> textarea[aria-invalid="true"]) > label::before {
    content: "⚠ ";
    color: var(--form-error-color);
}

/* mobiel: groter, opvallender, korte shake-puls bij verschijnen */
@media (max-width: 40rem) {
    section.ticketing.order.wrap form .text-rose-600,
    section.ticketing.order.wrap form p.text-rose-600,
    section.ticketing.order.wrap form [class*="text-rose"] {
        padding: 0.875rem 1rem;
        font-size: 1.0625rem;
        border-left-width: 0.5rem;
        animation: kkv-form-error-pulse 0.6s ease-out 1;
    }

    section.ticketing.order.wrap form .text-rose-600::before {
        width: 1.625rem;
        height: 1.625rem;
        font-size: 1.375rem;
    }
}

@keyframes kkv-form-error-pulse {
    0%   { transform: translateX(0); }
    20%  { transform: translateX(-0.3125rem); }
    40%  { transform: translateX(0.3125rem); }
    60%  { transform: translateX(-0.1875rem); }
    80%  { transform: translateX(0.1875rem); }
    100% { transform: translateX(0); }
}

/* --- Vertaal-tabbladen (productieformulier) --------------------------------
   Staan achter een vinkje: de meeste voorstellingen hebben geen vertaling.
--------------------------------------------------------------------------- */
.translations .translation-tabs {
    display: flex;
    gap: 0.25rem;
    margin-bottom: -1px;
}

.translations .translation-tab {
    padding: 0.5rem 1rem;
    border: 1px solid #ccc;
    border-bottom: none;
    background: #f1f1f1;
    color: #444;
    font: inherit;
    line-height: 1.2;
    cursor: pointer;
}

.translations .translation-tab:hover {
    background: #e8e8e8;
}

.translations .translation-tab.active {
    background: #fff;
    color: #000;
    font-weight: 600;
}

/* Bolletje = deze taal heeft al inhoud. */
.translations .translation-tab .dot {
    margin-left: 0.4rem;
    color: #2a8a5a;
    font-size: 0.7em;
    vertical-align: middle;
}

.translations .translation-panel {
    padding: 1rem;
    border: 1px solid #ccc;
    background: #fff;
}

.translations .translation-panel .hint {
    margin: 0 0 1rem;
    color: #666;
    font-size: 0.9rem;
}

/* ── De platen van een vertaling ─────────────────────────────────────────────

   Bij Hotel Modern hangen er twee aan een vertaling: het titellogo en het
   voorwerp dat als knop op de scène ligt. Allebei klein — een woordbeeld, een
   uitgeknipt menukaartje. Ze stonden onder elkaar met het gewone uploadvak van
   zestien rem, en namen samen meer hoogte in dan alle tekst van die vertaling
   bij elkaar. Nu staan ze naast elkaar, en binnen elke plaat staat het
   sleepvak naast het beeld dat er al ligt.

   De selectors noemen `.index.admin.wrap` mee. Zonder dat won de beheeropmaak
   (`base/admin-delfts-blauw.css`) het van de maten hier — die zet elk beeld in
   een uploadveld op `width: 100%`, gezet voor een paneel over de volle breedte.
   In een halve kolom werd de duimnagel daardoor zo breed als de plaat zelf en
   viel de knop Verwijderen naast het kader.

   Twee kolommen alleen waar ze allebei ruim genoeg zijn. Dat hing eerst aan een
   mediaquery op 48 rem, en die mat het verkeerde: het venster, terwijl het
   werkblad van het beheer smaller is dan het scherm. Op een breed venster kreeg
   een paneel van 60 rem daardoor twee kolommen van nog geen 24 rem. `auto-fit`
   met een ondergrens rekent met de ruimte die er hier werkelijk is, en zet er
   één kolom neer zodra twee te krap zouden worden. */
.translations .translation-images {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
    gap: 1.5rem;
    margin-top: 1rem;
}

.index.admin.wrap .translations .translation-images .thumbnail {
    /* Het vak dat `base/form.css` op zestien rem zet, hier op een derde
       daarvan: er hoeft alleen een knop en een regel tekst in. */
    --uploadvak-hoogte: 5.5rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin: 0;
    padding: 1rem;
}

.index.admin.wrap .translations .translation-images .thumbnail > header {
    flex: 1 0 100%;
    margin: 0;
}

/* Het sleepvak zelf gaat ook terug: `base/drop.css` zet er twee rem omheen en
   nog eens een rem om de knop, want daar is het een vak van zestien rem hoog
   waarin die lucht klopt. Hier is het een strook. */
.index.admin.wrap .translations .translation-images .drop {
    gap: 0.5rem;
    padding: 0.75rem;
}

/* Achter de knop van een bestandsveld zet de browser nog "no file chosen". Die
   tekst staat doorzichtig (zie `base/drop.css`), maar telt wél mee in de
   breedte: zeventien rem die je niet ziet. In een paneel over de volle breedte
   valt dat niet op; hier is het precies de reden dat het sleepvak en de
   duimnagel niet meer naast elkaar pasten. Op nul zetten haalt de tekst uit de
   berekening; de knop krijgt zijn eigen maat terug. */
.index.admin.wrap .translations .translation-images .drop input[type="file"] {
    padding: 0;
    font-size: 0;
}

.index.admin.wrap
    .translations
    .translation-images
    .drop
    input[type="file"]::file-selector-button {
    font-size: 0.8125rem;
}

/* Sleepvak en huidig beeld delen de breedte; ligt er nog niets, dan neemt het
   sleepvak de hele plaat.

   `min-width: min-content` en niet nul. Op nul mag een flex-item smaller worden
   dan wat erin staat, en dan schuift de knop Verwijderen het kader uit — wat er
   bij een paneel van rond de 60 rem ook precies gebeurde. Nu houden de twee
   hun eigen inhoud aan als ondergrens, en gaan ze onder elkaar staan zodra ze
   naast elkaar niet meer passen. */
.index.admin.wrap .translations .translation-images .drop,
.index.admin.wrap .translations .translation-images .current-image,
.index.admin.wrap .translations .translation-images .flyer-preview {
    flex: 1 1 12rem;
    min-width: min-content;
    margin: 0;
}

/* Het beeld naast de kop, niet eronder: bij deze hoogte is een kolom van kop,
   plaatje en knop precies één regel te veel. */
.index.admin.wrap .translations .translation-images .current-image {
    display: grid;
    /* De tweede kolom op `min-content` en niet op nul: anders telt de inhoud van
       de kaart niet mee in haar eigen ondergrens en helpt de `min-width`
       hierboven niets. */
    grid-template-columns: auto minmax(min-content, 1fr);
    grid-template-rows: auto auto;
    align-items: center;
    gap: 0.35rem 0.75rem;
    padding: 0.75rem;
}

.index.admin.wrap .translations .translation-images .current-image > header {
    grid-column: 2;
    /* Op één regel houden: in een smalle kolom breekt "Huidig beeld:" anders
       in tweeën en is de plaat meteen een regel hoger. */
    white-space: nowrap;
    font-size: 0.8125rem;
}

/* De duimnagel blijft een duimnagel. `width: auto` en een bovengrens in beide
   richtingen, zodat een liggend woordbeeld en een staand menukaartje even veel
   ruimte innemen. */
.index.admin.wrap .translations .translation-images .current-image img {
    grid-row: 1 / span 2;
    flex: none;
    width: auto;
    max-width: 4.5rem;
    max-height: 4.5rem;
    margin: 0;
    object-fit: contain;
}

/* Verwijderen is hier een uitweg naast een duimnagel, geen balk over de volle
   breedte van het vak. */
.index.admin.wrap .translations .translation-images .current-image .button {
    grid-column: 2;
    justify-self: start;
    margin: 0;
    padding: 0.25rem 0.6rem;
    font-size: 0.8125rem;
    white-space: nowrap;
}

/* --- Aanmaken in vragen -------------------------------------------------- */
/* Eén vraag per scherm. Alles hier dient dat: veel lucht rond de vraag, de al
   gegeven antwoorden ingetogen erboven, en verder zo min mogelijk. De selectors
   noemen `.index.admin.wrap` mee waar ze de gewone beheeropmaak moeten winnen —
   die maakt van elke footer een plakkende balk en van elke link een knop, en dat
   is precies wat een vragenscherm niet moet zijn. */

.wizard > header p {
    color: #666;
    font-size: 0.9rem;
}

.wizard .wizard-answers,
.wizard .wizard-question,
.wizard .wizard-footnote,
.wizard footer.wizard-actions {
    max-width: 42rem;
}

/* Vier tot zes vragen achter elkaar: de knoppenrij mag niet gaan zwemmen. */
.wizard footer.wizard-actions .btn-small {
    white-space: nowrap;
}

.wizard .wizard-answers {
    margin: 1.5rem 0 0;
    padding: 0;
    list-style: none;
    border-left: 0.1875rem solid #e0e0e0;
}

.wizard .wizard-answers li {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.35rem 0 0.35rem 1rem;
    font-size: 0.9rem;
}

.wizard .wizard-answers .label {
    flex: 0 0 7rem;
    color: #888;
}

.wizard .wizard-answers .value {
    flex: 1 1 auto;
    color: #222;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.wizard .wizard-answers button {
    flex: 0 0 auto;
    border: 0;
    padding: 0;
    background: none;
    color: #666;
    font-size: 0.85rem;
    text-decoration: underline;
    cursor: pointer;
}

.wizard .wizard-answers button:hover {
    color: #000;
}

/* De beheeropmaak zet een scheidingslijn boven elke `section`; hier is er niets
   om van te scheiden — er staat maar één vraag. */
.wizard .wizard-question {
    margin: 2rem 0 0;
    padding-top: 0;
    border-top: 0;
}

.wizard .wizard-question header h3 {
    margin: 0;
    font-size: 1.4rem;
}

.wizard .wizard-question header p {
    margin: 0.35rem 0 1rem;
    color: #666;
    font-size: 0.95rem;
}

/* Het antwoordveld is het enige waar je hier iets mee kunt: dus groot. Maar niet
   hoger dan het antwoord: twee zinnen vragen geen half scherm. */
.index.admin.wrap.wizard .wizard-question > input[type="text"],
.index.admin.wrap.wizard .wizard-question > textarea {
    display: block;
    width: 100%;
    max-width: 42rem;
    padding: 0.75rem 0.9rem;
    border: 0.0625rem solid #bbb;
    background: #fff;
    font-family: inherit;
    font-size: 1.15rem;
    line-height: 1.45;
}

.index.admin.wrap.wizard .wizard-question > textarea {
    height: 6rem;
    min-height: 0;
    resize: vertical;
}

.wizard .wizard-question > input[type="text"]:focus,
.wizard .wizard-question > textarea:focus {
    border-color: #333;
    outline: none;
}

.wizard .wizard-question .hint {
    margin: 0.5rem 0 0;
    color: #888;
    font-size: 0.85rem;
}

/* Geen plakbalk onderaan: het scherm is kort, de knop hoort bij de vraag. */
.index.admin.wrap.wizard footer.wizard-actions {
    position: static;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    gap: 1.5rem;
    width: auto;
    margin: 2rem 0 0;
    padding: 0;
    border: 0;
    background: none;
}

/* Vorige, Nu al aanmaken en Annuleren zijn geen knoppen: het zijn uitwegen.
   (Het zijn technisch wél verzendknoppen — zie het formulier — dus ze worden op
   hun klasse aangesproken en niet op hun type.)

   `box-shadow: none` erbij: het beheer tekent de rand van een omlijnde knop
   (`a.button.back`, zie admin-delfts-blauw.css) als inset-schaduw, niet als
   border. Zonder deze regel bleef die rand staan en stond Annuleren als
   onderstreepte tekst in een krap kadertje. */
.index.admin.wrap.wizard footer.wizard-actions .btn-small,
.index.admin.wrap.wizard footer.wizard-actions a.back {
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: none;
    color: #666;
    font-size: 0.9rem;
    font-weight: 400;
    text-decoration: underline;
    cursor: pointer;
}

.index.admin.wrap.wizard footer.wizard-actions .btn-small:hover,
.index.admin.wrap.wizard footer.wizard-actions a.back:hover {
    background: none;
    color: #000;
}

/* Het publiceervinkje onder de aankondiging van een republiek-avond. */
.wizard .wizard-publiceren {
    display: flex;
    margin-top: 1.5rem;
}

.wizard .wizard-footnote {
    margin-top: 2rem;
    color: #888;
    font-size: 0.85rem;
}

/* De beeldvraag is er één van drie en hoort er niet zwaarder uit te zien dan de
   andere twee: geen omkaderd blok, en de bibliotheekknop laat de nadruk aan de
   knop waar het scherm mee eindigt. */
.index.admin.wrap.wizard .wizard-question.thumbnail {
    margin: 2rem 0 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
}

.index.admin.wrap.wizard .wizard-question.thumbnail > header {
    margin-bottom: 0;
    font-weight: 400;
    font-size: 1rem;
}

.index.admin.wrap.wizard .wizard-question .image-options {
    display: block;
    margin-bottom: 1rem;
}

.index.admin.wrap.wizard .wizard-question .image-options .button {
    background: none;
    border: 0.0625rem solid currentColor;
    color: inherit;
}

.index.admin.wrap.wizard .wizard-question .image-options .button:hover {
    background: rgba(0, 0, 0, 0.05);
}

/* Iconen zijn maskers: hun kleur komt uit de achtergrond. Op een knop zonder
   vulling moeten ze dus meekleuren met de tekst, anders zijn ze wit op wit. */
.index.admin.wrap.wizard .wizard-question .image-options .button [class*="icon-"] {
    background-color: currentColor;
}

.wizard .wizard-answers .value.leeg {
    color: #aaa;
    font-style: italic;
}

/* De schrijfvragen: de editor is het scherm, dus krijgt hij de ruimte. */
.wizard .wizard-rich .quill-container {
    max-width: 42rem;
}

.wizard .wizard-rich .ql-toolbar,
.wizard .wizard-rich .ql-container {
    border-color: #bbb;
}

/* De melding onder een Bunny-sleepzone. Staat bewust náást het sleepvak en niet
   erin: dat vak draagt `phx-update="ignore"`, dus alles binnenin blijft staan
   zoals de browser het achterliet en zou door de server nooit bijgewerkt worden.
   Een flash was hier de logische plek, maar die komt op dit platform niet in
   beeld — de flash_group staat in de root-layout, die LiveView na de eerste
   render niet meer aanraakt. */
.bunny-melding {
    margin: 0.5rem 0 0;
    padding: 0.5rem 0.625rem;
    border-radius: 0.1875rem;
    font-size: 0.875rem;
}

.bunny-melding-ok {
    background: #dff0d8;
    color: #2c5d2c;
}

.bunny-melding-fout {
    background: #f5d9d6;
    color: #7a2118;
}

/* Een reeks speelbeurten (`AgendaItemLive.Form`): de einddatum en de
   weekdagen onder het vinkje, de dagen naast elkaar. */
.reeks-velden > div {
    margin: 1rem 0;
}

.reeks-dagen {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    margin: 1rem 0;
    padding: 0;
    border: 0;
}

.reeks-dagen legend {
    width: 100%;
    margin-bottom: 0.5rem;
}

.reeks-overzicht {
    margin-top: 1rem;
}


/* ── ../base/drop.css ── */
.drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 2rem;
  border: 0.125rem dashed rgba(0, 0, 0, 0.3);
  border-radius: 0.5rem;
  transition:
    border-color 0.2s,
    background-color 0.2s;
}

.drop:hover {
  border-color: rgba(0, 0, 0, 0.5);
  background-color: rgba(0, 0, 0, 0.02);
}

.drop label {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  cursor: pointer;
  margin: 0;
}

.drop input[type="file"] {
  width: auto;
  padding: 1rem;
  margin: 0;
  /* De browser zet achter de knop nog "no file chosen", en in een sleepzone met
     een eigen regel eronder is dat ruis die bovendien buiten de zone uitsteekt.
     Alleen de tekst van het veld gaat weg; de knop hieronder zet zijn eigen
     kleur terug, en wat je koos zie je aan de voorbeeldkaart ernaast. */
  color: transparent;
}

.drop input[type="file"]::file-selector-button {
  background-color: #fff;
  color: black;
  border: 0.125rem solid;
  border-radius: 0.25rem;
  padding: 0 1rem;
  min-height: 2rem;
  font-variant: all-small-caps;
  cursor: pointer;
}

@media (hover: hover) {
  .drop input[type="file"]::file-selector-button:hover {
    opacity: 0.85;
  }
}

.drop span {
  text-align: center;
  font-size: 0.9375rem;
  opacity: 0.7;
}

/* De waarschuwing hoort bij de zone eromheen, niet bij één bestand: hij staat
   direct onder de streepjesrand en houdt de volle breedte. */
.upload-waarschuwing {
  margin: 0.75rem 0 0;
  padding: 0.75rem 1rem;
  border-left: 0.25rem solid #b3261e;
  border-radius: 0.25rem;
  background-color: rgba(179, 38, 30, 0.08);
  color: #7a1a15;
  font-size: 0.9375rem;
  line-height: 1.4;
}

/* ── Het Bunny-sleepvak ──────────────────────────────────────────────

   Stond als inline stijlen in de component. Verhuisd naar hier omdat het vak
   inmiddels in twee maten bestaat: het grote vak bovenaan een scherm, en het
   strookje onderin elk kaartje van de bioscoop. Een inline stijl is met CSS
   niet te overrulen, dus een tweede maat kon er niet naast bestaan.

   De zweefstand komt van de hook (`is-hover`), niet van `:hover`: het gaat om
   een bestand dat boven het vak zweeft, en dat is geen muispositie. */
.bunny-upload [data-bunny-dropzone] {
    padding: 1.5rem;
    border: 0.125rem dashed #bbb;
    border-radius: 0.375rem;
    text-align: center;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}

.bunny-upload [data-bunny-dropzone].is-hover {
    border-color: #29d;
    background: #f0f7ff;
}

.bunny-upload [data-bunny-dropzone] p {
    margin: 0;
}

.bunny-upload [data-bunny-dropzone] small {
    color: #888;
}

.bunny-upload input[type="file"] {
    display: none;
}

.bunny-upload [data-bunny-progress] {
    margin-top: 0.5rem;
}

.bunny-upload-balk {
    height: 0.5rem;
    border-radius: 0.25rem;
    background: #eee;
    overflow: hidden;
}

.bunny-upload-balk [data-bunny-progress-bar] {
    width: 0%;
    height: 100%;
    background: #29d;
    transition: width 0.2s;
}

/* Het strookje in een kaartje: dezelfde streepjeslijn, maar op één regel. */
.bunny-upload.compact [data-bunny-dropzone] {
    padding: 0.4rem 0.5rem;
    font-size: 0.75rem;
    line-height: 1.3;
}

.bunny-upload.compact [data-bunny-dropzone] p {
    display: inline;
}

.bunny-upload.compact [data-bunny-dropzone] small {
    display: block;
}

/* De eigen knop van `bestand_kiezen/1` in een sleepzone: de regel voor
   `.drop span` hierboven (doorschijnend, kleiner) is voor de uitleg eronder,
   niet voor de knop en de bestandsnaam. */
.drop .bestand-kiezen {
  flex-direction: column;
}

.drop .bestand-kiezen-knop,
.drop .bestand-kiezen-knop span {
  opacity: 1;
  font-size: inherit;
}

.drop .bestand-kiezen-naam,
.bestand-kiezen-naam {
  font-size: 0.875rem;
  opacity: 0.7;
}


/* ── ../base/language-toggle.css ── */
.language-toggle {
    text-align: right;
    margin-bottom: 1rem;
    position: absolute;
    top: 1rem;
    right: 1rem;
}

.language-btn {
    cursor: pointer;
    background-color: transparent;
    border: none;
    outline: none;
    letter-spacing: .25rem;
    line-height: 1;
    text-transform: uppercase;
    font-size: 1.0625rem;
    position: relative;
}
  
/* Een streepje tussen elk paar, dus achter alles behalve de laatste. Hier stond
   `:first-child`, en dat gaf precies één streepje: klopte zolang er twee talen
   waren, maar bij drie werd het "NL | EN FR". Bij twee talen is dit dezelfde
   knop, dus voor elke tenant die er twee heeft verandert er niets. */
.language-btn:not(:last-child)::after {
    content: "|";
    display: inline-block;
    transform: translateX(-.125rem);
    color: #333;
}
  

/* ── ../base/progress.css ── */
.progress {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-bottom: 1rem;
  }
  
  .progress .value {
    min-width: 2.25rem;
    font-size: .875rem;
    font-weight: 600;
    color: #333;
  }
  
  .progress .bar {
    flex: 1;
    height: .5rem;
    background-color: #e0e0e0;
    border-radius: .25rem;
    overflow: hidden;
  }
  
  .progress .bar span {
    display: block;
    height: 100%;
    background: linear-gradient(90deg, #4f46e5, #7c3aed);
    border-radius: .25rem;
    transition: width 0.3s ease;
  }
  
  .progress + button {
    padding: .375rem .625rem;
    background-color: #f3f4f6;
    border: .0625rem solid #d1d5db;
    border-radius: .25rem;
    font-size: 1.125rem;
    cursor: pointer;
    transition: background-color 0.2s;
  }
  
  .progress + button:hover {
    background-color: #e5e7eb;
  }
  
  .progress + button:active {
    background-color: #d1d5db;
  }
  
  .progress .error {
    display: block;
    margin-top: 4px;
    font-size: 12px;
    color: #dc2626;
  }

/* ── ../base/gallery.css ── */
section .production-gallery h3 {
    opacity: 0;
    height: 0;
    margin: 0;
}

.image-gallery {
    margin: 2rem 0;
}

.image-gallery span {
    display: inline-block;
    margin: 0.25rem 0 0 0.0625rem;
}

.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: 1rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.gallery-item:first-of-type {
    display: block;
}

.gallery-image-button {
    border: none;
    background: none;
    padding: 0;
    cursor: pointer;
    width: 100%;
}

.gallery-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    aspect-ratio: 9/6;
}

.gallery-caption {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
    color: white;
    padding: 1rem;
    font-size: 0.9rem;
    display: none;
}

.gallery-item {
    position: relative;
    border-radius: 0.0625rem;
    overflow: hidden;
    display: none;
}

.image-gallery span {
    font-size: 0.875rem;
    opacity: 0.7;
}

/* Masonry-variant — alle foto's zichtbaar, elk in de eigen verhouding.
   CSS Grid bepaalt het aantal kolommen; de MasonryGrid-hook zet per item
   `grid-row-end: span N` op basis van rijen van 1px.

   De verticale ruimte zit bewust in het item (padding-bottom) en niet in
   `row-gap`: met een row-gap wordt de spanberekening korrelig (rij + gap) en
   krijgt elk item een eigen afrondingsrest, waardoor de gaten verticaal groter
   en ongelijk worden. Met `row-gap: 0` is een span exact één pixel. */
.gallery-grid.masonry {
    --gallery-gap: 1.25rem;
    /* min() zodat een kolom op een smal scherm niet breder wordt dan de ruimte. */
    grid-template-columns: repeat(auto-fill, minmax(min(20rem, 100%), 1fr));
    grid-auto-rows: 1px;
    align-items: start;
    column-gap: var(--gallery-gap);
    row-gap: 0;
    /* Compenseert de padding onder de onderste rij. */
    margin-bottom: calc(-1 * var(--gallery-gap));
    opacity: 0;
    transition: opacity 0.2s ease-in;
}

.gallery-grid.masonry.masonry-ready {
    opacity: 1;
}

.gallery-grid.masonry .gallery-item {
    display: block;
    padding-bottom: var(--gallery-gap);
}

.gallery-grid.masonry .gallery-image-button {
    display: block;
    line-height: 0;
}

/* Niet bijsnijden: de hoogte van de foto bepaalt de hoogte van het item.
   `auto 3 / 2` = de eigen verhouding zodra de foto geladen is, daarvoor 3/2 als
   plaatshouder — anders klapt de grid in tot de laadmomenten binnen zijn. */
.gallery-grid.masonry .gallery-image {
    height: auto;
    aspect-ratio: auto 3 / 2;
}

/* De lightbox-stijlen stonden hier; ze staan nu in base/lightbox.css,
   samen met die van de nieuwe Lightbox-hook. Eén uiterlijk voor beide. */

@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.gallery-container {
    display: flex;
    flex-direction: column-reverse;
    padding: 2rem 1rem 0 2rem;
}

.gallery-container .gallery-actions {
    padding: 1rem;
}

.gallery-container .current-gallery-images .sortable-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
}

.gallery-container .current-gallery-images .gallery-item-image {
    width: 100%;
    border: 0.25rem solid #fff;
    box-shadow: 0 0 2rem rgba(0, 0, 0, 0.15);
    background-color: #f7f7f7;
}

.gallery-container .current-gallery-images .gallery-item-image img {
    object-fit: contain;
    width: 100%;
    height: 100%;
}

.gallery-item-controls {
    display: flex;
    padding: 0.5rem;
    justify-content: flex-end;
    align-items: center;
    gap: 0.5rem;
}

.gallery-item-controls .button {
    font-size: 0.875rem;
}

.button.delete::before {
    content: "!";
    color: var(--color-red, #c41c1c);
    font-weight: bold;
    font-size: 1.5rem;
    margin-right: 0.25rem;
}

.drag-handle .icon-dragdrop {
    background-color: #333;
    padding: 0 0.5rem 0.5rem 0.5rem;
}

/* DOCUMENTS */
.document-upload-section {
    background-color: #f7f7f7;
    padding: 2rem 0 2rem 1rem;
}

.document-upload-section header .icon-doc {
    background-color: #333;
    margin-left: 0.5rem;
}

.document-upload-section header {
    display: flex;
    align-items: center;
}

/* ── Beheerkaarten: galerij en bibliotheek ───────────────────────────

   Twee schermen, één uiterlijk. De sorteerbare galerij van het
   productieformulier en de fotobibliotheek tonen dezelfde foto's met dezelfde
   gegevens eronder; ze hoorden er nooit anders uit te zien. Daarom staan de
   regels hier onder één selectorpaar in plaats van twee keer nagebouwd — dan
   lopen ze bij de eerste wijziging niet weer uit elkaar.

   Beide liggen op de masonry uit `.gallery-grid.masonry` hierboven. De galerij
   laat hem leggen door de sorteerhook (SortableJS wil de container voor
   zichzelf, en twee LiveView-hooks op één element gaat niet); de bibliotheek
   heeft niets te slepen en gebruikt gewoon de MasonryGrid-hook. */

.gallery-container .current-gallery-images .sortable-gallery.masonry,
.image-grid.masonry {
    --card-gap: 1rem;
    display: grid;
    /* Vast op drie: met auto-fill kreeg je op een breed scherm vier of vijf
       kaarten naast elkaar en werd het een contactvel. Drie houdt de foto's
       groot genoeg om te herkennen wat je voor je hebt. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-rows: 1px;
    align-items: start;
    column-gap: var(--card-gap);
    row-gap: 0;
    margin-bottom: calc(2rem - var(--card-gap));
    padding: 0;
    list-style: none;
}

/* De bibliotheek wacht op de hook voor hij zich laat zien; de galerij niet.
   Daar legt de sorteerhook de kaarten, en die draait pas ná de eerste render —
   met een verborgen grid zou je in dat gat een lege galerij zien. */
.image-grid.masonry {
    opacity: 0;
    transition: opacity 0.2s ease-in;
}

.image-grid.masonry.masonry-ready {
    opacity: 1;
}

/* De galerij in het voorstellingsformulier staat op vier. Dat is dezelfde
   afweging als hierboven, maar met een andere uitkomst: hier staat er geen
   tekst meer onder de foto's, dus een kaart is niet veel meer dan de foto
   zelf. Vier van die kaarten naast elkaar scheelt een kwart van de hoogte, en
   dat is precies waar het om gaat — dit blok stond tussen de rest van een lang
   formulier in, en wie naar de filmpjes wil scrolt er nu niet meer aan voorbij.
   De bibliotheek houdt drie: daar staat wél tekst onder elke foto, en daar kies
   je uit driehonderd bestanden in plaats van er twintig te ordenen. */
.gallery-container .current-gallery-images .sortable-gallery.masonry {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.sortable-gallery.masonry .gallery-item-manager,
.image-grid.masonry .image-item {
    padding-bottom: var(--card-gap);
}

/* De kaart is het ijkpunt voor de knoppen rechtsonder. */
.sortable-gallery .gallery-item-image,
.image-grid.masonry .image-item {
    position: relative;
}

/* Niet bijsnijden op een vaste hoogte: de foto bepaalt de hoogte van de kaart,
   en dat is precies wat de masonry meet. Een staande en een liggende foto zijn
   zo ook op het oog uit elkaar te houden — in een bibliotheek van driehonderd
   bestandsnamen die op elkaar lijken is dat het eerste waar je op zoekt.
   `auto 3 / 2` is de plaatshouder tot de foto binnen is. */
.sortable-gallery .gallery-item-image img.sortable-thumbnail,
.image-grid.masonry .image-thumbnail img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: auto 3 / 2;
    object-fit: cover;
}

/* De regels onder de foto staan onder elkaar in plaats van naast elkaar: als
   flex-items werden ze tot hun langste wóórd samengeknepen en liepen ze de
   kaart uit. Onderaan blijft ruimte vrij voor de knoppen. */
.sortable-gallery .gallery-item-controls,
.image-grid.masonry .image-info {
    display: block;
    padding: 0.5rem 0.5rem 1.75rem;
    line-height: 1.35;
}

.image-grid.masonry .image-info p {
    margin: 0 0 0.15rem;
}

/* De knoppen verschijnen alleen in de beheerstand; in de kiesstand hoeft er
   dus geen ruimte voor vrij te blijven. */
.image-grid.masonry .image-item:not(:has(.image-actions)) .image-info {
    padding-bottom: 0.5rem;
}

/* Drie regels is genoeg om een foto te herkennen; de hele alt-tekst hangt in
   de tooltip. */
.sortable-gallery .image-caption-display,
.image-grid.masonry .image-alt-text {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 0.8rem;
    color: #333;
}

/* De galerij van een voorstelling toont de alt-tekst niet meer — die hangt in
   de tooltip van de foto. Wat er wél staat is de uitzondering: een foto zonder
   alt-tekst. Klein en in dezelfde maat als de rest van de kaart — het is geen
   alarm — maar wel in het rood, want tussen twintig kaarten die verder niets
   zeggen is dit de enige die om iets vraagt. */
.sortable-gallery .image-alt-ontbreekt {
    font-size: 0.8rem;
    font-variant: all-small-caps;
    line-height: 1.35;
    color: var(--color-red, #c41c1c);
    opacity: 0.8;
}

.sortable-gallery .image-credit,
.image-grid.masonry .image-credit {
    margin-top: 0.25rem;
    font-size: 0.8rem;
    font-weight: 600;
    color: #333;
}

.image-grid.masonry .image-title,
.image-grid.masonry .image-usage,
.image-grid.masonry .image-size,
.image-grid.masonry .image-dimensions {
    font-size: 0.8rem;
    color: #333;
}

/* ── De regel onderaan elke kaart ────────────────────────────────────

   Links wat de kaart zelf doet (slepen), rechts wat je ermee kunt (bewerken,
   verwijderen). Klein, dun en in dezelfde inkt: het zijn bijzaken naast de
   foto, geen knoppen die om aandacht vragen. Verwijderen kleurt pas rood als
   je erheen gaat. */

.sortable-gallery .drag-handle,
.sortable-gallery .gallery-item-delete,
.image-grid.masonry .image-actions button {
    color: #333;
    font-size: 0.8rem;
    font-weight: 400;
    font-variant: all-small-caps;
    line-height: 1;
    opacity: 0.7;
    transition: opacity 0.15s ease;
}

.sortable-gallery .drag-handle {
    padding: 0.25rem 0.5rem 0.5rem;
    padding-right: 7rem;
}

.sortable-gallery .drag-handle:hover,
.sortable-gallery .gallery-item-delete:hover,
.sortable-gallery .gallery-item-delete:focus-visible,
.image-grid.masonry .image-actions button:hover,
.image-grid.masonry .image-actions button:focus-visible {
    opacity: 1;
}

/* Bewust geen `.button`-uiterlijk: een rij vette knoppen trekt de aandacht weg
   van de foto's. */

/* De `z-index` is geen opsmuk maar het enige dat de knop klikbaar houdt. De
   sleepgreep eronder ligt op `opacity: 0.7`, en alles onder de 1 vormt een
   eigen stapellaag — die gaat vóór deze knop staan, ook al is die absoluut
   gepositioneerd, want de greep staat later in de HTML.

   Zonder deze regel raakte je in een lus zodra je de knop naderde: de greep
   ving de muis, `:hover` zette hem op 1, daarmee verloor hij zijn laag, de
   knop kwam bovenop en kleurde rood, de greep raakte zijn hover kwijt en zakte
   terug — en de greep lag er weer overheen. Zwart-rood-zwart-rood, met een
   sleep-handje boven een knop, en een klik die neerkwam op wat er toevallig
   net bovenop lag. */
.sortable-gallery .gallery-item-delete,
.image-grid.masonry .image-actions {
    position: absolute;
    z-index: 1;
    right: 0.5rem;
    bottom: 0.5rem;
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
}

.image-grid.masonry .image-actions button {
    display: inline-flex;
    align-items: center;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
}

.sortable-gallery .gallery-item-delete:hover,
.sortable-gallery .gallery-item-delete:focus-visible,
.image-grid.masonry .image-actions .btn-delete:hover,
.image-grid.masonry .image-actions .btn-delete:focus-visible {
    color: var(--color-red, #c41c1c);
}

.sortable-gallery .drag-handle .icon-dragdrop,
.sortable-gallery .gallery-item-delete .icon-trash,
.image-grid.masonry .image-actions [class*="icon-"] {
    width: 1rem;
    height: 1rem;
    padding: 0;
    margin-right: 0.25rem;
    background-color: currentColor;
}

/* Smallere schermen: liever twee grote kaarten dan drie postzegels. */
@media (width < 64rem) {
    .gallery-container .current-gallery-images .sortable-gallery.masonry,
    .image-grid.masonry {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (width < 40rem) {
    .gallery-container .current-gallery-images .sortable-gallery.masonry,
    .image-grid.masonry {
        grid-template-columns: minmax(0, 1fr);
    }
}


/* ── ../base/lightbox.css ── */
/* Lightbox — uiterlijk 1-op-1 van UIkit 3.25.
   Bron: `uikit/uikit-3.25.16/uikit.min.css` (lokale referentiekopie, staat in
   .gitignore en wordt niet geserveerd — vandaar dat de waarden hier overgetikt
   staan in plaats van geïmporteerd). Per blok staat welke uk-klasse hij
   naspeelt, zodat je bij een UIkit-upgrade kunt vergelijken.

   Deze klassen worden gebruikt door de `Lightbox`-hook (assets/js/hooks.js),
   die zijn eigen DOM bouwt. De oude LightboxModal-markup gebruikt dezelfde
   namen, dus die ziet er tijdens de overgang meteen hetzelfde uit. */

/* .uk-lightbox */
.lightbox-overlay {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    /* UIkit zet hier 1010, net boven zijn eigen navbar op 980. Die schaal
       houden de tenants niet aan: de balk van Hotel Modern staat op 1500 en de
       beheerbalk van zusjesvandijk en feikeshuis op 9999. De lightbox lag daar
       dus ónder, en precies de dingen die aan de rand liggen — de teller
       linksboven, het kruisje rechtsboven — verdwenen achter de kop van de
       site.

       De lightbox is per definitie de bovenste laag: hij vult het scherm en
       zet de pagina eronder stil (`body-no-scroll`). Vandaar één waarde boven
       alles wat tegelijk in beeld kan staan — de tenant-koppen (max 1500), de
       modals van Hotel Modern (2000), de beheerbalk (9999) en `.form-container`
       (10001). */
    z-index: 10500;
    background: #000;
    opacity: 0;
    transition: opacity 0.15s linear;
    touch-action: pinch-zoom;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    /* De foto schuift bij bladeren een volle breedte weg; zonder dit zou dat de
       pagina eronder verbreden. */
    overflow: hidden;
}

/* .uk-lightbox.uk-open */
.lightbox-overlay.is-open {
    opacity: 1;
}

.lightbox-overlay :focus-visible {
    outline-color: rgba(255, 255, 255, 0.7);
}

/* .uk-lightbox-items > * */
.lightbox-image-container {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* .uk-lightbox-items-fit > * > *
   Absoluut gepositioneerd omdat er tijdens een crossfade twee foto's over
   elkaar liggen; ze moeten op dezelfde plek staan, niet naast elkaar. */
.lightbox-image {
    position: absolute;
    max-width: 100vw;
    max-height: 100vh;
    object-fit: contain;
    cursor: default;
    opacity: 1;
    /* Eén bron van waarheid: de hook leest deze duur uit met getComputedStyle
       voor zijn opruimtimer, dus hier aanpassen volstaat. */
    transition: opacity 0.7s ease;
}

/* Beginstand van de binnenkomende foto; de hook haalt deze klasse er direct na
   het inhangen af, waarna de overgang loopt. */
.lightbox-image.is-entering {
    opacity: 0;
}

.lightbox-image.is-leaving {
    opacity: 0;
}

/* .uk-lightbox-iframe */
.lightbox-iframe {
    width: 80%;
    height: 80%;
    border: 0;
    cursor: default;
}

/* .uk-lightbox-caption */
.lightbox-caption {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 10px 10px;
    background: rgba(0, 0, 0, 0.3);
    color: rgba(255, 255, 255, 0.7);
    text-align: center;
    cursor: default;
}

.lightbox-caption:empty {
    display: none;
}

/* .uk-lightbox-counter */
.lightbox-counter {
    position: absolute;
    top: 10px;
    left: 15px;
    color: rgba(255, 255, 255, 0.7);
    cursor: default;
}

.lightbox-counter:empty {
    display: none;
}

/* .uk-slidenav, in de omkeerkleuren die UIkit op een donkere ondergrond
   gebruikt (.uk-light .uk-slidenav). De chevrons zijn de uikit-iconen. */
.lightbox-nav-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    padding: 10px 10px;
    border: 0;
    background: none;
    cursor: pointer;
    width: 4rem;
    height: 4rem;
    color: rgba(255, 255, 255, 0.7);
    transition: color 0.1s ease-in-out;
}

.lightbox-nav-btn::before {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    background-color: currentColor;
    mask-repeat: no-repeat;
    mask-position: center;
    mask-size: contain;
}

.lightbox-nav-btn:hover {
    color: rgba(255, 255, 255, 0.95);
}

.lightbox-nav-btn:active {
    color: rgba(255, 255, 255, 0.7);
}

.lightbox-prev {
    left: 1rem;
}

.lightbox-prev::before {
    mask-image: url(../../images/uikit-icons/chevron-left-66baa7923a58cdc14e4d91b1667c85b6.svg?vsn=d);
}

.lightbox-next {
    right: 1rem;
}

.lightbox-next::before {
    mask-image: url(../../images/uikit-icons/chevron-right-dd56d1008572fc326c0bd8dfb893d2e8.svg?vsn=d);
}

/* .uk-close-large — de tegenhanger van .uk-slidenav-large hierboven, en
   daarom in dezelfde maat en dezelfde omkeerkleuren als de chevrons.

   Hij stond op 2rem en 50% wit, tegenover 4rem en 70% voor de chevrons. Beide
   iconen zijn hetzelfde uikit-masker met een streek van ~1.05 in een viewBox
   van 20, dus die maat is meteen de streekdikte: 1,7px tegenover 2,3px voor de
   pijl ernaast. Fletser én dunner, in de hoek — met als gevolg dat hij over het
   hoofd gezien werd en mensen de lightbox met een klik naast de foto sloten.

   De schaduw is geen UIkit: daar houdt een lightbox een rand zwart om de foto,
   hier vult de foto het scherm (`max-width: 100vw`), dus het kruisje ligt óp
   het beeld. Boven een lichte hoek verdwijnt wit-op-wit. De schaduw volgt de
   vorm van het masker en niet het vierkant van de knop, vandaar `filter` op de
   ::before en niet `box-shadow`. */
.lightbox-close {
    position: absolute;
    top: 1rem;
    right: 1rem;
    width: 4rem;
    height: 4rem;
    padding: 10px 10px;
    border: 0;
    background: none;
    cursor: pointer;
    color: rgba(255, 255, 255, 0.7);
    transition: color 0.1s ease-in-out, opacity 0.1s ease-in-out;
}

.lightbox-close::before {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    background-color: currentColor;
    mask-image: url(../../images/uikit-icons/close-15b2ed35fd5b392564d057667b0b9a0d.svg?vsn=d);
    mask-repeat: no-repeat;
    mask-position: center;
    mask-size: contain;
    filter: drop-shadow(0 0 0.25rem rgba(0, 0, 0, 0.8));
}

.lightbox-close:hover {
    color: rgba(255, 255, 255, 0.95);
}

.lightbox-close:active {
    color: rgba(255, 255, 255, 0.7);
}

/* Om dezelfde reden ook onder de pijlen: die liggen midden op de foto. */
.lightbox-nav-btn::before {
    filter: drop-shadow(0 0 0.25rem rgba(0, 0, 0, 0.8));
}

/* Achtergrond niet mee laten scrollen zolang de lightbox open staat. */
body.body-no-scroll {
    overflow: hidden;
}


/* ── ../base/button.css ── */
.button,
input[type="file"]::file-selector-button {
  display: inline-flex;
  justify-content: center;
  align-items: center;
}

.button,
input[type="file"]::file-selector-button:not(:last-of-type) {
  margin-right: 1.25rem;
}

.button span {
  margin: 0 0.25rem;
}

.button.alt {
  background-color: transparent;
  border: 0.125rem solid;
}

.button.new-agenda-item {
  position: absolute;
  bottom: -4rem;
  right: 0;
  border: 0;
  font-size: 0.875rem;
}

footer.actions {
  position: sticky;
  bottom: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1.5rem;
  padding: 0.75rem 1.5rem;
  width: fit-content;
  background-color: #fff;
  border-radius: 0.25rem;
}

footer.actions p {
  margin-right: 2rem;
}

@media (hover: hover) {
  .button:hover {
    opacity: 0.85;
  }
}

.logout-link span {
  font-size: 0.7rem;
  display: block;
  margin-top: 0.5rem;
  text-transform: uppercase;
  letter-spacing: normal;
}

@media (width < 48rem) {
  .button.new-agenda-item {
    bottom: -5rem;
    font-size: 0.7rem;
  }
}

/* Visueel disabled — Phoenix zet `disabled` via phx-disable-with tijdens een
   server-roundtrip; zonder deze regels blijft de knop er gewoon klikbaar uitzien. */
button.button[disabled],
button.button:disabled,
.button[disabled],
.button:disabled {
  opacity: 0.55;
  cursor: progress;
  filter: grayscale(0.3);
  pointer-events: none;
}


/* ── ../base/tooltip.css ── */
.tooltip {
    display: flex;
    color: #333;
    padding: .5rem 0;
    position: relative;
    z-index: 1;
    margin-right: 1rem;
    font-variant: all-small-caps;
}

.tooltip::after {
    content: "";
    width: 100%;
    width: 1.5rem;
    background-color: #f1e740;
    height: 1.5rem;
    /* background-color: #f1e740; */
    top: -.125rem;
    left: .1875rem;
    position: absolute;
    z-index: -1;
    /* transform: rotate(1deg); */
    border-radius: 50%;
    /* background-image: linear-gradient(
        to right,
        #f1e740 1%,
        #f1e740 50%,
        transparent
    );


    background-image: linear-gradient(
        to right,
        #f1e740 0,
        #f1e740 1rem,
        transparent 3.5rem) */
}

.tooltip span {
    /* background-color: #333; */
    display: inline-block;
    margin: 0 .25rem;
}

.tooltip span.icon-bulb {
    background-color: #333;
}

/* ── ../base/moving-agenda.css ── */
.moving-agenda {
    overflow: hidden;
    padding: clamp(0.5rem, 0.368rem + 0.702vw, 1rem) 0;
    position: relative;
}

.moving-agenda::after {
    content: "Agenda";
    position: absolute;
    display: flex;
    align-items: center;
    left: 0;
    top: 0;
    width: clamp(8rem, 6.947rem + 5.614vw, 12rem);
    /*padding: 0 0 0 clamp(1rem, 0.211rem + 4.211vw, 4rem);*/
    padding-left: clamp(2rem, 1.474rem + 2.807vw, 4rem);
    font-size: clamp(1.125rem, 1.026rem + 0.526vw, 1.5rem);
    height: 100%;
    background-image: linear-gradient(
        to right,
        #000 50%,
        rgba(0, 0, 0, 0.7) 80%,
        transparent
    );
}

.moving-agenda ul {
    display: flex;
}

.moving-agenda ul li {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: clamp(0.5rem, 0.368rem + 0.702vw, 1rem);
    padding: clamp(0.255rem, 0.191rem + 0.344vw, 0.5rem)
        clamp(0.5rem, 0.368rem + 0.702vw, 1rem);
    color: #000;
    flex-shrink: 0;
    border-radius: 0.125rem;
}

.moving-agenda ul li:not(:first-of-type) {
    margin-left: 1rem;
}

.moving-agenda ul li .production-location .title {
    font-size: clamp(1.125rem, 1.092rem + 0.175vw, 1.25rem);
}

.moving-agenda ul.scrolling {
    animation: scroll-left 30s linear infinite;
}

.moving-agenda:hover ul.scrolling {
    animation-play-state: paused;
}

@keyframes scroll-left {
    from {
        transform: translateX(0);
    }
    to {
        transform: translateX(var(--scroll-width));
    }
}


/* ── ../base/speelbeurten.css ── */
/* ── Het bolletje onder aan een bijladende lijst ─────────────────────────────

   Het was een wit rondje van twee rem, op een vlak dat bij de meeste tenants
   ook licht is, en het stond er alleen zolang de server bezig was. Wie snel
   naar beneden veegt kijkt daar niet naar: je ziet niets gebeuren en denkt dat
   de lijst op is. Nu is het een balkje dat zégt wat er gebeurt, donker op
   licht, met hetzelfde bolletje ernaast. */
.loading-indicator {
  display: flex;
  position: fixed;
  /* Rechtsonder en niet in het midden: in het midden staat hij over de regel
     die je op dat moment aan het lezen bent, en dat is nou juist de regel die
     er net bij is gekomen. */
  bottom: 1.5rem;
  right: 1.5rem;
  z-index: 100;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  /* Een zachte hoek, geen volledige pil: op een doosje dat drie keer zo breed
     is als hoog maakt een halfronde kop er een uitgerekte capsule van. */
  border-radius: 0.5rem;
  background: rgba(24, 24, 24, 0.9);
  color: #fff;
  font-size: 0.8125rem;
  line-height: 1;
  box-shadow: 0 0.125rem 0.75rem rgba(0, 0, 0, 0.25);
}

.loading-indicator .icon-loading {
  display: inline-block;
  /* Niet meekrimpen met de tekst ernaast: een ovaal bolletje draait scheef. */
  flex: none;
  width: 1rem;
  height: 1rem;
  border: 0.125rem solid currentColor;
  border-radius: 50%;
  border-top-color: transparent;
  animation: spin 0.8s linear infinite;
}

/* Wie beweging heeft uitgezet krijgt hem trager, niet stil: een bolletje dat
   stilstaat zegt precies het tegenovergestelde van wat het moet zeggen. */
@media (prefers-reduced-motion: reduce) {
  .loading-indicator .icon-loading {
    animation-duration: 3s;
  }
}

#agenda-content form.search-form,
#locations-content form.search-form {
  margin: 0 0 2rem 0;
  display: flex;
  flex-direction: column;
}

#agenda-content form.search-form header,
#locations-content form.search-form header {
  padding: 0.25rem 0 0.5rem 0;
}

#agenda-content form.search-form input {
  border: 0.0625rem solid;
  border-radius: 0.25rem;
  width: clamp(20rem, 13.571rem + 17.143vw, 29rem);
}

.speelbeurten {
  position: relative;
  display: grid;
  grid-template-columns: 12.5rem 7fr;
  gap: clamp(0.25rem, -0.211rem + 2.456vw, 2rem);
  word-break: break-word;
  word-wrap: normal;
  hyphens: auto;
}

section#agenda-target.speelbeurten {
  margin-bottom: 6rem;
}

.speelbeurten .img {
  background-repeat: repeat-y;
  background-size: contain;
}

.speelbeurten h4 {
  margin-top: 0;
  margin-bottom: 1.25rem;
}

.speelbeurt {
  position: relative;
}

.speelbeurt .admin.actions {
  position: absolute;
  bottom: 1rem;
  left: 60%;
}

.button.static.new-agenda-item {
  margin: 2rem 0;
}

.speelbeurt a.edit,
.speelbeurt a.delete,
.speelbeurt button.delete {
  margin-right: 1rem;
  padding: 0.25rem 0.5rem;
  font-size: 0.875rem;
  display: inline-flex;
  align-items: center;
}

.speelbeurt a.edit span,
.speelbeurt a.delete span,
.speelbeurt button.delete span {
  height: 1rem;
  width: 1rem;
  margin-left: 0.25rem;
}

.speelbeurt header,
.speelbeurt .middle,
.speelbeurt footer {
  display: flex;
  justify-content: space-between;
}

.speelbeurt header {
  padding-top: 0.7rem;
}

.speelbeurt header .description {
  font-size: 0.75rem;
  display: inline-block;
  margin-right: 2rem;
}

.speelbeurt .left-part .location {
  position: relative;
  display: inline-block;
  margin-left: 1rem;
}

.speelbeurt .left-part .location::before {
  content: "/";
  position: absolute;
  top: 0;
  left: -0.75rem;
}

.speelbeurt header .start {
  font-size: 0.75rem;
}

.agenda .middle .event {
  color: #ff5b5b;
  text-transform: uppercase;
  font-size: clamp(1.125rem, calc(1.0341rem + 0.4545vw), 1.375rem);
  font-family: "Stolzl Medium", sans-serif;
  line-height: 1;
}

.speelbeurt .middle .city,
.speelbeurt .middle .location,
.speelbeurt .middle .tickets,
.speelbeurt .middle .productie {
  font-size: clamp(1rem, 0.901rem + 0.526vw, 1.375rem);
}

.speelbeurt .middle a {
  text-decoration: underline;
}

.speelbeurt .middle .productie {
  text-transform: uppercase;
  line-height: 1;
  text-decoration: none;
  display: inline-block;
  margin-right: 0.5rem;
}

.speelbeurt footer {
  padding-bottom: 0.7rem;
}

.production-detail .side .speelbeurten {
  display: block;
}

section.index.agenda-items {
  padding: 2rem 0 12rem;
}

section.index.agenda-items header.actions,
section.index.agenda-items header .admin.actions {
  justify-content: flex-start;
}

#agenda_items.speelbeurten .speelbeurt .img {
  width: 100%;
  height: 100%;
  background-size: cover;
}

#agenda_items.speelbeurten {
  display: block;
}

#agenda_items.speelbeurten .speelbeurt {
  display: grid;
  grid-template-columns: 12.5rem 1fr;
  gap: clamp(0.25rem, -0.211rem + 2.456vw, 2rem);
}

#agenda_items.speelbeurten .speelbeurt footer .actions {
  top: 80%;
  padding-left: clamp(2rem, -0.632rem + 14.035vw, 12rem);
  display: flex;
}

#agenda_items.speelbeurten .speelbeurt footer .actions .button {
  margin-top: 0.5rem;
}

#agenda_items.speelbeurten .speelbeurt footer .actions .button:not(:has(~ .button)) {
  margin-right: 0;
}

#agenda_items.speelbeurten .speelbeurt .left-part h3 {
  margin: 0 clamp(0.5rem, 0.105rem + 2.105vw, 2rem);
  font-size: clamp(1rem, 0.934rem + 0.351vw, 1.25rem);
}

#agenda_items.speelbeurten .speelbeurt .left-part {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.date.short {
  display: none;
}

@media (width < 90rem) {
  section.index.agenda-items {
    padding-left: 1rem;
    padding-right: 1rem;
  }
}

@media (width < 48rem) {
  #agenda_items.speelbeurten .speelbeurt,
  .date.short {
    display: block;
  }

  .date.long {
    display: none;
  }
}

@media (width < 25rem) {
  .speelbeurt .left-part {
    max-width: 85%;
  }
}


/* ── ../base/flash.css ── */
.flash-container {
    position: fixed;
    top: 1rem;
    left: 1rem;
    z-index: 1000;
    pointer-events: none;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    max-width: 28rem;
}

.flash-container > * {
    pointer-events: auto;
}

/* De verbindingsmelding. Ze staat in de opmaak met `hidden` en wordt door
   LiveView zichtbaar gemaakt — maar alleen als ze binnen de LiveView staat, en
   in deze app staat de chrome eromheen. `app.js` zet daarom zelf de klasse op
   <body>; hier staat wat die klasse doet. De regel is specifieker dan het
   `hidden`-attribuut van de browser, dus die wint. */
body.verbinding-weg #client-error[hidden] {
    display: block;
}

#flash-group > div[role="alert"] {
    backdrop-filter: blur(.5rem);
    border: .0625rem solid rgba(255, 255, 255, 0.7);
    box-shadow: 0 .5rem 2rem rgba(0, 0, 0, 0.12);
    transition: all 0.3s ease;
    width: 26rem;
    padding: 0 2rem;
    position: relative;
    border-radius: 1rem 1rem 1rem .25rem;
}

#flash-group > div[role="alert"]:not([class*="rose"]) {
    background-color: rgb(0 102 158 / 70%);
    color: #fff;
}

/* Error flash styling (rose colors) */
#flash-group > div[role="alert"][class*="rose"] {
    background: linear-gradient(135deg, #fef2f2 0%, #fecaca 100%);
    border-left: .25rem solid #ef4444;
    color: #7f1d1d;
}

 /* Enhanced button styling */
#flash-group button[aria-label="close"] {
    transition: all 0.2s ease;
    width: 1.25rem;
    height: 1.25rem;
}

#flash-group button[aria-label="close"]:hover {
    background: rgba(255,255,255,.7);
    transform: scale(1.1);
}

/* Progress bar for auto-dismiss */
.flash-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    height: .1875rem;
    background: linear-gradient(90deg, #10b981, #059669);
    border-radius: 0 0 .5rem .5rem;
    animation: flashProgress 5s linear;
}

.flash-progress.error {
    background: linear-gradient(90deg, #ef4444, #dc2626);
}

@keyframes flashProgress {
    from { width: 100%; }
    to { width: 0%; }
}

/* Pulse animation for better visibility */
#flash-group > div[role="alert"]:not([hidden]) {
    animation: flashPulse 0.5s ease-out;
}

@keyframes flashPulse {
    0% {
      transform: scale(0.95);
      opacity: 0;
    }
    50% {
      transform: scale(1.02);
    }
    100% {
      transform: scale(1);
      opacity: 1;
    }
}

  /* Dark mode enhancements */
  /* @media (prefers-color-scheme: dark) {
    #flash-group > div[role="alert"]:not([class*="rose"]) {
      background: linear-gradient(135deg, #064e3b 0%, #065f46 100%);
      color: #a7f3d0;
      border-left-color: #34d399;
    }

    #flash-group > div[role="alert"][class*="rose"] {
      background: linear-gradient(135deg, #7f1d1d 0%, #991b1b 100%);
      color: #fca5a5;
      border-left-color: #f87171;
    }

    #flash-group button[aria-label="close"] {
      background: rgba(255, 255, 255, 0.1);
    }

    #flash-group button[aria-label="close"]:hover {
      background: rgba(255, 255, 255, 0.2);
    }
  } */

.flash-close {
    position: absolute;
    top: .5rem;
    right: 0.5rem;
    color: aliceblue;
    font-size: 2.25rem;
}

/* Mobile responsiveness */
@media (max-width: 48rem) {
    .flash-container {
      left: 1rem;
      right: 1rem;
      max-width: none;
    }

    #flash-group > div[role="alert"] {
      width: calc(100vw - 2rem) !important;
    }
}
/* Het bedankje van het contactformulier. De flash-melding bovenaan komt na het
   versturen niet in beeld: die staat in de root-layout, en die rendert maar één
   keer. Daarom zet de contactpagina zelf deze melding neer, en na vijf seconden
   weer weg. Zonder opmaak belandt ze als losse regel onderaan de pagina; dit is
   de basis. `:where` houdt de specificiteit op nul, zodat een tenant met een
   eigen `.success-banner` (Evrim, Kiki, Margje) gewoon wint. */
:where(.success-banner) {
    position: fixed;
    left: 50%;
    bottom: 1.5rem;
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: max-content;
    max-width: calc(100vw - 2rem);
    padding: 0.9rem 1.5rem;
    background: rgb(0 0 0 / 80%);
    color: #fff;
    border-radius: 0.75rem;
    box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / 25%);
    line-height: 1.3;
    animation:
        melding-in 0.4s ease-out both,
        melding-uit 0.5s ease 4.5s both;
}

:where(.success-banner__icon) {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background: #fff;
    color: #000;
    font-weight: 700;
}

:where(.success-banner__text) {
    margin: 0;
}

@keyframes melding-in {
    from { opacity: 0; transform: translate(-50%, 1.5rem); }
    to { opacity: 1; transform: translate(-50%, 0); }
}

@keyframes melding-uit {
    from { opacity: 1; transform: translate(-50%, 0); }
    to { opacity: 0; transform: translate(-50%, 0.75rem); }
}

@media (prefers-reduced-motion: reduce) {
    :where(.success-banner) {
        animation: none;
        transform: translateX(-50%);
    }
}

/* De foutmelding van het contactformulier, op dezelfde plek als het bedankje.
   Ze verdwijnt niet vanzelf: ze blijft tot een nieuwe poging of tot de
   bezoeker haar wegklikt. */
:where(.error-banner) {
    position: fixed;
    left: 50%;
    bottom: 1.5rem;
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: max-content;
    max-width: calc(100vw - 2rem);
    padding: 0.9rem 1rem 0.9rem 1.5rem;
    background: #fef2f2;
    color: #7f1d1d;
    border-left: 0.25rem solid #ef4444;
    border-radius: 0.75rem;
    box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / 25%);
    line-height: 1.3;
    animation: melding-in 0.4s ease-out both;
}

:where(.error-banner__icon) {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background: #ef4444;
    color: #fff;
    font-weight: 700;
}

:where(.error-banner__text) {
    margin: 0;
}

:where(.error-banner__close) {
    flex: 0 0 auto;
    padding: 0 0.5rem;
    background: none;
    border: 0;
    color: inherit;
    font: inherit;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
    :where(.error-banner) {
        animation: none;
        transform: translateX(-50%);
    }
}


/* ── ../base/settings-production.css ── */
.settings-production-layout {
  max-width: 1200px;
  margin: 0 auto;
}

.settings-production-layout header {
  margin-bottom: 2rem;
}

.settings-production-layout header h2 {
  margin-bottom: 0.5rem;
}

.settings-production-layout header p {
  color: #666;
  font-size: 1rem;
}

.settings-actions {
  margin-bottom: 2rem;
  text-align: right;
}

.layout-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
  margin: 2rem 0;
}

.column-config {
  background: #f8f9fa;
  padding: 1.5rem;
  border-radius: 8px;
}

.column-config h3 {
  margin: 0 0 0.5rem;
  font-size: 1.25rem;
}

.column-config .help-text {
  font-size: 0.9rem;
  color: #666;
  margin: 0 0 1.5rem;
}

.sections-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.section-item {
  background: white;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 1rem;
  margin-bottom: 0.75rem;
  transition: all 0.2s ease;
}

.section-item:hover {
  border-color: #999;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.section-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

.section-name {
  font-weight: 500;
  flex: 1;
}

.section-actions {
  display: flex;
  gap: 0.5rem;
}

.button.small {
  padding: 0.4rem 0.8rem;
  font-size: 0.9rem;
}

.settings-info {
  background: #e7f3ff;
  border: 1px solid #b3d9ff;
  border-radius: 4px;
  padding: 1rem;
  margin: 2rem 0;
}

.settings-info p {
  margin: 0;
  color: #004085;
}

.sortable-sections {
  min-height: 150px; /* Zodat je kan slepen naar lege kolom */
  background: #fafafa;
  padding: 1rem;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.sortable-sections.drag-over {
  background-color: #e3f2fd; /* Licht blauw als je erover dragged */
  border: 2px dashed #2196f3;
}

.section-item {
  background: white;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 1rem;
  margin-bottom: 0.75rem;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  gap: 1rem;
  cursor: move;
}

.section-item:hover {
  border-color: #999;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.drag-handle {
  cursor: grab;
  color: #333;
  /* font-size: .7rem; */
  display: flex;
  /* flex-direction: row-reverse; */
  align-items: center;
  font-variant: all-small-caps;
  /* text-transform: uppercase; */
}

.drag-handle:active {
  cursor: grabbing;
}

.section-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex: 1;
}

.sortable-ghost {
  opacity: 0.4;
  background: #f0f0f0;
}

.sortable-drag {
  opacity: 0.8;
  transform: rotate(2deg);
  box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}

/* Responsive */
@media (max-width: 768px) {
  .layout-columns {
    grid-template-columns: 1fr;
  }
  
  .section-info {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .section-actions {
    width: 100%;
    justify-content: space-between;
  }
}
/* De schakelaar "Tonen" per sectie. Een uitgezette sectie blijft in de lijst
   staan en op zijn plek: dat is het verschil met weggooien — aanzetten zet
   hem terug waar hij hoorde. Hij ligt alleen zichtbaar stil. */
.section-toggle {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin: 0;
  font-size: 0.875rem;
  white-space: nowrap;
  cursor: pointer;
}

.section-toggle input {
  width: auto;
  margin: 0;
}

.section-item.is-uit {
  background: #f4f4f4;
  border-style: dashed;
}

.section-item.is-uit .section-name {
  opacity: 0.55;
  text-decoration: line-through;
}


/* ── ../base/search-field.css ── */
/* 

.search-field span.icon-search {
    position: absolute;
    right: 0;
} */

.search-field,
#filter-form {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
}

.search-field .search-input input {
    border: none !important;
    width: clamp(17.5rem, 16.136rem + 7.273vw, 20.5rem) !important;
}

.search-input {
    display: flex;
    align-items: center;
    border-bottom: .1875rem solid var(--color-black);
}

.search-input input {
    margin-bottom: 0;
    background-color: transparent;
    /* padding: 1.5rem 0 1rem; */
}

.search-input input::placeholder {
    color: var(--color-black);
}

.search-input span.icon-search {
    /* transform: translateX(-1.5rem); */
    width: 1.9rem;
    height: 1.9rem;
    /* background-color: var(--color-blue-darker); */
    background-color: var(--color-black);
}

.tooltip {
    color: var(--color-black);
    padding: 0;
    letter-spacing: .125rem;
}

#agenda-content section.search-field {
    padding: initial;
}

@media (width <= 48rem) {
    .search-field,
    #filter-form {
        flex-direction: column;
    }

    .tooltip {
        margin-bottom: 1rem;
    }
}

/* ── ../base/fixed-back.css ── */
.production-detail footer.actions {
    background-color: transparent;
}

.production-detail footer.actions .button.back {
    width: 12rem;
    height: 4rem;
    align-items: center;
    text-align: center;
    border-radius: .5rem;
    position: relative;
    z-index: 1;
    box-shadow: 0 0 1rem rgba(0,0,0,.25);
}

.production-detail footer.actions .button.back::after {
    content: "";
    width: 2rem;
    height: 2rem;
    position: absolute;
    left: 0;
    top: 1rem;
    transform: rotate(-45deg);
    z-index: -1;
}

@media (width > 90rem) {
    .production-detail footer.actions .button.button.back {
        transform: translateX(.25rem);
    }
}

@media (width < 90rem) {
    footer.actions {
        margin-left: 1rem;
    }
}

@media (width < 48rem) {
    .production-detail footer.actions .button.back {
        height: 3rem;
    }

    .production-detail footer.actions .button.back::after {
        height: 1.5rem;
        width: 1.5rem;
    }
    
}

/* ── ../base/page-intro.css ── */
/* CSS voor de page-intro
Alleen zichtbaar voor margjewittermans
Laat een intro zien met mogelijkheid van een foto
Deze wordt getoond als achtergrond
Standaard display:none
Template:
/kaapkunstvlijt_web/live/settings_live/page_settings.ex */

.page-intro {
    display: none;
    gap: 2rem;
    align-items: flex-start;
    margin-bottom: 2rem;
    flex-wrap: wrap;
}

.page-intro.has-bg-image {
    background-size: cover;
    background-position: center;
    padding: 3rem 2rem;
    min-height: 16rem;
    align-items: flex-end;
}

.page-intro-image {
    flex: 0 1 auto;
}

.page-intro-image img {
    max-width: 20rem;
    height: auto;
    display: block;
}

.page-intro-text {
    flex: 1 1 20rem;
}


/* ── ../base/press-item.css ── */
.press .press-items-container {
    max-height: 30rem;
    overflow: hidden;
    position: relative;
    transition: max-height 0.3s ease;
}

/* Optional: Add a fade effect at the bottom when collapsed */
.press.side-card .press-items-container::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 3rem;
    background: linear-gradient(
        to bottom,
        transparent,
        rgba(255, 255, 255, 0.5) 25%,
        white
    );
    pointer-events: none;
    opacity: 1;
    transition: opacity 0.3s ease;
}

.press .press-toggle-checkbox {
    display: none;
}

.press .press-toggle-checkbox:checked ~ .press-items-container {
    max-height: none;
}

.press .press-toggle-checkbox:checked ~ .press-items-container::after {
    opacity: 0;
}

.press .button {
    color: white;
    cursor: pointer;
    transition: background 0.2s ease;
}

.press .button .show-less {
    display: none;
}

.press .press-toggle-checkbox:checked ~ .button .show-more {
    display: none;
}

.press .press-toggle-checkbox:checked ~ .button .show-less {
    display: inline;
}

.press-item {
    padding: 1rem 0 2rem;
    position: relative;
}

.press-item:not(:last-of-type)::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 25%;
    height: 0.0625rem;
    background-color: rgba(0, 0, 0, 0.15);
}

.press-item .press-summary {
    font-style: italic;
    quotes: initial;
    line-height: 1.5;
    margin: 0.5rem 0;
}

.press-item .press-source {
    display: block;
    margin-bottom: 0.25rem;
}

.press-item .press-link {
    font-style: italic;
}

q::before,
q::after {
    content: "";
}


/* ── ../base/document-grid.css ── */
.document-grid {
    padding: 2rem 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
    gap: 1rem;
}

.document-grid li{
    background-color: rgba(255,255,255,.7);
    padding: 2rem 1rem;
    border-radius: 1rem;
}

/* ── ../base/documents.css ── */
.index.documents {
    padding: 3.5rem clamp(1rem, calc(0.2727rem + 2.2727vw), 3rem);
    position: relative;
    word-wrap: break-word;
    word-break: break-word;
    hyphens: auto;
}

.index.documents .actions {
    display: flex;
    justify-content: flex-end;
    padding: clamp(1rem, 0.737rem + 1.404vw, 2rem) 0;
}

.index.documents .content h2 {
    margin: 2rem 0;
}

ul.documents-list li {
    display: grid;
    align-items: baseline;
    position: relative;
    height: 10rem;
    grid-template-columns: repeat(auto-fill, minmax(14em, 1fr));
    grid-template-columns: repeat(4, 1fr);
    gap: 2.5rem;
    padding: 1rem 1.5rem;
    background-color: rgba(255, 255, 255, .85);
    margin-bottom: 2.5rem;
    border-radius: .5rem;
}

ul.documents-list li .type {
    display: none
}

.index.documents ul.documents-list li footer.actions {
    padding: 0;
    flex-wrap: wrap;
    justify-content: center;
    position: absolute;
    bottom: -1.5rem;
    right: 50%;
    transform: translateX(50%);
    background-color: transparent;
    box-shadow: none;
}

.current-document,
.selected-document,
.document-item {
    border: .25rem solid #fff;
    padding: 2rem 1rem 4rem;
    background-color: rgba(255,255,255,.5);
    position: relative;
    box-shadow: 0 0 2rem rgba(0, 0, 0, 0.15);
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

.document-info {
    flex-grow: 1;
}

.current-document p,
.selected-document p,
.document-item p {
   line-height: 1.25;
}

.current-document h4,
.selected-image h4,
.selected-document header {
   font-size: 1.35rem;
   color: #555;
}

.current-document [class*=icon-],
.selected-document [class*=icon-],
.document-item [class*=icon-] {
    background-color: #555;
}

.current-document .document-icon span.icon-pdf,
.selected-document .document-icon span.icon-pdf,
.document-item span.icon-pdf {
    width: 3rem;
    height: 3rem;
}

.document-title,
.document-type,
.document-size {
   background-color: #555;
   color: #fff;
   padding: .5rem;
}

.document-type {
    color: #555;
    display: inline-block;
}

.document-size {
    display: block;
    width: fit-content;
}

.document-info .document-title span,
.current-document .document-type span,
.selected-document .document-type span,
.selected-document .document-size span {
    font-weight: normal;
    font-style: italic;
    font-size: .875rem;
 }

 .document-actions,
 .current-document .document-info a,
 .document-preview a,
 .current-document button,
 .document-item button,
 .document-item a {
    display: flex;
    align-items: center;
 }

 .document-actions {
   justify-content: space-between;
 }

 .current-document .document-info a span {
    display: inline-block;
    margin-right: .25rem;
 }

 .current-document button {
    position: absolute;
    right: 1rem;
    bottom: .5rem;
    display: flex;
    align-items: center;
 }

 .document-preview a,
 .current-document button,
 .document-item button,
 .document-item a {
    font-variant: all-small-caps;
    color: #333;
 }


/* ── ../base/after-page.css ── */
/* After-page: full-width layout (no sidebar) */
.after-page .col-body {
    display: block;
}

.after-page .col-body .main {
    padding: clamp(1rem, 0.5rem + 2.5vw, 3rem);
}

/* Header */
.after-page-header {
    margin-bottom: 2rem;
    border-bottom: 0.0625rem solid rgba(0, 0, 0, 0.1);
    padding-bottom: 1rem;
}

.after-page-header h2 {
    margin-bottom: 0.25rem;
}

.after-page-subtitle {
    margin: 0;
    opacity: 0.6;
    font-size: 0.9375rem;
}

/* Text sections */
.after-page-intro,
.after-page-extra {
    margin-bottom: 2rem;
}

/* Video */
.after-page-video {
    margin-bottom: 2rem;
}

.after-page-video h3 {
    margin-bottom: 1rem;
}

/* Eén film krijgt de volle breedte; vanaf twee staan ze naast elkaar. Met
   `:has()` en niet met een klasse uit de opmaak: het aantal staat al in de DOM,
   en twee plekken die hetzelfde moeten weten lopen na verloop van tijd uiteen.

   Onder de 48rem blijft het één kolom: een speler van een halve telefoon is
   geen speler meer. */
.after-page-videos {
    display: grid;
    gap: 1.5rem;
}

@media (width >= 48rem) {
    .after-page-videos:has(> :nth-child(2)) {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Het beheerscherm: de films onder elkaar, elk met een eigen knop om hem van
   de pagina te halen. Geen bolletjes — het is een lijst in de zin van "meer dan
   één", niet in de zin van een opsomming. */
.after-page-videos-beheer {
    margin: 0 0 1.5rem;
    padding: 0;
    list-style: none;
}

.after-page-videos-beheer > li + li {
    margin-top: 2rem;
    padding-top: 2rem;
    border-top: 0.0625rem solid rgba(0, 0, 0, 0.12);
}

.video-container {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
}

.video-container iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

/* Gallery */
.after-page-gallery {
    margin-bottom: 2rem;
}

.after-page-gallery h3 {
    margin-bottom: 1rem;
}

/* gallery-grid and gallery-item are styled in base/gallery.css;
   override display:none on gallery-item since we're not using the
   production show's first-of-type trick here */
.after-page-gallery .gallery-item {
    display: block;
}

/* Vaste trappen en geen `auto-fit`: die van base/gallery.css gaat op 20rem
   minimum, en op een vel van tachtig rem levert dat vier kolommen op die per
   venster net iets anders uitvallen. Hier staat wat er staat — twee, drie,
   vier — en niet meer dan vier: een afterpagina is geen contactblad. */
.after-page-gallery .gallery-grid {
    grid-template-columns: repeat(2, 1fr);
}

@media (width >= 48rem) {
    .after-page-gallery .gallery-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (width >= 64rem) {
    .after-page-gallery .gallery-grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* Upcoming dates */
.after-page-dates {
    margin-bottom: 2rem;
}

.after-page-dates h3 {
    margin-bottom: 1rem;
}

table.speeldata {
    width: 100%;
    border-collapse: collapse;
}

table.speeldata td {
    padding: 0.5rem 1rem 0.5rem 0;
    vertical-align: top;
}

table.speeldata tr:not(:last-child) td {
    border-bottom: 0.0625rem solid rgba(0, 0, 0, 0.1);
}

/* Guestbook.

   Staat nu tweede op de pagina, direct onder de introtekst. Het is het enige
   wat deze pagina de bezoeker vraagt, en dan hoort het er niet uit te zien als
   een voetnoot: een eigen vlak, zodat het als een blok op zichzelf leest en
   niet als de staart van de tekst erboven. */
.after-page-guestbook {
    margin-bottom: 2rem;
    padding: clamp(1.25rem, 3vw, 2rem);
    border-radius: 0.25rem;
    background: rgba(0, 0, 0, 0.04);
}

/* De kop is de vraag van de makers ("Wat heeft de voorstelling met je
   gedaan?"), niet een label. Vandaar groter dan de andere kopjes op deze
   pagina — je leest hem als een vraag aan jou. */
.after-page-guestbook h3 {
    margin-bottom: 1rem;
    font-size: 1.25em;
    line-height: 1.3;
}

.guestbook-entries {
    margin-bottom: 2rem;
}

.guestbook-entry {
    padding: 1rem 0;
    border-bottom: 0.0625rem solid rgba(0, 0, 0, 0.1);
}

.guestbook-entry:first-child {
    border-top: 0.0625rem solid rgba(0, 0, 0, 0.1);
}

.guestbook-body {
    margin: 0 0 0.5rem;
    font-style: italic;
}

.guestbook-meta {
    font-size: 0.875rem;
    opacity: 0.6;
}

.guestbook-thanks {
    padding: 1.5rem;
    background-color: rgba(0, 0, 0, 0.04);
    border-radius: 0.25rem;
}

.guestbook-form {
    margin-top: 1rem;
}

.guestbook-prompt {
    margin-bottom: 1.5rem;
    font-size: 1.0625rem;
}

.guestbook-form .form-group {
    margin-bottom: 1rem;
}

.guestbook-form label {
    display: block;
    margin-bottom: 0.375rem;
    font-size: 0.9375rem;
}

.guestbook-form input[type="text"],
.guestbook-form textarea {
    display: block;
    width: 100%;
    max-width: 36rem;
    padding: 0.625rem 0.75rem;
    border: 0.0625rem solid rgba(0, 0, 0, 0.2);
    border-radius: 0.25rem;
    font-family: inherit;
    font-size: 1rem;
    color: inherit;
    background-color: #fff;
}

.guestbook-form textarea {
    resize: vertical;
}

.form-hint {
    margin: 0.75rem 0 1.25rem;
    font-size: 0.875rem;
    opacity: 0.65;
    font-style: italic;
}

/* Footer */
.after-page-footer {
    margin-top: 3rem;
    padding-top: 1.5rem;
    border-top: 0.0625rem solid rgba(0, 0, 0, 0.1);
}

.after-page-footer .back-link {
    font-size: 0.9375rem;
    text-decoration: underline;
}


/* ── ../base/cards.css ── */
.cards {
  padding: 1rem 0 6rem;
  word-wrap: break-word;
  word-break: break-word;
  hyphens: auto;
}

.cards.masonry {
  opacity: 0;
  transition: opacity 0.2s ease-in;
  /* grid-auto-rows: 1px; */
  align-items: start;
}

.cards.masonry.masonry-ready {
  opacity: 1;
}

.cards li .draft-label {
  position: absolute;
  background-color: black;
  color: white;
  top: -1rem;
  padding: 0.25rem 2rem;
  text-transform: uppercase;
  letter-spacing: 0.125rem;
}

/* Scrollspy: per-card fade, 150ms stagger in document order (LTR per row) */
[phx-hook="CardAnimation"] .cards li {
  opacity: 0;
}

[phx-hook="CardAnimation"] .cards li.visible {
  animation: kkv-scrollspy-fade 0.8s linear both;
}

@keyframes kkv-scrollspy-fade {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  [phx-hook="CardAnimation"] .cards li,
  [phx-hook="CardAnimation"] .cards li.visible {
    animation: none;
    opacity: 1;
  }
}


/* ── ../base/video.css ── */
/* De maat van een video op een voorstellingspagina. Alleen Hotel Modern
   importeert dit bestand. */

/* De gevel krijgt hetzelfde kader als de speler die er bij een klik in komt:
   voor de opmaak is er geen verschil tussen "de film staat er" en "de film kan
   er komen". Zie de gedeelde gevel in base/base.css.

   Let op de `>`: dit gaat over het kader, niet over de speler eríń. Zonder die
   pijl raakte deze regel ook de iframe binnen een gevel, en dan won de
   `margin-top` het van de `margin: 0` in base/base.css — gelijke specificiteit,
   en dit bestand wordt later geladen. Die 2rem duwde de speler omlaag in een
   kader met `overflow: hidden`, en wat er onderaan afviel was precies de balk
   met de knoppen: de bezoeker zag een speler zonder bediening, bij Vimeo en bij
   Bunny allebei. Gevonden op 09-09-2026.

   Ook geen `height: 100%` meer: met een hoogte én een breedte laat de browser
   `aspect-ratio` vallen, en dan hangt de maat van het kader af van wat er
   toevallig in staat. */
.video-players > iframe,
.video-players .bunny-poster-card {
    aspect-ratio: 16/9;
    width: 100%;
    margin-top: 2rem;
}

/* ── In de kamer ─────────────────────────────────────────────────────────

   De regels hiervoor staan in hotelmodern/components/roomview.css, bij de rest
   van het vel. Deze twee staan hier, omdat het over de gevel gaat en niet over
   het vel: `.hm-room-block` is alleen het adres waar hij hangt. */

/* Alle films staan in hetzelfde kader, ook als de bron dat niet is: twee kaders
   van verschillende hoogte onder elkaar lezen als een fout.

   16/10 en niet 16/9: bij een staande bron blijft er in een 16/9-kader een
   smalle strook over, en de speler heeft onderin ook nog zijn balk staan. Iets
   meer hoogte scheelt daar zichtbaar, en voor een liggende 16:9-film is het een
   band zwart van nog geen 1.5rem boven en onder — die valt weg tegen de zwarte
   achtergrond van het kader. Het beeld zelf wordt nergens meer afgesneden: dat
   doet `object-fit: contain` in base/base.css. */
.hm-room-block > .video-players .bunny-poster-card {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 10;
    background: #000;
}

/* De films staan in de rechterhelft van het sluitstuk, onder elkaar. Elk is
   daarmee een halve breedte van het vel — in de zijkolom waren ze 23.5rem en
   dus een postzegel, over het hele vel werd de kamer een filmzaal. */
.hm-room-closing .video-players {
    display: flex;
    flex-direction: column;
    /* Dezelfde tussenruimte als tussen de foto's ernaast — die staat als
       `--gallery-gap` in base/gallery.css. Twee rasters naast elkaar met een
       verschillend ritme lezen als twee verschillende bladen. */
    gap: 1.25rem;
}

/* De marge tussen de spelers zat op het kader zelf; hier doet de tussenruimte
   van de kolom dat werk, en zou hij er bovenop komen. */
.hm-room-closing .video-players .bunny-poster-card {
    margin-top: 0;
}



/* ── base/fonts.css ── */
/* Hotel Modern — typografie.

   De WordPress-site laadde in de <head> wel Playfair Display en Droid Serif via
   Google Fonts, maar geen enkele themaregel verwees ernaar: die site rendert in
   werkelijkheid in de Bootstrap-systeemstack. De letter van de oude site is
   daarom níet uit de CSS te lezen — wél uit de pixels. De introtekst op /over
   zat als beeld in de achtergrondfoto gebakken; door die plaat van de tekstloze
   af te trekken bleef precies de tekst over, en die legde het tegen 24
   kandidaten af als Droid Serif (het rode "lees meer" in de cursief).

   Dat is dus de letter die de oude site feitelijk toonde, en de richting die we
   houden. Droid Serif zelf is bij Google Fonts uitgefaseerd en heeft alleen
   `latin`; we gebruiken daarom de aangewezen opvolger, Noto Serif — dezelfde
   vorm, wél onderhouden en met `latin-ext` erbij, wat we nodig hebben zodra
   Frans en Spaans erbij komen.

   Zelf gehost, niet via Google Fonts: dat scheelt een externe verbinding op elke
   pagina, en het scheelt de bezoeker een verzoek naar een derde partij. De
   bestanden zijn met `pyftsubset` uit de systeem-TTF's gesneden en per bereik
   gesplitst, zodat een Nederlandse pagina alleen de kleine `latin`-snede haalt
   (~23 kB per snit) en de zwaardere `latin-ext` blijft liggen tot een tekst hem
   nodig heeft. Licentie: SIL Open Font License 1.1. */

@font-face {
  font-family: "Noto Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/noto-serif/noto-serif-regular-bbb4c32ab866d19df52b0f050d93ed4e.woff2?vsn=d") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Noto Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/noto-serif/noto-serif-regular-ext-817e11ce51a9a7e7cd32fa79f140d681.woff2?vsn=d") format("woff2");
  unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Noto Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/noto-serif/noto-serif-italic-2c839c2ac0e94703c2cc076b9a78f56b.woff2?vsn=d") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Noto Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/noto-serif/noto-serif-italic-ext-23444f443b64c72c42062c7421dcf1ca.woff2?vsn=d") format("woff2");
  unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Noto Serif";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("vendor/noto-serif/noto-serif-bold-10f5faf16d76d76d4db4c14d066eec15.woff2?vsn=d") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Noto Serif";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("vendor/noto-serif/noto-serif-bold-ext-d21eff221eb7c7b4b8f052fe47170247.woff2?vsn=d") format("woff2");
  unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Noto Serif";
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url("vendor/noto-serif/noto-serif-bolditalic-9bb46ee7cf49e1d2209e48cc788cd6b9.woff2?vsn=d") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Noto Serif";
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url("vendor/noto-serif/noto-serif-bolditalic-ext-83b586531f70f3128873d2e4d32f8b17.woff2?vsn=d")
    format("woff2");
  unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* De props zijn de uitzondering op die ene familie. Het woord HOME onder het
   belletje stond op de oude site in de PNG gebakken, en dat was aantoonbaar
   Impact: op dezelfde hoogte gezet komt "HOME" uit op exact 57x21 pixels, precies
   het origineel, met dezelfde M en E. Impact staat op vrijwel elke Windows en
   macOS, dus die roepen we gewoon aan. Voor wie hem niet heeft — Linux, Android —
   is Anton de vrije tegenhanger: iets smaller, maar dezelfde zwarte condensed
   grotesk, en zelf gehost zodat er geen verzoek naar een derde partij gaat.
   Licentie: SIL Open Font License 1.1. */
@font-face {
  font-family: "Anton";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/anton/anton-latin-1c010b50547cf4e25af867c331e547c1.woff2?vsn=d") format("woff2");
  unicode-range: U+0020-007E, U+00A0-00FF;
}

/* Eén familie voor de hele tenant: koppen zijn dezelfde letter in 700, zoals in
   het boek van de oude site. De twee variabelen blijven bestaan omdat de
   componenten ze noemen — en omdat een latere splitsing dan één regel is. */
:root {
  --hotelmodern-font-heading: "Noto Serif", Georgia, "Times New Roman", serif;
  --hotelmodern-font-body: "Noto Serif", Georgia, "Times New Roman", serif;
  --hotelmodern-font-prop: Impact, Haettenschweiler, "Anton", "Arial Narrow",
    sans-serif;
}


/* ── base/colors.css ── */
/* Hotel Modern — kleurpalet, afgeleid uit de originele theme-CSS. */
:root {
  --hotelmodern-bg: #d2c3b0;        /* warm perkament (receptie-achtergrond) */
  --hotelmodern-fg: #111111;
  --hotelmodern-accent: #871d0f;    /* diep hotel-rood */
  --hotelmodern-accent-dark: #460f08;
  --hotelmodern-paper: #ffffff;
  --hotelmodern-border: #000000;
  /* Antraciet als geverfd bordje (RAL 7016). Voor knopjes die op een scènefoto
     liggen: die kan alles zijn van een donkere kelder tot een lichte muur, dus
     ze hebben een eigen ondergrond nodig in plaats van een aanname. */
  --hotelmodern-plaque: #383e42;

  /* Scrollbalken. Inkt op perkament is de standaard; donkere vlakken zetten de
     duim zelf lichter (zie `.hm-scroll-dark` in components/scene.css). Bewust
     géén accentrood: dat betekent in deze tenant "hier kun je heen", en dat wil
     je niet verwateren met chroom. */
  --hotelmodern-scroll-thumb: rgba(43, 26, 16, 0.35);
  --hotelmodern-scroll-track: transparent;
}


/* ── components/button.css ── */
/* Hotel Modern — hoe een knop eruitziet.

   `.button` is de basisklasse van het platform: wie hem opschrijft, wil een
   knop. De gedeelde `base/button.css` regelt alleen de vorm (inline-flex,
   uitlijning); hoe hij eruitziet is per tenant. Dat stond hier lange tijd
   nergens, en dus schreef elke plek zijn eigen knop op — dezelfde declaraties
   in de kamer, in de perssectie, in de gang. Nu staat het één keer hier.

   Twee ondergronden, meer zijn het er niet:

   1. Op papier — het vel van de voorstellingskamer, de recensies. Rood omlijnd,
      dezelfde inkt als elke andere aanklikbare tekst op dat vel; de rand zegt
      dat er iets gebeurt in plaats van dat er iets te lezen valt.
   2. Op een scènefoto — de beheerknopjes in de gang en onder in de kamer. Die
      foto kan alles zijn van een donkere kelder tot een lichte muur, dus daar
      hoort een eigen bordje onder in plaats van een aanname.

   Wijkt een plek af, dan overschrijft die plek één ding (zie de gestreepte rand
   van "speelbeurt toevoegen" in roomview.css) — niet de hele knop opnieuw. */

/* ── Op papier ───────────────────────────────────────────────────── */

.hm-stage .button {
    /* `base/button.css` zet 1.25rem rechts voor knoppenrijen in het beheer. In
       een scène staan knoppen zelden naast elkaar, en op een smal scherm eet
       die marge de breedte op waardoor het label afbreekt. */
    margin: 0.4rem 0 0;
    padding: 0.4rem 0.9rem;
    border: 0.0625rem solid var(--hotelmodern-accent);
    border-radius: 0.15rem;
    background: none;
    color: var(--hotelmodern-accent);
    font-family: var(--hotelmodern-font-body);
    font-size: 0.9rem;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition:
        background 0.2s ease,
        color 0.2s ease;
}

/* De pictogrammen zijn maskers: ze zijn precies zo zichtbaar als hun
   achtergrondkleur, en zonder kleur helemaal niet. Op een scène zet niemand die
   kleur — het plusje voor "speelbeurt toevoegen" was er wel, maar onzichtbaar,
   en hield alleen een gat van 1,5rem open. Met `currentColor` volgt het de
   letters, ook als de knop bij hover omkeert. Op tekstmaat, want naast een
   label van 0,9rem is de standaard 1,5rem een prent. */
.hm-stage .button [class*="icon-"] {
    width: 1.1em;
    height: 1.1em;
    background-color: currentColor;
}

.hm-stage .button:hover,
.hm-stage .button:focus-visible {
    background: var(--hotelmodern-accent);
    color: #f6f3e9;
    text-decoration: none;
}

/* ── Gevuld: de knop die wél om aandacht vraagt ──────────────────── */

/* Eén knop per vel mag dat. "Bekijk de hele tour" is er zo een: wie de eerste
   vijf speelbeurten leest en meer wil, moet hem zien staan zonder te zoeken.
   Omlijnd las hij als nog een verwijzing tussen de tekst.

   Het is dezelfde knop als hierboven, omgekeerd: de inkt wordt de ondergrond.
   Daarmee blijft het één knoppenstelsel — geen tweede kleur, geen tweede vorm,
   alleen vol in plaats van leeg, en een maat en gewicht groter zodat hij ook
   van een halve meter afstand het eerst opvalt. Bij hover verdiept hij naar de
   donkere kant van dezelfde kleur; omkeren kan niet nog een keer.

   Gevraagd door de redactie, 14-09-2026. */
.hm-stage .button.is-gevuld {
    padding: 0.55rem 1.3rem;
    background: var(--hotelmodern-accent);
    color: #f6f3e9;
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.hm-stage .button.is-gevuld:hover,
.hm-stage .button.is-gevuld:focus-visible {
    background: var(--hotelmodern-accent-dark);
    color: #fff;
}

/* ── Op een scènefoto ────────────────────────────────────────────── */

.hm-corridor-admin .button,
.hm-roomview-admin .button {
    margin: 0;
    border-color: rgba(255, 255, 255, 0.45);
    background: rgba(0, 0, 0, 0.55);
    font-size: 0.85rem;
    color: #fff;
}

.hm-corridor-admin .button:hover,
.hm-corridor-admin .button:focus-visible,
.hm-roomview-admin .button:hover,
.hm-roomview-admin .button:focus-visible {
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
}



/* De scènes van Hotel Modern, in cascade-volgorde: eerst de doos waar ze in
   hangen, dan per scène wat erin staat. */
/* ── components/scene.css ── */
/* Hotel Modern — de zwarte doos.
   Body-brede stand van zaken voor de scène-pagina's (receptie, gang, kamer): de
   platform-header en -footer eruit, de scène uit de gecentreerde `.wrap`, en het
   zwart dat doorloopt tot de schermrand. Alleen de doos zelf staat hier; wat
   erin hangt staat per scène in reception.css, corridor.css en roomview.css. */

body.hotelmodern {
    background: var(--hotelmodern-accent-dark);
    color: var(--hotelmodern-fg);
    font-family: var(--hotelmodern-font-body);
}

/* Formulier-elementen erven de letter niet van de body — die vallen terug op de
   UA-default (Arial). Meestal onzichtbaar omdat het om een kruisje of een pijl
   gaat, maar zodra er een woord in staat valt het meteen op. */
body.hotelmodern :is(button, input, select, textarea) {
    font-family: inherit;
}

/* Koppen in de kopletter. Het gewicht stond hier op 400 omdat de vorige
   kopletter (Special Elite) er maar één had en de browser-default `bold` dus
   synthetisch verzwaard werd; Noto Serif heeft een echte 700, en zo stonden de
   koppen in het boek van de oude site ook. Dekt via specificiteit ook
   .hm-preview-title (een h3) en de koppen in .hm-room-content-inner. */
body.hotelmodern h1,
body.hotelmodern h2,
body.hotelmodern h3,
body.hotelmodern .hm-modern-title {
    font-family: var(--hotelmodern-font-heading);
    font-weight: 700;
}

/* De ruime letterafstand kwam van de typemachine-kop, waar hij de ongelijke
   aanslag rustiger maakte. Een serif heeft dat niet nodig; wat overblijft is
   een spatiëring die de kop nog als bordje laat lezen. */
body.hotelmodern h3 {
    font-size: 1.675rem;
    letter-spacing: 0.08em;
}

/* Op de scène-pagina's (receptie, gang) vervangen de props de navigatie: verberg
   de platform-header/footer en laat de scène uit de gecentreerde `.wrap` breken,
   zodat de scène de oude site benadert en full-bleed kan schalen. */
body.hotelmodern:has(.hm-stage) .header,
body.hotelmodern:has(.hm-stage) .footer {
    display: none;
}

body.hotelmodern:has(.hm-stage) .wrap {
    max-width: none;
}

body.hotelmodern:has(.hm-stage) .main {
    margin: 0;
    padding: 0;
}

/* Full-bleed zwarte doos: de body zelf zwart (anders piept de bordeaux
   body-achtergrond door), en de gereserveerde scrollbalk-gutter eraf — een
   scène scrollt niet, dus die gutter zou alleen een strook rechts opeten. */
html:has(.hm-stage) {
    scrollbar-gutter: auto;
}

body.hotelmodern:has(.hm-stage) {
    background: #000;
    overflow: hidden;
}

/* ── Scrollende vlakken (gedeeld) ────────────────────────────────── */

/* Eén behandeling voor alles wat in een scène scrollt. Stond eerder vier keer
   apart in de componenten, elke keer net anders, terwijl juist de twee grootste
   vlakken (het krantvel en de modals) de kale OS-balk hielden.

   `thin` is hier de ondergrens, geen smaakkeuze: onder ±8px wordt de balk een
   muisdoel dat je niet meer pakt, en dat treft precies wie de minste precisie
   heeft. Verbergen doen we alleen waar iets anders het overneemt — in het boek
   zeggen de pijlen en het weglopende papier samen dat er meer is. */
.hm-scroll {
    scrollbar-width: thin;
    scrollbar-color: var(--hotelmodern-scroll-thumb) var(--hotelmodern-scroll-track);
}

/* Op zwart (filmdoek, album, kranten-overlay) draait de duim om. */
.hm-scroll-dark {
    --hotelmodern-scroll-thumb: rgba(255, 255, 255, 0.4);
}

/* ── Scrollpijlen (gedeeld) ──────────────────────────────────────── */

/* Twee pijlen in de hoek van een scrollend vlak: ze melden dat er meer is, en
   zetten het vlak op een klik een schermhoogte op of neer. Ze horen bij de
   scrollbalk en niet bij de inhoud, dus ze staan búiten het scrollende vlak —
   anders schuiven ze met de eerste muisbeweging weg. Verbergen zolang alles
   past, en uitgaan aan het boven- of ondereind, doet de hook HmScroll.

   Eén bestand voor beide richtingen: `arrow.svg` als masker, de bovenste een
   halve slag gedraaid. De pijl neemt de inkt van zijn omgeving aan, dus op
   papier is hij donker en op het zwart licht; de plek bepaalt het onderdeel
   zelf. Deze twee klassen zijn de maat die overal gelijk hoort te zijn — het
   sleutelbord, het boek en de agenda hebben elk nog hun eigen kopie hiervan,
   van vóór dit blok. */
.hm-scroll-arrows {
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.hm-scroll-arrows[hidden] {
    display: none;
}

.hm-scroll-arrows button {
    padding: 0.2rem;
    border: 0;
    background: none;
    color: inherit;
    cursor: pointer;
    opacity: 0.7;
    transition: opacity 0.2s ease;
}

.hm-scroll-arrows button:hover,
.hm-scroll-arrows button:focus-visible {
    opacity: 1;
}

.hm-scroll-arrows button:disabled {
    opacity: 0.2;
    cursor: default;
}

.hm-scroll-arrow {
    display: block;
    width: clamp(0.5rem, 0.8vw, 0.75rem);
    aspect-ratio: 19 / 40;
    background: currentColor;
    -webkit-mask: url("/assets/hotelmodern/voorstellingen/arrow-9e91cac7deb036c17c0a0931e14d3913.svg?vsn=d") center /
        contain no-repeat;
    mask: url("/assets/hotelmodern/voorstellingen/arrow-9e91cac7deb036c17c0a0931e14d3913.svg?vsn=d") center / contain no-repeat;
}

[data-scroll="up"] .hm-scroll-arrow {
    transform: rotate(180deg);
}

/* ── Scène-doos (gedeeld) ────────────────────────────────────────── */

/* Elke scène ligt in een "zwarte doos": geen kader of inzet, het zwart loopt
   door tot de schermrand en blijft alleen als band over waar de beeldverhouding
   afwijkt. `position: fixed; inset: 0` pint de doos exact op het venster, los van
   de omliggende layout-keten (anders sijpelt daar hoogte doorheen als banden). */
.hm-stage {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: #000;
}

/* ── Mediakamer (gedeeld) ────────────────────────────────────────── */

/* De drie mediakamers — bioscoop, radio, fotogalerie — zijn dezelfde doos: één
   geschilderde plaat van 1366x768 met alles erin absoluut gepositioneerd. Ze
   stonden drie keer los in hun eigen bestand, elke keer gelijk; hier staan ze
   één keer.

   `width: min(...)` in plaats van `max-width/max-height: 100%`. Met alleen
   maxima had de kamer geen eigen breedte en viel hij terug op de intrinsieke
   maat van de achtergrondplaat: 1366px, en geen pixel meer. Op een venster van
   2560 lag de scène dus als een eilandje van 1366 in het zwart, terwijl er
   1920 beschikbaar was. Nu volgt de kamer de kleinste van de twee grenzen —
   breedte of hoogte — en vult hij de doos in beide richtingen. Zelfde regel als
   de receptie (`.hm-room`).

   `container-type: inline-size` maakt de kamer de maat voor `cqw`: alles in de
   scène — tekst, tussenruimtes, rasters — schaalt met de scène en niet met het
   venster. Die twee lopen uiteen zodra er zwarte banden staan, en dat is precies
   waar de tekst te groot uitviel.

   Het zwarte kader van 15px eromheen is weg: de doos eronder is al zwart, dus
   het was onzichtbaar zwart op zwart dat alleen de scène 30px kleiner maakte —
   en dankzij `box-sizing: content-box` ook nog eens buiten de maxima viel. */
.hm-cinema-room,
.hm-radio-room,
.hm-gallery-room {
    position: relative;
    aspect-ratio: 1366 / 768;
    width: min(100vw, calc(100dvh * 1366 / 768));
    container-type: inline-size;
    overflow: hidden;
}

/* De achtergrondplaat vult de kamer; die heeft dezelfde verhouding, dus `cover`
   snijdt niets weg. */
.hm-cinema-bg,
.hm-radio-bg,
.hm-gallery-bg {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Portret: hier stond de kamer eerst op volle hoogte en pande je er horizontaal
   doorheen. Dat zag er goed uit voor de plaat, maar het zette de inhoud buiten
   beeld: op een telefoon is nog geen derde van de scène in beeld, en de
   radiogids, de bel, het filmdoek en de hele fotokolom vielen allemaal in het
   deel waar je pas naartoe scrolt. Precies datgene waarvoor je de pagina opent.

   Dus dezelfde omslag als de receptie in portret maakt: de plaat wordt een
   schermvullende hero-crop en de kamer een transparante laag daarover. Wat erin
   hangt wordt per kamer opnieuw ingedeeld — dat staat in radio.css, gallery.css
   en cinema.css. De percentages van de liggende scène blijven werken omdat de
   kamer nog steeds de positioneer-context is; alleen slaan ze nu op het venster.

   `container-type: normal`: `cqw` zou hier de vensterbreedte zijn en is dus geen
   maat meer voor tekst — een letter van 0,95% van een telefoonscherm is 4px. In
   portret staan de lettermaten daarom in rem.

   `max-aspect-ratio: 5 / 6` erbij, want `orientation: portrait` alleen klapt om
   zodra een venster één pixel hoger is dan breed — en dat haalt een desktop al
   met devtools ernaast. Op 1110x1254 (0,885) kreeg je zo de telefoonindeling
   terwijl er ruimte zat voor de hele liggende scène. De omslag hoort pas te
   komen als het scherm echt staand is: 1,2 keer hoger dan breed. Dan valt een
   iPad Pro (1024x1366, 0,75) er nog altijd binnen en een half desktopvenster
   niet. Dezelfde grens die de receptie en frame-list al gebruiken.

   Deze query staat vier keer: hier voor de kamer zelf, en in cinema.css,
   radio.css en gallery.css voor wat erin hangt. Ze horen bij elkaar — verander
   je er één, dan krijg je een schermvullende kamer met liggende percentages
   erin. */
@media (orientation: portrait) and (max-aspect-ratio: 5 / 6) {
    .hm-cinema-room,
    .hm-radio-room,
    .hm-gallery-room {
        position: absolute;
        inset: 0;
        width: auto;
        aspect-ratio: auto;
        container-type: normal;
    }
}

/* ── De bel naar huis (gedeeld) ──────────────────────────────────── */

/* Elf pagina's hadden hun eigen bel: zeven verschillende plaatjes, elf plekken,
   zes maten, en het woord HOME in vijf kleuren. Op het opengeslagen boek viel
   hij daardoor niet in de schermhoek maar in de kantlijn van de rechter-
   bladzijde, naast de kop van het hoofdstuk — hinderlijk juist omdat elke
   andere pagina hem wél in de hoek zet.

   Hier staat hij één keer: één plek, één maat, één letter. Wat een scène nog
   mag zeggen is de inkt, en daarvoor is er precies één schakelaar (`.on-paper`
   hieronder) in plaats van vijf improvisaties.

   `cqw` en niet `%`: de bel hangt in de ene scène los in de kamer en in de
   andere in een `nav` naast het bordje terug. Een percentage rekent dan tegen
   een andere ouder en levert per pagina een andere bel op — precies de fout die
   we hier opruimen. `cqw` rekent altijd tegen de scène zelf. Om dezelfde reden
   staan boven- en zijkant allebei in `cqw`: een `top` in procenten meet tegen
   de hóógte, en dan is de hoekmarge boven 19px en opzij 34px terwijl er één
   getal staat.

   Drie pagina's hebben geen 16:9-scène — het nieuwsbord, het berichtvel en de
   agenda dragen geen maquettefoto, dus valt er niets bij te snijden en is er ook
   geen `cqw` om tegen te rekenen. Daar wordt `cqw` de vensterbreedte en zou de
   bel op een breed scherm doorgroeien terwijl de kamer eronder al stilstaat. Die
   drie lenen daarom de rechthoek van de gang; zie hieronder. */
body.hotelmodern {
    --hm-bell-size: 5cqw;
    --hm-bell-inset: 1.6cqw;
}

/* De rechthoek van de gang: de grootste 16:9 die in het venster past. Elke
   maquettekamer legt haar foto zo neer (corridor.css, roomview.css, de
   mediakamers), en de agenda legt er haar marmeren blad in. Hij staat hier omdat
   de drie kamers zónder foto hem óók nodig hebben — niet om iets in te leggen,
   maar om te weten waar de hoek van het beeld ligt. */
:root {
    --hotelmodern-scene-rect: min(100vw, calc(100dvh * 16 / 9));
}

/* Die drie zetten de bel dus op de maat van de gang: 5% van die rechthoek breed,
   1,6% inzet. Zo landt hij op elk scherm op precies dezelfde plek als op
   /voorstellingen — en dat is de hele bedoeling van deze hoek.

   Ze hingen hiervoor op een eigen `clamp` in rem, afgeleid van de breedte waarop
   hun kamer stilstaat. Optisch kwam dat in de buurt, maar niet gelijk: op een
   breed scherm stond de agendabel op 24px van de vensterrand en die in de gang
   op 70px, want dáár telt de zwarte band naast de kamer mee. Naast elkaar gezet
   is dat verschil meteen te zien.

   `--hm-scene-side` is die band. De bel hangt bij deze drie aan de scène (het
   hele venster) en niet ín de rechthoek, dus komt de band er zijdelings bij; de
   `top` heeft hem niet nodig, want alle drie lopen van boven tot onder door. */
.hm-stage:is(.hm-agenda, .hm-news, .hm-newssheet) {
    --hm-bell-size: calc(var(--hotelmodern-scene-rect) * 0.05);
    --hm-bell-inset: calc(var(--hotelmodern-scene-rect) * 0.016);
    --hm-scene-side: calc((100vw - var(--hotelmodern-scene-rect)) / 2);
}

.hm-stage:is(.hm-agenda, .hm-news, .hm-newssheet) > .hm-bell,
.hm-stage:is(.hm-agenda, .hm-news, .hm-newssheet) > .hm-scene-langs {
    right: calc(var(--hm-bell-inset) + var(--hm-scene-side));
}

.hm-bell {
    position: absolute;
    top: var(--hm-bell-inset);
    right: var(--hm-bell-inset);
    /* Dezelfde laag als de props in de fotogalerie, de pers-ordner en de
       vitrine. Lager mag niet: het fotoalbum en het nieuwsbord leggen een vlak
       over de hele scène, en daar verdween de bel achter. Hoger ook niet — op
       2000 liggen de modals, en die horen de uitgang wél af te dekken. */
    z-index: 1000;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: var(--hm-bell-size);
    text-decoration: none;
    transition: transform 0.2s ease-out, filter 0.2s ease-out;
}

.hm-bell:hover,
.hm-bell:focus-visible {
    transform: scale(1.04);
    filter: brightness(1.12);
}

.hm-bell img {
    display: block;
    width: 100%;
    height: auto;
}

/* Impact heeft zijn eigen krappe spatiëring; het origineel gebruikte die
   ongewijzigd, dus hier geen letter-spacing. Gewicht ook niet: de letter is al
   zwart, en `bold` levert alleen een nagemaakte verdikking op.

   0,425 keer de bel: daarmee wordt HOME bijna precies zo breed als het belletje
   zelf — de verhouding waarin het woord er op de oude site in gebakken zat.

   Gerekend vanaf `--hm-bell-size` en niet nog eens los in `cqw`. Het stond hier
   als 2,125cqw, wat op een 16:9-scène hetzelfde getal oplevert (de bel is daar
   5cqw), maar dat gold alleen zolang niemand de bel een andere maat gaf. De
   agenda en het nieuwsbord doen dat wél: die dragen geen maquettefoto, dus daar
   is `cqw` de vensterbreedte en zetten ze de bel op een `clamp` die bij 4,5rem
   stilstaat. Het woord bleef intussen met het venster meegroeien. Op 1925px was
   de bel 72px en HOME 91px: het woord stak er negentien pixels buiten, en op de
   agenda — waar de bel in de schermhoek hangt in plaats van in een kolom — kwam
   het daardoor op 15px van de rand terwijl de bel zelf keurig op 24px stond.
   Zo volgt het woord de bel, wat de maat hierboven ook is. */
.hm-bell span {
    /* Krap tegen het voetje, en met opzet negatief: in het originele plaatje
       (hotelmodern.nl, `partials/production/default/assets/img/prop/nl/bell.png`)
       raakt de bovenkant van HOME de onderrand van het bordeaux voetje. Onze
       bel draagt onderaan nog een stuk slagschaduw, dus zonder deze correctie
       hangt het woord er een regel onder en staan bel en woord als twee dingen
       in plaats van als één prop. */
    margin-top: calc(var(--hm-bell-size) * -0.06);
    font-family: var(--hotelmodern-font-prop);
    /* Opgemeten aan het origineel: daar is HOME ongeveer even breed als het
       belletje zelf. Stond op 0,425 en dat is een kwart te groot — het woord
       werd het zwaarste ding in de hoek in plaats van het onderschrift van een
       prop. Zie docs/ voor de vergelijking. */
    font-size: calc(var(--hm-bell-size) * 0.34);
    line-height: 1;
    text-transform: uppercase;
}

/* De enige inkt-keuze die een scène nog heeft. Standaard is wit met een donkere
   halo eromheen: dat houdt zich staande op het gele behang van de gang, op de
   wisselende scènefoto van een voorstellingskamer én op het zwart van het
   filmdoek, zonder dat de bel per pagina een eigen regel nodig heeft.

   Hier stond eerder `mix-blend-mode: difference`, dat op donker wit werd en op
   licht zwart. Slim, maar niet betrouwbaar: het werkt alleen zolang niets
   eromheen een eigen stapelcontext maakt (bij de gang deed een `z-index` dat al,
   en die staat nu hierboven voor álle bellen), en op middentonen zoals het kant
   van de vitrine kwam er een vuilgrijs woord uit in plaats van zwart of wit. */
.hm-bell span {
    /* Zwart met een lichte halo, zoals in het originele plaatje: daar staat
       HOME in puur zwart (0,0,0) met de slagschaduw van de prop eromheen.

       Hier stond wit met een donkere schaduw. Dat was een verdedigbare keuze —
       het houdt zich staande op elke ondergrond — maar het maakt van het woord
       het lichtste ding in de hoek, terwijl het in het origineel juist wegzakt
       in de scène. De klant vroeg om de oude bel terug, en dit is het verschil
       dat je ziet.

       De halo doet wat de witte letter deed: op het mos van de bioscoop, het
       donkere album van de fotogalerie en de schemerige gang van het nieuwsbord
       licht hij de letter van de ondergrond af. Alle vier nagekeken op 1600
       breed; zwart houdt daar stand. */
    color: #000000;
    text-shadow: 0 0 0.22em rgba(255, 255, 255, 0.85);
}

/* Licht papier: het boek, de agenda, de radiokamer (een houtsnede die
   rechtsboven wit is) en het kant van de vitrine. Daar is een witte letter met
   een schaduw een vlek; donkere inkt is wat er in het origineel ook stond. */
.hm-bell.on-paper span {
    color: #2b1a10;
    text-shadow: none;
}

/* Vier pagina's hangen de bel niet los in de scène maar in een rij: de
   voorstellingskamer en de fotogalerie zetten hem bóven hun tweede uitgang (het
   bordje terug, het bioscoop-bordje), en de agenda en het nieuwsbord zetten hem
   in hun kopregel op het papier zelf. Daar bepaalt de rij de plek; maat, letter
   en inkt blijven van hierboven — en de rij zelf neemt de hoek over, zodat de
   bel toch op precies dezelfde plek uitkomt. */
.hm-bell.is-inline {
    position: static;
    /* Nooit meekrimpen. Drie van die vier rijen zijn flexrijen met tekst ernaast
       (het register op het nieuwsbord, de kopregel van de agenda, de propsrij van
       de fotogalerie), en een flexitem geeft standaard mee. Op een telefoon werd
       de bel in het register zo van 3,4rem naar 1,8rem gedrukt: een streepje in
       plaats van een uitgang. De bel is een plaatje met een vaste verhouding en
       de maat komt hierboven vandaan — die hoort niet van de buren af te hangen. */
    flex: 0 0 auto;
}

/* Staand houdt de scène-eenheid op: `container-type` gaat in portret uit (zie de
   mediakamers hierboven en roomview.css), dus `cqw` is daar de vensterbreedte en
   zou de bel op een telefoon 20 px breed maken. In rem, en ruim: dit is de
   uitgang van de pagina, en op 3,4rem haalt het trefvlak met het woord eronder
   de 44 px die een vinger nodig heeft. */
@media (max-aspect-ratio: 6/5) {
    body.hotelmodern {
        --hm-bell-inset: 0.8rem;
        --hm-bell-size: 3.4rem;
    }

    .hm-bell span {
        margin-top: 0.12rem;
        font-size: 0.8rem;
    }
}

/* ── De kopregel (alleen staand) ─────────────────────────────────── */

/* Liggend bestaat deze balk niet. Daar zijn de uitgangen rekwisieten in de
   scène: het hotelbelletje rechtsboven in de plaat, daaronder een eventueel
   bordje terug, en daaronder de taalbordjes. Dat is het ontwerp van deze
   tenant, en op de oude site geldt het zonder uitzondering — op élke pagina
   hangt precies dat belletje in de rechterbovenhoek, met wat lucht eromheen.

   In 1.2.7 stond deze balk even op elk formaat. De aanleiding was dat die
   losse rekwisieten op een breed scherm rommelig ogen: drie dingen die per
   pagina ergens anders opduiken en met de foto concurreren. Hotel Modern wil
   dat niet — die rommeligheid is het ontwerp en geen fout. Teruggedraaid op
   2026-09-05, in overleg met de artistieke leiding.

   Staand blijft de balk wél. Daar valt het rekwisieten-ontwerp echt uit
   elkaar: de ene kamer legt zijn plaat tegen de onderrand, de andere centreert
   hem, een derde laat inhoud voorgaan, en de bel landt op elke pagina ergens
   anders. En de oude site heeft voor mobiel een eigen ontwerp in plaats van
   een versmalde desktop, dus er is hier niets om naar terug te keren. Zie
   `hotelmodern_topbar/1`.

   Eén gevolg van het teruggaan, bewust: de AGENDA-link bestond alleen in deze
   balk. Liggend loopt de weg naar de agenda dus weer via het agenda-prop op de
   balie, zoals op de oude site. Staand houdt de balk hem.

   Blijft buiten de query staan voor het geval een scherm er geen scène onder
   heeft. */
.hm-topbar {
    display: none;
}

@media (max-aspect-ratio: 6/5) {
    body.hotelmodern:has(.hm-stage) {
        /* Vaste hoogte, niet uit de inhoud gerekend: de scènes eronder moeten
           weten hoeveel er van hun bovenrand af gaat, en een balk die met zijn
           letter meegroeit maakt daar een raadsel van. De bel is hier 2,4rem en
           met het woord eronder 3,19rem hoog; de rest is lucht. */
        --hm-topbar-h: 3.75rem;
    }

    /* Alleen als er een scène is. Een beheerscherm draagt er geen en heeft de
       gewone platform-header al (zie admin.css); twee koppen boven elkaar. */
    body.hotelmodern:has(.hm-stage) .hm-topbar {
        position: fixed;
        inset: 0 0 auto;
        height: var(--hm-topbar-h);
        /* Boven de rekwisieten (1000) en onder de modals (2000): de balk hoort
           een prop af te dekken, maar geen open venster. */
        z-index: 1500;
        display: flex;
        align-items: center;
        /* Als variabele, want de groep uitgangen hieronder houdt dezelfde maat
           aan en de tablet-uitvoering onderaan zet hem één keer om. Krap, want de
           balk draagt op de smalste telefoon vier dingen naast elkaar: twee
           sectienamen, de taalbordjes en de bel. */
        --hm-topbar-gap: 0.7rem;
        gap: var(--hm-topbar-gap);
        padding: 0 0.9rem;
        /* Bijna zwart en niet half doorzichtig: een waas laat de plaat erdoorheen
           schemeren en dan is het weer geen grond — dezelfde afweging als bij de
           open voorstellingskamer, waar deze balk vandaan komt. */
        background: rgba(12, 9, 6, 0.94);
        box-shadow: 0 0.15rem 0.6rem rgba(0, 0, 0, 0.5);
        /* Eén letter voor de hele balk: dezelfde waarmee HOME onder de bel staat
           en waarmee de bordjes in de scènes zijn gezet. Zonder dit staat de
           taalwissel er in het broodschrift van de platform-CSS bij, twee keer zo
           groot als de rest, en leest de balk als drie losse dingen. */
        font-family: var(--hotelmodern-font-prop);
        --hm-bell-size: 2.4rem;
    }

    /* De bel staat rechts, als laatste in de rij: dat is de hoek waar hij op elke
       liggende scène hangt, en een uitgang die per schermformaat van kant
       verwisselt is er geen. Kleiner dan op de scène, want in een rij telt de
       hoogte. Op 2,4rem blijft de balk onder de 4rem en haalt het trefvlak met
       het woord eronder nog steeds de 44 pixels die een vinger nodig heeft. */
    /* In de balk blijft de letter licht. De inkt hierboven is sinds de
       terugkeer naar de oude hoek zwart met een lichte halo — dat werkt op een
       scène, maar de balk is bijna-zwart en daar zou HOME een veeg worden. */
    .hm-topbar .hm-bell span {
        margin-top: 0.1rem;
        font-size: 0.6rem;
        color: #ffffff;
        text-shadow: none;
    }

    /* De uitgangen als groep, en de groep duwt de taalbordjes en de bel naar
       rechts. Dat `margin-right: auto` stond eerst op de link zelf — met één link
       is dat hetzelfde, met twee zou de eerste de tweede wegduwen. De
       tussenruimte is die van de balk, zodat twee uitgangen naast elkaar even ver
       uit elkaar staan als de bordjes en de bel.

       Krimpen mag, en afkappen ook: op een scherm van 320 is de rij vol, en dan
       is een half woord beter dan een bel die van het scherm loopt of een
       sectienaam die dwars door de taalbordjes heen valt. Zonder de `overflow`
       gebeurde dat laatste — de groep kromp wél, maar de woorden erin liepen er
       gewoon uit. Vanaf 375 breed (de smalste telefoon die nog verkocht wordt)
       past alles zonder afkappen, ook met drie talen. */
    .hm-topbar-links {
        display: flex;
        align-items: center;
        min-width: 0;
        overflow: hidden;
        gap: var(--hm-topbar-gap);
        margin-right: auto;
    }

    /* Dezelfde letter als het woord onder de bel: het zijn uitgangen naast elkaar,
       geen kop en een link. */
    .hm-topbar-link {
        color: rgba(255, 255, 255, 0.85);
        font-size: 0.75rem;
        letter-spacing: 0.06em;
        line-height: 1;
        text-transform: uppercase;
        text-decoration: none;
        /* Het woord is één regel van 13px hoog; het raakvlak eromheen niet. */
        padding: 0.75rem 0.25rem;
    }

    .hm-topbar-link:hover,
    .hm-topbar-link:focus-visible {
        color: #fff;
    }

    /* Op de gang wijst deze link naar de pagina waar je al staat. Hij blijft
       staan en wordt gemarkeerd in plaats van weggelaten: een balk die per pagina
       een ander aantal items heeft, verspringt onder je duim. Dit is hetzelfde
       goud als een gekozen taal ernaast en een gekozen logo in de fotogalerie —
       door de hele tenant betekent die kleur "hier sta je".

       Ná de hover-regel, met dezelfde specificiteit: anders wint wit zodra je
       hem aanraakt, en dan verdwijnt de markering precies op het moment dat je
       hem aanwijst. */
    .hm-topbar-link.is-current {
        color: #e8b04b;
        font-weight: 700;
    }

    /* Naast elkaar en niet onder elkaar: de balk is één regel hoog. De bel staat
       er rechts van (zie de HTML), zodat de uitgang ook hier in de hoek zit. */
    .hm-topbar-langs {
        display: flex;
        flex: 0 0 auto;
        align-items: center;
        gap: 0.35rem;
        line-height: 1;
    }

    /* Dezelfde ovaaltjes als in de scènes, maar met de code erin in plaats van
       het woord (zie `hm_section_switch/1`) en krapper gezet: hier liggen ze in
       een rij náást twee sectienamen en de bel, op een scherm van 320 breed.

       Met `.hm-langs-plaque` erbij in de selector, anders wint de maat van het
       ovaaltje hierboven — die staat op drie klassen en deze stond op twee. */
    body.hotelmodern .hm-topbar-langs.hm-langs-plaque .language-btn {
        padding: 0.4em 0.8em;
        font-size: 0.65rem;
    }

    /* Wat de balk overneemt, gaat in de scène uit. Zonder dit staat de bel er
       twee keer: een keer in de hoek van de kamer en een keer in de kop. De
       receptie draagt deze balk sowieso niet — haar bel staat op de balie en
       haar taalwissel is een eigen plaatje.

       Het bordje terug in de voorstellingskamer hoort in dat rijtje thuis. Het
       draagt hetzelfde woord als de link in de balk en wijst naar dezelfde plek,
       en twee keer "Voorstellingen" op één scherm leest als een fout. Liggend
       staat deze regel niet meer, en dan is de hele hoek weer wat hij op de oude
       site was. */
    .hm-stage .hm-bell,
    .hm-stage .hm-scene-langs,
    .hm-stage .hm-roomview-back {
        display: none;
    }
}

/* ── De kopregel op een tablet (staand) ──────────────────────────── */

/* Dezelfde balk, maar een tablet is geen grote telefoon. De maten hierboven
   zijn gezet tegen een scherm van 390 breed: daar beslaat 3,75rem bijna een
   tiende van de hoogte en vult de bel de balk van boven tot onder. Op 768 ligt
   diezelfde balk als een streepje boven een plaat die twee keer zo breed is, en
   staan de woorden erin kleiner dan alles wat eronder ligt — terwijl er juist
   ruimte zat.

   Alles schaalt hier met ongeveer de helft mee. De scènes eronder rekenen hun
   bovenrand uit `--hm-topbar-h` (roomview, agenda, pers, bioscoop, radio, boek,
   fotogalerie), dus die schuiven vanzelf mee en er hoeft nergens anders iets
   bij.

   De verhouding staat er weer bij en de hoogte-ondergrens is eruit. Die
   ondergrens (`min-height: 32rem`) kwam uit 1.2.7, toen de balk ook liggend
   stond: een telefoon op zijn kant (844x390) viel binnen `min-width: 48rem` en
   kreeg een balk van een kwart scherm. Nu de balk alleen staand bestaat kan dat
   niet meer — een scherm dat staand 48rem breed is, is nooit een telefoon. */
@media (max-aspect-ratio: 6/5) and (min-width: 48rem) {
    body.hotelmodern:has(.hm-stage) {
        --hm-topbar-h: 6rem;
    }

    body.hotelmodern:has(.hm-stage) .hm-topbar {
        --hm-topbar-gap: 1.9rem;
        padding: 0 1.8rem;
        /* De bel plus het woord eronder komt op 5,2rem: er blijft dus lucht
           boven en onder, net als in de smalle uitvoering. */
        --hm-bell-size: 4rem;
    }

    .hm-topbar .hm-bell span {
        margin-top: 0.16rem;
        font-size: 0.95rem;
    }

    .hm-topbar-link {
        font-size: 1.35rem;
        padding: 1rem 0.5rem;
    }

    body.hotelmodern .hm-topbar-langs.hm-langs-plaque .language-btn {
        font-size: 1rem;
    }
}

/* ── Taalwissel (gedeeld) ────────────────────────────────────────── */

/* De platform-CSS (base/language-toggle.css) geeft `.language-btn` alleen een
   vorm — letterafstand, kapitalen, een scheidingsstreepje — en géén kleur, en
   ook geen regel voor `.active`. De component zét die klasse wel. Op de scènes
   van deze tenant stonden NL en EN daardoor allebei in dezelfde kleur: je zag
   dus nergens in welke taal je stond.

   Staat hier en niet in news.css omdat het dezelfde knop is op de
   voorstellingskamer (.hm-roomview-langs) en op de nieuwspagina's
   (.hm-news-langs); die twee hoorden niet uiteen te lopen. */
body.hotelmodern .language-btn {
    color: rgba(255, 255, 255, 0.6);
    font-weight: 400;
    text-decoration: none;
    transition: color 0.15s ease-out;
}

body.hotelmodern .language-btn:hover,
body.hotelmodern .language-btn:focus-visible {
    color: #fff;
}

/* Hetzelfde goud als een gekozen tabblad in het nieuwsregister en een gekozen
   logo in de fotogalerie: door de hele tenant betekent die kleur "hier sta je".

   Kleur en gewicht, géén onderstreping — anders dan bij de tabbladen hiernaast.
   Het scheidingsstreepje is een `::after` ván de knop ervóór (zie
   base/language-toggle.css), dus staat het binnen diens randvak: is NL actief,
   dan loopt een `border-bottom` net zo goed onder de `|` door en lijkt de
   markering scheef te staan. */
body.hotelmodern .language-btn.active {
    color: #e8b04b;
    font-weight: 700;
}

/* Datzelfde streepje staat in de platform-CSS op #333 — op deze donkere scènes
   vrijwel onzichtbaar. Het hoort bij geen van beide talen, dus het blijft grijs
   ook als de knop eromheen goud wordt. */
body.hotelmodern .language-btn:not(:last-child)::after {
    color: rgba(255, 255, 255, 0.35);
    font-weight: 400;
}

/* De taalwissel als twee bordjes: het uiterlijk. Elke scène zet zelf waar ze
   liggen (`.hm-roomview-langs`, `.hm-vitrine-langs`); dit is hoe ze eruitzien.
   Gebruikt waar de ondergrond een foto is die per productie of per kamer een
   andere helderheid heeft — in de gang en op het nieuwsbord is de ondergrond
   vast en volstaat de kale tekst hierboven.

   Hier stond `mix-blend-mode: difference`, en dat was een elegante gedachte: wit
   keert zichzelf om tegen wat erachter ligt, dus je hoeft per scène geen kleur
   te kiezen — donker op licht behang, licht in een donkere kelder. Twee dingen
   spraken die elegantie tegen. Difference rekent per kanaal, dus een gekleurde
   letter verschiet mee: het goud dat in de rest van de tenant "hier sta je"
   betekent werd op licht behang donkerblauw en zei niets meer, en de markering
   moest het met helderheid en gewicht doen. En op een middentonige ondergrond —
   de bakstenen muur van Garnalen Verhalen — is het verschil met wit nou juist
   klein, dus daar verdween de actieve taal alsnog.

   Een geverfd bordje neemt niets aan over wat erachter ligt. Het past ook beter
   bij een maquette dan een blend-truc, en het geeft het accentrood zijn rol
   terug: antraciet is de rustende taal, hotelrood de taal waar je in staat.

   NB: het woord HOME onder het belletje gebruikt dezelfde truc nog wel. Dat is
   één woord onder een fysieke prop en leest als deel daarvan; als dat ook een
   bordje moet worden is dat een aparte beslissing. */
body.hotelmodern .hm-langs-plaque .language-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    /* De maten van de balie, in em zodat het bordje één vorm blijft bij elke
       lettergrootte: 0,8929 hoog en 1,4929 breed van de letter. Daar staan ze in
       de originele CSS van het ovaaltje op de receptie. */
    padding: 0.8929em 1.4929em;
    /* Een ellips en geen afgeronde rechthoek: 50% van een doos die veel breder
       is dan hoog geeft precies het langwerpige ovaaltje dat op de balie ligt.
       Het woord erin bepaalt dus de vorm — "Nederlands" wordt een langer ovaal
       dan "English", net als daar. */
    border-radius: 50%;
    background: #000000;
    /* Verdana en niet de propletter van de tenant: het ovaaltje op de balie is
       als enige prop geen opname uit de maquette maar echte tekst, en dít is de
       letter waarin die daar staat. Zie reception.css. */
    font-family: Verdana, "DejaVu Sans", Geneva, sans-serif;
    /* De basisknop staat op `letter-spacing: .25rem` en `uppercase` — gezet voor
       twee letters in een kale hoek. De taal staat hier voluit, en dan is dat
       een woord uit elkaar getrokken. */
    letter-spacing: 0;
    text-transform: none;
    white-space: nowrap;
    /* De maat van het bordje. Stond op 0,8rem en las als een bijschrift naast
       de bel in plaats van als een prop die op de balie ligt; de padding is in
       em, dus dit getal maakt het hele ovaaltje mee groter. */
    font-size: 0.95rem;
    font-weight: 700;
    line-height: 1;
    color: #9e9e9e;
    transition:
        background-color 0.3s ease,
        color 0.3s ease;
}

/* De bordjes hangen als een stapeltje ónder de bel en niet als een rij ernaast.
   Voluit uitgeschreven is elk bordje drie tot vier keer zo breed als "NL", en
   naast elkaar werd dat een band van ruim 12rem dwars door de hoek: op de agenda
   lag die half op het papier, op het nieuwsbord half over de lampenrand. Onder
   elkaar is de stapel zo breed als het langste woord en blijft hij in de marge
   staan, waar ook de bel hangt.

   Gecentreerd en niet rechts uitgelijnd: de woorden zijn ongelijk lang
   ("Nederlands" is een halve centimeter langer dan "English"), en tegen een
   rechte kantlijn wordt dat een rafelrand aan de linkerkant. Om een midden
   gelegd staan de drie als één ding onder de bel.

   De tussenruimte staat hier en niet in de tien kamers apart: die zetten hem
   allemaal op 0,35rem, wat als rij klopte en als stapel te krap is — de ovalen
   raken elkaar dan bijna. Twee klassen winnen het van hun ene.

   Alleen in de scènes. De kopregel op een smal scherm (`.hm-topbar-langs`) is
   zelf een rij en houdt haar bordjes dus naast elkaar. */
body.hotelmodern .hm-scene-langs.hm-langs-plaque {
    flex-direction: column;
    align-items: center;
    /* Ruimer dan de 0,6rem waar dit op stond: twee ovalen die elkaar bijna
       raken lezen als één ding met een streep erdoor. Met een volle regel
       ertussen ligt er een stapeltje losse bordjes onder de bel. */
    gap: 1.1rem;
}

/* Het accentrood van de tenant en niet het lichtblauw van de hover: de balie
   kent geen actieve taal (daar ligt alleen het bordje van de ándere), maar in de
   kamers liggen ze allemaal naast elkaar en moet er één zeggen "hier sta je".
   Diezelfde betekenis heeft die kleur op het nieuwsregister en de fotogalerie. */
body.hotelmodern .hm-langs-plaque .language-btn.active {
    background: var(--hotelmodern-accent);
    color: #ffffff;
}

/* Het lichtblauw van de balie. */
body.hotelmodern .hm-langs-plaque .language-btn:hover,
body.hotelmodern .hm-langs-plaque .language-btn:focus-visible {
    background: #86c0d8;
    color: #363636;
}

body.hotelmodern .hm-langs-plaque .language-btn.active:hover,
body.hotelmodern .hm-langs-plaque .language-btn.active:focus-visible {
    background: #a3240f;
    color: #ffffff;
}

/* Het streepje tussen de talen komt uit de platform-CSS. Tussen twee losse
   bordjes hoort geen scheiding: die dóén de scheiding al. */
body.hotelmodern .hm-langs-plaque .language-btn:not(:last-child)::after {
    content: none;
}

/* Op een smal scherm is het bordje het trefvlak. */
@media (max-aspect-ratio: 6/5) {
    body.hotelmodern .hm-langs-plaque .language-btn {
        font-size: 1rem;
    }
}

/* ── Het filter op voorstelling, voor smalle en lage schermen ─────── */

/* De sleutelhanger op de balie en de logokolom op het nieuwsbord verdwijnen
   allebei zodra het scherm smal wordt (of laag, bij een liggende telefoon). Dat
   is met reden zo — zie agenda.css en news.css — maar daarmee verdween ook de
   mogelijkheid om te filteren, terwijl er negentig speelbeurten en 173 berichten
   in die lijsten staan.

   Deze keuzelijst vult dat gat. Hij staat standaard uit: waar de kolom er wél
   is, is hij overbodig en zou hij een tweede bedieningselement voor hetzelfde
   zijn. De twee mediaqueries hieronder zijn letterlijk dezelfde als die de kolom
   en de hanger wegzetten, zodat het één van beide is en nooit allebei of geen
   van beide. */
.hm-production-picker {
    display: none;
}

.hm-production-picker select {
    width: 100%;
    max-width: 22rem;
    padding: 0.35rem 0.5rem;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 0.2rem;
    background: rgba(0, 0, 0, 0.35);
    color: #fff;
    font-family: var(--hotelmodern-font-body);
    font-size: 1rem;
}

/* Op het papier van de balie is de achtergrond licht, dus daar donkere inkt. */
.hm-agenda-room .hm-production-picker select {
    border-color: rgba(28, 20, 8, 0.3);
    background: rgba(255, 255, 255, 0.6);
    color: #1c1408;
}

@media (max-width: 48rem) {
    .hm-production-picker {
        display: block;
        margin: 0.5rem 0 0;
    }
}

/* De liggende telefoon: breed genoeg voor de kolom, te laag voor de hanger. */
@media (min-width: 48rem) and (max-height: 30rem) {
    .hm-agenda-room .hm-production-picker {
        display: block;
        margin: 0.5rem 0 0;
    }
}

/* ── De dienstingang van een kamer ───────────────────────────────────

   Een balkje in de rechteronderhoek waarmee een redacteur van de kamer naar
   het scherm gaat waar de inhoud van díe kamer staat (de filmpjes van de
   bioscoop, de fragmenten van de hoorspelkamer, de foto's van de voorstelling
   waar je in staat). Alleen zichtbaar voor wie mag bewerken; voor een bezoeker
   staat het element niet in de HTML.

   `fixed` en niet `absolute`: de kamers zijn op de millimeter rond een
   achtergrondfoto gebouwd, en iets dat meetelt in de opmaak duwt daar altijd
   iets weg. Zo is dit het enige verschil tussen een ingelogd en een uitgelogd
   scherm, en meet de scène in beide gevallen hetzelfde.

   Antraciet omdat het op een scènefoto ligt die alles kan zijn van een donkere
   kelder tot een lichte muur (zie `--hotelmodern-plaque`). Bewust niet in het
   accentrood: dat betekent in deze tenant "hier kun je heen" en hoort bij de
   site, niet bij het chroom eromheen.

   Onder de lightbox (10500) en onder de modals, boven de props (1000): als er
   een film over de kamer heen staat, hoort deze knop eronder te verdwijnen. */
.hm-beheer-balk {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 1500;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.45rem 0.8rem;
    border-radius: 0.2rem;
    background-color: var(--hotelmodern-plaque);
    color: #fff;
    font-family: var(--hotelmodern-font-body);
    font-size: 0.85rem;
    line-height: 1;
    text-decoration: none;
    /* Genoeg om van een lichte muur af te komen, te weinig om een slagschaduw
       te worden op een donkere. */
    box-shadow: 0 0.1rem 0.5rem rgba(0, 0, 0, 0.35);
    opacity: 0.85;
    transition: opacity 0.15s ease-out, transform 0.15s ease-out;
}

.hm-beheer-balk:hover,
.hm-beheer-balk:focus-visible {
    opacity: 1;
    transform: translateY(-0.1rem);
}

.hm-beheer-balk .icon-edit {
    width: 0.9rem;
    height: 0.9rem;
    background-color: currentColor;
}


/* ── components/reception.css ── */
/* Hotel Modern — de receptie (homepage).
   Reconstructie van de oude WordPress-scène: één geïllustreerde balie
   (background.jpg) met absoluut-gepositioneerde prop-PNG's als klikbare
   hotspots. De prop-posities (percentages) komen 1-op-1 uit de originele
   reception-CSS. Onderaan staat de portret-stand, waar de scène rechtop gaat en
   de props herschikken. De lichtbak in de lijst linksboven: frame-list.css. */

/* De props zijn hier de navigatie en liggen tegen de randen, dus we tonen de
   hele foto (contain) i.p.v. te croppen — de zwarte doos vangt de rest op als
   harde zwarte banden, pristine beeld zonder overgang. */
/* `container-type: inline-size` maakt de scène de maat voor `cqw`-eenheden: de
   tekst in de lichtlijst schaalt zo mee met de scène i.p.v. met het venster
   (die twee lopen uiteen zodra er zwarte banden zijn). */
.hm-room {
    position: relative;
    aspect-ratio: 1366 / 768;
    width: min(100vw, calc(100dvh * 1366 / 768));
    container-type: inline-size;
    overflow: hidden;
    line-height: 0;
    background: var(--hotelmodern-bg);
}

.hm-room-bg {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Intro-animatie tussen achtergrond (z-index 0) en props (z-index 3). */
.hm-room-animation {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    overflow: hidden;
}

.hm-room-animation svg,
.hm-room-animation canvas {
    display: block;
    width: 100% !important;
    height: 100% !important;
}

.hm-props {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-prop {
    position: absolute;
    z-index: 3;
    margin: 0;
}

.hm-prop img {
    display: block;
    width: 100%;
    height: auto;
}

.hm-prop-link {
    display: block;
    position: relative;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

/* Crossfade i.p.v. harde PNG↔animatie-swap: de hover-variant ligt absoluut over
   de default en faden we in/uit op opacity. Zachtere overgang, geen "klap". */
.hm-prop img.hm-prop-img,
.hm-prop img.hm-prop-img-hover {
    transition: opacity 0.3s ease;
}

.hm-prop img.hm-prop-img-hover {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: auto;
    opacity: 0;
}

.hm-prop-link:hover img.hm-prop-img,
.hm-prop-link:focus-visible img.hm-prop-img {
    opacity: 0;
}

.hm-prop-link:hover img.hm-prop-img-hover,
.hm-prop-link:focus-visible img.hm-prop-img-hover {
    opacity: 1;
}

/* Beweging-arme voorkeur: geen crossfade-overgang. */
@media (prefers-reduced-motion: reduce) {
    .hm-prop img.hm-prop-img,
    .hm-prop img.hm-prop-img-hover,
    .hm-prop-social-list a,
    .hm-prop-language .hm-prop-link {
        transition: none;
    }
}

/* Prop-posities — overgenomen uit de originele reception style.min.css */
.hm-prop-productions {
    width: 21.8155197657%;
    right: 1%;
    top: 1%;
}
.hm-prop-mailing {
    width: 9.2972181552%;
    right: 22%;
    top: 18%;
}
.hm-prop-bell {
    width: 13.17715959%;
    right: 51%;
    top: 44%;
}
.hm-prop-media {
    width: 7.906295754%;
    right: 10%;
    top: 24%;
}
.hm-prop-news {
    width: 16.0322108346%;
    right: 11%;
    bottom: 0;
}
.hm-prop-phone {
    width: 14.934114202%;
    right: 14%;
    top: 42%;
}
.hm-prop-about {
    width: 11.1273792094%;
    right: 4%;
    top: 46%;
}
.hm-prop-agenda {
    width: 21.9619326501%;
    right: 27%;
    top: 51.5%;
}
.hm-prop-chandelier {
    width: 7.906295754%;
    left: 39%;
    top: 0;
}
.hm-prop-framebottom {
    width: 22.6939970717%;
    left: 20%;
    top: 0;
    z-index: 1;
}

.hm-prop-iphoneperspective {
    width: 7.906295754%;
    right: 14%;
    top: 64%;
}

/* De social-badges op de balie, naast de telefoon met "social media" op het
   schermpje: die is het opschrift, de badges zijn de deuren.

   Ze liggen op het marmer, dus ze staan in het perspectief van het blad. Dat is
   twee dingen tegelijk, en die zaten hier eerder in elkaars vaarwater:

   1. De rij volgt de voorrand van het blad. Die rand is opgemeten en loopt op
      dy/dx = −0,218, oftewel 12,3 graden omhoog naar rechts.
   2. Elke badge staat rechtop: zijn as wijst loodrecht naar onderen.

   Precies zoals het woord NIEUWS op de krant ernaast: de regel loopt schuin mee
   met het papier, maar de letters staan stuk voor stuk rechtop. Een `rotateZ` op
   de hele rij deed alleen het eerste — die kantelt elke badge mee, en dan staan
   ze scheef. Weglaten deed alleen het tweede, en dan lag de rij kaarsrecht over
   een blad dat dat niet is. Daarom nu de trap: de rij krijgt geen draai, maar
   elke badge een eigen verschuiving omhoog.

   De stap volgt uit de steek. De rij is 16% van de scène breed, een badge is
   22,222% daarvan en de tussenruimte 3,704%, dus de steek is 4,148cqw en de
   stap 4,148 × 0,218 = 0,904cqw. De verschuiving loopt van +1,5 tot −1,5 stap in
   plaats van 0 tot 3, zodat de rij om zijn eigen midden kantelt en niet als
   geheel omhoog kruipt — net als de `rotateZ` die er eerst stond.

   De kanteling zit op de badge en niet meer op de rij: zo krijgt elke badge
   dezelfde vervorming (ze liggen immers even ver weg, op één lijn evenwijdig aan
   de rand) en blijft de verschuiving een schone verticaal in het scherm.
   Volledig in het vlak van het blad is ongeveer 57 graden, maar dan wordt een
   badge een ellips van 0,55 hoog en is het YouTube-blokje niet meer te lezen; op
   45 graden zijn ze rond genoeg om te herkennen en liggen ze nog duidelijk op de
   balie.

   `perspective` staat in `cqw` en niet in `rem`: de scène schaalt met het
   venster, dus de kijkafstand moet dat ook doen. In `rem` zou de vertekening op
   een groot scherm verdwijnen en op een klein scherm overdreven worden. */
.hm-prop-social {
    width: 16%;
    right: 6.5%;
    top: 68.5%;
}

.hm-prop-social-list {
    display: flex;
    gap: 3.7037037037%;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* De volgorde van de functies telt: `rotateX` werkt op de badge zelf, de
   `translateY` daarbuiten verschuift het resultaat in het scherm. */
.hm-prop-social-list li {
    width: 22.2222222222%;
    transform: translateY(calc(var(--hm-social-step, 0) * 0.904cqw)) perspective(32cqw)
        rotateX(45deg);
}

.hm-prop-social-list li:nth-child(1) {
    --hm-social-step: 1.5;
}

.hm-prop-social-list li:nth-child(2) {
    --hm-social-step: 0.5;
}

.hm-prop-social-list li:nth-child(3) {
    --hm-social-step: -0.5;
}

.hm-prop-social-list li:nth-child(4) {
    --hm-social-step: -1.5;
}

/* Geen crossfade zoals bij de andere props — een badge heeft geen animatie-
   variant. Wel hetzelfde duwtje als op /contact, waar dezelfde vier hangen. */
.hm-prop-social-list a {
    display: block;
    transition:
        transform 0.2s ease-out,
        filter 0.2s ease-out;
}

.hm-prop-social-list a:hover,
.hm-prop-social-list a:focus-visible {
    transform: scale(1.08);
    filter: brightness(1.12);
}

/* Taalwissel. De enige prop die geen opname uit de maquette is maar tekst op een
   ovaal, en daarom hier getekend in plaats van als PNG-paar meegeleverd. Dat
   scheelt een plaat per taal: het bordje groeit met het woord, dus Nederlands
   (langer dan English) en straks Frans en Spaans passen vanzelf. Het blijft ook
   scherp op elk scherm, en als Verdana ontbreekt wordt het bordje hooguit een
   slag breder in plaats van dat de tekst niet meer past.

   De maatvoering is overgenomen van de originele WP-plaat, `prop/english.png`
   (99 bij 39 beeldpunten, ovaal precies om het doek): de letter is Verdana Bold
   op 14/1366 van de scènebreedte, met opzij (99 − 57,2)/2 en boven en onder
   (39 − 14)/2 daarvan als lucht — vandaar de em-waarden hieronder. Kleuren idem:
   zwart met grijze letter, bij hover lichtblauw met donkere letter. Die plaat
   blijft in de map staan als ijkpunt; hij wordt niet meer ingeladen. */
.hm-prop-language {
    width: auto;
    right: 1%;
    bottom: 1%;
    font: bold 1.0249cqw/1 Verdana, "DejaVu Sans", Geneva, sans-serif;
}

.hm-prop-language .hm-prop-link {
    display: flex;
    align-items: center;
    justify-content: center;
    width: auto;
    padding: 0.8929em 1.4929em;
    border-radius: 50%;
    background: #000;
    color: #9e9e9e;
    text-decoration: none;
    white-space: nowrap;
    transition:
        background-color 0.3s ease,
        color 0.3s ease;
}

.hm-prop-language .hm-prop-link:hover,
.hm-prop-language .hm-prop-link:focus-visible {
    background: #86c0d8;
    color: #363636;
}

/* ── Portret ─────────────────────────────────────────────────────────
   De liggende scène past staand niet, maar de navigatie wél: alle klikbare
   props liggen in de rechterhelft van de plaat. Daarom tonen we staand een
   UITSNEDE van diezelfde plaat, in plaats van de props te verplaatsen. De
   scène houdt zo haar eigen maatstelsel — de percentages hierboven blijven
   gelden, en met hen de `cqw` van de badges, de taalwissel en de lichtbak.
   Er is dus maar één set coördinaten te onderhouden; hiervoor stonden er
   twee, en de tweede was met de hand gemikt.

   De uitsnede loopt altijd door tot de rechterrand, dus één getal beschrijft
   hem: `--hm-crop-x`, de linkerrand in % van de scène. `--hm-zoom` volgt
   daaruit — 100 / (100 − crop-x) — en zegt hoeveel keer breder de scène is
   dan het venster. Die staat er apart bij omdat CSS wel door een getal mag
   delen maar niet door een variabele.

   Verder naar rechts dan 50% kan niet: Agenda begint op 51% van de scène.

   De kamer staat MIDDEN in het venster; het overschot valt in gelijke delen
   boven en onder de plaat, en groeit daar naar buiten toe naarmate het scherm
   langer wordt. Onderaan uitlijnen is geprobeerd — de balie op de schermrand
   en al het zwart in één veld erboven — maar dat leest als een plaat die naar
   beneden is weggezakt in plaats van als een kader. Symmetrisch zwart leest
   als een kader.

   `max-aspect-ratio: 5/6` houdt bijna-vierkante vensters buiten deze stand.
   De uitsnede zelf is 0,89 breed-op-hoog (50% van 1366 op 768); bij een
   venster dat daar overheen gaat zou de kamer bovenlangs het scherm uit
   steken en viel de VOORSTELLINGEN-krant weg. Zulke vensters vallen terug op
   de liggende regel hierboven: hele plaat, banden boven en onder. */
@media (orientation: portrait) and (max-aspect-ratio: 5 / 6) {
    .hm-room {
        /* Telefoon: de krapste uitsnede die alle navigatie bevat. */
        --hm-crop-x: 50;
        --hm-zoom: 2;
        /* De hoogte van de kamer volgt uit haar breedte (768/1366 is de
           verhouding van de plaat); wat er dan overblijft is het zwart, en dat
           gaat er in twee gelijke helften boven en onder omheen. */
        --hm-room-height: calc(100vw * var(--hm-zoom) * 768 / 1366);
        --hm-band: calc(100dvh - var(--hm-room-height));

        position: absolute;
        top: calc(var(--hm-band) / 2);
        left: calc(-1vw * var(--hm-crop-x) * var(--hm-zoom));
        width: calc(100vw * var(--hm-zoom));
    }

    /* De intro-animatie loopt links achter de lobby langs — buiten de
       uitsnede, dus er valt niets te zien. */
    .hm-room-animation {
        display: none;
    }
}

/* De taalwissel schaalt met de scène (`cqw`), en die is staand veel breder dan
   het venster — in de uitsnede twee keer zo breed, en in het terugvalvenster
   hierboven is de scène juist heel klein. Beide keren wordt de letter een half
   rem. Vandaar een vloer, buiten de uitsnede-stand zodat hij voor allebei
   geldt. Op een tablet haalt de scène die vloer vanzelf. */
@media (orientation: portrait) {
    .hm-prop-language {
        font-size: max(0.8125rem, 1.0249cqw);
    }
}

/* Tablet-portret heeft hoogte over, dus daar mag de uitsnede ruimer. Op 40%
   komen de receptionist, de bel en de kroonluchter erbij — het kader uit de
   schets — en krimpt het zwarte veld van ruim 40% naar ongeveer 30% van het
   scherm. Verder dan dit kan niet zonder de balie te laten krimpen. */
@media (orientation: portrait) and (max-aspect-ratio: 5 / 6) and (width >= 600px) {
    .hm-room {
        --hm-crop-x: 40;
        --hm-zoom: 1.6667;
    }
}


/* ── components/frame-list.css ── */
/* Hotel Modern — de lichtbak in de receptie.
   De lijst linksboven in de balie is een lichtbak met één bericht erin: vers
   nieuws, een naderende première of de eerstvolgende voorstelling. De lampenrand
   is de schakelaar, het paneel erbinnen de link. */

/* De lijst blijft op z-index 1, dus de garnaal-kelner loopt er vóór langs.
   Klikken werkt toch: de animatielaag heeft `pointer-events: none`. */
.hm-frame {
    line-height: 1.4;
}

.hm-frame-plate {
    transition: filter 0.5s ease;
}

/* De schakelaar is de lampenrand zelf: hij vult de hele lijst en ligt ónder
   het paneel, zodat alleen de rand overblijft als klikvlak. Staat de lichtbak
   uit, dan laat het paneel geen klikken door en is de hele lijst de knop. */
.hm-frame-switch {
    position: absolute;
    inset: 0;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.hm-frame-switch:focus-visible {
    outline: 2px solid #ffc670;
    outline-offset: 2px;
}

/* Het paneel valt precies in de opening van de lampenrand — gemeten op
   frame.png (676×768): 5,5% horizontaal, 4,5% verticaal. */
/* De panel-laag zelf vangt geen klikken; alleen de link erin. Zo vallen
   klikken door naar de schakelaar zodra de lichtbak uit staat. */
.hm-frame-panel {
    position: absolute;
    top: 4.5%;
    right: 5.6%;
    bottom: 4.6%;
    left: 5.5%;
    pointer-events: none;
}

.hm-frame-link {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.7cqw;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    padding: 6% 9%;
    pointer-events: auto;
    text-align: center;
    text-decoration: none;
    color: #2b1a10;
    /* Verlicht van binnenuit: warme lichtbak, feller naar het midden. */
    background: radial-gradient(
        120% 90% at 50% 40%,
        #fff9ee 0%,
        #f7e8cd 55%,
        #e8d2ab 100%
    );
    box-shadow:
        0 0 2.5cqw rgba(255, 198, 112, 0.4),
        inset 0 0 1.2cqw rgba(255, 255, 255, 0.7);
    transition:
        opacity 0.5s ease,
        box-shadow 0.5s ease;
}

.hm-frame-kicker {
    font-family: var(--hotelmodern-font-body);
    font-size: 0.85cqw;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--hotelmodern-accent);
}

.hm-frame-title {
    font-family: var(--hotelmodern-font-heading);
    font-size: 1.4cqw;
    line-height: 1.25;
    /* Geïmporteerde nieuwstitels zijn soms hele perscitaten; hard afkappen. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Samenvatting (nieuws: `summary` van het artikel, agenda-takken: van de
   productie). Ook afkappen: het paneel is maar ±280px breed. */
.hm-frame-summary {
    font-size: 0.8cqw;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.hm-frame-meta {
    font-size: 0.9cqw;
    color: #6b5540;
}

.hm-frame-place::before {
    content: " · ";
}

.hm-frame-link:hover .hm-frame-title,
.hm-frame-link:focus-visible .hm-frame-title {
    color: var(--hotelmodern-accent);
}

/* Uit: paneel dooft, lampjes dimmen — wat overblijft is de lege lijst zoals
   in de oude scène. Het paneel vangt dan geen klikken meer, dus de hele lijst
   werkt als schakelaar om hem weer aan te doen. */
.hm-frame-off .hm-frame-link {
    opacity: 0;
    box-shadow: none;
    pointer-events: none;
}

.hm-frame-off .hm-frame-plate {
    filter: brightness(0.5) saturate(0.5);
}

@media (prefers-reduced-motion: reduce) {
    .hm-frame-plate,
    .hm-frame-link {
        transition: none;
    }
}

/* Alleen voor screenreaders: de knop is verder een onzichtbaar klikvlak. */
.hm-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ── Portret ─────────────────────────────────────────────────────────
   Staand toont de receptie alleen de rechterkant van de plaat (zie
   reception.css) en valt de wand met de lichtlijst buiten de uitsnede.

   Hij heeft even in het zwarte veld boven de balie gehangen, toen de kamer nog
   onderaan uitgelijnd stond en al het zwart in één veld bij elkaar kwam. Nu de
   plaat in het midden staat is dat veld in tweeën gedeeld en houdt de lijst
   ongeveer 10rem hoogte over — op frame.png (676 bij 768) is dat een paneel
   van nog geen 7rem breed, en daar past geen titel meer in.

   Dus staat hij staand weer uit, en is de feed daar niet te zien. Dat is een
   open punt, geen eindoordeel: wie hem terug wil, moet de plaat niet centreren
   maar bovenaan een strook vrijhouden en de kamer in de rest centreren. */
@media (orientation: portrait) and (max-aspect-ratio: 5 / 6) {
    .hm-prop.hm-frame {
        display: none;
    }
}


/* ── components/corridor.css ── */
/* Hotel Modern — de gang (voorstellingen-index).
   Het sleutelbord tegen de wand, met een bordje per voorstelling. Maten zijn
   percentages van de gang, tekst schaalt op `cqw` mee (= 1% van de gangbreedte);
   met `vw` zou hij naast de zwarte banden gaan lopen. Het kaartje dat bij een
   bordje verschijnt staat in preview.css. */

/* Zelfde principe als de receptie: de gangfoto zo groot mogelijk in de zwarte
   doos, beeldverhouding intact. De maten binnen de gang zijn percentages van de
   gang zelf, de tekst schaalt op `cqw` (= 1% van de gangbreedte) mee — met vw
   zou hij naast de zwarte banden gaan lopen. */
.hm-corridor-room {
    position: relative;
    aspect-ratio: 16 / 9;
    width: min(100vw, calc(100dvh * 16 / 9));
    container-type: inline-size;
    overflow: hidden;
    line-height: 0;
}

.hm-corridor-bg {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Het sleutelbord hangt linksboven tegen de rand, net als in de oude scène; de
   plaat bepaalt de hoogte, de lijst ligt erin. */
.hm-keyboard {
    position: absolute;
    /*top: 0.5%;*/
    bottom: 0;
    left: 0.5%;
    width: 31%;
    line-height: 1.3;
}

.hm-keyboard-plate {
    display: block;
    width: 100%;
    height: auto;
}

/* De bovenste derde van de plaat is sleutel + label; de titels beginnen
   daaronder en scrollen binnen het perkament als het er meer zijn. De inzet is
   gemeten op keyboard.webp: het perkament loopt van 2,5% tot 81% van de plaat,
   de rest is de sleutel die erbuiten steekt. */
.hm-keyboard-list {
    position: absolute;
    top: 36%;
    right: 25%;
    bottom: 3%;
    left: 9%;
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.hm-keyboard-item + .hm-keyboard-item {
    margin-top: 4%;
}

.hm-keyboard-link {
    display: block;
    padding: 3% 5%;
    border: 0.15cqw solid rgba(43, 26, 16, 0.75);
    text-decoration: none;
    color: #2b1a10;
    transition:
        background-color 0.3s ease,
        color 0.3s ease;
}

.hm-keyboard-link:hover,
.hm-keyboard-link:focus-visible {
    background: rgba(135, 29, 15, 0.12);
    color: var(--hotelmodern-accent);
}

.hm-keyboard-kicker {
    display: block;
    text-align: right;
    font-family: var(--hotelmodern-font-body);
    font-size: 0.8cqw;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}

.hm-keyboard-title {
    display: block;
    font-family: var(--hotelmodern-font-heading);
    font-size: 1.9cqw;
    line-height: 1.15;
}

/* Sleutelbord: de eigen typografie van de voorstelling als logo. De titeltekst
   blijft in de DOM (schermlezer, zoekmachine, hover-preview) maar wordt visueel
   vervangen zodra er een logo is. */
.hm-keyboard-logo {
    display: block;
    width: 100%;
    height: auto;
    max-height: 6cqw;
    object-fit: contain;
    object-position: left center;
}

.hm-keyboard-title.has-logo .hm-keyboard-title-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}

/* De pijlen staan rechts van de bordjes, tegen de gescheurde rand van het
   perkament aan — daar hingen ze op de oude site ook. `arrow.svg` dient als
   masker, zodat één bestand beide richtingen dekt en de pijl de kleur van de
   tekst aanneemt. */
.hm-keyboard-scroll {
    position: absolute;
    right: 18%;
    bottom: 6%;
    display: flex;
    flex-direction: column;
    gap: 0.6cqw;
}

.hm-keyboard-scroll[hidden] {
    display: none;
}

.hm-keyboard-scroll button {
    padding: 0.3cqw;
    border: 0;
    background: none;
    color: #2b1a10;
    cursor: pointer;
    opacity: 0.75;
    transition: opacity 0.3s ease;
}

.hm-keyboard-scroll button:hover,
.hm-keyboard-scroll button:focus-visible {
    opacity: 1;
}

.hm-keyboard-scroll button:disabled {
    opacity: 0.2;
    cursor: default;
}

.hm-keyboard-arrow {
    display: block;
    width: 1.7cqw;
    aspect-ratio: 19 / 40;
    background: currentColor;
    -webkit-mask: url("/assets/hotelmodern/voorstellingen/arrow-9e91cac7deb036c17c0a0931e14d3913.svg?vsn=d") center /
        contain no-repeat;
    mask: url("/assets/hotelmodern/voorstellingen/arrow-9e91cac7deb036c17c0a0931e14d3913.svg?vsn=d") center / contain
        no-repeat;
}

[data-scroll="up"] .hm-keyboard-arrow {
    transform: rotate(180deg);
}

/* Alleen zichtbaar zolang de lijst leeg is (stream zonder items). */
.hm-keyboard-empty {
    display: none;
    position: absolute;
    top: 40%;
    right: 25%;
    left: 9%;
    margin: 0;
    font-family: var(--hotelmodern-font-body);
    font-size: 1.1cqw;
    line-height: 1.4;
    color: #2b1a10;
}

.hm-keyboard-list:empty + .hm-keyboard-empty {
    display: block;
}

/* Beheerknoppen los in de gang, uit de weg van het sleutelbord. Ze horen niet
   bij de scène, dus ze schalen er ook niet mee: maten in rem. */
.hm-corridor-admin {
    position: absolute;
    right: 2%;
    bottom: 3%;
    display: flex;
    gap: 0.5rem;
    line-height: 1.4;
}

/* Portret: de liggende gang past niet staand. Dan vult de foto het scherm als
   cover-crop en hangt het sleutelbord er groter en gecentreerd voor. */
@media (orientation: portrait) {
    .hm-corridor-room {
        position: absolute;
        inset: 0;
        width: auto;
        aspect-ratio: auto;
    }

    /* `bottom: 0` staat in de liggende regel hierboven; samen met de `top: 3%`
       hier rekte dat het bordje uit tot de onderrand van het scherm, terwijl de
       plaat zelf (breedte 100%, hoogte auto) korter bleef. De lijst erin staat
       op `top: 36%` / `bottom: 3%` van dát uitgerekte vak, en liep daardoor van
       "De Lange Gang" af het perkament af, over het tapijt. Met `bottom: auto`
       volgt de hoogte weer de plaat. */
    /* Het bordje wordt hier zelf de container, zodat `cqw` binnenin op de
       bréédte van het bordje slaat en niet op die van het venster. Liggend
       vallen die twee bijna samen (het bordje is 31% van de gang en de maten
       zijn daarop afgestemd), maar in portret is het bordje 90% van het scherm
       — dezelfde cqw-waarde was daar dus drie keer zo veel bordje, en de logo's
       werden tot een dun streepje geperst. Alle maten hieronder zijn nu
       percentages van het bordje en blijven dus op telefoon én tablet gelijk.

       `width: min(90%, 50dvh)`: de plaat is 448x750, dus anderhalf keer zo hoog
       als breed. Op 90% van een tablet in portret werd hij daardoor hoger dan
       het scherm en liep de onderkant eraf; 50dvh is de breedte waarbij hij
       precies binnen de overgebleven hoogte past. */
    .hm-keyboard {
        top: 13%;
        bottom: auto;
        left: 50%;
        width: min(90%, 50dvh);
        container-type: inline-size;
        transform: translateX(-50%);
    }

    .hm-keyboard-kicker {
        font-size: 2.8cqw;
    }

    .hm-keyboard-title {
        font-size: 7cqw;
    }

    /* Liggend komt het plafond op 19% van het bordje uit; hier ruimer, want op
       een telefoon zijn de logo's het enige wat een voorstelling herkenbaar
       maakt en op 19% werden ze dun en breekbaar. */
    .hm-keyboard-logo {
        max-height: 24cqw;
    }

    .hm-keyboard-empty {
        font-size: 3.6cqw;
    }

    .hm-keyboard-arrow {
        width: 5.6cqw;
    }
}

/* ── De taalwissel ───────────────────────────────────────────────── */

/* Onder de bel, in dezelfde hoek. De gang heeft verder geen vrije plek: links
   hangt het sleutelbord van boven tot onder en rechtsonder staan de
   beheerknoppen. En het staat er niet slecht: de uitgang en de taal zijn allebei
   "waar ga ik heen".

   De afstand is uit de bel zelf gerekend — zijn hoogte is 1,33 × zijn breedte,
   het woord eronder meegeteld — en niet in `cqw`, want in de staande stand
   schakelt hij over op rem (zie scene.css). Zo blijft de tussenruimte in beide
   standen gelijk aan de inzet van de bel.

   Als bordje, net als in een voorstellingskamer en in de vitrine: dat is door de
   scènes heen dezelfde knop, dus hij hoort er ook overal hetzelfde uit te zien.
   Het uiterlijk staat in scene.css (`.hm-langs-plaque`), inclusief het rood voor
   de taal waar je in staat. */
.hm-corridor-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}


/* ── components/vitrine.css ── */
/* Hotel Modern — de vitrine (over-pagina).
   Porseleinen musici rond de miniatuur-wolkenkrabber. De introtekst met "lees
   meer" zit linksboven IN de foto gebakken, net als op de oude site; er ligt
   alleen een onzichtbaar vlak overheen dat naar het verhaal leidt.
   Maten zijn percentages van de scène, tekst op `cqw`, net als de gang. */
.hm-vitrine-room {
    position: relative;
    aspect-ratio: 1366 / 768;
    width: min(100vw, calc(100dvh * 1366 / 768));
    container-type: inline-size;
    overflow: hidden;
    line-height: 0;
}

/* De <picture> moet zelf de doos vullen, anders heeft de `height: 100%` van de
   plaat geen hoogte om zich tegen af te zetten en valt hij terug op `auto`. */
.hm-vitrine-room > picture {
    display: block;
    width: 100%;
    height: 100%;
}

.hm-vitrine-bg {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Alles wat over de foto ligt, in één laag: die laag is de opname zelf. In de
   liggende plaat valt hij samen met de scène, in de staande zakt hij naar de
   onderste 44,99% — daar zit de oorspronkelijke 1366×768 in de 1366×1707. Zo
   hoeft geen enkele hotspot hieronder een tweede set percentages te krijgen. */
.hm-vitrine-props {
    position: absolute;
    inset: 0;
    /* De laag is een maatraam, geen oppervlak: zonder dit ligt hij als een vel
       glas over de introtekst-hotspot, die ervóór in de DOM staat. */
    pointer-events: none;
}

.hm-vitrine-props > * {
    pointer-events: auto;
}

/* Smaller dan 6:5 wint de staande plaat: precies het punt waar de liggende
   plaat, die altijd hélemaal in beeld moet passen, tot een strook inkrimpt. */
@media (max-aspect-ratio: 6/5) {
    .hm-vitrine-room {
        aspect-ratio: 1366 / 1707;
        width: min(100vw, calc(100dvh * 1366 / 1707));
    }

    .hm-vitrine-props {
        top: 55.01%;
        height: 44.99%;
        bottom: auto;
    }
}

/* Onzichtbaar vlak over de gebakken introtekst; het loopt door tot onder "lees
   meer", zodat dat handvat meeklikt. Maten uit de liggende plaat zelf: het
   tekstblok begint op x 2,34% / y 4,82%, de langste regel eindigt op 47,07% en
   het rode "lees meer" loopt tot y 30,9%. Met een randje speling eromheen. */
.hm-vitrine-intro {
    position: absolute;
    top: 4.2%;
    left: 1.9%;
    width: 46%;
    height: 27.5%;
    display: block;
}

/* In de staande plaat ligt het vel papier hoger én is de tekst opnieuw gezet op
   ruim het dubbele corps — anders krimpt hij op een telefoon mee tot een grijze
   veeg. Dus eigen maten; deze query staat ná de regel hierboven, want even
   specifiek en dan wint de laatste. */
@media (max-aspect-ratio: 6/5) {
    .hm-vitrine-intro {
        top: 21.2%;
        left: 3.7%;
        width: 70.9%;
        height: 30.9%;
    }
}

/* Onzichtbaar vlak over de wolkenkrabber in de foto; het neonbord "OVER HOTEL
   MODERN" is de affordance, dus hier geen eigen vormgeving — alleen een cursor. */
.hm-vitrine-tower {
    position: absolute;
    top: 6%;
    left: 47%;
    width: 16%;
    height: 62%;
    display: block;
}

/* Het boek ligt rechtsonder op het tafelblad en leidt naar /over/boek, het
   opengeslagen boek (components/book.css). */
.hm-vitrine-book {
    position: absolute;
    right: 6%;
    bottom: 6%;
    width: 13%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    transition: transform 0.25s ease, filter 0.25s ease;
}

/* Op een telefoon is het boek op 13% nog geen 5 mm breed en verdwijnt het
   tussen het porselein. Ruimer, zodat het een prop blijft en geen stofje.
   Ná de regel hierboven, want even specifiek en dan wint de laatste. */
@media (max-aspect-ratio: 6/5) {
    .hm-vitrine-book {
        width: 20%;
    }
}

.hm-vitrine-book img {
    display: block;
    width: 100%;
    height: auto;
}

.hm-vitrine-book:hover,
.hm-vitrine-book:focus-visible {
    transform: scale(1.06) rotate(-1.5deg);
    filter: brightness(1.08);
}

@media (prefers-reduced-motion: reduce) {
    .hm-vitrine-book {
        transition-duration: 0s;
    }
}

/* ── De taalwissel ───────────────────────────────────────────────── */

/* Liggend: onder de bel, in dezelfde hoek en op dezelfde afstand als in de gang
   (zie corridor.css voor de rekensom). Als bordje en niet als kale tekst: deze
   scène is licht kant met een druk bloemmotief, en daar houdt losse tekst — wit
   noch donker — geen stand. Het uiterlijk staat in scene.css
   (`.hm-langs-plaque`). */
.hm-vitrine-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}

/* Geen staande uitzondering meer. De bel hing hier vroeger in de propslaag en
   zakte staand met die laag mee naar de onderste 44,99% — het midden van het
   scherm — waarna de wissel de hoek maar overnam. De bel hangt nu aan de kamer
   (zie de markup) en dus in beide platen in de hoek; de wissel hoort er in
   beide gewoon onder. */


/* ── components/book.css ── */
/* Hotel Modern — het boek (`/over/boek` en de hoofdstukken eronder).

   Reconstructie van de oude `/over/boek/`: de foto van een écht opengeslagen
   boek, links de inhoudsopgave met het huidige hoofdstuk in rood, rechts de
   tekst, rechtsboven de bel naar huis, linksonder de props naar de andere
   kamers en tegen de snee de twee pijlen.

   Verschil met het origineel: dáár was het één JS-pagina die de rechterpagina
   verwisselde zonder dat het adres meebewoog. Bij ons heeft elk hoofdstuk zijn
   eigen URL (`/over/<slug>`) en is de inhoudsopgave een rij gewone links; het
   boek is de vormgeving, niet de machinerie.

   De plaat is 1366×768 en alles ligt er in percentages overheen, net als in de
   receptie en de vitrine — opgemeten aan de oude pagina. Maten in `cqw`, dus
   het hele boek schaalt als één geheel mee. */
.hm-book-spread {
    position: relative;
    aspect-ratio: 1366 / 768;
    width: min(100vw, calc(100dvh * 1366 / 768));
    container-type: inline-size;
    overflow: hidden;
}

.hm-book-plate {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ── Linkerbladzijde: de inhoudsopgave ───────────────────────────── */

.hm-book-toc {
    position: absolute;
    top: 7.6%;
    left: 3.8%;
    width: 23%;
}

.hm-book-toc ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-book-toc li + li {
    margin-top: 0.55em;
}

.hm-book-toc a {
    font-family: var(--hotelmodern-font-heading);
    font-size: 1.45cqw;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-decoration: none;
    color: #1c1408;
}

.hm-book-toc a:hover,
.hm-book-toc a:focus-visible {
    color: var(--hotelmodern-accent);
}

/* Het hoofdstuk waar het boek op openligt. In het origineel was dat ook rood. */
.hm-book-toc a[aria-current="page"] {
    color: var(--hotelmodern-accent);
}

/* Het beheer van het over-gedeelte, onder de inhoudsopgave. Niet in een hoek
   van de scène zoals op het nieuwsbord: dit ís de bladzijde waar de hoofdstukken
   op staan, dus hier hoort het werk.

   In het hotelrood en met een pictogram, waar de andere dienstregels van deze
   tenant grijs en kaal zijn. Dat verschil is hier verdiend: op de agenda ligt de
   knop tussen het werk zelf en mag hij wegvallen, maar hier staat hij onder een
   inhoudsopgave in dezelfde kopletter en dezelfde kapitalen. In dunne inkt las
   hij als een achtste hoofdstuk dat toevallig lichter was gezet. De kleur zegt:
   dit is een handeling, geen bladzijde.

   Een streepje erboven scheidt hem van het laatste hoofdstuk — het boek heeft
   geen kaders, dus een haarlijn in de inkt van het papier is genoeg. */
.hm-book-admin {
    margin-top: 1.1em;
    padding-top: 0.9em;
    border-top: 0.0625rem solid rgba(28, 20, 8, 0.18);
    display: flex;
    flex-wrap: wrap;
    gap: 0.55em 1.1em;
    font-family: var(--hotelmodern-font-heading);
    font-size: 1.1cqw;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1.2;
}

.hm-book-admin a {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    color: var(--hotelmodern-accent);
    text-decoration: none;
}

.hm-book-admin a:hover,
.hm-book-admin a:focus-visible {
    color: var(--hotelmodern-accent-dark);
    text-decoration: underline;
    text-underline-offset: 0.25em;
}

/* De pictogrammen zijn maskers zonder eigen kleur (base/icons.css); ze krijgen
   hem hier van het woord ernaast, zoals op de agenda. Op kapitaalhoogte en een
   haartje omlaag, zodat ze op de regel staan en er niet boven zweven. */
.hm-book-admin [class*="icon-"] {
    width: 1em;
    height: 1em;
    background-color: currentColor;
    vertical-align: -0.1em;
    flex: 0 0 auto;
}

/* De props onderaan de linkerbladzijde: dezelfde objecten als op de receptie,
   hier als uitgang naar de andere kamers. Ze liggen ín het boek, dus geen
   kader; de posities komen uit de oude pagina. */
.hm-book-props {
    position: absolute;
    top: 66%;
    left: 3.6%;
    width: 23.5%;
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 4% 5%;
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-book-props img {
    display: block;
    width: 100%;
    height: auto;
    transition: transform 0.25s ease;
}

.hm-book-props a:hover img,
.hm-book-props a:focus-visible img {
    transform: scale(1.06) rotate(-1.5deg);
}

/* ── Rechterbladzijde: het hoofdstuk ─────────────────────────────── */

/* Scrollt binnen de bladzijde, maar zonder scrollbalk: die hoort niet in een
   boek. De pijlen tegen de snee doen het werk (hook HmScroll), en muiswiel,
   touch en toetsenbord werken gewoon. */
.hm-book-text {
    position: absolute;
    top: 7.4%;
    left: 36.6%;
    right: 12.4%;
    bottom: 4%;
    overflow-y: auto;
    font-family: var(--hotelmodern-font-body);
    font-size: 1.15cqw;
    line-height: 1.55;
    color: #1c1408;
    scrollbar-width: none;
}

.hm-book-text::-webkit-scrollbar {
    display: none;
}

.hm-book-text h1 {
    margin: 0 0 1.2em;
    font-size: 1.45cqw;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.hm-book-text :is(p, ul, ol) {
    margin: 0 0 1em;
    line-height: inherit;
}

.hm-book-text :is(p, ul, ol):last-child {
    margin-bottom: 0;
}

.hm-book-text a {
    color: var(--hotelmodern-accent);
}

.hm-book-empty {
    font-style: italic;
    opacity: 0.7;
}

/* De onderkant van de bladzijde uit laten vloeien, zodat de tekst niet hard
   afgeknipt lijkt maar in het papier wegloopt.

   Het masker hangt aan de zichtbare bak, niet aan de tekst die eronder
   doorschuift: die onderste band vervaagt dus altijd. Onder de tekst ligt
   daarom net zo'n band leeg papier (`padding-bottom`), zodat het einde van een
   hoofdstuk op blanco papier uitvloeit in plaats van op de slotregel — anders
   staat de bron onder een artikel half weggepoetst en lijkt dat een fout.
   Eén maat voor beide, zodat ze niet uit elkaar kunnen lopen. */
.hm-book-text {
    --hm-book-fade: 3.5cqw;

    padding-bottom: var(--hm-book-fade);
    -webkit-mask-image: linear-gradient(
        to bottom,
        #000 0,
        #000 calc(100% - var(--hm-book-fade)),
        transparent 100%
    );
    mask-image: linear-gradient(
        to bottom,
        #000 0,
        #000 calc(100% - var(--hm-book-fade)),
        transparent 100%
    );
}

/* ── De pijlen tegen de snee ─────────────────────────────────────── */

.hm-book-scroll {
    position: absolute;
    right: 6.6%;
    bottom: 4.5%;
    display: flex;
    flex-direction: column;
    gap: 0.9cqw;
}

.hm-book-scroll[hidden] {
    display: none;
}

.hm-book-scroll button {
    padding: 0.3cqw;
    border: 0;
    background: none;
    color: var(--hotelmodern-accent);
    cursor: pointer;
    opacity: 0.8;
    transition: opacity 0.3s ease;
}

.hm-book-scroll button:hover,
.hm-book-scroll button:focus-visible {
    opacity: 1;
}

.hm-book-scroll button:disabled {
    opacity: 0.2;
    cursor: default;
}

/* Eén bestand voor beide richtingen: `arrow.svg` als masker, de bovenste
   gedraaid. Zelfde behandeling als de pijlen in de gang. */
.hm-book-arrow {
    display: block;
    width: 1.5cqw;
    aspect-ratio: 19 / 40;
    background: currentColor;
    -webkit-mask: url("/assets/hotelmodern/voorstellingen/arrow-9e91cac7deb036c17c0a0931e14d3913.svg?vsn=d") center /
        contain no-repeat;
    mask: url("/assets/hotelmodern/voorstellingen/arrow-9e91cac7deb036c17c0a0931e14d3913.svg?vsn=d") center / contain
        no-repeat;
}

[data-scroll="up"] .hm-book-arrow {
    transform: rotate(180deg);
}

/* Taalwissel: onder de bel, in dezelfde hoek en op dezelfde afstand als in de
   gang en de vitrine (zie corridor.css voor de rekensom). Het uiterlijk staat in
   scene.css (`.hm-langs-plaque`). */
.hm-book-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}

/* ── Portret: het boek een kwartslag ─────────────────────────────── */

/* Twee bladzijden naast elkaar passen niet op een telefoonbreedte — de
   inhoudsopgave werd een strook van 90 px — maar een kwartslag gedraaid past
   hetzelfde boek wél: de linkerbladzijde wordt de menubalk, de vouw loopt
   horizontaal en de rechterbladzijde krijgt de rest. Het is hetzelfde voorwerp,
   alleen omgeslagen als een schrijfblok.

   Hiervóór klapte het boek staand dicht tot één doorlopend vel papier, met de
   tekst boven en de inhoudsopgave eronder. Leesbaar, maar het voorwerp was weg:
   je las een webpagina met een papieren achtergrondje, en de hele reden dat
   deze scène een foto van een echt boek is verdween precies op het scherm waar
   de meeste bezoekers hem zien.

   Eén gedraaide plaat, geen lagen. De perskamer knipt zijn ordner staand wél in
   drieën, en dat moet daar ook: het blauwe vel, de ringen en het roze vel zijn
   scherpe vlakken die op de paneelranden moeten vallen. Dit boek heeft die
   vlakken niet — het is van boven tot onder papier met één flauwe vouw — dus er
   valt niets uit te lijnen en kan de hele plaat als achtergrond van de scène
   liggen. De panelen hieronder zijn doorzichtige bakken op die ene foto. Een
   eerdere poging knipte hier alsnog drie stroken uit; die naden lazen als een
   strookje papier óp het boek, en dat is precies wat er niet moet staan.

   `orientation: portrait` en niet de 6/5 die deze tenant verder aanhoudt: een
   kwartslag vraagt een scherm dat écht hoger is dan breed. Tussen 1,0 en 1,2
   blijft de liggende plaat staan, en daar is ruimte voor — bij die verhouding
   is de plaat door de breedte begrensd en houdt hij boven en onder een marge
   over die groter is dan de kopregel. */
@media (orientation: portrait) {
    .hm-book {
        align-items: stretch;
    }

    .hm-book-spread {
        /* Eén maat voor de linkerkant van alle drie de lagen, zodat de
           hoofdstukken, de props en de tekst op dezelfde lijn beginnen. Een
           tablet krijgt hier bijna het dubbele van een telefoon: op 768px is de
           marge van een telefoon een kantlijn van niks. */
        --hm-book-kantlijn: clamp(1rem, 4cqw, 3rem);
        /* Rechts houdt het papier op bij ±96,5% van de breedte: daar ligt de
           bovenrand van het boek, die gedraaid de rechterrand werd. Een
           percentage en geen rem-plafond, want die grens schuift mee met de
           breedte — met een vast plafond loopt de tekst op een breed scherm
           alsnog over de rand. */
        --hm-book-papierrand: max(1.5rem, 6cqw);

        aspect-ratio: auto;
        width: 100%;
        display: flex;
        flex-direction: column;
        /* De plaat staat stil terwijl de tekst erover scrollt, en daar is geen
           `background-attachment: fixed` voor nodig: in portret ís dit element
           het venster (`.hm-stage` staat `fixed` op `inset: 0` en rekt zijn kind
           uit), dus een gewone achtergrond doet hetzelfde. Scheelt de
           iOS-Safari-onzekerheid rond `fixed`.

           `top` en niet `center`: op een scherm dat minder hoog is dan de plaat
           snijdt `cover` er verticaal wat af, en met `center` gaat dat er aan
           twee kanten af — dan zakt de vouw tot boven de props. Vanaf de
           bovenrand blijft hij binnen een regel of drie van de onderrand van de
           menubalk, over de hele reeks van telefoon tot tablet. */
        background: url("over/book-portrait-19bb4318dd1e2c2a2e6b76dd25d11ba3.jpg?vsn=d") top center / cover no-repeat;
    }

    .hm-book-plate,
    .hm-book-scroll {
        display: none;
    }

    /* 1. De linkerbladzijde: de inhoudsopgave en de props eronder, samen de
          menubalk. */
    .hm-book-toc,
    .hm-book-props {
        position: static;
        /* Niet krimpen: als flex-item zou de inhoudsopgave regels inleveren
           zodra de tekst eronder om ruimte vraagt, en dan sta je te scrollen in
           een menu dat juist volledig zichtbaar moest zijn. */
        flex: 0 0 auto;
        top: auto;
        left: auto;
        width: auto;
    }

    /* De kopregel (scene.css, `.hm-topbar`) ligt over de bovenrand. Een
       binnenmarge en geen verschuiving: het papier hoort dóór te lopen tot de
       bovenrand van het scherm — dat is de bladzijde, en die houdt niet op waar
       de balk begint. Alleen de regels erop schuiven eronderuit. De balk staat
       vanaf 6/5 aan en portret valt daar binnen, dus `--hm-topbar-h` is hier
       altijd gezet. */
    .hm-book-toc {
        padding: calc(var(--hm-topbar-h) + 0.85rem) var(--hm-book-papierrand) 0
            var(--hm-book-kantlijn);
    }

    /* De hoofdstukken naast elkaar in plaats van onder elkaar: staand is dit
       een balk en geen kolom. Ze houden hun kopletter en kapitalen, dus het
       blijft een inhoudsopgave en wordt geen navigatiemenu. */
    .hm-book-toc ul {
        display: flex;
        flex-wrap: wrap;
        column-gap: 1.1em;
        row-gap: 0.15em;
        font-size: clamp(0.83rem, 2.4cqw, 1.05rem);
    }

    .hm-book-toc li + li {
        margin-top: 0;
    }

    .hm-book-toc a {
        font-size: inherit;
    }

    /* `cqw` is in portret de vensterbreedte, en dan wordt 1,1cqw op een telefoon
       een streepje van 4px. Zelfde ondergrens-en-plafond als de hoofdstukken
       erboven, een maatje kleiner. Het streepje erboven vervalt: staand is deze
       regel de onderrand van de menubalk en staat er al een rand onder de
       props. */
    .hm-book-admin {
        margin-top: 0.6em;
        padding-top: 0;
        padding-bottom: 0.2rem;
        border-top: 0;
        font-size: clamp(0.72rem, 2.1cqw, 0.92rem);
    }

    /* De props op een rij van vier onder de hoofdstukken. Het plafond staat op
       de kolommen en niet op het vel: met een `max-width` op de lijst zelf houdt
       het papier op waar de props ophouden, en dan valt er rechts een zwart gat
       in de menubalk. `minmax(0, …)` laat ze op een smalle telefoon alsnog
       krimpen; zonder de ondergrens 0 lopen ze de kantlijn uit. */
    .hm-book-props {
        grid-template-columns: repeat(4, minmax(0, clamp(4rem, 15cqw, 7rem)));
        justify-content: start;
        gap: 0;
        column-gap: clamp(1rem, 4cqw, 2.5rem);
        padding: 0.9rem var(--hm-book-papierrand) 0.9rem var(--hm-book-kantlijn);
    }

    /* 2. De rechterbladzijde neemt wat er over is en scrollt zelf, net als
          liggend — de pijlen tegen de snee zijn hier weg, want een vinger
          veegt. */
    .hm-book-text {
        /* De band waarover het papier wegloopt, en tegelijk de lucht eronder —
           één maat voor allebei, zoals liggend (zie `--hm-book-fade` daar). In
           portret in rem en niet in `cqw`: `cqw` is hier de vensterbreedte, en
           dat maakte van 3,5cqw op een telefoon een band van 15px. */
        --hm-book-fade: 2.5rem;

        position: static;
        flex: 1 1 auto;
        min-height: 0;
        top: auto;
        left: auto;
        right: auto;
        bottom: auto;
        width: auto;
        padding: var(--hm-book-kantlijn) var(--hm-book-papierrand) var(--hm-book-fade)
            var(--hm-book-kantlijn);
        /* De ondergrens houdt de telefoon vlak (daar telt elke regel), het
           plafond laat een tablet doorgroeien. */
        font-size: clamp(0.95rem, 2.6cqw, 1.25rem);
        line-height: 1.6;
    }

    .hm-book-text h1 {
        font-size: clamp(1.15rem, 3.2cqw, 1.6rem);
    }
}


/* ── components/anbi.css ── */
/* Hotel Modern — de ANBI-bladzijde (`/anbi`).

   Dit is geen eigen scène maar een bladzijde van het boek: alles hangt aan de
   `.hm-book-*`-klassen uit book.css, inclusief de staande uitvoering waarin het
   boek een kwartslag draait. Hier staat alleen wat het boek niet heeft.

   Waarom een bladzijde en geen kamer: op WordPress stond dit onder
   `/over/boek/anbi`, letterlijk in dit boek, en `LegacyWpRedirect` stuurt dat
   adres hierheen. Tot nu toe droeg `/anbi` als enige pagina van deze tenant het
   platformsjabloon, met de header die overal elders verborgen is. */

/* ── Lange adressen ──────────────────────────────────────────────── */

/* De stichtingsgegevens staan vol met uitgeschreven URL's — de
   publicatieverplichting bij anbi.nl, de cao, de belastingdienst. Zonder dit
   duwen die de bladzijde uit: op een telefoon van 390 rem-eenheden breed werd
   `scrollWidth` 492 en scrolde de hele pagina horizontaal mee.

   `anywhere` en niet `break-word`, omdat alleen `anywhere` de regel óók laat
   meetellen bij het berekenen van de minimale breedte — precies wat hier de
   overloop veroorzaakte. */
.hm-anbi .hm-book-text {
    overflow-wrap: anywhere;
}

/* ── Koppen binnen de tekst ──────────────────────────────────────── */

/* De ANBI-tekst is de enige body van deze tenant met koppen erín
   (`<h2>Beloningoverzicht</h2>` uit de WP-bron; de vijf boekhoofdstukken hebben
   er nul). Zonder dit staan die koppen groter dan de titel van de bladzijde
   zelf: `scene.css` zet `body.hotelmodern h3` op 1.675rem en een `h2` valt terug
   op de browser-default van 1.5em — 26.8 en 24.8 tegen een `h1` van 1.45cqw
   (20.9 op 1440 breed). Een kop ín de tekst hoort onder de titel te blijven.

   De maten zijn in `cqw` net als de rest van de bladzijde, zodat ze meeschalen
   met het boek. Twee klassen diep (`.hm-anbi` erbij) omdat `body.hotelmodern h3`
   anders wint. */
.hm-anbi .hm-book-text :is(h2, h3) {
    margin: 1.6em 0 0.5em;
    font-size: 1.25cqw;
    letter-spacing: 0.02em;
}

.hm-anbi .hm-book-text h3 {
    font-size: 1.15cqw;
}

/* ── De documentenkast ───────────────────────────────────────────── */

/* Jaarstukken, statuten en het KVK-uittreksel. Ze staan onder de tekst op
   dezelfde bladzijde en niet in een eigen kader: het is een bijlage bij de
   stichtingsgegevens, geen tweede onderwerp. De streep erboven doet het werk
   dat een kader zou doen, zonder een doos op papier te leggen. */
.hm-anbi-docs {
    margin-top: 2.5em;
    padding-top: 1.5em;
    border-top: 1px solid rgba(28, 20, 8, 0.25);
}

/* Het kopje van de kast krijgt kapitalen in plaats van meer punten: zo leest hij
   als opschrift zonder harder te roepen dan de titel van de bladzijde. */
.hm-anbi .hm-anbi-docs h2 {
    margin: 0 0 1em;
    font-size: 1.25cqw;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.hm-anbi-doc-group + .hm-anbi-doc-group {
    margin-top: 1.4em;
}

/* De categorie (Jaarverslagen, Statuten, KVK) is niet meer dan een tussenkopje
   boven een lijstje — vandaar op de maat van de lopende tekst, alleen vet. */
.hm-anbi .hm-anbi-doc-group h3 {
    margin: 0 0 0.4em;
    font-size: 1.15cqw;
    letter-spacing: 0.02em;
    text-transform: none;
}

.hm-anbi-doc-group ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-anbi-doc-group li + li {
    margin-top: 0.35em;
}

/* Het documenticoon als masker, zodat het de inkt van de bladzijde aanneemt
   net als de bladerpijlen. Geen los bestand: dit is de enige plek waar het
   staat. */
.hm-anbi-doc-group a {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5em;
    color: var(--hotelmodern-accent);
}

.hm-anbi-doc-group a::before {
    content: "";
    flex: none;
    align-self: center;
    width: 1em;
    aspect-ratio: 3 / 4;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3C/svg%3E")
        center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3C/svg%3E")
        center / contain no-repeat;
}

/* ── Staand: mee met het gedraaide boek ──────────────────────────── */

/* Zelfde grens als book.css: staand is `cqw` de vensterbreedte en niet de
   breedte van de bladzijde, dus een kopje van 1,25cqw wordt op een telefoon
   5px. In `em` en niet in pixels: de tekst eronder staat daar in een `clamp`
   die met het scherm meegroeit, en met een vaste maat lopen kop en tekst op een
   tablet uit elkaar. */
@media (orientation: portrait) {
    .hm-anbi .hm-book-text :is(h2, h3),
    .hm-anbi .hm-anbi-doc-group h3 {
        font-size: 1.05em;
    }

    /* De kop van de documentenkast blijft net onder de titel van de bladzijde,
       die op 1,21em van de tekst staat (book.css). */
    .hm-anbi .hm-anbi-docs h2 {
        font-size: 1.15em;
    }
}


/* ── components/preview.css ── */
/* Hotel Modern — het kaartje bij een bordje in de gang.
   Eén vast paneel dat naast het bordje verschijnt waar de muis op staat — op de
   plek waar de oude site een modal opende. Het staat buiten de scrollende lijst
   (die zou het klippen) en wisselt alleen van inhoud, zodat het niet bij elke
   muisbeweging verschijnt en verdwijnt. Alleen op apparaten mét hover; op touch
   bestaat het niet (JS bedraadt het daar ook niet) en gaat een tik direct naar
   de voorstelling. Positie, inhoud en timing komen uit de hook
   HmKeyboardPreview in assets/js/hooks.js. */
.hm-keyboard-preview {
    display: none;
}

@media (hover: hover) and (pointer: fine) {
    .hm-keyboard-preview {
        /* Timing van het hele verschijnen, op één plek. `--hm-preview-delay` is
           de stilte tussen "muis blijft hangen" en "kaartje komt op"; bovenop de
           hover-intentie in HmKeyboardPreview (JS) komt dat neer op ~0,4s bij het
           eerste bordje en ~0,5s bij elk volgend — lang genoeg om langs de lijst
           te kunnen vegen, kort genoeg om als antwoord te voelen. */
        --hm-preview-delay: 0.22s;
        --hm-preview-fade: 0.4s;
        --hm-preview-leave: 0.25s;
        --hm-preview-text-fade: 0.35s;

        display: block;
        position: absolute;
        border-radius: 0.4cqw;
        /* Startpositie voor het geval de hook nog niets heeft gemeten; daarna
           zet die `top`/`left` per bordje (zie HmKeyboardPreview). */
        top: 30%;
        left: 40%;
        width: 27%;
        padding: 2.1cqw 1.3cqw;
        background: var(--hotelmodern-paper, #f4f0e6);
        /* Geen rand en geen slagschaduw: die liep als een streep dwars door het
           staartje. De schaduw wordt namelijk buiten de kaart uitgeblurd, dus ook
           links van de rand — precies waar het driehoekje zit, dat maar een halve
           cqw breed is en er dus in verdwijnt. Het papier drijft nu op zijn eigen
           kleur en op de scherpte van de tekst. */
        color: var(--hotelmodern-fg, #2b1a10);
        opacity: 0;
        visibility: hidden;
        transform: translateY(0.35cqw);
        pointer-events: none;
        /* Weggaan mag vlotter dan komen: wie de gang weer in beweegt, wil het
           papier niet achter zich aan slepen. Geen vertraging hier — die zit al
           in de gratieperiode van de hook. */
        transition:
            opacity var(--hm-preview-leave) ease,
            transform var(--hm-preview-leave) ease,
            visibility 0s linear var(--hm-preview-leave);
    }

    /* Het staartje van het praatwolkje: een driehoekje van dezelfde papierkleur,
       links van de kaart, op ooghoogte van het bordje waar het bij hoort. De
       hook zet `--hm-preview-tail` per bordje; 50% is de val-terug voor het
       geval er nog niets gemeten is. Staat de kaart links van het bordje
       (`is-flipped`), dan wijst het staartje de andere kant op. */
    .hm-keyboard-preview::before {
        content: "";
        position: absolute;
        top: var(--hm-preview-tail, 50%);
        left: -0.5cqw;
        width: 0;
        height: 0;
        transform: translateY(-50%);
        border-style: solid;
        border-width: 0.45cqw 0.5cqw 0.45cqw 0;
        border-color: transparent var(--hotelmodern-paper, #f4f0e6) transparent
            transparent;
        pointer-events: none;
    }

    .hm-keyboard-preview.is-flipped::before {
        left: auto;
        right: -0.5cqw;
        border-width: 0.45cqw 0 0.45cqw 0.5cqw;
        border-color: transparent transparent transparent
            var(--hotelmodern-paper, #f4f0e6);
    }

    .hm-keyboard-preview.is-visible {
        /* Niet helemaal dekkend: de gang blijft flauw door het papier heen te
           zien, zodat het paneel een vel over de scène is en niet een tweede
           scherm. */
        opacity: 0.85;
        visibility: visible;
        transform: translateY(0);
        /* De hele kaart is de knop: erop klikken brengt je naar de voorstelling
           waar ze bij hoort (de hook stuurt de klik door naar het bordje). Pas
           klikbaar zodra ze zichtbaar is — onzichtbaar mag ze niets afvangen,
           daarom schakelt `visibility` hieronder ook pas ná de vertraging mee. */
        pointer-events: auto;
        cursor: pointer;
        transition:
            opacity var(--hm-preview-fade) ease var(--hm-preview-delay),
            transform var(--hm-preview-fade) ease var(--hm-preview-delay),
            visibility 0s linear var(--hm-preview-delay);
    }

    /* De tekst komt ná het papier binnen, in leesvolgorde: eerst de titel, dan
       de samenvatting. Zo leidt het paneel het oog naar beneden i.p.v. in één
       klap een blok tekst neer te zetten.

       Alleen bij het eerste verschijnen: schuif je daarna van bordje naar bordje
       terwijl het paneel open blijft, dan wisselt de inhoud direct — `is-visible`
       gaat er dan niet af, dus er wordt niets opnieuw ingefade. Dat is de
       bedoeling: het trage begin helpt bij het oriënteren, daarna is het volgen. */
    .hm-preview-title,
    .hm-preview-body {
        opacity: 0;
        transform: translateY(0.4cqw);
        transition:
            opacity var(--hm-preview-text-fade) ease,
            transform var(--hm-preview-text-fade) ease;
    }

    .hm-keyboard-preview.is-visible :is(.hm-preview-title, .hm-preview-body) {
        opacity: 1;
        transform: translateY(0);
    }

    .hm-keyboard-preview.is-visible .hm-preview-title {
        transition-delay: calc(var(--hm-preview-delay) + 0.1s);
    }

    .hm-keyboard-preview.is-visible .hm-preview-body {
        transition-delay: calc(var(--hm-preview-delay) + 0.2s);
    }

    .hm-preview-title {
        margin: 0 0 0.5cqw;
        font-family: var(--hotelmodern-font-heading);
        font-size: 1.3cqw;
        line-height: 1.15;
    }

    /* De samenvatting staat er voluit; ze komt uit de import op ~300 tekens, dus
       de kaart blijft vanzelf binnen de gang. `flow-root` vangt de flyer op:
       zonder dat zou een korte tekst de float onder de kaart uit laten steken. */
    .hm-preview-body {
        display: flow-root;
        font-family: var(--hotelmodern-font-body);
        font-size: 0.85cqw;
        line-height: 1.45;
    }

    /* Ouderwets omfloten: de flyer staat ín de samenvatting (de hook zet hem daar
       terug na elke innerHTML), niet ernaast als los blok — een float wordt alleen
       omstroomd door tekst in hetzelfde blok. Smal genoeg (een poster is hoger dan
       breed) dat er ook echt regels onderdoor lopen. */
    .hm-preview-flyer {
        display: block;
        float: right;
        width: 36%;
        margin: 0.2cqw 0 0.5cqw 0.9cqw;
        border-radius: 0.2cqw;
    }

    .hm-preview-flyer[hidden] {
        display: none;
    }

    .hm-preview-body :is(p, ul, ol) {
        margin: 0 0 0.4cqw;
    }

    .hm-preview-body :is(p, ul, ol):last-child {
        margin-bottom: 0;
    }
}

/* De vertraging moet hier óók weg, niet alleen de beweging: `transition-duration: 0s`
   laat een `transition-delay` gewoon staan, en dan blijft het paneel `hidden` tot
   de vertraging om is en klapt het er daarna in één keer in. */
@media (prefers-reduced-motion: reduce) {
    .hm-keyboard-preview,
    .hm-keyboard-preview.is-visible,
    .hm-preview-title,
    .hm-preview-body,
    .hm-keyboard-preview.is-visible :is(.hm-preview-title, .hm-preview-body) {
        transition-duration: 0s;
        transition-delay: 0s;
        transform: none;
    }
}


/* ── components/roomview.css ── */
/* Hotel Modern — de kamer (detailpagina van een voorstelling).
   Zelfde principe als de gang: scènefoto zo groot mogelijk in de zwarte doos.
   De krant linksonder is de knop naar de inhoud. */
.hm-roomview-scene {
    /* Eén procent van de scènebreedte, als eigen eenheid. Liggend is dat
       precies wat `cqw` doet. Staand zetten we `container-type` uit — dat
       impliceert namelijk `contain: layout`, en dan wordt de scène de houder
       van álles wat erin `position: fixed` staat, inclusief de bel die juist
       aan het venster moet hangen. Daar rekenen we de maat dus uit de hoogte,
       wat op een 16:9-scène op hetzelfde neerkomt. */
    --hm-cqw: 1cqw;

    position: relative;
    aspect-ratio: 16 / 9;
    width: min(100vw, calc(100dvh * 16 / 9));
    container-type: inline-size;
    overflow: hidden;
    line-height: 0;
}

.hm-roomview-bg {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Gepositioneerd, zodat de spiegellaag eronder blijft: twee gepositioneerde
       broers zonder z-index worden in DOM-volgorde geschilderd, en de kamer
       staat later. Zo hoeft er nergens een z-index bij — die zou de vleugel en
       de props, die ook gepositioneerd zijn, juist onder de foto duwen. */
    position: relative;
}

/* De spiegel. In de terugvalkamer zit op de plek van het spiegelvlak een gat in
   de plaat; deze laag ligt eronder en is dus alleen dáár te zien. Bij een
   voorstelling met een eigen scènefoto is die foto dekkend en blijft de laag
   onzichtbaar — er hoeft dus niets aan- of uitgezet te worden.

   Links en breedte komen uit het oude thema en vallen samen met het gat. De
   bovenkant niet: die stond op -16%, waarmee de foto met zijn kop boven de
   scène uitstak en je door de spiegel een middenstrook zag. Nu ligt de bovenrand
   van de foto tegen de bovenrand van de scène, zodat je de kop van de foto ziet
   en de lijst er als vanouds bovenlangs uitloopt. Nudgen kan met
   `--hm-mirror-top`. */
.hm-room-mirror {
    position: absolute;
    top: var(--hm-mirror-top, 0%);
    left: 28%;
    width: 29.3%;
    height: auto;
}

/* Bel en bordje hangen rechtsboven tegen de rand, zoals op de oude site: daar
   stonden ze allebei op `right: 1%` en dus rechts uitgelijnd, niet gecentreerd
   onder elkaar. Gecentreerd steekt het smalle belletje links uit onder het
   bredere bordje en gaat het zweven.

   Deze pagina is de enige waar de bel niet alleen in de hoek hangt: er staat een
   tweede uitgang onder. De nav neemt daarom de hoek van de bel over (`.is-inline`
   in de markup zet zijn eigen positionering uit) en het bordje volgt eronder. */
.hm-roomview-nav {
    position: absolute;
    /* Precies dezelfde hoek als op elke andere pagina: de bel hoort op alle
       pagina's op dezelfde plek te hangen, anders springt hij bij het klikken
       van scherm tot scherm. Hier stond eerder de halve inzet om ruimte te
       maken voor de bladen eronder, maar die beginnen pas op 12% van de
       scènebreedte (zie `.hm-room-scroll`) en dat is ruim genoeg voor bel én
       bordje. */
    top: var(--hm-bell-inset);
    right: var(--hm-bell-inset);
    /* Dezelfde laag als de bel (scene.css), en op de nav en niet op de losse
       plankjes: de bel draagt die 1000 zelf en kwam daarmee bóven de open
       kamer uit, maar het bordje en de taalwissel niet — die lagen achter de
       scrollbak van de modal en waren dus niet aan te klikken zodra je de krant
       had opengedaan. Met de laag op de nav komt de stapel als geheel omhoog en
       kun je vanuit de tekst ook terug naar de speellijst of van taal wisselen. */
    z-index: 1000;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    /* De oude site liet zo'n 2,5% van de scènehoogte tussen bel en bordje; hier
       staan ze tegen elkaar aan. De bel is sinds de gedeelde maat 5cqw in plaats
       van 4, en dat schuift het bordje omlaag: bij Garnalen Verhalen komt de
       onderrand ervan nu op ~20% en raakt hij de bovenhoek van het schilderij
       dat daar in de scènefoto hangt. Dichter op elkaar wint het grootste deel
       van dat verschil terug en leest de stapel ook als één ding. */
    gap: 0.15cqw;
}

.hm-roomview-back img {
    display: block;
    width: 100%;
    height: auto;
}

.hm-roomview-back {
    width: 8.5cqw;
}

/* Het bordje draagt het woord al in het hout; die tekst is er alleen voor
   schermlezers. */
.hm-roomview-back span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}

/* De taalwissel ligt in de rechteronderhoek, op dezelfde inzet als de taalplaat
   op de balie (reception.css, `.hm-prop-language`: 1% van de scène). Uiterlijk in
   scene.css (`.hm-langs-plaque`): hetzelfde bordje als in de vitrine.

   Hij heeft onder het bordje terug gehangen, in de stapel rechtsboven. Dat is
   waar de andere secties hem hebben, maar de balie — de pagina waar een bezoeker
   binnenkomt — heeft hem altijd rechtsonder gehad, en die zet de maat. Staand
   verdwijnt hij hier helemaal: dan draagt de kopregel de talen (scene.css zet
   `.hm-scene-langs` in die stand uit).

   Dezelfde laag als de hoekstapel, zodat je ook met de krant open van taal kunt
   wisselen. */
.hm-roomview-langs {
    position: absolute;
    right: 1%;
    /* Boven de beheerknoppen, die op 3% tegen de vloer liggen: de stapel begint
       daarboven. Uitgelogd — en dat is verreweg de meeste bezoekers — staat er
       niets onder en ligt de onderste taal een handbreedte van de onderrand. */
    bottom: 9%;
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}


/* Beheerknoppen op de scène. Zelfde vorm en plek als in de gang
   (.hm-corridor-admin), zodat het ingelogde beeld door de tenant heen hetzelfde
   is. In rem en niet in cqw: dit is gereedschap, geen decor — het hoort leesbaar
   te blijven op een klein scherm, ook als de scène daar krimpt. */
.hm-roomview-admin {
    position: absolute;
    right: 2%;
    /* Tegen de vloer; de taalbordjes stapelen erbovenop (zie
       `.hm-roomview-langs`). */
    bottom: 3%;
    /* Onder de open krant (die staat op 40), en dat blijft zo: deze twee knoppen
       horen bij de kamer, niet bij het vel. Wie de krant openslaat vindt
       dezelfde twee ingangen in de kop van het papier (`.hm-room-admin`) — daar
       hebben ze de vorm van dat vel. Een zwart knopvlak dat over het papier
       heen blijft zweven leest als een bedieningspaneel op een krant. */
    z-index: 2;
    display: flex;
    gap: 0.5rem;
    line-height: 1.4;
}

/* Verwijderen is de enige knop hier zonder weg terug; hij mag zich niet
   voordoen als de andere twee. */
.hm-roomview-admin .button.delete {
    border-color: rgba(255, 140, 130, 0.5);
    color: #ffb3ab;
}

/* De basisopmaak zet een rood uitroepteken voor elke verwijderknop. In de
   scène, in het serif-lettertype van de tenant, leest dat als een streep — een
   rendeerfoutje, niet als een waarschuwing. De rode letters zeggen het hier al. */
.hm-roomview-admin .button.delete::before {
    content: none;
}

.hm-roomview-admin .button.delete:hover {
    background: rgba(120, 20, 15, 0.75);
    color: #fff;
}

/* De krant ligt plat in de scène, zoals hij op de oude site lag: het papier is
   in het beeld zelf al gekreukt en scheef afgesneden, en een draaiing daar
   bovenop laat hem zweven in plaats van liggen. Hier stond `rotate(-2deg)` —
   bedoeld als "licht gedraaid zoals in de scène", maar dat was hij niet.

   Waar hij écht past verschilt per beeld, dus de drie percentages komen als
   custom property van de voorstelling mee (zie `hm_newspaper_style/1`). Binnen
   de scène is 1% breedte gelijk aan 1cqw — de scène ís de container — dus de
   eenheden mogen door elkaar.

   De terugval hieronder is de plek uit het oude thema: op het kussen in de
   hotelkamer, de scène die elke voorstelling zonder eigen kamer krijgt. Dat is
   waar de krant hoort te liggen zolang niemand hem verzet. Hier stond eerder
   linksonder op 4% — een neutrale hoek, maar in die kamer valt de krant dan
   naast het bed op de vloer, buiten het licht en half achter het voeteneind. */
.hm-newspaper {
    position: absolute;
    bottom: var(--hm-newspaper-bottom, 24.5%);
    left: var(--hm-newspaper-left, 34.7%);
    width: var(--hm-newspaper-width, calc(21.3 * var(--hm-cqw)));
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    transition:
        transform 0.25s ease,
        filter 0.25s ease;
}

/* Aanraken tilt het voorwerp iets op. Dat geldt voor beide soorten; alleen wat
   er verder gebeurt verschilt. */
.hm-newspaper:hover,
.hm-newspaper:focus-visible {
    transform: scale(1.04);
    filter: brightness(1.08);
}

/* Een eigen voorwerp is uit de scène zelf gesneden en hoort er ook onder de
   muis bij te blijven: oplichten maakt het losser van de foto. Vandaar een gloed
   eromheen in plaats van erin — dezelfde `drop-shadow(0 0 10px #F6F3E9)` die het
   oude thema op ál zijn props zette, de krant inbegrepen. Dat de generieke krant
   hier oplicht in plaats van gloeit is dus onze keuze, geen erfenis. */
.hm-newspaper-own:hover,
.hm-newspaper-own:focus-visible {
    filter: drop-shadow(0 0 var(--hm-cqw) rgba(246, 243, 233, 0.9));
}

.hm-newspaper-plate {
    display: block;
    width: 100%;
    height: auto;
}

/* Het logo ligt op het papier; de rotatie volgt de hoek van de krant. */
/* Het vlakke middenveld van de blanco krant; hier ligt de titel. Bijstellen als
   het krantje ooit vervangen wordt (de inzet is op-het-oog op newspaper.webp). */
.hm-newspaper-label {
    position: absolute;
    /* inset: boven rechts onder links. Hoger = eerste omlaag + derde omhoog;
       meer naar rechts = vierde omhoog + tweede omlaag (blok blijft even groot). */
    inset: 19% 8% 29% 18%;
    display: flex;
    align-items: center;
    justify-content: center;
    transform: rotate(-4deg);
}

.hm-newspaper-logo {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* Fallback als er voor deze taal geen logo is (bv. Frans/Spaans). */
.hm-newspaper-text {
    font-family: var(--hotelmodern-font-heading);
    font-size: calc(3 * var(--hm-cqw));
    line-height: 1.05;
    color: #1a1206;
    text-align: center;
    text-wrap: balance;
}

/* De inhoud: standaard buiten beeld, door de krant naar voren gehaald.

   De onderrand loopt weg in de kamer: een `mask-image` laat de laatste 9vh
   vervagen, zodat de bladen in de scènefoto erachter zakken in plaats van hard
   tegen de vensterrand te eindigen. Dat verloop is meteen het teken dát er meer
   komt — de scrollbalk hoeft dat niet in zijn eentje te doen.

   Dat masker zat tot 22-08-2026 op dit element, en dus óók op het donkere waas
   dat hier de achtergrond is. Onderin verdween daarmee niet alleen het papier
   maar ook het waas, en schoot de scènefoto in volle kleur door de onderrand
   heen — bij Garnalen Verhalen, met zijn limegroene vloer, als een groengele
   band die eruitzag als een renderfout. Het masker hoort alleen om de bladen, en
   staat nu op `.hm-room-scroll` (zie daar). Het waas blijft egaal tot de rand.

   De ruimere `padding-bottom` hoort erbij: zonder die marge zou het eind van de
   tekst zélf in het verloop vallen en lijk je nooit uitgelezen. Nu eet de
   vervaging alleen lege ruimte op zodra je beneden bent. */
.hm-room-content {
    /* Het papier en de enige regel op het vel.

       De kleur is het gemiddelde van de vezelscan hieronder, zodat het vel de
       goede tint houdt zolang dat beeld nog niet binnen is. De scan draagt zijn
       kleur zelf, dus er ligt geen tint meer onder — dat scheelt een blend-modus.

       Ze staan hier en niet op het vel zelf, omdat de sluitknop erbuiten hangt
       en wel van hetzelfde papier hoort te zijn. */
    --krant-papier: #eeece6;
    --krant-regel: rgba(17, 17, 17, 0.82);

    /* De maten van de bladenkolom staan hier en niet op `.hm-room-scroll`, omdat
       de sluitknop ze ook nodig heeft: die moet rechtsboven de tekst hangen en
       niet in de hoek van het venster, want daar hangt de bel.

       `--hm-scene-w` is de scènebreedte nagerekend in plaats van overgenomen:
       `container-type` staat op `.hm-roomview-scene` en dit is daar een buur
       van, dus `cqw` telt hier niet. Zelfde formule als daar. */
    --hm-scene-w: min(100vw, calc(100dvh * 16 / 9));
    /* Hoe ver de scène van de bovenrand van het scherm af begint. De scène is
       16:9 en staat verticaal gecentreerd, dus is het venster hoger dan dat, dan
       ligt er een zwarte band boven en begint de bel daar pas — niet bij de rand
       van het venster. Zonder deze term rekent de marge hieronder vanaf het
       venster, en dan schuift de stapel op een hoog venster over de bladen heen:
       precies het geval waarin de scène wél breed genoeg is maar het scherm te
       hoog. Is het venster breder dan 16:9, dan vult de scène de hoogte en is
       deze term vanzelf nul. */
    --hm-scene-top: calc((100dvh - var(--hm-scene-w) * 9 / 16) / 2);
    /* Waar de bladen beginnen: bovenaan de hoogte van bel + bordje vrijhouden.
       De nav beslaat ruim 10% van de scènebreedte; 12% laat er lucht omheen.

       De rem erbij is de band waar de sluitknop in hangt. Zonder die band komt
       hij ergens tegen het bordje aan: bel en bordje schalen met de scène en
       hangen op een breed venster tot over de tekstkolom heen, dus "rechtsboven
       de tekst" is dan precies waar het bordje ligt. Nu ligt de knop er netjes
       onder, met lucht aan twee kanten.

       Twee termen en niet één percentage: de stapel schaalt met de scène (bel en
       bordje in `cqw`) maar de taalwissel eronder staat in rem en blijft dus
       even hoog op elk scherm. Alleen een percentage zou daardoor op een klein
       venster te krap worden en op een groot venster te ruim. */
    --hm-room-top: calc(var(--hm-scene-top) + var(--hm-scene-w) * 0.115 + 5rem);
    /* De donkere marge naast de bladen: 4vw, of wat de 80rem-kolom overlaat als
       het venster breder is. Zo staat de sluitknop op de rand van het papier. */
    --hm-room-gutter: max(4vw, calc((100vw - 80rem) / 2));

    position: fixed;
    inset: 0;
    z-index: 40;
    background: rgba(0, 0, 0, 0.75);
    overflow: hidden;
    opacity: 0;
    visibility: hidden;
    transition:
        opacity 0.28s ease,
        visibility 0s linear 0.28s;
}

.hm-room-content.is-open {
    opacity: 1;
    visibility: visible;
    transition:
        opacity 0.28s ease,
        visibility 0s;
}

/* Het scrollen zit een niveau lager dan het verloop: een masker op een vlak dat
   zélf scrollt schuift in Chromium met de inhoud mee, waardoor de vervaging
   middenin de tekst valt in plaats van tegen de onderrand. */
.hm-room-scroll {
    /* Houder voor het kruisje: dat staat hierbinnen absoluut geplaatst, en een
       absoluut geplaatst kind van een scrollende bak schuift mee met wat erin
       staat. Zo blijft de plek exact hetzelfde als toen hij aan de modal hing —
       de bak beslaat immers de hele modal — maar loopt hij nu met de tekst mee
       naar boven. */
    position: relative;

    /* Het verloop aan de onderrand hoort hier en niet op `.hm-room-content`:
       daar lag het ook over het donkere waas, en dan schijnt de scènefoto er
       onderin doorheen (zie daar). Op deze bak raakt het alleen de bladen. */
    -webkit-mask-image: linear-gradient(
        to bottom,
        #000 0,
        #000 calc(100% - 9vh),
        transparent 100%
    );
    mask-image: linear-gradient(
        to bottom,
        #000 0,
        #000 calc(100% - 9vh),
        transparent 100%
    );

    height: 100%;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    /* Boven- en zijmarge komen van `.hm-room-content`: de sluitknop mikt op
       dezelfde twee maten. */
    padding: var(--hm-room-top) 4vw 14vh;
    overflow-y: auto;
}

/* ── Het vel ──────────────────────────────────────────────────────────────
   Eén vel papier voor de hele kamer, en niet een stapel losse blaadjes.

   Het papier, de ronding en de slagschaduw zaten tot 07-09-2026 op
   `.hm-room-block`, en elk blok droeg dus zijn eigen vel. Los van elkaar zag dat
   er verzorgd uit, maar samen las het als een reeks kaarten op een website —
   precies waar de artistieke leiding op afknapte. Op de oude site was de
   opengeslagen krant één vel met regels ertussen; dat is dit nu ook.

   De blokken houden hun klasse: `.hm-room-block` levert op /nieuws en /agenda
   nog steeds wél een eigen vel, dus het afzetten hieronder gebeurt uitsluitend
   binnen de kamer. */
.hm-room-content-inner {
    display: flex;
    flex-direction: column;
    gap: 2.25rem;
    width: 100%;
    /* Smaller dan het scherm toelaat; de breedte die overblijft is de donkere
       marge rondom het vel. */
    max-width: 80rem;
    /* Onder ruimer dan boven: de laatste regel stond bijna op de snijrand, en op
       papier leest dat als afgeknipt. Een vel heeft onderaan meer wit nodig dan
       bovenaan om als vel te lezen. */
    padding: 2.75rem clamp(1.5rem, 3vw, 3rem) 4.5rem;

    /* Geschept papier met vezels, uit een foto van een echt vel (bron: Downloads/
       newspaper.jpg, 4536x6048). Van die opname is een vlak middenstuk genomen,
       de belichting eruit gedeeld — anders tegelt de vignettering mee — en de
       tekening iets aangezet; het resultaat is 800x800 en tegelt naadloos.

       `repeat` en niet `cover`: het vel is zo hoog als de hele kamer, en één
       uitgerekte scan wordt daarop een verticale veeg in plaats van een textuur.
       Het oude `paper-background.jpg` ligt er nog voor /nieuws en /agenda. */
    background-color: var(--krant-papier);
    background-image: url(/images/hotelmodern/paper-fibre-14789b293d17400767515634ff033e55.webp?vsn=d);
    background-repeat: repeat;
    box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.45);

    color: var(--hotelmodern-fg, #2b1a10);
    font-family: var(--hotelmodern-font-body);
    line-height: 1.6;
}

/* De blokken liggen op het vel in plaats van er zelf een te zijn. Wat ze
   scheidt is de tussenruimte van de kolom plus hun eigen kop — geen randen,
   geen schaduwen, geen strepen.

   De galerij staat er apart in omdat ze uit de gedeelde sectie-module komt en
   `.hm-room-block` niet zelf draagt. */
.hm-room-content :is(.hm-room-block, .production-gallery) {
    padding: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
}

.hm-room-block > :first-child {
    margin-top: 0;
}

/* De marge die de galerij buiten de kamer van de scène scheidde, zit nu in de
   padding van het vel; zonder dit staat de bovenste foto 4rem van de rand. */
.hm-room-content .production-gallery > .image-gallery {
    margin: 0;
}

/* De speler vult het kader precies — het kader bepaalt de maat (16/10, zie
   base/video.css), de speler volgt. Hij droeg hier eerst zijn eigen
   `aspect-ratio: 16/9`, en twee verschillende verhoudingen op twee elementen die
   over elkaar heen liggen is precies hoe er onderaan iets wegvalt. */
.hm-room-block > .video-players iframe {
    /* `block` en niet de standaard `inline`: een inline iframe staat op de
       tekstregel, en die laat er onderaan een streepje wit onder staan. */
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;

    /* Zwart onder de speler. De trailer van Kamp is 418 bij 320 — bijna 4:3,
       zoals meer van het oude materiaal — en staat dus met balken links en
       rechts in een liggend kader. Een Vimeo-speler is standaard doorzichtig,
       dus zonder dit schijnt het papier door die balken heen en lijkt de film
       te smal voor zijn vel. Zwart maakt er een filmkader van. */
    background: #000;
}

/* De kop draagt de ruimte boven de eerste speler al. */
.hm-room-block > .video-players > iframe:first-of-type {
    margin-top: 0;
}

/* ── De kop van de krant ──────────────────────────────────────────────────
   De titelkop loopt over het hele vel en niet over de linkerkolom: dat is het
   verschil tussen de kop van een krant en een kop boven een artikel. In de
   grid hieronder pakt hij daarom beide kolommen.

   De regel eronder is de enige lijn op het vel. Er stonden er meer — een
   dubbele hier, een lijn tussen de kolommen, een streep boven elke sectiekop —
   maar op een vel met koppen erop doet de kop dat werk al. Deze blijft, omdat
   hij de enige is die iets scheidt wat verder niets scheidt: de titelkop van
   de krant en de pagina eronder. */
.hm-room-masthead {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    column-gap: 1.5rem;
    padding-bottom: 1.75rem;
    border-bottom: 3px solid var(--krant-regel);
}

/* Het jaartal als oortje naast de titelkop, in zeer lichte inkt: een stempel op
   het papier, geen tweede kop. */
.hm-room-edition {
    justify-self: start;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    font-family: var(--hotelmodern-font-heading);
    color: rgba(17, 17, 17, 0.22);
}

/* Het bordje boven het jaartal: zeer klein, want het benoemt alleen wát dat getal
   is. Zwart vlak met witte letter — een stempeltje op de krantenpagina, net als
   het statuslabel aan de andere kant van de kop, alleen dan zonder de rode klad.

   In rem en niet meeschalend met het jaartal: dat groeit mee met het scherm, en
   een bordje dat meegroeit wordt een tweede kop. Ruime spatiëring zoals de
   andere kleine opschriften in deze tenant (de stad op de balie, "dit seizoen"
   in de gang).

   `align-self: flex-start` zodat het vlak om de tekst sluit en niet over de hele
   breedte van het jaartal uitloopt — de kolom staat op `align-items: flex-start`,
   maar dit is expliciet omdat het vlak nu zichtbaar is en de breedte dus telt. */
.hm-room-edition-label {
    align-self: flex-start;
    margin-bottom: 0;
    padding: 0.25rem 0.45rem;
    background: #000;
    color: var(--krant-papier);
    font-size: 0.7rem;
    letter-spacing: 0.14em;
    line-height: 1.2;
    text-transform: uppercase;
}

.hm-room-edition-year {
    font-size: clamp(2.5rem, 1.4rem + 4vw, 5rem);
    line-height: 1;
}

/* Het statuslabel ligt als stempel op een rode inktklad: op een krantenpagina
   is dat het enige wat er ná het drukken bij is gekomen.

   `isolation` maakt hier het stacking-context, zodat de klad hieronder met
   `z-index: -1` achter de tekst blijft maar niet achter het papier van het vel
   zakt. Dat mag niet van een `transform` afhangen: die is vormgeving en kan weg. */
.hm-room-status {
    position: relative;
    isolation: isolate;
    justify-self: end;
    /* Een stempel breekt niet af. De kolom is 1fr en wordt smal zodra het logo in
       het midden breed is; dan viel "À l'affiche" uiteen in twee regels, en met de
       inktklad eromheen leest dat als een fout. De kolom krijgt zijn maat nu van
       het hele woord: de grid geeft de ruimte uit de logokolom, die van zichzelf
       al krimpt. */
    white-space: nowrap;
    padding: 0.65em 1.5em;
    font-size: 0.75rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--krant-papier);
}

/* De klad staat in een pseudo-element en niet als achtergrond van het label
   zelf: zo mogen de spatten buiten de tekstdoos vallen zonder de kolombreedte
   in de masthead-grid op te rekken. De negatieve inset is zo gekozen dat het
   woord binnen de dekkende kern van de klad blijft en de spatten erbuiten. */
.hm-room-status::before {
    content: "";
    position: absolute;
    inset: -1.15em -1.4em;
    z-index: -1;
    background-image: url(/assets/hotelmodern/voorstellingen/status-splash-8fb3c30f306e791a1be1f13d4d5946f9.svg?vsn=d);
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

/* justify-self, want de grid-kolom wordt op de nátuurlijke breedte van het logo
   gemeten terwijl max-width het beeld smaller maakt — anders staat de titel
   net links van het midden. */
.hm-room-content-logo {
    display: block;
    justify-self: center;
    max-width: min(100%, 26rem);
    height: auto;
}

/* Het colofon van het vel: bewerken en verwijderen, onderaan de kop en tegen de
   streep aan. Ze staan hier omdat de knoppen op de scène achter de open krant
   liggen — wie in de tekst staat die hij wil wijzigen, hoefde daarvoor eerst de
   krant te sluiten.

   Dezelfde vorm als het potlood bij de speelbeurten verderop in dit vel
   (`.hm-room-agenda-admin`): kleine gespatieerde kapitalen in lichte inkt, het
   pictogram ervoor. Op papier is beheer een aantekening in de kantlijn en geen
   knop; de knopvorm is van de scène.

   Rechts uitgelijnd en over de hele breedte van de kop: onder het statusstempel,
   aan de kant waar het jaartal níét staat — dat is een cijfer van vijf rem hoog
   en daar valt niets kleins naast te lezen. */
.hm-room-admin {
    grid-column: 1 / -1;
    justify-self: end;
    display: flex;
    gap: 1.5rem;
    padding-top: 1rem;
}

.hm-room-admin a,
.hm-room-admin button {
    /* Zelf een flexregel, om dezelfde reden als bij de speelbeurten: de afstand
       tussen pictogram en woord hoort los te staan van de afstand tussen de twee
       knopjes. */
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: rgba(17, 17, 17, 0.5);
    font-family: var(--hotelmodern-font-body);
    font-size: 0.8rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
}

.hm-room-admin a:hover,
.hm-room-admin button:hover,
.hm-room-admin a:focus-visible,
.hm-room-admin button:focus-visible {
    color: var(--hotelmodern-accent);
}

/* Zie de gelijkluidende noot bij de speelbeurten: het masker heeft een
   achtergrondkleur nodig, en op een scènepagina zet niemand die. */
.hm-room-admin [class*="icon-"] {
    width: 0.9rem;
    height: 0.9rem;
    background-color: currentColor;
    vertical-align: -0.1em;
}

.hm-room-masthead h1 {
    margin: 0;
    font-size: clamp(2rem, 1rem + 3.6vw, 4rem);
    line-height: 1.02;
    text-align: center;
    text-wrap: balance;
}

/* ── De koppen ────────────────────────────────────────────────────────────
   De sectiekoppen zijn wat ze op de oude site ook waren: de kop van de tenant,
   in de gewone maat. Ze hebben tussen 07-09-2026 en vandaag als kleine
   gespatieerde kapitalen onder een zware streep gestaan; dat was krantenmeubilair
   waar de artistieke leiding niet om gevraagd had. Wat de secties nu scheidt is
   de witruimte tussen de kolomblokken plus de kop zelf. */
.hm-room-content-inner :is(h1, h3) {
    font-family: var(--hotelmodern-font-heading);
    margin: 1.5rem 0 0.5rem;
}

/* ── Het openingsartikel ──────────────────────────────────────────────────
   De voorpagina: de flyer links, de tekst loopt er rechts omheen en onder door.
   Geen kolommen — die knipten de tekst los van het beeld.

   `flow-root` houdt de float binnen het vel: is de tekst korter dan de flyer,
   dan stak die anders onder het papier uit. */
.hm-room-lead {
    display: flow-root;
}

/* De eerste alinea leest als een lead, net als in een krant: iets groter, en
   daarmee het aanknopingspunt naast de flyer. */
.hm-room-lead :is(.body, .summary) > p:first-of-type {
    margin-bottom: 1.5rem;
    font-size: 1.2rem;
    line-height: 1.7;
}

/* De tekst loopt om een zwevende flyer heen, dus de kolom ernaast is smal — op
   een telefoon niet veel breder dan een paar woorden. Nederlands zit vol
   samenstellingen, en zonder afbreken schuift een woord als
   "voorstellingsbezoek" in zijn geheel naar de volgende regel en blijft er een
   gat van een halve regel achter.

   `hyphens: auto` kiest zijn woordenboek op de taal van het document; die staat
   in `<html lang>` en volgt de locale, dus onder /en breekt hij Engels af.

   De grenzen erbij, want de standaard van de browser breekt ook woorden van vijf
   letters af: minstens zes letters in het woord, en minstens drie aan elke kant
   van het streepje. Anders staat er "ge-" aan het eind van een regel, en dat
   leest slechter dan het gat dat we ermee oplossen. */
.hm-room-lead :is(.body, .summary) {
    -webkit-hyphens: auto;
    hyphens: auto;
    -webkit-hyphenate-limit-before: 3;
    -webkit-hyphenate-limit-after: 3;
    hyphenate-limit-chars: 6 3 3;
}

.hm-room-content-inner .summary {
    font-size: 1.1rem;
    margin-bottom: 1.2rem;
}

/* De flyer zweeft links, de tekst loopt er rechts omheen. Breedte in procenten
   met een bovengrens: op een breed vel zou een poster van 40% zo groot worden
   dat de tekst ernaast tot een kolommetje verschrompelt. */
.hm-room-flyer {
    float: left;
    width: min(38%, 17rem);
    margin: 0.4rem 3rem 1.5rem 0;
}

.hm-room-flyer :is(img, picture) {
    display: block;
    width: 100%;
    height: auto;
}

/* ── De namenlijst ────────────────────────────────────────────────────────
   De credits staan sinds 07-09-2026 onder de synopsis in plaats van in de
   zijkolom. Het is een colofon en geen artikel: korte regels, klein gezet, en
   in eigen kolommen zodat een lijst van twaalf functies geen halve meter vel
   kost.

   De opmaak moet tegen twee vormen kunnen, want de import heeft ze allebei
   achtergelaten: functie en namen als losse alinea's (`<p><strong>Spelers</strong>
   </p><p>...</p>`), en functie en namen achter elkaar in één alinea. Vandaar dat
   de functie aan de `<strong>` hangt en niet aan een eigen klasse. */
.hm-room-content .credits {
    font-size: 0.92rem;
    line-height: 1.5;
    text-align: left;
}

.hm-room-content .credits > h3 {
    margin-top: 0;
}

.hm-room-content .credits p {
    margin: 0 0 0.75rem;
}

/* Een alinea die alleen de functie bevat hoort tegen de namen eronder aan te
   staan, niet op een eigen regel te zweven. `break-after: avoid` houdt ze bij
   elkaar als de kolom net daar afbreekt. */
.hm-room-content .credits p:has(> strong:only-child) {
    margin-bottom: 0;
    break-after: avoid;
}

/* Doorlopend en niet in kolommen, op verzoek van de artistieke leiding: de lijst
   leest van boven naar beneden door, zoals in een programmaboekje. Ze heeft even
   in twee kolommen gestaan om de hoogte te beperken; dat maakte er een tabel van
   waarin je moest zoeken in welke helft een functie stond.


/* ── Smal ─────────────────────────────────────────────────────────────── */
@media (max-width: 48rem) {
    .hm-room-content-inner {
        padding: 2rem 1.5rem 3rem;
        gap: 1.75rem;
    }

    .hm-room-masthead {
        grid-template-columns: 1fr 1fr;
        row-gap: 1rem;
        justify-items: center;
        padding-bottom: 1.25rem;
    }

    .hm-room-content-logo,
    .hm-room-masthead h1 {
        order: -1;
        grid-column: 1 / -1;
    }

    /* Te smal om nog omheen te lezen: de flyer gaat boven de tekst staan. */
    .hm-room-flyer {
        float: none;
        width: 100%;
        margin: 0 0 2rem;
    }
}

/* ── De twee kolommen ─────────────────────────────────────────────────────
   Onder 64rem staan ze onder elkaar en gedragen ze zich als de losse blokken
   van vroeger: dezelfde tussenruimte, dus aan de opmaak is niet te zien dat er
   een wikkel omheen zit. */
.hm-room-col {
    display: flex;
    flex-direction: column;
    /* Ruimer dan de 1,5rem van vroeger: toen droeg elk blok een eigen vel met
       zijn eigen marge eromheen, nu liggen de secties op hetzelfde papier en is
       deze tussenruimte het enige wat ze scheidt. */
    gap: 3rem;
    /* Een grid-item is standaard minstens zo breed als zijn smalste inhoud. Met
       `min-width: 0` klopt 2:1 op de pixel in plaats van dat een brede foto of
       een lang woord de kolom oprekt; het vangnet ernaast breekt zo'n woord dan
       liever af dan het over de papierrand te laten steken. */
    min-width: 0;
    overflow-wrap: break-word;
}

/* Vanaf 64rem liggen de voorpagina en de zijkolom naast elkaar: het verhaal met
   de galerij en de namenlijst krijgt twee derde, de recensies en de films een
   derde. Die verhouding komt uit de inhoud zelf — het zijn korte regels, en over
   de volle breedte van het vel werd dat een blad met meer papier dan letters.

   Pas op 64rem en niet eerder: bij 48rem werd de galerij in de linkerkolom één
   kolom breed en bleef er van het album een sliert over.

   `:has`: ligt er niets in de zijkolom, dan is er geen tweede element en blijft
   het vel over de volle breedte staan in plaats van een derde leeg te laten.

   Tussen de kolommen staat wit en geen lijn: op één vel met koppen erop is een
   kolomlijn een streep te veel. `align-items: start` zodat een korte zijkolom
   niet wordt uitgerekt — er hangt niets meer aan wat tot onderaan door moet. */
@media (min-width: 64rem) {
    .hm-room-content-inner:has(> .hm-room-col-aside) {
        display: grid;
        grid-template-columns: 2fr 1fr;
        column-gap: 3.5rem;
        row-gap: 2.5rem;
        align-items: start;
    }
}

/* ── Het sluitstuk ────────────────────────────────────────────────────────

   Het beeldmateriaal onder allebei de kolommen door, net als de titelkop
   erboven over de volle breedte loopt: links de foto's, rechts de films.

   Twee gelijke helften en niet 2:1 zoals de kolommen erboven — dit is geen
   verhaal met een marge ernaast maar twee dingen van gelijk gewicht. Een halve
   breedte is ook precies de maat die een film nodig heeft: in de zijkolom was
   hij 23.5rem en dus een postzegel, over de volle breedte werd de kamer een
   filmzaal.

   Staat er maar één van de twee — een voorstelling met foto's maar zonder
   film, of andersom — dan houdt die de linkerhelft en blijft de rechter leeg
   papier. Een film over het hele vel is een filmzaal, een album over het hele
   vel een fotoboek met een voorstelling ernaast.

   De band gaat al vanaf 48rem in tweeën, eerder dan de kolommen erboven (die
   wachten tot 64rem). Dat mag hier: een halve breedte van 48rem is nog altijd
   ruimer dan de zijkolom waar de films vandaan komen, en foto's naast film is
   een eenvoudiger paar dan een lopend verhaal naast een zijkolom.

   Onder 48rem is er geen grid meer en stapelt alles vanzelf. */
@media (min-width: 48rem) {
    .hm-room-closing {
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: 3.5rem;
        row-gap: 2.5rem;
        align-items: start;
    }
}

/* De kop van de galerij staat platformbreed op onzichtbaar (base/gallery.css:
   `opacity: 0; height: 0`), want op de andere tenants staat er al een kop
   boven. Hier is hij de tegenhanger van "Video's" ernaast, en twee helften
   waarvan er één een kop draagt staan scheef. */
.hm-room-closing .production-gallery h3 {
    opacity: 1;
    height: auto;
    /* Geen marge bovenaan: de kop van de films ernaast is het eerste kind van
       zijn blok en krijgt die van `.hm-room-block > :first-child` afgehaald. Met
       een marge hier stonden de twee koppen 1.5rem uit elkaar. */
    margin: 0 0 0.5rem;
}

/* De galerij stond in de tekstkolom en rekende met kolommen van 15rem; in een
   halve breedte van het vel (zo'n 36rem) passen er dan twee. Dat is de maat
   die het album hier hoort te hebben — drie zou van elke foto een postzegel
   maken naast een film van 36rem. */
.hm-room-closing .gallery-grid.masonry {
    grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
}

/* Het album ligt in de linkerkolom en houdt daarvan, na de rand van het vel,
   nog zo'n 33rem over. De gedeelde masonry rekent met kolommen van 20rem, en
   vlak boven de omslag past er dan nog maar één in — een album van één foto
   breed. Met 15rem blijven het er twee, van 1024px tot het breedste scherm. */
.hm-room-col-main .gallery-grid.masonry {
    grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
}

/* Een lang album krijgt een kolom erbij. Kamp heeft er 22, en in twee kolommen
   is dat een trap van elf treden waar je langs moet: het album wordt dan het
   zwaarste deel van de kamer terwijl het naschrift is. Vanaf twaalf foto's
   worden ze kleiner en komen ze met z'n drieën naast elkaar.

   `:has(> :nth-child(12))` = er ís een twaalfde foto. Wil je de grens
   verleggen, dan is dat het enige getal dat mee hoeft.

   13rem en niet 15: bij 15rem past de derde kolom net níét (drie van 15rem plus
   twee tussenruimtes is 3px meer dan er ligt). Smaller wordt het scherm, dan
   valt hij vanzelf terug op twee en daarna op één. */
.hm-room-col-main .gallery-grid.masonry:has(> :nth-child(12)) {
    grid-template-columns: repeat(auto-fill, minmax(min(13rem, 100%), 1fr));
}

/* Rechtsboven de tekst, niet in de hoek van het venster: die hoek is van de bel,
   op elke pagina. Zo stonden ze elkaar in de weg — de bel hangt in de scène en
   schuift dus met de 16:9-uitsnede mee, de knop hing aan het venster, en hoe
   vierkanter het scherm hoe dichter ze op elkaar kwamen.

   Nu ligt de knop op de rechterrand van de bladen, in de donkere band net
   erboven. `fixed` blijft: hij hoort niet mee te scrollen met wat eronder
   langsgaat. */
.hm-room-close {
    /* `absolute` binnen de scrollbak: die is de houder (zie daar), dus de maten
       hieronder meten tegen dezelfde randen als toen de knop nog aan het venster
       hing — maar hij schuift nu mee met de bladen.

       Niet `fixed`: dat hangt aan het venster, en zodra een voorouder een
       transform draagt (een pagina-overgang, een extensie) wordt díé de houder
       en gaat zo'n knop juist meescrollen met het document terwijl de rest staat.
       Precies andersom dus als wat je wilt. */
    position: absolute;
    /* Boven de bladen. Zonder dit was de knop wél te zien maar niet aan te
       klikken: de scrollbak draagt een `mask-image` voor het verloop onderaan, en
       dat maakt er een eigen stapelcontext van. De knop is doorzichtig gedekt,
       niet zichtbaar gedekt — vandaar dat het eruitzag alsof er niets aan de hand
       was. */
    z-index: 1;
    /* 3rem = de knop (2,5rem) plus een streepje lucht tot het bovenste vel. */
    top: calc(var(--hm-room-top) - 3rem);
    /* Voorbij de rand van het papier, de donkere marge in: op de rand zelf kleeft
       hij aan het vel en leest hij als iets van de tekst. Op een smal venster is
       die marge er niet, dan houdt de 1rem hem van de schermrand af. */
    right: max(1rem, calc(var(--hm-room-gutter) - 2.75rem));

    width: 2.5rem;
    height: 2.5rem;
    border: 0;
    border-radius: 50%;
    background: var(--krant-papier, #f4f0e6);
    color: var(--hotelmodern-fg, #2b1a10);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
}

body.body-no-scroll {
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .hm-newspaper,
    .hm-room-content,
    .hm-room-content.is-open {
        transition-duration: 0s;
    }
}

/* ── De vleugel ────────────────────────────────────────────────────────────
   Bij Garnalen Verhalen zit er een garnaal achter de piano. Hoveren laat hem
   spelen: hij wiegt, er komen nootjes uit de toetsen en — zodra de browser het
   toestaat — klinkt er een nocturne.

   Waarom die reparatieplek: om de garnaal te laten bewegen moet hij een eigen
   laag zijn, en dan blijft er een garnaalvormig gat in de foto achter. `plek`
   is een stukje van diezelfde foto waarin dat gat is dichtgemaakt; de rand is
   naar doorzichtig toe verlopen, zodat je nergens een naadje ziet liggen. */
.hm-piano {
    position: absolute;
    inset: 0;
    /* De laag beslaat de hele scène maar vangt niets af: alleen het
       hovervlak hieronder luistert. Anders lag hij over de krant heen. */
    pointer-events: none;
    line-height: 0;
}

.hm-piano-plek,
.hm-piano-figuur {
    position: absolute;
    display: block;
}

.hm-piano-plek {
    left: var(--hm-piano-plek-left, 0%);
    top: var(--hm-piano-plek-top, 0%);
    width: var(--hm-piano-plek-width, 20%);
}

/* Het draaipunt zit in het onderlijf: daar rust de figuur, dus daar hoort de
   wieging omheen. Boven het draaipunt hangen, geeft een bungelend poppetje. */
.hm-piano-figuur {
    left: var(--hm-piano-figuur-left, 0%);
    top: var(--hm-piano-figuur-top, 0%);
    width: var(--hm-piano-figuur-width, 14%);
    transform-origin: 34% 82%;
    will-change: transform;
}

.hm-piano-speelt .hm-piano-figuur {
    animation: hm-piano-wieg 3.4s ease-in-out infinite;
}

@keyframes hm-piano-wieg {
    0%,
    100% {
        transform: rotate(-0.9deg)
            translate(calc(-0.25 * var(--hm-cqw)), calc(0.05 * var(--hm-cqw)));
    }

    50% {
        transform: rotate(1.1deg)
            translate(calc(0.25 * var(--hm-cqw)), calc(-0.05 * var(--hm-cqw)));
    }
}

.hm-piano-toets {
    position: absolute;
    left: var(--hm-piano-hotspot-left, 4%);
    top: var(--hm-piano-hotspot-top, 64%);
    width: var(--hm-piano-hotspot-width, 28%);
    height: var(--hm-piano-hotspot-height, 34%);
    padding: 0;
    border: 0;
    background: transparent;
    pointer-events: auto;
    cursor: pointer;
}

.hm-piano-toets:focus-visible {
    outline: 0.15rem dashed #ffffff;
    outline-offset: -0.15rem;
}

.hm-piano-noten {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

/* Inkt met een lichte gloed. `mix-blend-mode: difference` — zoals bij HOME —
   werkt hier niet: op het felgroen van de vloer wordt een noot dan een vale
   donkere vlek in plaats van een noot. De gloed vangt de momenten op dat een
   nootje over het donkere hout van de vleugel drijft. */
.hm-piano-noot {
    position: absolute;
    font-size: calc(4.6 * var(--hm-cqw));
    line-height: 1;
    color: #14100a;
    text-shadow:
        0 0 calc(0.35 * var(--hm-cqw)) rgba(255, 255, 255, 0.95),
        0 0 calc(0.9 * var(--hm-cqw)) rgba(255, 255, 255, 0.7);
    will-change: transform, opacity;
    animation: hm-piano-zweef var(--duur) cubic-bezier(0.25, 0.5, 0.5, 1)
        forwards;
}

@keyframes hm-piano-zweef {
    0% {
        opacity: 0;
        transform: translate(0, 0) rotate(0deg) scale(0.5);
    }

    12% {
        opacity: 0.95;
    }

    100% {
        opacity: 0;
        transform: translate(var(--dx), var(--dy)) rotate(var(--draai))
            scale(1.15);
    }
}

/* Wie beweging heeft afgezet, krijgt de muziek wel en het gewieg niet. De
   nootjes laat de hook dan weg. */
@media (prefers-reduced-motion: reduce) {
    .hm-piano-speelt .hm-piano-figuur {
        animation: none;
    }
}

/* ── Portret: door de scène schuiven ─────────────────────────────── */

/* De scène is 16:9 en dus staand onleesbaar: op een telefoon van 375 breed werd
   het een strook van 211 hoog met zwart erboven en eronder, en de menukaart op
   tafel bij Garnalen Verhalen — de ingang naar de inhoud — was 36 pixels.

   Bijsnijden mag niet. Bij tien voorstellingen is die ingang een voorwerp dat
   uit de scènefoto zelf is geknipt, op een percentage dat per voorstelling in
   het CMS staat: van 12,8% bij Heden Stad tot 67,3% bij Vliegboot Moederschip.
   Een vaste uitsnede laat op een telefoon nog geen derde van de breedte zien en
   duwt de eerste twee dus met knop en al buiten beeld. Datzelfde geldt voor de
   piano-laag, die uit de foto gesneden is en op zijn eigen plek ligt.

   Dus: de scène houdt zijn verhouding, wordt zo hoog als het scherm, en je
   schuift er horizontaal doorheen — zoals de bioscoop en de hoorspelkamer al
   doen. Alles blijft geregistreerd op de foto en er gaat niets stuk. Dat je
   moet zoeken naar de ingang lost `HmScenePan` op: die begint niet links maar
   bij het voorwerp. */
@media (orientation: portrait) {
    .hm-roomview {
        justify-content: flex-start;
        align-items: stretch;
        overflow-x: auto;
        overflow-y: hidden;
        overscroll-behavior-x: contain;
    }

    .hm-roomview-scene {
        flex: 0 0 auto;
        height: 100dvh;
        width: calc(100dvh * 16 / 9);
        container-type: normal;
        --hm-cqw: calc(100dvh * 16 / 9 / 100);
    }

    /* De hoekstapel verdwijnt staand helemaal: de kopregel in de layout
       (scene.css, `.hm-topbar`) draagt hier alles wat erin stond. De bel en de
       taalwissel zet die query zelf al uit; het bordje terug gaat hier uit, want
       "Voorstellingen" in de balk brengt je naar precies dezelfde lijst.

       Hier stond eerder de voorloper van die balk: dezelfde drie voorwerpen die
       zich tot een donkere kopregel vouwden zodra de kamer openging, "want props
       over een tekst staan op niets en een balk heeft grond". Dat bleek voor de
       hele tenant te gelden en niet alleen voor deze kamer met de krant open, dus
       is het verhuisd naar scene.css. Wat hier overblijft is het gat dat de balk
       vrij moet houden. */
    .hm-roomview-nav {
        display: none;
    }

    .hm-roomview-admin {
        position: fixed;
        right: 0.6rem;
        bottom: 0.6rem;
    }

    /* Wat er vrijgehouden moet worden is nu één balk in plaats van een hele
       stapel: de kopregel plus de 3rem-band waar het kruisje in ligt, plus lucht.
       Was 14rem toen de bel, het bordje en de taalwissel hier nog onder elkaar
       hingen.

       Krap zou 6,75rem zijn; dit is 2rem ruimer, op het oog van de user. Een vel
       dat meteen onder de balk begint leest als weggeschoven in plaats van als
       neergelegd — de lucht eromheen is wat het een vel maakt.

       In rem en niet in de scène-eenheid: `--hm-room-top` rekent normaal tegen de
       scènebreedte, en die is staand de vensterbreedte — op een telefoon een
       tiende van 420px en dus veel te weinig. */
    .hm-room-content {
        --hm-room-top: calc(var(--hm-topbar-h) + 5rem);
    }
}

/* ── De speellijst in de kamer ───────────────────────────────────── */

/* Zelfde vorm als de balie-agenda: de weekdag en het dagnummer op één regel, de
   tijd ernaast in rood, waar het speelt eronder, en de kaartjes daar weer onder.
   Het is dezelfde speelbeurt op twee plekken in de site, dus hij hoort er twee
   keer hetzelfde uit te zien. Maten en kleuren komen uit agenda.css; wat hier
   afwijkt is dat het affiche en de titel ontbreken — je bent al in de kamer van
   déze voorstelling, die hoeft zichzelf niet nog eens aan te kondigen.

   Gestapeld en niet in vier kolommen naast elkaar. Die vier kolommen stonden er
   zolang de lijst onder het artikel lag en dus twee derde van het vel breed was;
   sinds 07-09-2026 staat hij in de zijkolom, en daar is 23rem beschikbaar. Dat
   is de breedte waarvoor de smalle variant hieronder al bestond — die geldt nu
   altijd, want de lijst komt nergens anders meer voor. */
.hm-room-agenda {
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-room-agenda > li {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas:
        "datum tijd"
        "plaats plaats"
        "kaartjes kaartjes";
    column-gap: clamp(0.6rem, 1.2vw, 1.2rem);
    row-gap: 0.2rem;
    align-items: start;
    padding: 0.7rem 0;
    border-bottom: 1px solid rgba(28, 20, 8, 0.15);
}

.hm-room-agenda > li:last-child {
    border-bottom: 0;
}

/* De datum draagt de regel, dus groot — maar in gedempte inkt, zodat hij de
   plaatsnaam niet beconcurreert. Precies zoals op de balie. */
.hm-room-agenda-day {
    grid-area: datum;
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    color: rgba(0, 0, 0, 0.6);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

/* De maand staat op de balie in een kop boven de groep; hier is de lijst te kort
   voor groepen, dus hij staat op de regel zelf. */
.hm-room-agenda-weekday,
.hm-room-agenda-daynum,
.hm-room-agenda-month {
    font-size: 1.05rem;
    letter-spacing: 0.06em;
    line-height: 1.2;
}

.hm-room-agenda-hour {
    grid-area: tijd;
    justify-self: end;
    color: var(--hotelmodern-accent);
    font-size: 0.95rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.hm-room-agenda-where {
    grid-area: plaats;
}

/* Stad in kapitaal-achtige spatiëring, zaal eronder — de rangschikking van de
   balie. Het scheidingsteken dat hier eerst stond kan daarmee weg. */
.hm-room-agenda-where > span:first-child {
    display: block;
    font-size: 1rem;
    letter-spacing: 0.12em;
}

.hm-room-agenda-where > a,
.hm-room-agenda-where > span:nth-child(2) {
    display: block;
    margin-top: 0.1rem;
    font-size: 0.95rem;
    color: var(--hotelmodern-accent);
}

.hm-room-agenda-note {
    display: block;
    margin-top: 0.1rem;
    color: rgba(0, 0, 0, 0.6);
    font-size: 0.85rem;
    line-height: 1.35;
}

/* Rechts uitgelijnd, dus recht onder de aanvangstijd. De rij loopt links naar
   rechts van dag naar tijd, en de kaartjes horen bij die tijd — links onder de
   plaatsnaam kwamen ze in de kolom van iets anders te staan. */
.hm-room-agenda-tickets,
.hm-room-agenda-soldout {
    grid-area: kaartjes;
    justify-self: end;
    padding-top: 0.2rem;
    white-space: nowrap;
}

.hm-room-agenda-tickets {
    color: var(--hotelmodern-accent);
}

.hm-room-agenda-soldout {
    color: rgba(0, 0, 0, 0.55);
}

/* Ingelogd krijgt de regel een vierde rij voor het potlood. Alleen dan: een
   bezoeker ziet de speellijst onveranderd, en het potlood valt zo nooit over de
   kaartjeslink heen — die deelt anders zijn rij. */
.hm-room-agenda > li.is-admin {
    grid-template-areas:
        "datum tijd"
        "plaats plaats"
        "kaartjes kaartjes"
        "beheer beheer";
}

.hm-room-agenda-admin {
    grid-area: beheer;
    justify-self: start;
    display: flex;
    gap: 1.5rem;
    padding-top: 0.3rem;
}

.hm-room-agenda-admin a,
.hm-room-agenda-admin button {
    /* Zelf een flexregel: dan telt de witruimte tussen het pictogram en het
       woord in de opmaak niet mee, en staat de afstand ertussen (0.35rem) los
       van de afstand tussen de twee knopjes (1.5rem). Anders lijken ze even ver
       en hoort het pictogram net zo goed bij het woord ernaast. */
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: rgba(0, 0, 0, 0.5);
    font-size: 0.8rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
}

.hm-room-agenda-admin a:hover,
.hm-room-agenda-admin button:hover,
.hm-room-agenda-admin a:focus-visible,
.hm-room-agenda-admin button:focus-visible {
    color: var(--hotelmodern-accent);
}

/* Zie de gelijkluidende noot in agenda.css: het masker heeft een
   achtergrondkleur nodig, en op een scènepagina zet niemand die. */
.hm-room-agenda-admin [class*="icon-"] {
    width: 0.9rem;
    height: 0.9rem;
    background-color: currentColor;
    vertical-align: -0.1em;
}

/* ── Beheer onder de speellijst ──────────────────────────────────── */

/* Speelbeurt toevoegen staat alleen voor een beheerder onder de lijst. Dezelfde
   knop als "bekijk de hele tour" erboven — die vorm komt uit components/button.css
   — maar met een gestippelde rand: dit is beheer en geen bezoekersinhoud, en dat
   hoort te zien te zijn zonder dat er een tweede knopvorm bij komt. */
.hm-room-agenda-new .button {
    border-style: dashed;
}

/* Waar de lijst vandaan komt als TOP hem vult. Alleen voor een beheerder, dus
   een terzijde en geen mededeling die om aandacht vraagt. */
.hm-room-agenda-source {
    margin-top: 0.6rem;
    max-width: 34rem;
    font-size: 0.85rem;
    line-height: 1.4;
    opacity: 0.7;
}

/* ── Geen vervaging onder de ingeklapte recensies ────────────────── */

/* `base/press-item.css` legt onder de ingeklapte lijst een verloop dat naar
   effen wit toe loopt. Dat is gemaakt voor een witte kaart; hier ligt het blok
   op een papiertextuur, dus dekte die band de textuur af en stond er een lichte
   rechthoek middenin het vel — bij Garnalen Verhalen, met de groengele scène
   erachter, viel dat het meest op. Het las als een renderfout, niet als "er komt
   meer". Dat werk doet de knop eronder nu zelf. */
.hm-room-block .press.side-card .press-items-container::after {
    content: none;
}


/* ── components/afterroom.css ── */
/* Hotel Modern — de afterpagina als kamer met het licht aan.
   ==========================================================================

   Opbouw geleend van het nieuwsvel (components/news.css): doorlopende tekst
   scrollt niet lekker over een maquette, dus ligt ze op een vel papier in de
   zwarte doos. Wat hier bij komt is de plaat van de eigen voorstelling, en het
   licht dat erover opkomt.

   De maten staan in rem/%/vw; alleen de haarlijnen zijn in rem uitgedrukt
   (0.0625rem = 1px bij de standaard wortelmaat). */

/* ── De doos en de plaat ──────────────────────────────────────────── */

.hm-stage.hm-afterroom {
    background-color: #000;
}

/* De scènefoto als eigen laag en niet als achtergrond van de doos: alleen zo
   kan het licht er als filter overheen zonder het vel papier en de rode strook
   mee te doven. `cover` volgt de lijn van de tenant — liever een uitsnede dan
   zwarte banden om de maquette heen. */
.hm-afterroom-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

/* Een scrim over de plaat, want hier ligt leesbare tekst overheen. Zwaarder en
   vlakker dan bij de gang van /nieuws: daar dooft één plafondlamp bovenin, hier
   kan de hele plaat fel zijn. Garnalen Verhalen is de proef op de som — een
   limoengroen tafelblad met garnalen op ware grootte — en op 0,35 in het midden
   vocht die foto met het vel om de aandacht.

   Niet nóg donkerder: de plaat is de reden dat deze pagina een kamer is, en
   onder ongeveer een halve stop wordt het een zwart vlak met een vermoeden van
   een scène erin. */
.hm-afterroom::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.62) 0%,
        rgba(0, 0, 0, 0.5) 35%,
        rgba(0, 0, 0, 0.5) 65%,
        rgba(0, 0, 0, 0.66) 100%
    );
    pointer-events: none;
}

/* ── Het zaallicht ───────────────────────────────────────────────────

   Het enige wat op deze pagina uit zichzelf beweegt. Een voorstelling eindigt
   met het licht dat opkomt; deze pagina ís dat moment, dus begint de set donker
   en klaart hij één keer op. Filter op de plaat en niet op de doos, zodat de
   tekst erbuiten valt en meteen leesbaar is.

   `backwards` zet de donkere begintoestand al vóór de vertraging: zonder dat
   flitst de plaat eerst op volle sterkte voorbij. */
.hm-afterroom-bg {
    animation: hm-zaallicht 1.6s cubic-bezier(0.33, 0, 0.2, 1) 0.1s backwards;
}

@keyframes hm-zaallicht {
    from {
        filter: brightness(0.18) saturate(0.55);
    }

    to {
        filter: brightness(1) saturate(1);
    }
}

/* ── Het vel ─────────────────────────────────────────────────────── */

.hm-afterroom-room {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100%;
    margin: 0 auto;
}

.hm-afterroom-scroll {
    height: 100%;
    overflow-y: auto;
    /* Onderaan meer lucht dan boven: het vel moet vrij van de vensterrand
       kunnen eindigen, anders lijkt de tekst afgesneden. Zelfde maat als het
       nieuwsvel. */
    padding: clamp(2rem, 6vh, 4rem) clamp(1rem, 2.5vw, 3rem) clamp(4rem, 10vh, 8rem);
    box-sizing: border-box;
}

.hm-afterroom-sheet {
    /* De maat van het platform (`.wrap`, base/base.css). Het nieuwsvel is
       46rem en dit vel stond op 52, want er staat meer op dan lopende tekst —
       maar met films naast elkaar en een fotoraster van vier is dat te krap.
       Dezelfde tachtig rem als elke andere pagina, zodat het vel niet een
       eigen maat gaat voeren. */
    max-width: 80rem;
    margin: 0 auto;
    padding: clamp(1.5rem, 4vw, 3.5rem);
    line-height: 1.6;
    color: var(--hotelmodern-fg, #111);

    /* Hetzelfde papier als het nieuwsvel en de krant op de voorstellingspagina:
       het is dezelfde soort inhoud, dus hetzelfde materiaal. */
    background: var(--hotelmodern-paper, #f4f0e6);
    background-image: url(/images/hotelmodern/paper-background-c8e2d61dc60d49c9943493f21bc5333c.jpg?vsn=d);
    background-size: cover;
    background-position: center;
    box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.45);
}

/* ── De kop ──────────────────────────────────────────────────────── */

.hm-afterroom-head {
    position: relative;
    margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
}

.hm-afterroom-title {
    margin: 0;
    font-size: clamp(1.75rem, 1.1rem + 3vw, 3rem);
    line-height: 1.1;
    font-weight: 700;
}

/* De strook. Handgescheurd papier in het accentrood: in deze tenant betekent
   dat rood "hier ben je", en papier is waar dit gezelschap zijn hele wereld van
   bouwt. De scheur zit in een clip-path en niet in een plaatje, zodat hij met
   het woord meegroeit en in elke taal even rafelig is — "Na afloop", "After the
   show" en straks "Après le spectacle" zijn alle drie even lang niet.

   De lichte kanteling is één graad: genoeg om te lezen als iets dat met de hand
   is neergelegd, te weinig om als een truc op te vallen. */
.hm-afterroom-band {
    display: inline-block;
    margin: 0.75rem 0 0;
    padding: 0.45rem 1.5rem 0.55rem;
    background: var(--hotelmodern-accent, #871d0f);
    color: #fff;
    transform: rotate(-1deg);
    transform-origin: left center;
    clip-path: polygon(
        0.4% 8%, 8% 0, 22% 9%, 35% 2%, 49% 10%, 63% 1%, 77% 9%, 90% 2%, 100% 10%,
        99.5% 90%, 91% 100%, 78% 91%, 64% 99%, 50% 90%, 36% 98%, 23% 90%, 9% 99%, 0 91%
    );
}

.hm-afterroom-band span {
    font-size: clamp(1rem, 0.85rem + 0.7vw, 1.375rem);
    letter-spacing: 0.02em;
}

/* ── De papierbui ────────────────────────────────────────────────────

   Een voorstelling eindigt en het papier komt naar beneden. Eerst een echte
   bui over de volle breedte, een seconde of drie; daarna valt er nog af en toe
   eentje na.

   De eerste versie had er zes, die vlak onder de titel bleven liggen. Dat was
   bedoeld als "geen behang" — een snipper die het beeld verlaat vraagt om een
   volgende — maar zes stukjes op een handbreedte lezen als een sierrandje, en
   dat is precies het zuinige dat eruit zag als een fout. De oplossing is niet
   minder maar méér, en dan ophouden: een bui is iets dat overgaat.

   De maten per snipper worden in de opmaak uitgerekend (`hm_snippers/0`);
   hier staat alleen wat ze allemaal delen. */
.hm-afterroom-snippers {
    /* Absoluut op de scène en niet `fixed`: `.hm-stage` is zelf al een vast
       venster met `overflow: hidden`, dus dit dekt precies het beeld — en het
       blijft werken als er ooit een transform op de scène komt, waar `fixed`
       stilletjes op zou stukgaan. */
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    /* Boven het vel, onder de bel en de taalbordjes (die staan op 1000). */
    z-index: 900;
}

.hm-snipper {
    position: absolute;
    /* Boven de bovenrand beginnen, zodat niemand ze ziet verschijnen. */
    top: -3rem;
    opacity: 0;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
    animation-delay: var(--wacht);
    animation-duration: var(--tijd);
}

.hm-snipper-bui {
    animation-name: hm-snipper-val;
}

/* De naval valt op dezelfde manier, alleen later en één keer. Geen lus: een
   snipper die op een vast tempo terugkomt wordt na een minuut alsnog behang.
   De tussenpozen groeien (zie `hm_naval_wacht/1` in de opmaak), dus het dooft
   uit vanzelf. */
.hm-snipper-na {
    animation-name: hm-snipper-val;
}

@keyframes hm-snipper-val {
    0% {
        transform: translate(0, 0) rotate(0deg);
        opacity: 0;
    }

    4% {
        opacity: 1;
    }

    90% {
        opacity: 1;
    }

    100% {
        transform: translate(var(--zij), 105vh) rotate(var(--draai));
        opacity: 0;
    }
}


/* ── De inhoud op het vel ────────────────────────────────────────────

   De blokken zelf komen uit base/after-page.css en zijn tenant-neutraal. Hier
   staat alleen wat er op dít papier anders moet: de scheidslijnen zijn daar
   zwart-op-wit gedacht en vallen op perkament te hard uit. */

.hm-afterroom :is(.after-page-intro, .after-page-extra, .after-page-video, .after-page-gallery, .after-page-dates, .after-page-guestbook) {
    margin-bottom: clamp(1.75rem, 4vw, 2.5rem);
}

.hm-afterroom :is(.after-page-video, .after-page-gallery, .after-page-dates) h3 {
    font-size: clamp(1.125rem, 1rem + 0.5vw, 1.5rem);
}

.hm-afterroom .after-page-guestbook h3 {
    font-size: clamp(1.375rem, 1.1rem + 0.9vw, 1.875rem);
}

.hm-afterroom :is(table.speeldata tr:not(:last-child) td, .guestbook-entry, .guestbook-entry:first-child) {
    border-color: rgba(43, 26, 16, 0.22);
}

.hm-afterroom .after-page-footer {
    border-top-color: rgba(43, 26, 16, 0.22);
}

/* Het vlak van het gastenboek is op perkament een tint dieper papier, niet het
   grijs van base/after-page.css: grijs op perkament leest als vuil. */
.hm-afterroom .after-page-guestbook {
    background: rgba(43, 26, 16, 0.06);
    box-shadow: inset 0 0 0 0.0625rem rgba(43, 26, 16, 0.12);
}

/* Het formulier staat op papier, niet op wit: een wit invoerveld op perkament
   is een gat in het vel. */
.hm-afterroom .guestbook-form :is(input[type="text"], textarea) {
    background-color: rgba(255, 255, 255, 0.55);
    border-color: rgba(43, 26, 16, 0.3);
}

.hm-afterroom .guestbook-form :is(input[type="text"], textarea):focus {
    background-color: rgba(255, 255, 255, 0.85);
    border-color: var(--hotelmodern-accent, #871d0f);
    outline: 0.125rem solid var(--hotelmodern-accent, #871d0f);
    outline-offset: 0.125rem;
}

.hm-afterroom .guestbook-thanks {
    background-color: rgba(135, 29, 15, 0.08);
    border-left: 0.1875rem solid var(--hotelmodern-accent, #871d0f);
    border-radius: 0;
}

.hm-afterroom .after-page-footer .back-link {
    color: var(--hotelmodern-accent, #871d0f);
}

/* ── De hoek met de bel ──────────────────────────────────────────────

   Zelfde uitwijking als op het nieuwsvel: het vel houdt de hoek vrij waar de
   bel en de taalbordjes hangen, anders ligt de bel op de kop van de pagina. */
.hm-stage.hm-afterroom {
    --hm-bell-size: calc(var(--hotelmodern-scene-rect) * 0.05);
    --hm-bell-inset: calc(var(--hotelmodern-scene-rect) * 0.016);
}

/* Het bordje hangt onder de bel, op dezelfde maat als in de agenda, het boek,
   de perskamer en de contactkamer: de bel is `--hm-bell-size` hoog plus zijn
   onderschrift (×1,33), en daar komt de inzet twee keer bij. Zonder deze regel
   heeft `.hm-scene-langs` geen eigen plek — scene.css geeft hem alleen zijn
   uiterlijk — en zakt hij naar het midden van de scène. */
.hm-afterroom-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    z-index: 1000;
    /* Deze twee regels ontbraken, en daardoor raakten de bordjes elkaar. De
       tussenruimte staat in scene.css (`.hm-scene-langs.hm-langs-plaque`,
       1,1rem), maar `gap` doet niets op een blok — en zonder `display: flex`
       was dit er een. De andere kamers (gang, vitrine, kijkkast) zetten hem
       wél; hier was hij vergeten. */
    display: flex;
    line-height: 1;
}

/* Het nieuwsvel knijpt hier zijn rechterkant in om de hoek vrij te houden. Dat
   doen we niet: dit vel staat gecentreerd, en een eenzijdige inzet trekt het
   zichtbaar uit het midden. De bel raakt het vel pas op een smal scherm, en
   daar wijkt de kop ervoor (zie onderaan). */

/* ── Stilstand op verzoek ────────────────────────────────────────────

   Wie beweging heeft uitgezet krijgt het eindbeeld: de set in het licht en een
   handvol snippers waar ze zouden landen. Niet "geen snippers" — het
   feestelijke hoort bij de pagina, alleen de val niet. */
@media (prefers-reduced-motion: reduce) {
    .hm-afterroom-bg {
        animation: none;
    }

    /* Zestig stilstaande snippers over de hele pagina zijn geen confetti maar
       rommel. Er blijven er acht liggen, bovenin, ongeveer waar ze bij een val
       terecht zouden komen — genoeg voor de feestelijke noot, die verder al bij
       de rode strook zit. De rest komt niet in beeld. */
    .hm-snipper {
        animation: none;
        opacity: 0;
    }

    .hm-snipper-bui:nth-child(-n + 8) {
        opacity: 1;
        transform: translate(var(--zij), 9rem) rotate(var(--draai));
    }
}

/* ── Staand scherm ───────────────────────────────────────────────────

   Dit is de echte gebruikssituatie: iemand staat in de foyer met een telefoon in
   één hand. De tenant schakelt daar niet op breedte maar op beeldverhouding
   (`max-aspect-ratio: 6/5`, scene.css), en die grens hoort deze kamer aan te
   houden — anders staat de kopregel er al wel en wijkt dit vel er niet voor.

   Over de bel en de taalbordjes hoeft hier niets: scene.css verbergt die op elke
   scène zodra de kopregel het overneemt (`.hm-stage .hm-bell` e.a.). Wat wél
   moet, is de hoogte van die balk van de bovenrand af halen, net als het
   nieuwsbord en de agenda doen. */
@media (max-aspect-ratio: 6/5) {
    /* Op een telefoon de helft van de bui. Het beeld is daar veel kleiner, dus
       honderdvijftig snippers zien er even vol uit als driehonderd op een
       laptop — en het scheelt datzelfde toestel de helft van het tekenwerk,
       precies op het apparaat waar deze pagina in de praktijk op wordt
       geopend. */
    .hm-snipper-bui:nth-of-type(2n) {
        display: none;
    }

    /* Longhand en geen shorthand: de regel hierboven zet `padding` in één keer,
       en een shorthand hier zou de zijkanten stilzwijgend meenemen. */
    .hm-afterroom-scroll {
        padding-top: calc(var(--hm-topbar-h) + 1rem);
        /* Het vel loopt tot de randen: een zwarte marge naast een vel van 20rem
           kost leesbreedte die er niet is. */
        padding-left: 0;
        padding-right: 0;
    }

    .hm-afterroom-sheet {
        padding: 1.25rem 1rem 2rem;
    }
}


/* ── components/cinema.css ── */
/* Hotel Modern — de bioscoop (/media/bioscoop/).
   Een filmzaal met porseleinen publiek; het "filmdoek" is een scrollend raster
   van videokaartjes. Percentages zijn 1-op-1 uit de originele
   `partials/page/cinema` CSS overgenomen, zodat de props op de geschilderde
   scène blijven staan waar ze horen. De doos én de kamer staan in scene.css,
   samen met die van de radio en de fotogalerie; maten in `cqw` schalen mee met
   de scène. */

/* ── Props ───────────────────────────────────────────────────────── */

.hm-cinema-props {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-cinema-prop {
    position: absolute;
    z-index: 1000;
}

.hm-cinema-prop img {
    display: block;
    width: 100%;
    height: auto;
}

/* Alleen de klikbare props reageren; album en boek zijn (nog) decor. */
.hm-cinema-prop a {
    display: block;
    transition: transform 0.2s ease-out, filter 0.2s ease-out;
}

.hm-cinema-prop a:hover,
.hm-cinema-prop a:focus-visible {
    transform: scale(1.04);
    filter: brightness(1.12);
}

.hm-cinema-prop-album {
    width: 12.3718887262%;
    left: 1%;
    top: 0;
}

.hm-cinema-prop-radio {
    width: 9.663250366%;
    left: 1%;
    top: 18%;
}

.hm-cinema-prop-book {
    width: 8.1259150805%;
    left: 1%;
    top: 30%;
}

/* ── Het filmdoek ────────────────────────────────────────────────── */

/* De inzet valt exact samen met het doek op de achtergrondfoto. Het doek is de
   inzet; het scrollende vlak ligt erin. Die twee lagen zijn er omdat de pijlen
   rechtsonder stil moeten blijven staan: hingen ze in het scrollvlak zelf, dan
   zouden ze bij de eerste muisbeweging mee naar boven schuiven. */
.hm-cinema-doek {
    position: absolute;
    top: 10%;
    right: 23%;
    bottom: 37%;
    left: 26%;
}

.hm-cinema-screen {
    position: absolute;
    inset: 0;
    padding-right: 1.1cqw;
    overflow-y: auto;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
}

/* De pijlen staan in de hoek van het doek, een balkbreedte naar binnen: precies
   in de strook die het doek voor de scrollbalk vrijhoudt, dus naast de balk en
   niet op de kaartjes. Maat en masker komen uit scene.css, de inkt en de plek
   van hier.

   Wit met een schaduw eronder, niet wit alleen: die strook is het geschilderde
   lijstwerk van het doek en dat is lichtbruin, dus een witte pijl valt er
   zonder rand bijna in weg. De schaduw is ook wat hem staand overeind houdt,
   waar hij wél over een kaartje kan komen te liggen. */
.hm-cinema-scroll-arrows {
    right: 1.1cqw;
    bottom: 0.75rem;
    color: #fff;
    filter: drop-shadow(0 0 0.15rem rgba(0, 0, 0, 0.85));
}

/* Drie kaartjes per rij met 1% marge — het raster van het origineel, maar met
   flex in plaats van floats. */
/* Was een <button>, is nu een <a data-lightbox> voor de gedeelde hook. */
.hm-cinema-video {
    display: block;
    text-decoration: none;
    width: 31.3333333333%;
    margin: 1%;
    padding: 0;
    border: 0;
    position: relative;
    background-color: #111;
    background-position: center center;
    background-size: cover;
    cursor: pointer;
    font: inherit;
    color: #fff;
}

/* 16:9 zonder vaste hoogte, zoals het origineel met een :before deed. */
.hm-cinema-video::before {
    content: "";
    display: block;
    width: 100%;
    padding-top: 56.25%;
}

/* Lichte sluier over de hele poster: genoeg om de kaartjes één zaal te laten
   zijn, licht genoeg om de filmbeelden te laten zien. De leesbaarheid van het
   bijschrift komt niet meer hiervandaan maar van de sluier eronder. */
.hm-cinema-video::after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.3);
    transition: background-color 0.2s ease-out;
}

.hm-cinema-video:hover::after,
.hm-cinema-video:focus-visible::after {
    background-color: rgba(0, 0, 0, 0.1);
}

/* Het bijschrift hangt onderin, op een verloop dat alleen daar donker is; het
   afspeelteken staat als eerste (kolom-)element in de ruimte die daarboven
   overblijft. Dat is een kolom en geen absolute plaatsing, want een kaartje
   met vier regels titel — in portret de regel, niet de uitzondering — heeft
   in het midden geen vrije ruimte meer: het teken zou dwars door de titel
   staan. Nu schuift het mee omhoog. */
.hm-cinema-video-content {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    text-align: center;
    padding: 0.4cqw;
    font-weight: bold;
    font-size: 0.8cqw;
    line-height: 1.25;
    color: #fff;
    text-wrap: balance;
    background-image: linear-gradient(
        to top,
        rgba(0, 0, 0, 0.75) 0%,
        rgba(0, 0, 0, 0.45) 35%,
        rgba(0, 0, 0, 0) 65%
    );
}

/* ── Het bewegende beeld ─────────────────────────────────────────── */

/* Het lusje van Bunny ligt over de poster: die staat er meteen, het lusje komt
   er per kaartje bij zodra het in beeld komt (`loading="lazy"` in de HEEX).
   Onder de sluier, dus het krijgt dezelfde temperatuur als de stilstaande
   kaartjes en de tekst blijft leesbaar. */
.hm-cinema-video-beweegt {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Wie beweging heeft afgezet krijgt de poster. Het lusje wordt dan nog wel
   opgehaald — een `<img>` die je in CSS verbergt haalt de browser toch op —
   maar dat is een enkele bezoeker, en de rest van de pagina hangt er niet van
   af. Een variant die de bytes óók bespaart vraagt om JavaScript, en dat is
   deze afweging niet waard zolang het om één laag gaat die nergens toe leidt. */
@media (prefers-reduced-motion: reduce) {
    .hm-cinema-video-beweegt {
        display: none;
    }
}

/* ── Het afspeelteken ────────────────────────────────────────────── */

/* Een schijf met een driehoek: het teken dat meteen "hier zit film onder"
   zegt. Eén pseudo-element van het bijschrift — de driehoek is de tekening
   ín de schijf, niet een tweede vlak ernaast — dus geen extra markup en geen
   pictogram-bestand. De maten in `cqw` schalen mee met de scène.

   De twee `auto`-marges verdelen de vrije ruimte gelijk boven en onder de
   schijf: op een kaartje met één regel titel staat hij midden op het beeld,
   op een kaartje met vier regels net erboven. */
.hm-cinema-video-content::before {
    content: "";
    flex: none;
    width: 2.6cqw;
    height: 2.6cqw;
    margin: auto;
    border: 0.12cqw solid rgba(255, 255, 255, 0.9);
    border-radius: 50%;
    background-color: rgba(0, 0, 0, 0.45);
    /* De driehoek staat een haar naar rechts (op 9 van de 24) omdat een punt
       naar rechts optisch verder reikt dan het rekenkundige midden. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M9 6.5v11l9-5.5z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 60%;
    transition: transform 0.2s ease-out;
}

.hm-cinema-video:hover .hm-cinema-video-content::before,
.hm-cinema-video:focus-visible .hm-cinema-video-content::before {
    transform: scale(1.12);
}

.hm-cinema-empty {
    margin: auto;
    color: #fff;
    text-align: center;
}

/* ── Portret ─────────────────────────────────────────────────────── */

/* De omslag zelf staat in scene.css: de zaal wordt een schermvullende crop en de
   kamer een transparante laag daarover. Het doek zat op de liggende scène in het
   midden en viel in portret dus buiten beeld; hier wordt het een vlak dat de
   ruimte onder de props vult, met de kaartjes twee op een rij.

   Voor de grens `max-aspect-ratio: 5 / 6` zie scene.css: pas omklappen als
   het scherm 1,2 keer hoger is dan breed, anders pakt een smal desktopvenster
   de telefoonindeling. Die query hoort gelijk te lopen met die van de kamer. */
@media (orientation: portrait) and (max-aspect-ratio: 5 / 6) {
    .hm-cinema-prop-album {
        width: 24%;
        left: 4%;
        top: 3%;
    }

    .hm-cinema-prop-radio {
        width: 18%;
        left: 32%;
        top: 3%;
    }

    .hm-cinema-prop-book {
        width: 15%;
        left: 54%;
        top: 2.5%;
    }

    .hm-cinema-doek {
        top: calc(16% + var(--hm-topbar-h));
        right: 1rem;
        bottom: 1rem;
        left: 1rem;
    }

    .hm-cinema-screen {
        padding-right: 0;
    }

    /* Staand rekent de scène niet meer in `cqw` (zie scene.css), dus hier in
       rem — ongeveer een scrollbalkbreedte naar binnen. */
    .hm-cinema-scroll-arrows {
        right: 0.75rem;
    }

    /* ── Ruimte voor de kopregel ─────────────────────────────────── */

    /* Staand ligt de balk (scene.css, `.hm-topbar`) over de bovenrand van de
       plaat, en juist daar staat de proppenrij. De hele laag zakt daarom een
       balkhoogte; de percentages erbinnen rekenen tegen de laag en houden dus
       hun onderlinge verhouding. Het filmdoek schuift even ver mee, anders
       zou de rij er bovenop komen te staan. */
    .hm-cinema-props {
        top: var(--hm-topbar-h);
    }

    .hm-cinema-video {
        width: 48%;
    }

    .hm-cinema-video-content {
        padding: 0.4rem;
        font-size: 0.8rem;
    }

    /* In portret staat de scène los van de container-query-maat, dus het
       afspeelteken krijgt hier rem-maten. Kleiner dan liggend: de kaartjes
       staan twee op een rij en de titels lopen er tot vier regels over. */
    .hm-cinema-video-content::before {
        width: 2rem;
        height: 2rem;
        border-width: 0.1rem;
    }
}

/* Taalwissel: onder de bel, in dezelfde hoek en op dezelfde afstand als in de
   gang en de vitrine (zie corridor.css voor de rekensom). Het uiterlijk staat in
   scene.css (`.hm-langs-plaque`). */
.hm-cinema-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}


/* ── components/radio.css ── */
/* Hotel Modern — de hoorspelkamer (/media/radio/).
   Zelfde zwarte doos als de bioscoop; de kamer zelf staat in scene.css. De
   radiogids rechtsonder klapt een opengeslagen boek over de scène: links de
   welkomsttekst, rechts de hoorspelen. Percentages komen uit de originele
   `partials/page/radio` CSS, maten in `cqw` — 1cqw is 1% van de scène, dus alles
   op deze pagina schaalt met de plaat eronder in plaats van met het venster. */

/* ── Props ───────────────────────────────────────────────────────── */

.hm-radio-props {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    transition: opacity 0.2s ease-in;
}

.hm-radio-prop {
    position: absolute;
    z-index: 1000;
}

.hm-radio-prop img {
    display: block;
    width: 100%;
    height: auto;
}

.hm-radio-prop a,
.hm-radio-prop button {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    transition: transform 0.2s ease-out, filter 0.2s ease-out;
}

.hm-radio-prop a:hover,
.hm-radio-prop a:focus-visible,
.hm-radio-prop button:hover,
.hm-radio-prop button:focus-visible {
    transform: scale(1.04);
    filter: brightness(1.12);
}

.hm-radio-prop-cinema {
    width: 9.7364568082%;
    left: 1%;
    top: 1%;
}

.hm-radio-prop-album {
    width: 7.8330893119%;
    left: 2%;
    top: 10%;
}

.hm-radio-prop-book {
    width: 8.1259150805%;
    left: 1.5%;
    top: 25%;
}

.hm-radio-prop-guide {
    width: 26.2811127379%;
    right: 5%;
    bottom: 2%;
}

/* ── De gids: het opengeslagen boek ──────────────────────────────── */

.hm-radio-guide {
    position: absolute;
    inset: 0;
    z-index: 2000;
    display: none;
}

.hm-radio-guide.hm-modal-open {
    display: block;
}

/* Zolang het boek open ligt zijn de props weg — anders liggen ze eroverheen.
   In het origineel deed `.modal-open .room-props-container` dit.

   De bel en de taalwissel horen in datzelfde rijtje. Ze zitten niet ín de
   proplijst maar liggen wél onder het boek (z-index 1000 tegen 2000), dus ze
   bleven zichtbaar terwijl elke klik erop in de boekachtergrond landde: een
   knop die er staat en niets doet. Nu gaan ze mee weg, en klikken op die plek
   doet wat het overal buiten het boek doet — het boek sluiten. */
.hm-radio-room:has(.hm-radio-guide.hm-modal-open)
    :is(.hm-radio-props, .hm-bell, .hm-radio-langs) {
    opacity: 0;
    pointer-events: none;
}

/* Dezelfde overgang als de props, zodat ze samen weglopen en niet wegknippen. */
.hm-radio-room :is(.hm-bell, .hm-radio-langs) {
    transition: opacity 0.2s ease-in;
}

.hm-radio-guide-bg {
    position: absolute;
    inset: 0;
}

/* De boekplaat ligt over de hele scène, ook waar geen boek te zien is, en ving
   daarmee elke klik af — inclusief die op de achtergrond eronder, die het boek
   juist hoort te sluiten. Alleen wat je écht aanklikt (het kruisje en de twee
   bladzijden) vangt hier nog: klikken naast het boek sluit het weer. */
.hm-radio-guide-page {
    pointer-events: none;
}

.hm-radio-guide-page > * {
    pointer-events: auto;
}

/* De boekplaat vult de scène; de tekst valt binnen de inzet van het origineel. */
.hm-radio-guide-page {
    position: absolute;
    inset: 0;
    background-image: url("radio/prop/openbook-5c3715b3acdfcd49d25bf6e07bd60ad2.png?vsn=d");
    background-size: 68.0819912152%;
    background-position: center center;
    background-repeat: no-repeat;
}

/* Het kruisje hoort in de bovenhoek van de rechterbladzijde, en die hoek is
   krap: links loopt de tekstkolom tot 76,5%, rechts begint de krul op 79,3% en
   de schuine kop van het blad ligt op ±12,1%. Deze drie maten zetten het knopje
   precies in dat gat (76,8–79,0% breed, 13,5–17,4% hoog) — het raakt niets. */
.hm-radio-guide-close {
    position: absolute;
    top: 13.5%;
    right: 21%;
    z-index: 1;
    width: 2.2%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.hm-radio-guide-close img {
    display: block;
    width: 100%;
    height: auto;
}

/* Twee kolommen binnen de inzet, zoals de row/col-6 van het origineel.

   De boekplaat (openbook.png, 930x650 op 68,08% van de scène) ligt gecentreerd
   en beslaat dan 15,96–84,04% in de breedte en 7,68–92,32% in de hoogte. Maar
   het papier vult die rechthoek niet: de randen lopen schuin, en rechts zit
   een omgekrulde hoek. Uitgemeten op de plaat zelf, omgerekend naar de scène:

     linkerrand papier   16,6% bovenin → 20,0% onderin
     vouw                47,96%
     rechterrand vlák    79,3% (daarachter 79,3–81,3% de krul)
     bovenrand           10,2% links, 12,8% rechts (de rechterbladzijde ligt lager)
     onderrand           84,7% links, 88,1% rechts

   De vorige inzet (top 14%, bottom 17%, links 20%, rechts 21,5%) viel binnen de
   rechthoek maar niet binnen het papier: de rechterkolom eindigde op 78,5% en
   liep dus mét scrollbalk tegen de krul, en de bovenrand van 14% lag ruim een
   procent van de schuine kop van de rechterbladzijde. Deze maten houden overal
   minimaal ±1,5% van de scène over tot de dichtstbijzijnde papierrand.

   De rechterkolom krijgt daarbij een eigen `padding-right`: de scrollbalk staat
   aan de binnenrand van de doos, en zonder die ruimte plakt de tekst ertegenaan. */
.hm-radio-guide-left,
.hm-radio-guide-right {
    position: absolute;
    top: 16.5%;
    bottom: 19%;
    overflow-y: auto;
    color: #000;
    font-size: 0.95cqw;
}

.hm-radio-guide-left {
    left: 21.5%;
    width: 25.5%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-right: 1.8cqw;
}

.hm-radio-guide-right {
    right: 23.5%;
    width: 27%;
    padding-left: 1.8cqw;
    padding-right: 1.2cqw;
}

.hm-radio-guide-left h2 {
    font-size: 1.4cqw;
    margin-bottom: 1.2cqw;
}

.hm-radio-guide-intro p {
    margin: 0 0 0.6em;
}

/* De introtekst komt uit het beheer en is overgenomen uit WordPress; daar is
   `<h6>` gebruikt voor de twee regels kleine letter onderaan ("Klik op een titel
   om..." en "Veel luisterplezier!"). Niets in deze tenant zet h4 t/m h6 — die
   vallen dus terug op de UA-default van 0,67em, en 0,67 van een letter die zelf
   al met de scène meekrimpt komt uit op 8,7px liggend en 9,4px op een telefoon.

   Kleine letter mag kleiner zijn dan de rest, maar niet onleesbaar. `0.9em`
   houdt het verschil zichtbaar; de `max()` met een rem eronder zet er een bodem
   van 12px in, zodat de scène de regel wel kleiner mag maken maar niet
   wegdrukken. Geldt voor beide standen: dit blok staat bewust buiten de
   portret-query. */
.hm-radio-guide-intro :is(h4, h5, h6) {
    font-size: max(0.75rem, 0.9em);
    margin: 0 0 0.6em;
}

.hm-radio-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-radio-item {
    margin-bottom: 1.2cqw;
}

/* `body.hotelmodern h3` in scene.css zet een vaste 1.675rem met letterafstand,
   en dat is één klasse specifieker dan `.hm-radio-item h3` — dus dít blok werd
   genegeerd en de hoorspeltitels stonden op 26,8px, twee keer zo groot als de
   tekst op de linkerbladzijde en los van de schaal van de scène. Vandaar
   `body.hotelmodern` ervoor: gelijke specificiteit, en deze regel staat later.

   1,15cqw ligt tussen de broodtekst (0,95) en de kop van de linkerbladzijde
   (1,4): groot genoeg om als titel te lezen, klein genoeg om de twee bladzijden
   in balans te houden. */
body.hotelmodern .hm-radio-item h3 {
    font-size: 1.15cqw;
    letter-spacing: normal;
    margin: 0 0 0.3cqw;
}

/* De audiospeler is een UA-widget: onder ±2rem knippen de knoppen eraf. Vandaar
   een bodem in rem én meeschalen met de scène erboven. */
.hm-radio-item audio {
    width: 100%;
    height: max(2rem, 2.3cqw);
}

.hm-radio-empty {
    color: #000;
}

/* Een titel zonder opname. De regel staat op de plaats van de speler en neemt
   ongeveer diens hoogte in, zodat de lijst niet gaat springen tussen items die
   er wel en niet een hebben. Cursief en gedempt: het is een mededeling over het
   programma, geen programmaonderdeel. */
.hm-radio-announced {
    margin: 0;
    line-height: max(2rem, 2.3cqw);
    font-style: italic;
    opacity: 0.65;
}

/* De titel erboven mag dan ook wat rustiger staan dan een titel die je kunt
   aanklikken — anders belooft de grootste letter op de bladzijde juist datgene
   wat er niet is. */
.hm-radio-item.is-announced h3 {
    opacity: 0.8;
}

/* ── Portret ─────────────────────────────────────────────────────── */

/* De omslag zelf staat in scene.css: de plaat wordt een schermvullende crop van
   de radio en de kamer een transparante laag daarover. Hier ligt alleen de
   herindeling: de props op een rij langs de bovenrand met de gids groot
   onderaan, en het boek als een vel over het volle scherm.

   De props waren op de liggende scène 6 tot 26% breed; op een telefoon is dat
   een doel van 24 tot 100px. Ze zijn hier dus allemaal groter, en de gids het
   meest — dat is waar de pagina om draait.

   Voor de grens `max-aspect-ratio: 5 / 6` zie scene.css: pas omklappen als
   het scherm 1,2 keer hoger is dan breed, anders pakt een smal desktopvenster
   de telefoonindeling. Die query hoort gelijk te lopen met die van de kamer. */
@media (orientation: portrait) and (max-aspect-ratio: 5 / 6) {
    .hm-radio-prop-cinema {
        width: 24%;
        left: 4%;
        top: 3%;
    }

    .hm-radio-prop-album {
        width: 15%;
        left: 32%;
        top: 3%;
    }

    .hm-radio-prop-book {
        width: 15%;
        left: 50%;
        top: 2.5%;
    }

    .hm-radio-prop-guide {
        width: 70%;
        left: 15%;
        right: auto;
        bottom: 12%;
    }

    /* ── Ruimte voor de kopregel ─────────────────────────────────── */

    /* Staand ligt de balk (scene.css, `.hm-topbar`) over de bovenrand van de
       plaat, en juist daar staat de proppenrij. De hele laag zakt daarom een
       balkhoogte. De gids hangt aan de ónderrand van diezelfde laag en merkt er
       dus niets van. */
    .hm-radio-props {
        top: var(--hm-topbar-h);
    }

    /* De boekplaat is liggend (930x650) en zou op een staand scherm een
       postzegel in het midden worden. Hier stond daarom eerst een egaal beige
       vlak in de plaats — een vel zonder papier, en daarmee viel juist het
       voorwerp weg waar de kamer om draait.

       Dus draait het boek een kwartslag mee: de vouw loopt horizontaal over het
       midden en de twee bladzijden liggen boven elkaar, als een omgeslagen
       schrijfblok. Wat er níet meer gebeurt is bijsnijden. Een eerdere versie
       schaalde de plaat op tot hij het scherm vulde, en daarmee sneuvelden
       precies de dingen waaraan je hem herkent: de buitenranden, de omgekrulde
       hoek, de vorm. Wat overbleef was grijs papier met een paar losse strepen
       erdoorheen — en die strepen liepen dwars door de tekst. Liggend zie je in
       één oogopslag een radiogids; gedraaid en uitvergroot zag je ruis.

       Daarom staat het hele boek nu in beeld. De doos krijgt de verhouding van
       de gedraaide plaat (650x930) en past zich in het venster zoals de kamer
       dat liggend doet — `min(breedte, hoogte maal verhouding)`. Wat overblijft
       is een band met de kamerfoto eromheen, precies zoals het boek liggend ook
       op de scène ligt. */
    .hm-radio-guide-page {
        inset: auto;
        top: 50%;
        left: 50%;
        width: min(100vw, calc(100dvh * 650 / 930));
        aspect-ratio: 650 / 930;
        transform: translate(-50%, -50%);
        background-image: none;
        overflow: visible;
        padding: 0;
        /* De doos is nu zelf de maat: `cqw` slaat hieronder op de breedte van
           het boek, niet op het venster. Zonder dit zou de tekst met de zwarte
           band mee schalen in plaats van met het papier. */
        container-type: inline-size;
    }

    /* De plaat, gedraaid, precies passend in de doos. Vóór het draaien is dit
       vak zo breed als de doos hóóg is (143,08% = 930/650) en met
       `aspect-ratio` zo hoog als de doos breed is; na de kwartslag valt het dus
       exact op de doos. Geen `cover`, want er mag niets meer af. */
    .hm-radio-guide-page::before {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: 143.0769230769%;
        aspect-ratio: 930 / 650;
        transform: translate(-50%, -50%) rotate(90deg);
        background: url("radio/prop/openbook-5c3715b3acdfcd49d25bf6e07bd60ad2.png?vsn=d") center center / contain no-repeat;
    }

    /* De twee bladzijden. Deze percentages zijn niet opnieuw bedacht maar
       overgezet: de liggende inzet (links 21,5–47%, rechts 49,5–76,5%, boven
       16,5%, onder 19% van de scène) omgerekend naar de plaat en daarna een
       kwartslag gedraaid — plaat-x wordt schermhoogte, plaat-y wordt
       schermbreedte maar omgekeerd. Daardoor houden ze dezelfde marge tot het
       papier als liggend, en valt de vouw (op 47% van de plaatbreedte, dus 47%
       van de schermhoogte) netjes in het gat tussen de twee.

       De bovenrand is 8,14% → 12%: daar moet het kruisje bij, dat liggend
       rechtsboven op de rechterbladzijde stond en gedraaid onderaan zou
       belanden. */
    .hm-radio-guide-left,
    .hm-radio-guide-right {
        position: absolute;
        left: 13.37%;
        right: 10.42%;
        width: auto;
        display: block;
        overflow-y: auto;
        padding: 0;
        font-size: clamp(0.875rem, 3.2cqw, 1.0625rem);
    }

    .hm-radio-guide-left {
        top: 12%;
        bottom: 54.41%;
    }

    /* De `margin-top` is er met het oog erbij gekomen. Op de omgerekende 49,27%
       begint de eerste hoorspeltitel vlak onder de vouw, en die vouw is geen
       lijn maar een reeks inktvegen die een eindje uitwaaieren — het stond
       tegen elkaar aan. Bij een absoluut vlak met zowel `top` als `bottom`
       schuift een marge de doos omlaag én maakt hem even veel korter, dus dit
       kost twee rem van de lijst. */
    .hm-radio-guide-right {
        top: 49.27%;
        bottom: 11.08%;
        margin-top: 2rem;
        padding-top: 0;
        border-top: 0;
    }

    /* Alles meet mee met het boek, met een bodem in rem. De bodem is het punt:
       zuiver op verhouding zou de broodtekst op een iPhone SE 7px worden, want
       het hele boek is daar maar 375px breed. Leesbaarheid gaat voor, dus op een
       klein scherm loopt de tekst de bladzijde uit en scrolt hij. */
    .hm-radio-guide-left h2 {
        font-size: clamp(1.125rem, 4.6cqw, 1.5rem);
        margin-bottom: 0.6em;
    }

    .hm-radio-item {
        margin-bottom: 1.1em;
    }

    body.hotelmodern .hm-radio-item h3 {
        font-size: clamp(0.9375rem, 3.6cqw, 1.1875rem);
        margin: 0 0 0.3em;
    }

    .hm-radio-item audio {
        height: clamp(2rem, 6.5cqw, 2.5rem);
    }

    /* Het kruisje hoort op het boek, niet op het venster — `fixed` kan hier
       trouwens ook niet meer, want de doos heeft een `transform` en is daarmee
       zelf het houvast geworden. Liggend zit het rechtsboven op de
       rechterbladzijde; gedraaid zou diezelfde hoek onderaan uitkomen, dus het
       verhuist naar de bovenhoek van de bovenste bladzijde. Daar is het papier
       schoon (de kop van de linkerbladzijde begint al op 1 à 6%).

       `max(2.25rem, 6%)`: op verhouding alleen zou het knopje op een telefoon
       17px worden en dus niet meer te raken zijn. */
    .hm-radio-guide-close {
        position: absolute;
        top: 4%;
        right: 4%;
        width: max(2.25rem, 6%);
    }
}

/* Taalwissel: zie cinema.css — zelfde hoek, zelfde afstand tot de bel. */
.hm-radio-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}


/* ── components/gallery.css ── */
/* Hotel Modern — de fotogalerie (/media/fotogalerie/), het "Verzamel Album".
   Links een kolom met de logo's van de voorstellingen, rechts hun foto's — de
   twee bladzijden van het opengeslagen album op de achtergrondplaat. De kamer
   zelf staat in scene.css.

   Percentages komen 1-op-1 uit de originele `partials/page/photo-gallery` CSS.
   Alles wat gééń percentage van de scène is staat in `cqw` (1cqw = 1% van de
   scène): tussenruimtes en lettermaten die in px of rem stonden bleven anders
   even groot terwijl de scène meegroeide, en juist dat trok de verhouding tussen
   de logokolom en de fotokolom scheef. */

/* ── Navigatie rechtsboven ───────────────────────────────────────── */

/* De hoek neemt de plek van de bel over — hij is het eerste item — en daaronder
   hangen het bioscoop-bordje en de taalwissel. Zelfde afspraak als de nav in de
   voorstellingskamer; de maten komen uit scene.css, zodat de bel hier even groot
   uitvalt als op elke andere pagina.

   De stapel is één ding en niet twee: bordje én taalwissel stonden hier eerder
   los in dezelfde hoek als de bel, en dus bovenop de bel — in beide platen. */
.hm-gallery-corner {
    position: absolute;
    top: var(--hm-bell-inset);
    right: var(--hm-bell-inset);
    z-index: 1000;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
}

.hm-gallery-nav {
    width: var(--hm-bell-size);
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: right;
}

.hm-gallery-nav li {
    margin-bottom: 20%;
}

.hm-gallery-nav img {
    display: block;
    width: 100%;
    height: auto;
}

/* De bel eruit: die is zelf ook een `a`, maar staat als kolom (bel boven, woord
   eronder) en heeft zijn eigen hover in scene.css. `display: block` zou hem hier
   uit elkaar trekken. */
.hm-gallery-nav a:not(.hm-bell) {
    display: block;
    transition: transform 0.2s ease-out, filter 0.2s ease-out;
}

.hm-gallery-nav a:not(.hm-bell):hover,
.hm-gallery-nav a:not(.hm-bell):focus-visible {
    transform: scale(1.04);
    filter: brightness(1.12);
}

/* ── De kolom met bladwijzers ────────────────────────────────────── */

/* Dezelfde inzet als het album hiernaast (5% boven en onder). Stond op 0: de
   kop begon hoger dan de eerste foto en de onderste bladwijzer liep door tot de
   onderrand van de scène, terwijl het album daar al 5% eerder ophield — de twee
   bladzijden lagen dus niet op één lijn. */
.hm-gallery-selection {
    position: absolute;
    top: 5%;
    bottom: 5%;
    left: 1.5%;
    width: 14%;
    overflow: hidden;
    color: #fff;
    display: flex;
    flex-direction: column;
}

/* Kop en lijst verdeelden de hoogte eerst met een vaste 10/90-verdeling; met
   flex neemt de kop wat hij nodig heeft (ook als hij op twee regels valt) en
   krijgt de lijst de rest. `min-height: 0` omdat een flex-kind anders niet
   kleiner wordt dan zijn inhoud en dus niet scrollt. */
.hm-gallery-title {
    flex: 0 0 auto;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    line-height: 1;
    font-size: 0.9cqw;
    color: #fff;
    margin: 0 0 1.5cqw;
}

.hm-gallery-productions {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    padding: 0 1.5cqw 3.7cqw 0;
    margin: 0;
    list-style: none;
    overflow-y: auto;
    text-align: center;
}

.hm-gallery-production {
    border-top: 1px solid #fff;
    padding: 1.1cqw 0;
}

.hm-gallery-production button {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    color: #fff;
    font: inherit;
}

/* De logo's zijn donkere PNG's; `invert` maakt ze wit. De filterketen voor de
   gekozen bladwijzer is die van de oude site — een omweg om er een kleur van te
   maken, maar hij werkt ongeacht de inkt van het logo. */
.hm-gallery-logo {
    display: block;
    width: 100%;
    height: auto;
    filter: invert(100%);
    transition: filter 0.15s ease-out;
}

.hm-gallery-production button:hover .hm-gallery-logo,
.hm-gallery-production button:focus-visible .hm-gallery-logo,
.hm-gallery-production.selected .hm-gallery-logo {
    filter: contrast(1000%) invert(100%) sepia(100%) saturate(10000%) hue-rotate(310deg);
}

/* Voorstellingen zonder logo vallen terug op hun titel. */
.hm-gallery-production-title {
    font-size: 0.8cqw;
    line-height: 1.2;
}

.hm-gallery-production.selected .hm-gallery-production-title:not(.hm-sr-only) {
    color: var(--hotelmodern-accent, #871d0f);
}

/* Het premièrejaar onder het logo — zelfde bijschrift als op het nieuwsbord, en
   om dezelfde reden: deze kolom staat op première en niet op titel, en dat is
   aan een rij logo's anders niet te zien. */
.hm-gallery-year {
    display: block;
    margin-top: 0.35cqw;
    font-size: 0.65cqw;
    letter-spacing: 0.14em;
    line-height: 1;
    color: rgba(255, 255, 255, 0.45);
}

.hm-gallery-production button:hover .hm-gallery-year,
.hm-gallery-production button:focus-visible .hm-gallery-year,
.hm-gallery-production.selected .hm-gallery-year {
    color: #e8b04b;
}

/* De kopjes in de kolom: "Speelt dit seizoen" en "Archief". Zelfde letter als
   het jaartal onder de logo's, maar lichter dan de kop erboven — het zijn
   tussenkopjes in de lijst, geen tweede titel. De eerstvolgende bladwijzer
   draagt zijn streep al, die doet dienst als lijn onder het kopje. */
.hm-gallery-heading {
    padding: 0 0 0.6cqw;
    font-size: 0.65cqw;
    letter-spacing: 0.14em;
    line-height: 1.2;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.7);
}

/* Het tweede kopje staat midden in de lijst en heeft lucht nodig van de
   voorstelling erboven. */
.hm-gallery-heading:not(:first-child) {
    padding-top: 2.2cqw;
}

/* ── Het album ───────────────────────────────────────────────────── */

/* De wikkel is tegelijk de scroller en het anker van de SimpleLightbox-hook. */
.hm-gallery-album {
    position: absolute;
    top: 5%;
    bottom: 5%;
    left: 20%;
    width: 67%;
    padding-right: 1.1cqw;
    overflow-y: auto;
}

/* De gedeelde masonry rekent met kolommen van 20rem; dat zijn er hier maar twee
   in een album dat 67% van de scène breed is.

   Een vast áántal kolommen, zoals het origineel, in plaats van `auto-fill` op een
   kolombreedte in rem. Met een kolombreedte in rem groeide alleen het áántal
   kolommen mee met de scène en bleven de foto's even groot: op een breed scherm
   werden het acht kolommen postzegels naast een logokolom die wél meeschaalde.
   Nu groeien de foto's mee en blijft de indeling van het album staan. De masonry
   zelf blijft ongemoeid — de hook meet gewoon wat de grid hem geeft.

   Hoeveel kolommen het er zijn hangt af van de omvang van het album en komt uit
   `hm_gallery_columns/1` mee als variabele: vijf voor de grote albums, minder
   voor een voorstelling met een handvol foto's — die stonden anders als een rij
   postzegels boven een halve scène achtergrond.

   0,7cqw tussenruimte is de 0,6rem van hiervoor, maar dan meeschalend. */
.hm-gallery-grid.masonry {
    --gallery-gap: 0.7cqw;
    grid-template-columns: repeat(var(--hm-gallery-columns, 5), 1fr);
}

.hm-gallery-grid .gallery-image {
    display: block;
    width: 100%;
    height: auto;
    transition: transform 0.2s ease-out, filter 0.2s ease-out;
}

.hm-gallery-grid a:hover .gallery-image,
.hm-gallery-grid a:focus-visible .gallery-image {
    transform: scale(1.05);
    filter: brightness(1.1);
}

.hm-gallery-empty {
    margin: auto;
    color: #fff;
    text-align: center;
}

/* ── Portret ─────────────────────────────────────────────── */

/* De omslag zelf staat in scene.css: het leer wordt een schermvullende crop en
   de kamer een transparante laag daarover. Van het opengeslagen album blijft in
   portret niets over — twee bladzijden naast elkaar op een telefoon zijn twee
   kolommen van anderhalve duim — dus het wordt een gewone pagina op leer: de
   bladwijzers als een liggende strook onder de kop, het album eronder.

   `.hm-gallery-container` had geen enkele regel (de twee helften stonden los
   absoluut in de kamer); hier is hij de indeling.

   Voor de grens `max-aspect-ratio: 5 / 6` zie scene.css: pas omklappen als
   het scherm 1,2 keer hoger is dan breed, anders pakt een smal desktopvenster
   de telefoonindeling. Die query hoort gelijk te lopen met die van de kamer. */
@media (orientation: portrait) and (max-aspect-ratio: 5 / 6) {
    .hm-gallery-container {
        position: absolute;
        inset: 0;
        display: flex;
        flex-direction: column;
        /* Boven de kopregel plus de ruimte voor het bioscoop-bordje eronder. */
        padding: calc(var(--hm-topbar-h) + 3.5rem) 1rem 1rem;
    }

    /* ── Ruimte voor de kopregel ─────────────────────────────────── */

    /* Van de hoekstapel houdt de balk (scene.css, `.hm-topbar`) alleen het
       bioscoop-bordje over — de bel en de taalwissel staan daar nu in. Dat
       bordje zakt onder de balk door: het is de tweede uitgang van deze kamer en
       staat nergens in de kop. */
    .hm-gallery-corner {
        top: calc(var(--hm-topbar-h) + var(--hm-bell-inset));
    }

    /* De twee props stonden onder elkaar in een kolom van 7% — op een telefoon
       een doel van 27px. Naast elkaar en groter. De taalwissel blijft eronder
       hangen: de hoek is een kolom, alleen deze rij erin draait.

       Omgekeerd, want in een rij is de hoek de rechterkant: op leesvolgorde zou
       de bel links komen en het bioscoop-bordje de hoek krijgen, en dan hangt de
       uitgang op deze ene pagina een duim naar binnen. */
    .hm-gallery-nav {
        display: flex;
        flex-direction: row-reverse;
        gap: 0.75rem;
        width: auto;
    }

    /* De bel bepaalt de maat van de rij: staand is hij 3,4rem breed (scene.css),
       en het bordje ernaast hoort daar niet onder te duiken. */
    .hm-gallery-nav li {
        width: var(--hm-bell-size);
        margin-bottom: 0;
    }

    .hm-gallery-nav li:not(:first-child) {
        align-self: center;
    }

    .hm-gallery-selection {
        position: static;
        width: auto;
        flex: 0 0 auto;
    }

    .hm-gallery-title {
        justify-content: flex-start;
        font-size: 0.9rem;
        margin: 0 0 0.75rem;
    }

    /* Van kolom naar rooster. Dit was eerst één liggende strook waar je zijwaarts
       doorheen veegde, en dat verborg de voorstelling: er pasten drie
       bladwijzers op een telefoon en dat de rest rechts stond zag je niet — je
       kwam er domweg niet. Nu liggen ze in een rooster dat verticaal scrollt,
       net als de kolom op een breed scherm.

       Drie rijen hoog, en de rijhoogte ligt vast (`grid-auto-rows`) in plaats
       van per rij mee te geven met het hoogste logo — anders is "drie rijen"
       geen maat en werd het rooster telkens net zo hoog als de toevallige
       inhoud. De hoogte is daarmee gewoon uit te rekenen: drie rijen, drie
       tussenruimtes, plus een streepje van de vierde rij.

       Dat streepje is het teken dat er meer is; de fade eroverheen maakt er een
       weglopende rand van in plaats van een logo dat doormidden is gesneden.

       `height` en niet `max-height`: bij een plafond krimpt het vak mee als
       alles al past (een tablet zet er acht naast elkaar en is in drie rijen
       klaar), en dan valt de fade over de onderste rij lógo's in plaats van over
       lege ruimte. Met een vaste hoogte staat de band er altijd hetzelfde bij en
       fade je in dat geval niets weg.

       Eerder stond hier `max-height: 34dvh`, en daarvoor `40%`. Dat laatste gaf
       een gat van een paar honderd pixels: een procentuele `max-height` moet
       tegen de hoogte van de ouder worden afgezet, en die ouder is hier juist zo
       hoog als zijn inhoud — de browser rekent hem dan eerst uit zónder plafond
       en past het plafond pas daarna toe.

       De scheidingsstreep stond bóven elk item en werkt in een rooster niet
       meer; de tussenruimte doet het werk. */
    .hm-gallery-productions {
        --hm-bookmark-row: 4rem;
        --hm-bookmark-gap: 1rem;
        --hm-bookmark-peek: 2.25rem;
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(min(6rem, 100%), 1fr));
        gap: var(--hm-bookmark-gap);
        overflow-x: hidden;
        overflow-y: auto;
        flex: 0 0 auto;
        height: calc(
            3 * var(--hm-bookmark-row) + 3 * var(--hm-bookmark-gap) + var(--hm-bookmark-peek)
        );
        /* Ruimte tot het album eronder. */
        margin: 0 0 2.5rem;
        padding: 0 0.5rem 0 0;
        -webkit-mask-image: linear-gradient(
            to bottom,
            #000 0,
            #000 calc(100% - 2.5rem),
            transparent 100%
        );
        mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - 2.5rem), transparent 100%);
    }

    /* Het logo moet met het jaartal eronder binnen de vaste rijhoogte blijven:
       2,7rem logo + 0,4rem tussenruimte + 0,7rem jaartal past in 4rem. `contain`
       zodat een breed logo zijn verhouding houdt als de hoogte hem afknijpt. */
    .hm-gallery-logo {
        max-height: 2.7rem;
        object-fit: contain;
    }

    /* De vaste rijhoogte zat eerst op het rooster (`grid-auto-rows`), maar dan
       kreeg ook een kopje een hele logorij. Nu zit hij op de bladwijzer, en
       neemt een kopje alleen zijn eigen regel. */
    .hm-gallery-production {
        border-top: 0;
        padding: 0;
        height: var(--hm-bookmark-row);
        display: flex;
        flex-direction: column;
        justify-content: center;
    }

    /* Een kopje over de hele breedte van het rooster; de tussenruimte van het
       rooster staat er al onder. */
    .hm-gallery-heading {
        grid-column: 1 / -1;
        padding: 0;
        font-size: 0.7rem;
    }

    .hm-gallery-heading:not(:first-child) {
        padding-top: 0.75rem;
    }

    .hm-gallery-production-title {
        font-size: 0.8rem;
    }

    .hm-gallery-year {
        margin-top: 0.4rem;
        font-size: 0.7rem;
    }

    .hm-gallery-album {
        position: static;
        width: auto;
        flex: 1 1 auto;
        min-height: 0;
        padding-right: 0;
    }

    /* Vijf vaste kolommen zijn hier vijf postzegels naast elkaar. Hier telt de
       leesbare foto en niet de indeling van het album, dus wél op kolombreedte:
       twee op een telefoon, vier op een tablet in portret. */
    .hm-gallery-grid.masonry {
        --gallery-gap: 0.5rem;
        grid-template-columns: repeat(auto-fill, minmax(min(10rem, 100%), 1fr));
    }
}

/* De kop is tegelijk de knop naar het volledige album. */
.hm-gallery-all {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    cursor: pointer;
}

/* Hetzelfde goud dat de filterketen van een gekozen logo oplevert, zodat kop en
   bladwijzer dezelfde "aan"-stand hebben. */
.hm-gallery-all:hover,
.hm-gallery-all:focus-visible,
.hm-gallery-all.selected {
    color: #e8b04b;
}

/* Taalwissel. Onderaan de stapel in de hoek — de plek bepaalt `.hm-gallery-corner`
   hierboven, net als bij de bel en het bordje. Iets meer lucht boven zich dan er
   tussen de props zit: die horen als één ding te lezen, de wissel is er een
   derde naast. Zelfde afspraak als in de voorstellingskamer. */
.hm-gallery-langs {
    margin-top: 0.4rem;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}


/* ── components/news.css ── */
/* Hotel Modern — het nieuwsarchief (/nieuws/), een prikbord in een lichtbak.

   Anders dan de andere kamers heeft deze pagina géén scènefoto: er is geen
   maquette voor Nieuws, en er een lenen zou een decor betekenen dat ergens
   anders al iets anders betekent. Wat de scène draagt is de lampenrand uit de
   receptie, hier zo breed als het scherm.

   Daardoor is dit ook de enige kamer zonder vaste beeldverhouding: zonder foto
   valt er niets bij te snijden. Maar niet grenzeloos: boven de 90rem staat de
   kamer stil en loopt het zwart door tot de schermrand, zodat het bord een lijst
   blijft in plaats van een vlak dat meegroeit. Daaronder houdt de padding hem
   van de rand af. Ruimte genoeg hoe dan ook — de oude lightbox was een kolom van
   ±40rem. */

/* De maat staat op een eigen custom property omdat het losse bericht
   (.hm-newssheet-room) hem deelt: die twee horen even breed te zijn, anders
   springt de lijst van plaats zodra je een knipsel opent. */
:root {
    --hotelmodern-news-max: 90rem;
}

/* Achter het bord hangt de gang — dezelfde hotelgang als op de
   voorstellingen-index. Zo staat het nieuws ergens in het hotel in plaats van in
   het niets, en het wijkende perspectief geeft het bord diepte zonder zelf iets
   te willen.

   Het is één plaat: `nieuws/wall.jpg`, de gangfoto uit
   `tenant_page_settings.productions_index_theatre`, getemperd tot ±⅓ van zijn
   helderheid. Dat temperen zit in het bestand omdat het bij de plaat hoort — er
   staan witte logo's en een wit register overheen, en op de foto zoals hij uit
   de scène komt verdwijnen die.

   Een andere gang of een prikbord is dus één bestand vervangen; de CSS hoeft
   niet mee. Blijft het beeld dan te fel, verlaag de brightness bij het maken van
   de plaat — niet hier, anders gaat de scrim hieronder z'n werk dubbel doen. */
.hm-stage:is(.hm-news, .hm-newssheet) {
    background-color: #000;
    /* De scrim ligt vóór de foto (eerste laag wint) en dooft de plafondlamp
       boven in de gang: die is het felste punt van de plaat en zit precies waar
       het register staat. Alleen bovenin, zodat de gang zelf leesbaar blijft. */
    background-image:
        linear-gradient(to bottom, rgba(0, 0, 0, 0.72) 0%, rgba(0, 0, 0, 0.15) 22%, rgba(0, 0, 0, 0) 42%),
        url(/assets/hotelmodern/nieuws/wall-c8e74b58e6f692d8f8f1b62a639560ee.jpg?vsn=d);
    background-size: cover;
    background-position: center;
}

/* `relative` voor de redactieregel, die rechtsboven in de kamer hangt en niet in
   de beeldhoek: daar hangt de bel. Bel en taalbordjes hingen hier eerder ook aan
   — zie `.hm-news-langs` voor waarom ze nu aan de scène hangen. */
.hm-news-room {
    position: relative;
    display: grid;
    /* De kolom met voorstellingen, dan het bord. Dezelfde verhouding als in de
       fotogalerie (14% / rest), maar met een bovengrens: op een breed scherm
       wordt 14% een kolom waar de logo's in verdrinken. */
    grid-template-columns: minmax(8rem, 14%) 1fr;
    gap: clamp(1rem, 2vw, 2.5rem);
    width: 100%;
    max-width: var(--hotelmodern-news-max);
    height: 100%;
    margin: 0 auto;
    padding: clamp(1rem, 2.5vh, 2.5rem) clamp(1rem, 2.5vw, 3rem);
    /* Rechts wijkt het bord voor de hoek waar de bel en de bordjes hangen — maar
       alleen voor zover de zwarte marge naast de kamer dat niet al doet. Op een
       breed scherm kost dat dus niets: daar staat de kamer stil bij 90rem en is
       er ruimte zat. Onder die grens loopt het bord tot de rand en wijkt het
       hier. Zonder deze regel lag de bel op de hoek van het lampenkader en
       dekten de bordjes een knipsel af. */
    padding-right: max(
        clamp(1rem, 2.5vw, 3rem),
        calc(var(--hotelmodern-news-corner) - var(--hotelmodern-news-margin))
    );
    box-sizing: border-box;
    color: #fff;
}

/* ── Bel en taalwissel ───────────────────────────────────────────── */

/* De bel zelf staat in scene.css, en daar staat ook haar maat: deze twee kamers
   dragen als enige geen maquettefoto en lenen daarom de rechthoek van de gang om
   te weten waar de hoek van het beeld ligt. Wat hier bij komt is wat dat de
   kamer eronder kost. */
.hm-stage:is(.hm-news, .hm-newssheet) {
    /* De hoek die voor de bel en de bordjes vrij moet blijven, gemeten vanaf de
       schermrand. Niet de bel bepaalt hem maar het bordje eronder: "Nederlands"
       is 7,5rem breed bij de maat uit scene.css, de bel maar 5% van het beeld.
       Plus de inzet en de zwarte band waarop de stapel staat, en een rem lucht
       tot het bord.

       Dit is de enige kamer waar die hoek een maat kóst. Overal elders hangt de
       bel op een foto en mag er van alles achter liggen; hier is de rechterrand
       van het bord een lampenkader, en dat wil je niet half onder een bel. */
    --hotelmodern-news-corner: calc(var(--hm-bell-inset) + var(--hm-scene-side) + 8.5rem);

    /* Wat er naast de kamer al zwart is. Boven de 90rem staat de kamer stil en
       groeit die marge mee met het scherm; daaronder is hij nul. */
    --hotelmodern-news-margin: max(0px, calc((100vw - var(--hotelmodern-news-max)) / 2));
}

/* De taalbordjes hangen onder de bel, en die twee hangen in de hoek van de
   scène — niet in de kamer eronder. Dat verschil is op een breed scherm groot:
   de kamer stopt bij 90rem en de gang erachter loopt door tot de schermrand, dus
   in de kamer bleef de bel een heel eind naar binnen staan terwijl hij op elke
   andere pagina in de beeldhoek hangt. Het bord en het berichtvel waren daarmee
   de laatste twee die uit de pas liepen; de agenda deed dezelfde stap eerder
   (zie agenda.css), en de formule hieronder is letterlijk de hare.

   Twee keer de inzet plus de hoogte van de bel (1,33 × zijn breedte, het woord
   eronder meegeteld) — dezelfde formule als in de gang, de vitrine en het boek.
   De zijkant wordt hier niet gezet: die komt uit scene.css, waar de zwarte band
   naast de rechthoek erbij wordt geteld.

   Het uiterlijk van de bordjes komt uit scene.css (`.hm-langs-plaque`). */
.hm-news-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    /* Dezelfde laag als de bel in scene.css: het bord en het vel eronder
       scrollen in een eigen bak, en zonder deze laag liggen de bordjes daarachter
       en zijn ze niet aan te klikken. */
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}

/* De redactieregel: alleen zichtbaar voor wie is ingelogd. Zelfde vorm en toon
   als `.hm-agenda-admin`, maar licht in plaats van donker — de scène is hier een
   zwarte muur met een scrim erover.

   `absolute` en niet gewoon in de stroom: `.hm-news-room` is een grid van twee
   kolommen, dus een extra kind zou een cel opeisen en de kolom met
   voorstellingen naast het bord duwen.

   Rechtsboven in de kamer. Linksboven kan niet: daar begint meteen de kop van de
   voorstellingenkolom, en daar liep hij dwars doorheen. (Tot 2026-09-05 stond de
   taalwissel daar; die hangt nu onder de bel.) De bel hangt sinds 2026-09-07 in
   de hoek van de scène en niet meer in de kamer, dus de regel houdt hier alleen
   nog de hoek van de kamer aan — die ligt bij een breed scherm links van de bel
   en bij een smal scherm eronder, en botst dus nergens. */
.hm-news-admin {
    position: absolute;
    top: var(--hm-bell-inset);
    right: var(--hm-bell-inset);
    z-index: 2;
    display: flex;
    gap: 1rem;
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.hm-news-admin a {
    color: rgba(255, 255, 255, 0.55);
    text-decoration: none;
}

.hm-news-admin a:hover,
.hm-news-admin a:focus-visible {
    color: #fff;
}

/* ── De kolom met voorstellingen ─────────────────────────────────── */

.hm-news-selection {
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding-top: clamp(1.5rem, 4vh, 3rem);
}

.hm-news-column-title {
    margin: 0 0 1rem;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    line-height: 1;
    font-size: clamp(0.75rem, 0.9vw, 1rem);
}

.hm-news-all {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    cursor: pointer;
}

/* Hetzelfde goud als in de fotogalerie, zodat "aan" door de hele tenant
   dezelfde kleur heeft. */
.hm-news-all:hover,
.hm-news-all:focus-visible,
.hm-news-all.selected {
    color: #e8b04b;
}

.hm-news-productions {
    flex: 1;
    min-height: 0;
    margin: 0;
    padding: 0 1rem 3rem 0;
    list-style: none;
    overflow-y: auto;
    text-align: center;
}

.hm-news-production {
    border-top: 1px solid rgba(255, 255, 255, 0.5);
    padding: 0.9rem 0;
}

.hm-news-production button {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    color: #fff;
    font: inherit;
}

/* De logo's zijn donkere PNG's; `invert` maakt ze wit. De filterketen voor het
   gekozen logo komt uit de fotogalerie — een omweg om er een kleur van te maken,
   maar hij werkt ongeacht de inkt van het logo. */
.hm-news-logo {
    display: block;
    width: 100%;
    height: auto;
    filter: invert(100%);
    transition: filter 0.15s ease-out;
}

.hm-news-production button:hover .hm-news-logo,
.hm-news-production button:focus-visible .hm-news-logo,
.hm-news-production.selected .hm-news-logo {
    filter: contrast(1000%) invert(100%) sepia(100%) saturate(10000%) hue-rotate(310deg);
}

.hm-news-production-title {
    font-size: clamp(0.7rem, 0.8vw, 0.9rem);
    line-height: 1.25;
}

.hm-news-production.selected .hm-news-production-title:not(.hm-sr-only) {
    color: #e8b04b;
}

/* Het premièrejaar onder het logo: het maakt de volgorde van de kolom leesbaar.
   Bewust klein en gedempt — het is een bijschrift bij de bladwijzer, geen tweede
   knop, en het logo moet het beeld blijven dragen. */
.hm-news-year {
    display: block;
    margin-top: 0.35rem;
    font-size: clamp(0.6rem, 0.7vw, 0.75rem);
    letter-spacing: 0.14em;
    line-height: 1;
    color: rgba(255, 255, 255, 0.45);
}

.hm-news-production button:hover .hm-news-year,
.hm-news-production button:focus-visible .hm-news-year,
.hm-news-production.selected .hm-news-year {
    color: #e8b04b;
}

/* ── Het register ────────────────────────────────────────────────── */

.hm-news-main {
    display: flex;
    flex-direction: column;
    min-height: 0;
    min-width: 0;
}

/* De regel boven het bord: het register links, en op een smal scherm de
   keuzelijst ernaast. De bel stond hier ook in; die hangt sinds 2026-09-07 in de
   hoek van de scène. `align-items: end` legt de twee op één onderlijn, ook als
   het register over twee regels valt. */
.hm-news-header {
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: clamp(0.75rem, 2vw, 2rem);
    padding-bottom: clamp(0.75rem, 1.5vh, 1.25rem);
}

.hm-news-register {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(0.5rem, 1.5vw, 1.75rem);
}

.hm-news-tab {
    padding: 0.15em 0;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: rgba(255, 255, 255, 0.7);
    font: inherit;
    font-size: clamp(0.8rem, 1vw, 1rem);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition:
        color 0.15s ease-out,
        border-color 0.15s ease-out;
}

.hm-news-tab:hover,
.hm-news-tab:focus-visible {
    color: #fff;
}

.hm-news-tab.selected {
    color: #e8b04b;
    border-bottom-color: #e8b04b;
}

/* ── Het bord ────────────────────────────────────────────────────── */

/* De lampenrand. `frame-tile.png` is de lijst uit de receptie als 9-slice: vier
   hoeken en van elke rand precies één lampperiode. De hele plaat als
   `border-image` zou werken, maar de randstrook bevat tien lampjes en gaf op
   elke herhaling een dubbel gat; met één periode staan ze op elke breedte even
   ver uit elkaar.

   `round` en niet `repeat`: `round` schaalt de tegel zó dat er een heel aantal
   in past, dus eindigt de rand nooit halverwege een lampje.

   De maten (34 38 35 37) zijn de gemeten randdikte van frame.png in pixels —
   bewust geen rem: het is een uitsnede uit een bitmap, geen typografie. */
.hm-news-board {
    position: relative;
    flex: 1;
    min-height: 0;
    border-style: solid;
    border-width: clamp(1.1rem, 2.2vw, 2.2rem) clamp(1.2rem, 2.4vw, 2.4rem);
    border-image-source: url(/assets/hotelmodern/nieuws/frame-tile-8cd4af9425d5df44123aa203fc5fe1c0.png?vsn=d);
    border-image-slice: 34 38 35 37;
    border-image-repeat: round;
}

/* Het scrollen zit binnen het kader, niet erop: anders schuift de lampenrand
   mee omhoog zodra je door de knipsels gaat. */
.hm-news-scroll {
    height: 100%;
    overflow-y: auto;
    padding: clamp(0.75rem, 1.5vw, 1.5rem);
    box-sizing: border-box;
    /* De balk krijgt altijd zijn strook, ook als er niets te scrollen valt.
       Anders verandert de kolombreedte op het moment dat de balk verschijnt, en
       dat is precies de lus die de masonry aan het schommelen kan brengen: de
       tekst breekt anders af, de kaarten worden hoger, de grid wordt langer,
       de balk blijft — of gaat juist weg. */
    scrollbar-gutter: stable;
}

/* De gedeelde masonry rekent met kolommen van 20rem. Een knipsel is tekst, geen
   foto: onder ±16rem wordt een kop van tien woorden een smalle sliert. */
.gallery-grid.masonry.hm-news-grid {
    --gallery-gap: clamp(0.6rem, 1.2vw, 1.1rem);
    grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
}

/* De verticale tussenruimte, zoals `.gallery-item` die in de basis-masonry
   draagt — die klasse zelf staat op `display: none` tot de hook hem opmeet, dus
   die kan hier niet zomaar overheen. */
.hm-news-cell {
    padding-bottom: var(--gallery-gap);
}

/* ── Het knipsel ─────────────────────────────────────────────────── */

/* Hetzelfde papier als het krantvel op de voorstellingspagina — `cover` en niet
   tegelen, want de scan is niet naadloos. De lichte draaiing per knipsel maakt
   er een prikbord van in plaats van een tabel; hij is klein genoeg om de tekst
   recht te laten lezen. */
.hm-news-clipping {
    background: var(--hotelmodern-paper, #f4f0e6);
    background-image: url(/images/hotelmodern/paper-background-c8e2d61dc60d49c9943493f21bc5333c.jpg?vsn=d);
    background-size: cover;
    background-position: center;
    /* De schaduw zet het vel wel van het bord af, maar tussen twee knipsels
       onderling niet: op een donker bord verdwijnt een schaduw in de buurman.
       Een witte rand geeft elk knipsel een eigen einde — een passe-partout om het
       papier, dat zelf gescand en dus net niet wit is. Meebewegend tussen 0,125 en
       0,25 rem, zodat hij op een klein bord geen kolombreedte opeet en op een groot
       bord niet tot een haartje verschrompelt. */
    border: clamp(0.125rem, 0.25vw, 0.25rem) solid #ffffff;
    box-shadow: 0 0.4rem 1.2rem rgba(0, 0, 0, 0.5);
    transition:
        transform 0.2s ease-out,
        box-shadow 0.2s ease-out;
}

/* De telling zit op de cel: het knipsel is het enige kind van zijn cel, dus
   `nth-child` daarop zou elk vel dezelfde kant op draaien. */
.hm-news-cell:nth-child(3n) .hm-news-clipping {
    transform: rotate(-0.5deg);
}

.hm-news-cell:nth-child(4n) .hm-news-clipping {
    transform: rotate(0.4deg);
}

/* Via de cel en niet rechtstreeks: de twee draairegels hierboven zijn een
   afstammelingsselector en wegen daarmee zwaarder dan `.hm-news-clipping:hover`.
   Elk derde en vierde knipsel bleef daardoor scheef én ongeschaald liggen — het
   halve bord had geen hover. Dezelfde diepte hier maakt het gelijkspel, en dan
   wint deze regel omdat hij later staat. */
.hm-news-cell .hm-news-clipping:hover,
.hm-news-cell .hm-news-clipping:focus-within {
    transform: rotate(0deg) scale(1.02);
    box-shadow: 0 0.7rem 1.8rem rgba(0, 0, 0, 0.6);
}

/* De link is het hele vel en draagt zelf geen marge: die zit op de tekstdoos
   hieronder. Zo raakt de foto vanzelf de randen van het knipsel, zonder dat een
   negatieve marge de padding moet compenseren — dat werkte alleen zolang beide
   maten exact gelijk bleven, en dat hielden ze niet vol. */
.hm-news-clipping-link {
    display: block;
    color: var(--hotelmodern-fg, #2b1a10);
    text-decoration: none;
}

.hm-news-clipping-text {
    padding: clamp(0.9rem, 1.4vw, 1.4rem);
}

/* De negen berichten mét beeld: over de volle breedte van het vel, boven de
   tekst. `width: 100%` en niet `max-width`, zodat ook een bronbestand dat
   smaller is dan de kolom het knipsel vult in plaats van er wit naast te laten. */
.hm-news-clipping-image {
    display: block;
    width: 100%;
    height: auto;
}

.hm-news-clipping-meta {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    margin: 0 0 0.4rem;
    font-size: 0.7rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #6b5540;
}

.hm-news-clipping-kind {
    color: var(--hotelmodern-accent, #871d0f);
}

/* Een concept ligt alleen op het bord van de beheerder. Grijs stempeltje: het is
   geen fout, het is nog niet af. */
.hm-news-clipping-draft {
    margin-right: 0.4rem;
    padding: 0.05rem 0.35rem;
    border: 0.0625rem solid currentColor;
    color: #6b6b6b;
    text-transform: uppercase;
    letter-spacing: 0.05rem;
}

/* `body.hotelmodern` erbij omdat die selector de tenant-brede h3 zet (1.675rem
   met ruime spatiëring) en anders van deze wint: dat is een bordje-formaat, en
   een kop die hier uit een heel citaat bestaat wordt daarmee een muur. */
body.hotelmodern .hm-news-clipping-title {
    margin: 0 0 0.5rem;
    font-size: clamp(1rem, 1.15vw, 1.2rem);
    letter-spacing: 0;
    line-height: 1.25;
    text-wrap: pretty;
}

.hm-news-clipping-link:hover .hm-news-clipping-title,
.hm-news-clipping-link:focus-visible .hm-news-clipping-title {
    color: var(--hotelmodern-accent, #871d0f);
}

.hm-news-clipping-lead {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.5;
}

.hm-news-empty {
    margin: 3rem auto;
    color: #fff;
    text-align: center;
}

/* ── Smal en staand ──────────────────────────────────────────────── */

/* De kolom met logo's kost op een telefoon meer dan hij oplevert: hij duwt het
   bord in een strook en de logo's worden onleesbaar klein. Het register blijft
   wel staan — dat is één regel en scheelt hier het meest. */
@media (max-width: 48rem) {
    .hm-news-room {
        grid-template-columns: 1fr;
        padding: clamp(3rem, 8vh, 4.5rem) 0.75rem 0.75rem;
    }

    .hm-news-selection {
        display: none;
    }

    .hm-news-board {
        border-width: 0.9rem 1rem;
    }

    .hm-news-grid.masonry {
        grid-template-columns: 1fr;
    }
}

/* ── Eén bericht (/nieuws/<slug>) ────────────────────────────────── */

/* Het knipsel opengevouwen: hetzelfde papier als op het bord, maar nu op
   leesbreedte in plaats van in een kolom. Geen scène eromheen — die is er voor
   Nieuws niet, dus draagt de zwarte doos het vel. */
.hm-newssheet-room {
    position: relative;
    width: 100%;
    max-width: var(--hotelmodern-news-max);
    height: 100%;
    margin: 0 auto;
    padding: clamp(1rem, 2.5vh, 2.5rem) clamp(1rem, 2.5vw, 3rem);
    /* Zelfde uitwijking als op het bord hiernaast: het vel houdt de hoek vrij
       waar de bel en de bordjes hangen. */
    padding-right: max(
        clamp(1rem, 2.5vw, 3rem),
        calc(var(--hotelmodern-news-corner) - var(--hotelmodern-news-margin))
    );
    box-sizing: border-box;
}

.hm-newssheet-scroll {
    height: 100%;
    overflow-y: auto;
    /* Onderaan meer lucht dan bovenaan: het vel moet vrij van de vensterrand
       kunnen eindigen, anders lijkt de tekst afgesneden. */
    padding: clamp(2rem, 6vh, 4rem) 0 clamp(4rem, 10vh, 8rem);
}

.hm-newssheet-sheet {
    /* Smaller dan het bord: dit is doorlopende tekst, geen knipsel. Boven de
       ±70 tekens per regel wordt een recensie een muur. */
    max-width: 46rem;
    margin: 0 auto;
    padding: clamp(1.5rem, 4vw, 3.5rem);
    line-height: 1.6;

    /* Hetzelfde papier als de knipsels waar je vandaan klikt, en om dezelfde
       reden `cover`: die scan tegelt niet naadloos.

       Het kwam tot 07-09-2026 van `.hm-room-block`; die klasse gaf elk blok op
       de voorstellingspagina een eigen velletje, en toen die pagina één groot
       vel werd viel het papier hier weg. Wat overbleef was donkere tekst op de
       foto van de gang, en dat was niet te lezen. */
    background: var(--hotelmodern-paper, #f4f0e6);
    background-image: url(/images/hotelmodern/paper-background-c8e2d61dc60d49c9943493f21bc5333c.jpg?vsn=d);
    background-size: cover;
    background-position: center;
    box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.45);
}

.hm-newssheet-meta {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    margin: 0 0 1.25rem;
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #6b5540;
}

/* Het logo van de voorstelling, als bordje boven de kop. De logo's zijn donkere
   PNG's en het papier is licht, dus hier gaan ze — anders dan in de kolom —
   ongefilterd op. */
.hm-newssheet-production {
    display: block;
    margin: 0 auto 1.5rem;
    max-width: 14rem;
    text-align: center;
    color: var(--hotelmodern-accent, #871d0f);
    text-decoration: none;
}

.hm-newssheet-logo {
    display: block;
    width: 100%;
    height: auto;
    transition: opacity 0.15s ease-out;
}

.hm-newssheet-production:hover .hm-newssheet-logo,
.hm-newssheet-production:focus-visible .hm-newssheet-logo {
    opacity: 0.75;
}

.hm-newssheet-title {
    /* Een kop die uit een heel citaat bestaat mag hier niet op bordje-formaat
       staan; vandaar de bovengrens en de normale spatiëring. */
    margin: 0 0 1.5rem;
    font-size: clamp(1.4rem, 1rem + 1.6vw, 2.1rem);
    line-height: 1.2;
    letter-spacing: 0;
    text-wrap: balance;
}

.hm-newssheet-image {
    display: block;
    width: 100%;
    height: auto;
    margin: 0 0 1.5rem;
}

.hm-newssheet-body :is(p, ul, ol, blockquote) {
    margin: 0 0 1.1rem;
}

.hm-newssheet-body :first-child {
    margin-top: 0;
}

/* De eerste alinea als lead, net als op het krantvel van de voorstelling. */
.hm-newssheet-body > p:first-of-type {
    font-size: 1.15rem;
    line-height: 1.65;
}

.hm-newssheet-body a {
    color: var(--hotelmodern-accent, #871d0f);
}

.hm-newssheet-back {
    max-width: 46rem;
    margin: 1.5rem auto 0;
    padding: 0 clamp(1.5rem, 4vw, 3.5rem);
    box-sizing: border-box;
}

.hm-newssheet-back a {
    color: #e8b04b;
    text-decoration: none;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-size: 0.85rem;
}

.hm-newssheet-back a:hover,
.hm-newssheet-back a:focus-visible {
    text-decoration: underline;
}

@media (max-width: 48rem) {
    .hm-newssheet-room {
        padding: clamp(3rem, 8vh, 4.5rem) 0.75rem 0.75rem;
    }
}

/* ── Ruimte voor de kopregel ─────────────────────────────────────── */

/* Staand ligt de balk (scene.css, `.hm-topbar`) over de bovenrand van de kamer,
   want de scène zakt alleen liggend een balkhoogte. Elke andere scène ving dat
   op — agenda, pers, boek, bioscoop, radio, fotogalerie — en het nieuwsbord als
   enige niet. De bovenmarge hier is 2,5vh en daarmee altijd kleiner dan de balk:
   op een tablet in portret verdween het register er dus achter, en op 768 breed
   ook de bovenrand van de keuzelijst die daar de logokolom vervangt.

   Een binnenmarge en geen verschuiving, dezelfde afweging als op het persvel: de
   zwarte muur hoort dóór te lopen tot de schermrand, alleen wat erop staat
   schuift eronderuit. Een hele rem lucht en niet de 0,85 van het persvel, want
   hier grenst een rij tabbladen aan de balk en die dragen zelf een onderlijn.

   Achteraan het bestand, want de staande omslag hierboven zet een
   `padding`-shorthand op dezelfde kamer; een regel eerder in het bestand zou
   die eroverheen gaan. */
@media (max-aspect-ratio: 6/5) {
    .hm-news-room {
        padding-top: calc(var(--hm-topbar-h) + 1rem);
    }
}


/* ── components/agenda.css ── */
/* Hotel Modern — de agenda (/agenda/), het marmeren blad van de balie.

   De enige pagina van deze tenant die nog de platform-lijst droeg. De scène was
   er wel: het origineel heeft voor de agenda een eigen decor, en dat is geen
   kamer maar een blad — je kijkt van bovenaf op het marmer waar de
   receptioniste haar vel papier op heeft gelegd, met de sleutelhanger ernaast.

   Anders dan de andere scènes is er hier dus niets te croppen: het marmer is een
   textuur, geen opname met props tegen de randen. Vandaar `cover` in plaats van
   de `contain`-met-zwarte-banden van de receptie, en een vloeiende indeling in
   plaats van de vaste 1366×768 van het origineel. Wat op die maat was uitgemeten
   en wél is overgenomen, staat hieronder per plek genoemd. */

/* Het blad is de kamer van de gang: min(100vw, 100dvh x 16/9), precies de maat
   waarop corridor.css zijn gang uitlegt. Eén rechthoek voor beide pagina's, dus
   de rand van het marmer ligt waar in de gang de zijwand staat en de hanger
   ernaast is er even groot.

   Het stond hier eerst op 90rem, de maat van het nieuwsbord: boven die grens
   staat de balie stil en loopt het marmer door tot de schermrand. Dat hield de
   hanger klein (hij rekent hieronder in het blad) en daarmee ook het vel, want
   de kolom die de hanger vrijhoudt gaat van dezelfde maat af. Op een breed
   scherm was het resultaat een sleutel die kleiner was dan diezelfde sleutel in
   de gang, náást een vel dat de helft van het marmer onbeschreven liet. Nu
   groeien blad en hanger samen mee en gaat de winst naar het vel.

   De regels op het vel groeien niet mee: `.hm-agenda-month-block` houdt de
   speellijst op 54rem, anders komt de kaartjeslink meters van de titel af te
   staan. Wat het vel breder wordt is dus papier om de lijst heen — een vel op
   een blad, en niet een lijst die het marmer volschrijft. */
:root {
    --hotelmodern-agenda-max: var(--hotelmodern-scene-rect);
    /* De hanger is exact het sleutelbord uit de gang: daar is de plaat 31% van
       de kamer (zie corridor.css), hier 31% van het blad — en dat is sinds
       hierboven dezelfde rechthoek. Beide pagina's hangen dezelfde plaat van
       448x750 op, dus dezelfde formule geeft hetzelfde voorwerp op het scherm:
       aan de hoogte van het venster gebonden zolang het breder is dan 16:9, aan
       de breedte daaronder. */
    --hotelmodern-agenda-tag: calc(var(--hotelmodern-agenda-max) * 0.31);
    /* De marge van het blad. Staat als variabele hier omdat de kolom hieronder
       hem nodig heeft: de hanger begint bij de rand van het blad, het vel pas
       na de marge. */
    --hotelmodern-agenda-pad: clamp(1rem, 4vw, 5rem);
    /* Hoever de hanger over het vel valt. In het origineel raakt de sleutel het
       papier — hij ligt erop, hij staat er niet naast — en dat is precies wat
       dit stukje overlap teruggeeft. Twaalf procent van de plaat: het kaartje
       zelf houdt rechts een kwart vrij voor de gerafelde rand, dus wat er
       overheen komt te liggen is de sleutel en niet de tekst erop. */
    --hotelmodern-agenda-tag-overlap: calc(var(--hotelmodern-agenda-tag) * 0.12);
    /* De kolom die het vel opzij houdt. De hanger zelf hangt tegen de rand van
       het blad en staat niet meer in de grid (zie `.hm-agenda-tag`), maar het
       vel moet wel op zijn plek blijven liggen: het is een vel op een blad,
       geen pagina die het marmer volschrijft. De plaat, min de marge waar hij
       overheen begint en min de overlap waarmee hij op het papier landt. */
    --hotelmodern-agenda-tag-column: calc(
        var(--hotelmodern-agenda-tag) - var(--hotelmodern-agenda-pad) - var(--hotelmodern-agenda-tag-overlap)
    );
}

.hm-stage.hm-agenda {
    background-color: #000;
    background-image: url(/assets/hotelmodern/agenda/desk-956e2749d76b039c7e18d5b5b2f4f172.webp?vsn=d);
    background-size: cover;
    background-position: center;
}

/* ── De uitgang en de taal ───────────────────────────────────────── */

/* De bel zelf staat in scene.css en hangt aan de scène hierboven, dus in de hoek
   van het beeld — zoals op elke andere pagina. Hij stond eerst in de kopregel
   van het vel; op een breed scherm is dat een heel eind naar binnen, en dan is
   de agenda de enige pagina waar de uitgang ergens anders zit.

   De taalwissel eronder, met dezelfde formule als in de gang, de vitrine en het
   boek: twee keer de inzet plus de hoogte van de bel (1,33 × zijn breedte, het
   woord eronder meegeteld). Niet in `cqw`, want in de staande stand schakelt de
   bel over op rem.

   Als bordje (`.hm-langs-plaque`, uiterlijk in scene.css) en niet als kale
   letters: die zaten hier op het papier omdat ze op het marmer wegvielen, en dat
   is nou precies waar het geverfde bordje voor is. */
.hm-agenda-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}

.hm-agenda-room {
    position: relative;
    display: grid;
    /* Links de plek van de hanger, rechts het vel. De hanger ligt er los
       overheen, dus de eerste kolom is leeg: hij houdt alleen de ruimte vrij. */
    grid-template-columns: var(--hotelmodern-agenda-tag-column) minmax(0, 1fr);
    /* Eén rij, precies zo hoog als de scène. Zonder die maat leidt de browser de
       rijhoogte af uit de inhoud van het vel — en dat is de hele speellijst, dus
       werd de rij ruim tweeduizend pixels hoog en zakte de hanger ernaast tot
       buiten beeld. Met een vaste rij krijgt het vel een echte hoogte om zijn
       scrollvlak in te hangen. */
    grid-template-rows: minmax(0, 1fr);
    align-items: stretch;
    gap: clamp(0.5rem, 1.5vw, 1.5rem);
    width: 100%;
    max-width: var(--hotelmodern-agenda-max);
    height: 100%;
    margin: 0 auto;
    padding: clamp(1rem, 3vh, 3rem) var(--hotelmodern-agenda-pad);
    box-sizing: border-box;
}

/* De rechterbovenhoek is van de bel, ook hier. Zolang het blad smaller is dan
   het venster valt de bel vanzelf naast het vel: op een breed scherm staat het
   blad op 16:9 en blijft er marmer over. Maar een laptop is meestal 16:10 of
   krapper, en dan vult het blad het hele venster — op 1280 breed liep het vel
   door tot 32px van de rand terwijl de bel op 85px van die rand begint, dus
   lagen de bel én de taalbordjes op het papier.

   De marge rechts is daarom minstens zo breed als de hoek die de bel nodig heeft.
   Die hoek wordt niet door de bel bepaald maar door het breedste taalbordje
   eronder — "Nederlands" is 7,5rem bij de maat uit scene.css, de bel maar 5% van
   het blad — plus de inzet waarop de stapel staat en een handbreedte lucht.
   Blijft er meer over, dan wint de gewone bladmarge en verandert er niets.

   De zwarte band naast het blad telt hier niet meer mee: sinds de bel op de maat
   van de gang hangt, zit hij in de hoek van het blád en niet in die van het
   venster. Wat hier gerekend wordt is dus alles binnen het blad.

   Die lucht (7rem) is er niet alleen om botsing te vermijden maar om het vel
   smaller te maken: het is een vel op een blad, en dan hoort er marmer omheen te
   liggen. Zonder die marge liep het papier tot vlak naast de bel en las het als
   een vlak dat het venster vult. Ze stond op 6rem en daaronder op 3rem; met de
   speellijst die zelf bij 54rem stilstaat bleef er rechts van het papier ruimte
   over die nergens voor diende.

   Smaller máken kan alleen hier, aan de rechterkant: links ligt de sleutelhanger
   over het vel heen, en die overlap is nou juist de bedoeling.

   Alleen liggend. Staand hangt de bel in de kopregel en is die hoek gewoon
   papier; daar zou dit tachtig pixels weggooien voor niets. Telefoons vielen al
   buiten schot via de regel op `max-width: 48rem` verderop, maar een tablet in
   portret niet. */
@media (min-aspect-ratio: 6/5) {
    .hm-agenda-room {
        padding-right: max(
            var(--hotelmodern-agenda-pad),
            calc(var(--hm-bell-inset) + 7.5rem + 7rem)
        );
    }
}

/* ── De sleutelhanger ────────────────────────────────────────────── */

/* De verhouding is die van de plaat zelf (448×750): de hanger is een kaartje met
   een sleutel en een koord eraan, en dat rek je niet op. Doordat de wikkel
   dezelfde verhouding heeft, gelden de insets hieronder voor het kaartje en niet
   voor de kolom eromheen.

   Hij hangt tegen de linkerrand van de scène op `left: 0.5%`, dezelfde regel als
   het sleutelbord in de gang, en daarom hangt hij aan de scène en niet in de
   kamer: die staat gecentreerd binnen 90rem, dus vanuit de kamer gerekend zou
   "de rand" op elk scherm ergens anders liggen. */
.hm-agenda-tag {
    position: absolute;
    z-index: 2;
    /* Tegen de linkerrand van het blad, en dat is nu de zijwand van de gang:
       staat het blad smaller dan het venster (elk scherm hoger dan 16:9), dan
       schuift de hanger die halve marge mee naar binnen. Vult het blad het
       scherm, dan blijft de 0,5% over waarop het sleutelbord in de gang ook
       hangt. */
    left: max(0.5%, calc((100% - var(--hotelmodern-agenda-max)) / 2));
    /* Even laag als in de gang. Daar hangt het sleutelbord op `bottom: 0` van
       een kamer van 16:9 die midden in de zwarte doos staat; is die kamer hoger
       dan de doos — en dat is ze op elk scherm dat breder is dan 16:9 — dan
       loopt de plaat aan de onderkant het beeld uit. Dit is diezelfde onderrand,
       hier uitgerekend: de helft van het verschil tussen de scène (100%) en die
       kamer (min(100vw x 9/16, 100dvh)). Meestal negatief, en dan valt de plaat
       er net zo ver uit als in de gang.

       Gecentreerd stond hij hiervoor, omdat de gang zijn bord aan de onderrand
       van een kamer hangt en hier het scherm de kamer is. Maar dat liet hem
       halverwege het marmer zweven terwijl hij in de gang van boven tot onder
       staat, en dat is het verschil dat je ziet als je van de ene pagina naar de
       andere gaat. */
    bottom: calc((100% - min(100vw * 9 / 16, 100dvh)) / 2);
    width: var(--hotelmodern-agenda-tag);
    aspect-ratio: 448 / 750;
    /* De bordjes erop rekenen in `cqw`, dus in breedte van het kaartje zelf:
       zo schalen ze mee met de hanger in plaats van met het venster. Zelfde
       aanpak als het sleutelbord in de gang. */
    container-type: inline-size;
    /* Hij ligt over het vel heen, dus vangt hij daar geen klikken: onder dat
       stukje staat de speellijst. Het beschreven vlak krijgt ze terug — dat
       blijft ruim binnen de gerafelde rand. */
    pointer-events: none;
}

.hm-agenda-tag-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    filter: drop-shadow(0 0.5rem 1rem rgba(0, 0, 0, 0.45));
}

/* Het beschrijfbare vlak van het kaartje, uitgemeten in het origineel: onder de
   sleutel door (vanaf 32% hoogte) en van de gerafelde rechterrand af (25%). */
.hm-agenda-tag-inner {
    pointer-events: auto;
    position: absolute;
    top: 32%;
    right: 25%;
    bottom: 6%;
    left: 10%;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.hm-agenda-tag-title {
    margin: 0 0 0.5rem;
    text-align: center;
}

/* De bordjes. Op het sleutelbord in de gang staat elke voorstelling in een
   omlijst vakje met haar eigen typografie erin, en op de agenda van de oude site
   ook — dat is wat deze hanger hoort te tonen. Hier zijn het knoppen en geen
   links, want ze filteren de lijst ernaast in plaats van weg te navigeren.

   Inkt en lijn zijn die van het sleutelbord (#2b1a10 op karton), zodat een
   bordje overal in deze tenant hetzelfde ding is. */
.hm-agenda-key {
    display: block;
    width: 100%;
    padding: 3% 5%;
    border: 0.4cqw solid rgba(43, 26, 16, 0.75);
    background: none;
    color: #2b1a10;
    font: inherit;
    letter-spacing: 0.02em;
    text-align: center;
    cursor: pointer;
    transition:
        background-color 0.25s ease,
        color 0.25s ease;
}

.hm-agenda-key:hover,
.hm-agenda-key:focus-visible,
.hm-agenda-key-item.selected .hm-agenda-key {
    background: rgba(135, 29, 15, 0.12);
    color: var(--hotelmodern-accent, #871d0f);
}

.hm-agenda-key-title {
    display: block;
    font-family: var(--hotelmodern-font-heading);
    font-size: 6cqw;
    line-height: 1.15;
}

/* De eigen typografie van de voorstelling. De titeltekst blijft in de DOM voor
   schermlezer en zoekmachine, maar wordt visueel vervangen zodra er een logo is
   — dezelfde regel als op het sleutelbord en in de nieuwskolom. */
.hm-agenda-key-logo {
    display: block;
    width: 100%;
    height: auto;
    max-height: 14cqw;
    object-fit: contain;
}

.hm-agenda-key-title.has-logo .hm-agenda-key-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}

/* De kop boven de bordjes is geen bordje: hij zet de lijst terug op alles. */
.hm-agenda-tag-title .hm-agenda-key {
    padding: 0;
    border: 0;
    font-size: 4.5cqw;
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.hm-agenda-tag-title .hm-agenda-key:hover,
.hm-agenda-tag-title .hm-agenda-key:focus-visible,
.hm-agenda-tag-title .hm-agenda-key.selected {
    background: none;
    color: var(--hotelmodern-accent, #871d0f);
}

.hm-agenda-keys {
    flex: 1;
    min-height: 0;
    margin: 0;
    /* Onderaan ruimte voor de pijlen, die over het kaartje zweven: iets meer
       dan de twee knoppen samen hoog zijn, anders staat de onderste regel er
       nog half achter zodra je helemaal naar beneden scrolt. */
    padding: 0 0 3.75rem;
    list-style: none;
    overflow-y: auto;
}

/* Ruimte tússen de bordjes, niet eromheen: het eerste bordje hoort tegen de kop
   aan te staan. */
.hm-agenda-key-item + .hm-agenda-key-item {
    margin-top: 4%;
}

/* ── Het vel ─────────────────────────────────────────────────────── */

/* Het vel draagt zijn eigen papier. Dat kwam tot 07-09-2026 van
   `.hm-room-block`, de klasse die elk blok op de voorstellingspagina een eigen
   velletje gaf; sinds die pagina één groot vel is levert die klasse geen papier
   meer, en lag de speellijst hier kaal op het marmer. Nu staat het hier, met
   hetzelfde geschepte vel als de kamer (zie `.hm-room-content-inner` in
   roomview.css): dezelfde tenant, hetzelfde papier.

   `repeat` en niet `cover`: het vel is zo hoog als de scène, en de scan van
   800x800 tegelt naadloos — uitgerekt zou hij een verticale veeg worden. De
   kleur eronder is het gemiddelde van die scan, zodat het vel de goede tint
   houdt zolang het beeld nog niet binnen is.

   Verder alleen de indeling: het vel vult de hoogte van de scène en het scrollen
   gebeurt erbinnen, zodat de kop en het register blijven staan.

   De tweede kolom staat er expliciet bij: de eerste is leeg — de hanger hangt
   los tegen de schermrand — dus zonder deze regel schuift het vel er vanzelf
   in en ligt het over de volle breedte van het blad. */
.hm-agenda-paper {
    grid-column: 2;
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    height: 100%;
    background-color: #eeece6;
    background-image: url(/images/hotelmodern/paper-fibre-14789b293d17400767515634ff033e55.webp?vsn=d);
    background-repeat: repeat;
    box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.45);
    padding: clamp(1rem, 2.5vh, 2rem) clamp(1rem, 2.5vw, 2.5rem);
    /* Links de overlap erbij: het papier loopt onder de hanger door, maar wat
       erop staat begint pas voorbij de sleutel. Het vel wordt er dus breder van
       zonder dat de lijst onder de plaat schuift. */
    padding-left: calc(clamp(1rem, 2.5vw, 2.5rem) + var(--hotelmodern-agenda-tag-overlap));
    box-sizing: border-box;

    /* Inkt in plaats van zwart. Alles op dit vel stond op `rgba(0, 0, 0, …)`, en
       zuiver zwart op wit papier is precies wat drukwerk nooit is: het leest als
       tekst die óp het vel ligt in plaats van erin getrokken. Een warme donkere
       toon doet wat drukinkt doet — hij neemt de kleur van het papier aan.

       Als losse getallen, zodat de doorzichtigheid per plek kan verschillen
       zonder de kleur te herhalen: de titel staat vol, een bijschrift halfweg, de
       scheidingslijn nog lichter. Dat waren voorheen negen keer `0, 0, 0` met een
       eigen alfa erachter. */
    --hm-agenda-inkt: 42 32 24;
    color: rgb(var(--hm-agenda-inkt) / 0.92);
}

/* Het origineel had hier een dubbele lijn onder de kop. Die is eruit: het
   gestempelde AGENDA draagt de kop zelf al, en een streep erbij maakte van het
   vel een formulier. */
/* Alleen nog het stempel, in het midden van het vel: de taalwissel en de bel
   hangen nu in de hoek van de scène (zie bovenaan). Dat scheelde het raster van
   drie kolommen dat hier stond om die twee uit elkaar te houden. */
.hm-agenda-header {
    display: flex;
    justify-content: center;
    padding-bottom: clamp(0.4rem, 1vh, 0.75rem);
}

.hm-agenda-title {
    display: block;
    width: clamp(6rem, 12vw, 10rem);
    height: auto;
}

/* Het register: binnenkort of eerder gespeeld. Zelfde vorm als de tabbladen op
   het nieuwsbord, maar in inkt op papier in plaats van wit op zwart. */
.hm-agenda-register {
    display: flex;
    justify-content: center;
    gap: clamp(0.75rem, 2vw, 2rem);
    padding: clamp(0.5rem, 1.2vh, 1rem) 0;
}

.hm-agenda-tab {
    padding: 0.15em 0;
    border: 0;
    background: none;
    color: rgb(var(--hm-agenda-inkt) / 0.55);
    font: inherit;
    font-size: clamp(0.7rem, 0.9vw, 0.9rem);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
    transition: color 0.15s ease-out;
}

.hm-agenda-tab:hover,
.hm-agenda-tab:focus-visible {
    color: #000;
}

/* Alleen kleur, geen onderstreping: het register telt twee woorden, en die
   verschillen in kleur genoeg om te zien waar je staat. */
.hm-agenda-tab.selected {
    color: var(--hotelmodern-accent, #871d0f);
}

/* ── De pijlen ───────────────────────────────────────────────────── */

/* Twee pijlen rechtsonder, op het kaartje en op het vel — precies waar het
   origineel ze had. Daar wáren ze het scrollen; hier zeggen ze alleen dat er
   meer is. Dat is op deze twee vlakken geen overbodige mededeling: een vel
   papier en een kaartje met een gescheurde rand hebben geen zichtbare bodem, dus
   een afgesneden regel leest als het einde van de lijst.

   De pijl is `voorstellingen/arrow.svg` als masker, net als op het sleutelbord:
   één bestand voor beide richtingen, en hij neemt de inkt van zijn omgeving aan.
   Zichtbaarheid en het uitgaan aan het eind doet de hook HmScroll. */
.hm-agenda-arrows {
    position: absolute;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    z-index: 2;
}

.hm-agenda-arrows[hidden] {
    display: none;
}

.hm-agenda-arrows button {
    padding: 0.2rem;
    border: 0;
    background: none;
    color: #2b1a10;
    cursor: pointer;
    opacity: 0.7;
    transition: opacity 0.2s ease;
}

.hm-agenda-arrows button:hover,
.hm-agenda-arrows button:focus-visible {
    opacity: 1;
}

.hm-agenda-arrows button:disabled {
    opacity: 0.2;
    cursor: default;
}

.hm-agenda-arrow {
    display: block;
    width: clamp(0.5rem, 0.8vw, 0.75rem);
    aspect-ratio: 19 / 40;
    background: currentColor;
    -webkit-mask: url("/assets/hotelmodern/voorstellingen/arrow-9e91cac7deb036c17c0a0931e14d3913.svg?vsn=d") center /
        contain no-repeat;
    mask: url("/assets/hotelmodern/voorstellingen/arrow-9e91cac7deb036c17c0a0931e14d3913.svg?vsn=d") center / contain no-repeat;
}

[data-scroll="up"] .hm-agenda-arrow {
    transform: rotate(180deg);
}

/* Op de hanger staan ze buiten het beschreven vlak, tegen de gescheurde rand
   aan: de lijst houdt rechts een kwart van het kaartje vrij, en daar hoorden de
   pijlen in het origineel. Vandaar dat ze een stukje búiten hun vak steken. */
.hm-agenda-keys-arrows {
    right: -8%;
}

/* Op het vel staan ze in de hoek van het papier, met de lijst eromheen: vandaar
   de ruimte rechtsonder in het scrollvlak (zie .hm-agenda-scroll). */
.hm-agenda-scroll-arrows {
    right: clamp(0.25rem, 0.5vw, 0.75rem);
    bottom: clamp(0.25rem, 0.5vh, 0.75rem);
}

/* De redactieregel: alleen zichtbaar voor wie is ingelogd. Bewust klein en
   gedempt — het is gereedschap, geen onderdeel van de scène. */
.hm-agenda-admin {
    display: flex;
    justify-content: center;
    gap: 1rem;
    padding-bottom: 0.5rem;
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.hm-agenda-admin a {
    color: rgb(var(--hm-agenda-inkt) / 0.5);
    text-decoration: none;
}

.hm-agenda-admin a:hover,
.hm-agenda-admin a:focus-visible {
    color: var(--hotelmodern-accent, #871d0f);
}

/* Het scrollvlak. In het origineel scrolde dit alleen met de twee pijltjes
   ernaast — wiel noch veeg deed iets. Hier is het een gewoon scrollvlak; de
   pijltjes zijn daarmee overbodig geworden. */
.hm-agenda-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    /* De balk krijgt altijd zijn strook: verschijnt hij pas als de lijst lang
       genoeg is, dan verspringt de kolombreedte van de tabel eronder. */
    scrollbar-gutter: stable;
    /* Onderaan ruimte voor de pijlen: de laatste regel hoort er niet onder door
       te schuiven. Even hoog als de twee knoppen samen, plus wat lucht. */
    padding-bottom: 3.75rem;
}

/* ── De speellijst ───────────────────────────────────────────────── */

/* Geen tabel maar een raster per speelbeurt: datum en tijd links, dan de titel
   met de plaats eronder, en de kaartjeslink rechts. */

/* De lijst is zo breed als ze nodig heeft en staat gecentreerd op het vel. Zonder
   die grens rekt het raster mee met het papier en komt de kaartjeslink meters van
   de titel af te staan — hetzelfde gat dat de tabel eerder maakte. De maat is de
   54rem die de tenant overal voor een beschreven vel aanhoudt (zie
   `.hm-room-content-inner` in roomview.css); op de 46rem die hier stond bleef er
   op een breed scherm een strook papier leeg naast een lijst die zelf in de
   knel zat. */
.hm-agenda-month-block {
    max-width: 54rem;
    margin-inline: auto;
}

.hm-agenda-month-block + .hm-agenda-month-block {
    margin-top: clamp(2rem, 4vh, 3.5rem);
}

/* De maandkop staat op de oude site in rood en in kleine letters. Hij mag de
   lijst aankondigen, dus hij is groter dan een regel eronder en heeft lucht om
   zich heen — dat is wat de maanden uit elkaar houdt nu er geen streep meer
   tussen de regels staat. */
.hm-agenda-month {
    margin: 0 0 clamp(0.75rem, 1.5vh, 1.25rem);
    padding: 0;
    color: var(--hotelmodern-accent, #871d0f);
    font-family: var(--hotelmodern-font-heading);
    font-size: clamp(1.25rem, 1.9vw, 2rem);
    font-weight: 700;
    letter-spacing: 0.04em;
    line-height: 1.1;
    text-align: left;
}

/* De platform-CSS zet een eigen maat op elke h3 binnen deze tenant; die is voor
   bordjes bedoeld en wint anders van de regel hierboven. */
body.hotelmodern .hm-agenda-month {
    font-size: clamp(1.25rem, 1.9vw, 2rem);
    letter-spacing: 0.04em;
}

.hm-agenda-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Vier kolommen: datum, tijd, tekst, kaartjes. De datum loopt over beide rijen;
   de tekst vult ze — titel boven, plaats onder.

   Het affiche stond hier links en zette de hoogte van de regel. Het is eruit:
   een speellijst is bijna altijd één voorstelling, en dan herhaalt dezelfde foto
   zich tientallen keren onder elkaar. Zonder die kolom hoeft de regel ook niet
   meer twee rijen hoog te zijn om een staand affiche te vullen — datum, tijd,
   titel en plaats staan nu op één regel, zoals in een echte speellijst. */
.hm-agenda-item {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    grid-template-areas:
        "datum tijd titel kaartjes"
        "datum tijd plaats kaartjes";
    grid-template-rows: auto minmax(0, 1fr);
    column-gap: clamp(0.75rem, 1.5vw, 1.5rem);
    align-items: start;
    padding-bottom: clamp(0.45rem, 0.8vh, 0.7rem);
}

/* De scheiding tussen twee speelbeurten. Die deed het affiche: dat was hoger dan
   de tekst ernaast, dus zette het de regelafstand én stonden de affiches als een
   strook onder elkaar. Nu het weg is, is de regel precies zo hoog als zijn tekst
   en lopen twee speelbeurten in elkaar over — zeker als ze dezelfde titel dragen,
   wat op een speellijst de regel is en niet de uitzondering.

   Een haarlijn en geen extra witruimte: op een vel met tien of meer regels kost
   lucht alleen maar hoogte, terwijl een lijn zegt waar de ene datum ophoudt. Hij
   staat tússen de regels (`+`), dus niet boven de eerste onder een maandkop en
   niet onder de laatste. In dezelfde gedempte inkt als de bijschriften, zodat hij
   op het papier ligt en er geen formulier van maakt. */
.hm-agenda-item + .hm-agenda-item {
    border-top: 0.0625rem solid rgb(var(--hm-agenda-inkt) / 0.12);
    padding-top: clamp(0.45rem, 0.8vh, 0.7rem);
}

/* De datum draagt de regel, dus groot — maar in de gewone snede en in gedempte
   inkt, zodat hij de titel niet beconcurreert. Deze letter heeft alleen 400 en
   700; "lichter" komt hier dus van de kleur, niet van het gewicht. */
.hm-agenda-day {
    grid-area: datum;
    display: block;
    width: 3.5rem;
    padding-top: 0.2rem;
    color: rgb(var(--hm-agenda-inkt) / 0.6);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.hm-agenda-weekday {
    display: block;
    font-size: clamp(0.9rem, 1.1vw, 1.15rem);
    letter-spacing: 0.06em;
}

.hm-agenda-daynum {
    display: block;
    margin-top: 0.1rem;
    font-size: clamp(1.5rem, 1.9vw, 2rem);
    line-height: 1;
}

/* De tijd in de accentkleur van de tenant, verder gewoon: het donkere
   wekkerdisplay dat hier eerst stond trok alle aandacht naar het minst
   belangrijke getal op de regel. */
.hm-agenda-hour {
    grid-area: tijd;
    margin: 0;
    padding-top: 0.35rem;
    width: 3.25rem;
    color: var(--hotelmodern-accent, #871d0f);
    font-size: clamp(0.85rem, 1.05vw, 1.05rem);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

/* De twee tekstblokken erfden de regelafstand van het vel (1,8). Een titel van
   één regel zat daardoor in een regelbox van bijna twee, en dat twee keer per
   speelbeurt — bij elkaar de helft van de hoogte van de regel. Hier staat de
   afstand die bij een lijst hoort; de lucht tussen de speelbeurten doet het
   werk, niet de lucht binnen een regel. */
.hm-agenda-what,
.hm-agenda-where {
    line-height: 1.25;
}

.hm-agenda-what {
    grid-area: titel;
    margin: 0;
    padding-top: 0.25rem;
}

/* De aanzet van de inkt: een minieme vervaging in de eigen kleur, waardoor de
   letterrand niet kaarsrecht is maar een haartje uitloopt — wat inkt op papier
   doet. Alleen op de titel: die is vet en groot genoeg om het te dragen, terwijl
   een bijschrift van 0,85rem er alleen wazig van wordt. */
.hm-agenda-production {
    color: inherit;
    font-size: clamp(1.05rem, 1.35vw, 1.45rem);
    font-weight: 700;
    line-height: 1.15;
    text-decoration: none;
    text-shadow: 0 0 0.03em currentColor;
}

.hm-agenda-production:hover,
.hm-agenda-production:focus-visible {
    color: var(--hotelmodern-accent, #871d0f);
    text-decoration: underline;
}

/* De zaal, het soort speelbeurt, "franstalig": bijschriften bij de titel, dus
   kleiner en gedempt. Ze stonden tot 06-08-2026 op één regel mét de herkomst uit
   de importtaken ("uit de WP-agenda") — die staat nu in een eigen kolom in de
   database en niet meer op deze pagina. */
/* Stond onder de titel op een eigen regel. Achter de titel scheelt dat een hele
   regel per speelbeurt, en het leest ook zo: "Garnalen Verhalen · franstalig"
   is één mededeling. Het puntje komt uit de CSS en niet uit de opmaak, zodat er
   geen los teken blijft staan als er geen notitie is. */
.hm-agenda-note {
    display: inline;
    color: rgb(var(--hm-agenda-inkt) / 0.6);
    font-size: 0.85rem;
    line-height: 1.35;
}

.hm-agenda-production + .hm-agenda-note::before {
    content: "·";
    margin: 0 0.35rem;
}

/* De plaats is het tweede wat je zoekt na de datum, dus groot en in kapitalen —
   maar in de gewone snede en met ruime spatiëring, zodat het naast de vette
   titel geen tweede kop wordt. Direct onder de titel: uitgelijnd op de onderrand
   stond de plaatsnaam dichter bij de titel van de vólgende speelbeurt dan bij
   haar eigen, en dan leest de nabijheid je de verkeerde kant op. */
.hm-agenda-where {
    grid-area: plaats;
    align-self: start;
    margin: 0.05rem 0 0;
}

/* Stad en zaal stonden onder elkaar. Naast elkaar scheelt dat de tweede regel
   van het blok — samen met de notitie hierboven is dat de helft van de hoogte
   van een speelbeurt, en dat is waar de redactie om vroeg: meer data in beeld.
   De rangorde blijft zichtbaar in de letter zelf: de stad in kapitalen en
   gespatieerd, de zaal klein en gedempt erachter. */
.hm-agenda-city {
    display: inline;
    font-size: clamp(0.95rem, 1.15vw, 1.2rem);
    font-weight: 400;
    letter-spacing: 0.12em;
    line-height: 1.2;
    text-transform: uppercase;
    color: rgb(var(--hm-agenda-inkt) / 0.8);
}

.hm-agenda-venue {
    color: rgb(var(--hm-agenda-inkt) / 0.6);
    font-size: 0.85rem;
}

.hm-agenda-city + .hm-agenda-venue::before {
    content: "·";
    margin: 0 0.35rem;
}

a.hm-agenda-venue:hover,
a.hm-agenda-venue:focus-visible {
    color: var(--hotelmodern-accent, #871d0f);
}

/* Ingelogd krijgt de regel een derde rij, over de volle breedte onder titel en
   plaats. Een bezoeker ziet de lijst onveranderd, en het potlood deelt zo geen
   cel met de kaartjeslink. */
.hm-agenda-item.is-admin {
    grid-template-areas:
        "datum tijd titel kaartjes"
        "datum tijd plaats kaartjes"
        "datum tijd beheer beheer";
    grid-template-rows: auto minmax(0, 1fr) auto;
}

.hm-agenda-actions {
    grid-area: beheer;
    display: flex;
    gap: 1.5rem;
    padding-top: 0.3rem;
}

.hm-agenda-actions a,
.hm-agenda-actions button {
    /* Zelf een flexregel: dan telt de witruimte tussen het pictogram en het
       woord in de opmaak niet mee, en staat de afstand ertussen (0.35rem) los
       van de afstand tussen de twee knopjes (1.5rem). Anders lijken ze even ver
       en hoort het pictogram net zo goed bij het woord ernaast. */
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: rgb(var(--hm-agenda-inkt) / 0.5);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
}

.hm-agenda-actions a:hover,
.hm-agenda-actions button:hover,
.hm-agenda-actions a:focus-visible,
.hm-agenda-actions button:focus-visible {
    color: var(--hotelmodern-accent, #871d0f);
}

/* Het potlood en de prullenbak zijn maskers: zonder achtergrondkleur zijn ze
   er wel, maar zie je ze niet. Buiten de scènepagina's zet `admin.css` die
   kleur (`body.hotelmodern:not(:has(.hm-stage))`), en de balie ís een scène —
   dus hier zelf, op de kleur van het woord ernaast. Zo lopen ze mee naar het
   rood zodra je erop staat. */
.hm-agenda-actions [class*="icon-"] {
    width: 0.85rem;
    height: 0.85rem;
    background-color: currentColor;
    vertical-align: -0.1em;
}

.hm-agenda-tickets {
    grid-area: kaartjes;
    margin: 0;
    padding-top: 0.5rem;
    text-align: right;
    white-space: nowrap;
}

.hm-agenda-tickets a {
    color: var(--hotelmodern-accent, #871d0f);
    font-size: 0.85rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
}

.hm-agenda-tickets a:hover,
.hm-agenda-tickets a:focus-visible {
    text-decoration: underline;
}

/* Het labeltje uit de UIkit-set voor de kaartjeslink. Op kapitaalhoogte gezet en
   iets omlaag, zodat het op de regel staat en niet erboven zweeft; de
   onderstreping bij hover laat het met rust doordat het een eigen vak is. */
.hm-agenda-tickets .icon-tag {
    width: 0.95rem;
    height: 0.95rem;
    margin-right: 0.3rem;
    vertical-align: -0.15em;
}

.hm-agenda-soldout {
    color: rgb(var(--hm-agenda-inkt) / 0.45);
    font-size: 0.85rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.hm-agenda-empty {
    margin: 3rem 0;
    text-align: center;
}

/* ── Smal en laag ────────────────────────────────────────────────── */

/* De hanger kost op een telefoon meer dan hij oplevert: hij duwt het vel in een
   strook en de bordjes erop worden onleesbaar klein. Het register blijft — dat
   is één regel en scheelt hier het meest. Zelfde afweging als de logokolom op
   het nieuwsbord. */
@media (max-width: 48rem) {
    .hm-agenda-room {
        grid-template-columns: 1fr;
        padding: clamp(2rem, 6vh, 3rem) 0.75rem 0.75rem;
    }

    /* Geen hanger, dus ook niet de marge waar hij overheen valt. */
    .hm-agenda-paper {
        grid-column: 1;
        padding-left: clamp(1rem, 2.5vw, 2.5rem);
    }

    .hm-agenda-tag {
        display: none;
    }
}

/* Op een telefoon passen vier kolommen niet naast elkaar. Alles stapelt: datum
   en tijd op één regel, dan de titel, dan de plaats, dan de kaartjes. */
@media (max-width: 34rem) {
    .hm-agenda-item {
        grid-template-columns: auto minmax(0, 1fr);
        grid-template-areas:
            "datum tijd"
            "titel titel"
            "plaats plaats"
            "kaartjes kaartjes";
        align-content: start;
        padding-bottom: 1rem;
    }

    .hm-agenda-where {
        align-self: start;
        padding-bottom: 0;
    }

    .hm-agenda-tickets {
        padding-top: 0.35rem;
        text-align: left;
    }
}

/* Een liggende telefoon is breed genoeg voor de kolom maar te laag voor de
   hanger: die is anderhalf keer zo hoog als breed en zou eruit lopen. */
@media (min-width: 48rem) and (max-height: 30rem) {
    .hm-agenda-tag {
        display: none;
    }

    .hm-agenda-room {
        grid-template-columns: 1fr;
    }

    .hm-agenda-paper {
        grid-column: 1;
        padding-left: clamp(1rem, 2.5vw, 2.5rem);
    }
}

/* ── Ruimte voor de kopregel ─────────────────────────────────────── */

/* Staand ligt de balk (scene.css, `.hm-topbar`) over het marmer boven het vel.
   Het vel raakte niet bedekt, maar de kop AGENDA kwam er met veertien pixels
   onder te hangen en dat leest als weggeschoven. Een balkhoogte plus lucht zet
   hem op dezelfde afstand als de kop van het boek. */
@media (max-aspect-ratio: 6/5) {
    .hm-agenda-room {
        padding-top: calc(var(--hm-topbar-h) + 1rem);
    }
}


/* ── components/contact.css ── */
/* Hotel Modern — het kantoor (/contact/).
   Zelfde zwarte doos als de bioscoop en de hoorspelkamer. De bordjes op de
   tafels wisselen het naamkaartje in het lege vlak boven de scène.
   Percentages komen uit de originele `partials/page/contact` CSS. */

/* De maat van de kamer staat als variabele op de scène, want de vulstroken in
   portret moeten er exact even breed en op dezelfde plek uitkomen. */
.hm-contact {
    --hm-room-w: min(calc(100vw - 30px), calc((100dvh - 30px) * 1366 / 768));
    --hm-room-h: calc(var(--hm-room-w) * 768 / 1366);
}

/* Expliciete breedte en geen `max-width`, want `container-type` hieronder mag de
   inline-maat niet uit de inhoud halen. De 30px van het kader gaan er meteen af,
   anders steekt de doos precies zijn randdikte buiten het venster. */
.hm-contact-room {
    aspect-ratio: 1366 / 768;
    width: var(--hm-room-w);
    container-type: inline-size;
    position: relative;
    overflow: hidden;
    border: 15px solid #000;
    box-sizing: content-box;
}

/* De <picture> moet zelf de doos vullen, anders heeft de `height: 100%` van de
   plaat geen hoogte om zich tegen af te zetten en valt hij terug op `auto`. */
.hm-contact-room > picture {
    display: block;
    width: 100%;
    height: 100%;
}

.hm-contact-bg {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ── Props ───────────────────────────────────────────────────────── */

.hm-contact-props {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-contact-prop {
    position: absolute;
    z-index: 1000;
}

.hm-contact-prop img {
    display: block;
    width: 100%;
    height: auto;
}

.hm-contact-prop a,
.hm-contact-prop button {
    display: block;
    position: relative;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    transition: transform 0.2s ease-out, filter 0.2s ease-out;
}

/* Hover is een duwtje: even groter, en weer terug. Geldt óók voor het bordje dat
   al aan staat — een prop die niet reageert leest als kapot, niet als "die staat
   al aan". */
.hm-contact-prop a:hover,
.hm-contact-prop a:focus-visible,
.hm-contact-prop button:hover,
.hm-contact-prop button:focus-visible {
    transform: scale(1.04);
}

/* Het licht van hover alleen als het bordje níet aan staat, anders vecht het met
   de sterkere aan-filter hieronder. */
.hm-contact-prop a:hover,
.hm-contact-prop a:focus-visible,
.hm-contact-prop button:not(.hm-contact-switch-on):hover,
.hm-contact-prop button:not(.hm-contact-switch-on):focus-visible {
    filter: brightness(1.12);
}

/* Het bordje dat aan staat, blijft aan: licht plus een slagschaduw. De schaduw
   valt op de alpha van de uitgeknipte PNG en tilt de prop dus echt van het
   tafelblad — in een maquette het juiste gebaar, en iets heel anders dan het
   duwtje van hover, zodat "aangewezen" en "aan" niet op elkaar lijken. */
.hm-contact-prop button.hm-contact-switch-on {
    filter: brightness(1.2) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.55));
}

/* ── Raakvlak ────────────────────────────────────────────────────── */

/* De props zijn uitgeknipte foto's en hun hoogte volgt de plaat. Twee ervan
   liggen plat op het bureau en zijn dus breed en laag: op een telefoon van 390
   was PUBLICITEIT 55×19 en verkoop 36×13. Dat is te klein om te raken — WCAG
   2.5.8 vraagt 24×24, en een vingertop is eerder 40.

   Het raakvlak groeit hier zonder dat de tekening meebeweegt: een onzichtbare
   `::after` midden op de prop. `max()` betekent groeien-of-niets, dus een prop
   die al groot genoeg is (de ordner, het bordje MANAGER, de hele scène op een
   desktop) verandert niet.

   2,5rem en niet de 2,75rem van de Apple-richtlijn: op 390 staat verkoop 8 van
   PUBLICITEIT en het bordje MANAGER 1 van de telefoon. Bij 44 raken die elkaar;
   bij 40 blijft er tussen alle paren ruimte over. Beter een maat die overal past
   dan een maat die de knoppen op elkaar duwt — twee knoppen die elkaar
   overlappen is erger dan een knop die iets kleiner is. */
.hm-contact-prop > a::after,
.hm-contact-prop > button::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(100%, 2.5rem);
    height: max(100%, 2.5rem);
    transform: translate(-50%, -50%);
}

/* De vier social-badges staan op een vaste steek van elkaar (zie
   `.hm-contact-social`), dus hier is de ruimte de begrenzing en niet de plaat:
   op 390 is de steek 41 en zijn de badges 31. Op 2,25rem blijft er 5 tussen
   staan; op 2,5rem zou dat 1 zijn, en dan tikt de duim naast. */
.hm-contact-social a::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(100%, 2.25rem);
    height: max(100%, 2.25rem);
    transform: translate(-50%, -50%);
}

.hm-contact-social a {
    position: relative;
}

.hm-contact-prop-phone {
    width: 12.0058565154%;
    left: 1%;
    top: 23%;
}

.hm-contact-prop-manager {
    width: 8.5651537335%;
    left: 14.5%;
    top: 41%;
}

.hm-contact-prop-publicity {
    width: 10.8345534407%;
    right: 16.5%;
    top: 50%;
}

.hm-contact-prop-sales {
    width: 8.1259150805%;
    right: 8%;
    top: 51%;
}

.hm-contact-prop-press {
    width: 12.0058565154%;
    right: 10%;
    bottom: 0;
}

/* ── Social ──────────────────────────────────────────────────────── */

/* In het origineel stond dit blok zonder `left` — de li viel dan terug op zijn
   statische plek tegen de linkerrand. Hier staat dat er expliciet. */
.hm-contact-prop-social {
    width: 11.7130307467%;
    left: 0;
    bottom: 8%;
}

.hm-contact-social {
    display: flex;
    justify-content: center;
    gap: 2%;
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-contact-social li {
    width: 20%;
}

/* ── De naamkaartjes ─────────────────────────────────────────────── */

/* Het vlak bovenaan waar de drie kaartjes in wisselen. In het origineel had elk
   bordje zijn eigen `.prop-content`, met percentages ten opzichte van dat
   bordje; uitgerekend landen ze alle drie in ditzelfde vlak (x 424–1024,
   y 23 van 1366×768). Eén paneel dus, en de klapper zit in de klasse. */
.hm-contact-notes {
    position: absolute;
    left: 31.04%;
    top: 3%;
    width: 43.92%;
    z-index: 900;
    text-align: center;
    color: #000;
    font-size: 1.8cqw;
    font-weight: 700;
    line-height: 1.2;
}

.hm-contact-note {
    display: none;
}

.hm-contact-note-on {
    display: block;
}

/* De regelafstand hóórt hier te staan en niet alleen op `.hm-contact-notes`:
   `reset.css` zet `p { line-height: 1.8 }`, en een regel die de `p` zelf raakt
   wint van wat er overerft. Zonder dit staat het kaartje anderhalf keer te los —
   in portret loopt het dan de social-rij eronder in. */
.hm-contact-note p {
    margin: 0;
    line-height: 1.2;
}

/* De functie boven de naam, in de kopletter — het bordje op tafel zegt het al,
   maar niet meer zodra het kaartje het overneemt. */
.hm-contact-note .hm-contact-role {
    font-family: var(--hotelmodern-font-heading);
    margin-bottom: 0.2em;
}

.hm-contact-note a {
    color: var(--hotelmodern-accent);
    text-decoration: none;
}

.hm-contact-note a:hover,
.hm-contact-note a:focus-visible {
    text-decoration: underline;
}

/* Taalwissel: onder de bel, in dezelfde hoek en op dezelfde afstand als in de
   gang en de vitrine (zie corridor.css voor de rekensom). Het uiterlijk staat in
   scene.css (`.hm-langs-plaque`). */
.hm-contact-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}

/* ── Portret ─────────────────────────────────────────────────────── */

/* Smaller dan 6:5 wint de staande plaat, net als bij `/over`: precies het punt
   waar de liggende plaat — die altijd hélemaal in beeld moet passen — tot een
   strook inkrimpt. De hoorspelkamer lost dit op door de scène horizontaal te
   laten schuiven; dat kan daar, want daar is de hele kamer decor. Hier staat de
   inhoud van de pagina in de scène, en die mag je niet uit beeld moeten duwen.

   In de staande plaat (1366×1450) zit de opname in de onderste 52,97%. Door de
   props-laag daarheen te verplaatsen blijven álle percentages hierboven in beide
   platen kloppen — geen enkele hotspot krijgt een tweede set maten. */
@media (max-aspect-ratio: 6/5) {
    .hm-contact {
        --hm-room-w: min(100vw, calc(100dvh * 1366 / 1450));
        --hm-room-h: calc(var(--hm-room-w) * 1450 / 1366);

        /* Waar het kaartje begint, gerekend vanaf de bovenrand van de plaat. Het
           staat als variabele apart omdat de social-rij eronder moet blijven
           hangen: die zit in de props-laag en heeft dus een heel ander
           nulpunt. 140px de muur in, met een rem zodat hij op een toestel met
           minder ruimte niet half wegvalt: van de bovenrand van de kamer naar die
           van het scherm is 100dvh − plaathoogte. */
        --hm-card-top: max(
            calc(2dvh - 100dvh + var(--hm-room-h)),
            calc(var(--hm-room-h) * 0.03 - 140px)
        );

        /* De scène mag met het scherm meegroeien, de tekst en de knoppen niet.
           Een iPad mini geeft de plaat 768px breed — bijna het dubbele van een
           telefoon — en dan wordt 4,8% van die breedte een corps van 37px. Alles
           wat tekst of bedienend element is krijgt daarom een plafond; alles wat
           bij de maquette hoort (de bordjes, de telefoon, de ordner) blijft
           meeschalen, want dat hóórt bij de foto.

           In `--hm-room-w` en niet in `cqw`: container-eenheden rekenen tegen de
           dichtstbijzijnde container-voorouder, en `.hm-contact` ligt buiten
           `.hm-contact-room` en is dat dus niet. */
        --hm-card-font: min(calc(var(--hm-room-w) * 0.048), 22px);

        /* De band waar de kaartjes in staan, gerekend in regels en niet in een
           percentage van de plaat: zodra het corps een plafond heeft, groeit de
           inhoud niet meer mee met de kamer en zou een percentage een gat laten
           vallen tussen de tekst en de social-rij. Vier regels — functie, naam,
           nummer, e-mail — plus wat lucht. */
        --hm-card-h: calc(var(--hm-card-font) * 5.2);
    }

    /* De klip eraf, want de bel en het kaartje moeten bóven de plaat uit kunnen
       steken, het bijgemaakte stuk muur in. Dat mag hier: de plaat vult de doos
       exact en er is geen prop die per ongeluk buiten de rand valt. */
    .hm-contact-room {
        aspect-ratio: 1366 / 1450;
        border-width: 0;
        overflow: visible;
    }

    /* Op een staande telefoon is de plaat maar de helft van het scherm hoog —
       430×932 geeft 476px over — en dan leest de zwarte doos niet meer als doos
       maar als een pagina die niet af is.

       De plaat staat daarom tégen de ónderrand en het gat zit erboven, waar de
       muur het opvult. De omgekeerde volgorde is hier geprobeerd (plaat boven,
       vloer eronder) en die werkt niet: de vloer doortrekken geeft tafelpoten die
       als strepen omlaag lopen, en een effen band eronder leest als een balk
       onder de foto in plaats van als vloer. Boven is er niets van dat probleem,
       want daar staat alleen vlakke muur.

       De vulling is één strookje van 120px dat verticaal wordt uitgerekt. Dat mag
       omdat het een omgeklapt stuk lege muur is: uitrekken is dan een spiegeling
       van iets zonder kenmerken. Hij staat op de scène en niet in de kamer, want
       die klipt zijn inhoud, en krijgt zijn breedte uit dezelfde variabele zodat
       hij exact op de plaat uitlijnt.

       In liggende stand blijft de zwarte doos gewoon staan: daar is de band maar
       9% van het scherm en is het zwart een keuze, geen restje. */
    .hm-contact {
        align-items: flex-end;
    }

    .hm-contact::before {
        content: "";
        position: absolute;
        left: 50%;
        translate: -50% 0;
        width: var(--hm-room-w);
        top: 0;
        bottom: var(--hm-room-h);
        background-image: url("contact/wall-top-1a41d5aeb5f2ca9c7f4120f042e70867.jpg?vsn=d");
        background-repeat: no-repeat;
        background-size: 100% 100%;
    }

    .hm-contact-props {
        top: 47.03%;
        height: 52.97%;
        bottom: auto;
    }

    /* Het kaartje verhuist naar het bijgemaakte stuk muur, op ruim het
       tweeënhalfvoudige corps. Op 1,8cqw zou het hier een paar pixels hoog zijn.

       Vaste band, en níet een blok dat met zijn inhoud meegroeit: dan zou de
       social-rij eronder bij elk ander kaartje een stukje verspringen. */
    .hm-contact-notes {
        left: 6%;
        top: var(--hm-card-top);
        width: 88%;
        height: var(--hm-card-h);
        display: flex;
        align-items: flex-start;
        font-size: var(--hm-card-font);
    }

    .hm-contact-note-on {
        width: 100%;
    }


    /* De social-rij is het ergst: 11,7% breed met vier iconen op 20% elk komt op
       een telefoon neer op 10px per stuk. Ruim verviervoudigd — maar dan past hij
       niet meer in de hoek waar hij in de liggende plaat staat: hij loopt dwars
       over de MANAGER-wimpel en de linkerdame heen. Hij verhuist daarom naar de
       muur, vlak onder het kaartje. Daar hoort hij ook: het zijn geen rekwisieten
       uit de maquette maar een staartje van de contactgegevens.

       De negatieve `top` tilt hem uit de props-laag omhoog het bijgemaakte stuk
       muur in; die laag is een maatraam, geen vlak, dus dat mag. */
    /* De bordjes uitvergroot. Ze staan op de plek waar ze in de foto liggen en
       groeien om hun eigen midden, dus de schaal zit op de `li` en niet op de
       knop erin — die houdt zijn eigen `scale(1.04)` voor hover, en twee
       transforms op één element gaan niet samen.

       Dit tilt ze wel iets van het tafelblad: op deze maat kloppen ze niet meer
       precies met het perspectief van de opname. Dat is de prijs voor leesbaar en
       aantikbaar op een telefoon. Op 1,6x was dat te veel — dan zweefden ze
       zichtbaar; 1,3x houdt ze nog tegen hun meubel aan. */
    .hm-contact-prop-manager,
    .hm-contact-prop-publicity,
    .hm-contact-prop-sales,
    .hm-contact-prop-press {
        transform: scale(1.3);
    }

    /* PUBLICITEIT en verkoop liggen in de opname vlak naast elkaar; op 1,6× lopen
       ze over elkaar heen. Uit elkaar dus — ze staan toch al niet meer precies op
       hun plek op het blad. */
    .hm-contact-prop-publicity {
        right: 20%;
    }

    /* Verkoop is het kleinste bordje en stond na het uit elkaar trekken te ver
       naar rechts; hier iets minder vergroot dan de andere drie en een stukje
       terug naar het midden van het blad. */
    .hm-contact-prop-sales {
        transform: scale(1.15);
        right: 7.5%;
    }

    /* De ordner staat op `bottom: 0`; op 1,6× groeit hij om zijn midden en steekt
       hij dus onder de plaat uit — en die staat hier tegen de onderrand van het
       scherm, dus dat valt eraf. Een eindje omhoog. */
    .hm-contact-prop-press {
        bottom: 4%;
    }

    /* De social-rij liggend onder het kaartje, gecentreerd op de muur. Staand
       tegen de linkerrand paste hij nét niet: tussen de telefoon en de vloer zit
       te weinig hoogte voor vier iconen op aantikbaar formaat.

       Hij hangt onder het kaartje door dezelfde variabele te gebruiken, plus de
       bandhoogte en wat lucht. De aftrek van 47,03% zet dat om naar het nulpunt
       van de props-laag, die immers pas bij de opname begint. */
    .hm-contact-prop-social {
        top: calc(
            var(--hm-card-top) + var(--hm-card-h) + 14px -
                var(--hm-room-h) * 0.4703
        );
        bottom: auto;
        left: 50%;
        transform: translateX(-50%);
        width: min(40%, 180px);
    }

    /* De tussenruimte is niet cosmetisch: de iconen zijn hier zo'n 40px en het
       raakvlak eronder is minimaal 44px, dus zonder lucht ertussen overlappen die
       en tik je de buurman aan. In `cqw` en niet in procenten, want een
       procentuele `gap` rekent tegen een maat die hier niet vaststaat. */
    .hm-contact-social {
        gap: min(2.5cqw, 11px);
    }

    /* ── Raakvlakken ─────────────────────────────────────────────── */

    /* Niet alles kan groter. De bordjes liggen plat op het tafelblad en zijn maar
       een pixel of dertien hoog; ze opschalen zou ze van het blad tillen en het
       perspectief breken. En boven de foto is maar 215px muur, waarvan het
       kaartje er 132 vraagt — daar past geen rij van 44px iconen bij.

       Dus groeit hier het raakvlak en niet de afbeelding: een onzichtbaar vlak
       van minimaal 44px, gecentreerd op de prop. Wie al groot genoeg is (de
       telefoon, de ordner, de bel hierboven) merkt er niets van, want `width` en
       `height` blijven 100%. */
    .hm-contact-prop a::after,
    .hm-contact-prop button::after {
        content: "";
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 100%;
        height: 100%;
        min-width: 44px;
        min-height: 44px;
    }

    /* ── De uitgang ──────────────────────────────────────────────── */

    /* De bel hoort in de hoek van het scherm en niet in die van de plaat. Staand
       staat de plaat tegen de onderrand, en de hoek van de plaat ligt dan een
       kwart scherm omlaag — onder het kaartje, waar niemand een uitgang zoekt en
       waar hij op geen enkele andere pagina hangt.

       Hij steekt daarom boven de plaat uit, het bijgemaakte stuk muur in; dat is
       ook waarvoor de klip hierboven eraf ging. Van de bovenrand van de kamer
       naar die van het scherm is 100dvh − plaathoogte, dezelfde rekensom als bij
       `--hm-card-top`. De taalwissel houdt zijn afstand tot de bel en schuift dus
       even ver mee. */
    .hm-contact-room .hm-bell {
        top: calc(var(--hm-bell-inset) - 100dvh + var(--hm-room-h));
    }

    .hm-contact-langs {
        top: calc(
            var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33 - 100dvh +
                var(--hm-room-h)
        );
    }
}


/* ── components/pers.css ── */
/* Hotel Modern — de perskamer (/contact/pers/).
   Een opengeslagen ringband: links het register, rechts het roze vel met de
   gekozen tekst of foto's. Percentages komen uit de originele
   `partials/page/press` CSS: beide vellen beginnen op 7% en lopen door tot de
   onderrand, het linkervel is 30% breed en het rechter 50% met 10% marge. */

.hm-pers-room {
    aspect-ratio: 1366 / 768;
    width: min(calc(100vw - 30px), calc((100dvh - 30px) * 1366 / 768));
    container-type: inline-size;
    position: relative;
    overflow: hidden;
    border: 15px solid #000;
    box-sizing: content-box;
}

.hm-pers-bg {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ── Het register ────────────────────────────────────────────────── */

.hm-pers-index {
    position: absolute;
    left: 3%;
    top: 7%;
    bottom: 3%;
    width: 27%;
    overflow-y: auto;
    color: #000;
    font-size: 1.5cqw;
}

.hm-pers-index ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.hm-pers-index a {
    display: block;
    color: inherit;
    text-decoration: none;
}

/* De drie tabbladen, in de kopletter en met kapitalen zoals het origineel. */
.hm-pers-tab {
    font-family: var(--hotelmodern-font-heading);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-top: 0.6em;
}

/* Onder `.hm-pers-index` gezet, want de reset hierboven is `.hm-pers-index a` en
   dat is specifieker dan een losse klasse: zonder deze scoping wint
   `color: inherit` en blijft het actieve tabblad zwart. */
.hm-pers-index .hm-pers-tab-on,
.hm-pers-index .hm-pers-tab:hover,
.hm-pers-index .hm-pers-tab:focus-visible,
.hm-pers-index .hm-pers-titles a:hover,
.hm-pers-index .hm-pers-titles a:focus-visible,
.hm-pers-index .hm-pers-title-on {
    color: var(--hotelmodern-accent);
}

/* De titels staan ingesprongen onder hun tabblad, in kapitalen maar niet vet —
   zo blijft het tabblad de kop en de titel de regel. */
/* Even specifiek als de `ul`-reset hierboven (`.hm-pers-index ul`), anders wint
   die met zijn `margin: 0` en staat de inspringing er niet. */
.hm-pers-index .hm-pers-titles {
    margin-left: 1.2em;
}

.hm-pers-titles a {
    text-transform: uppercase;
    line-height: 1.35;
}

/* ── Het rechtervel ──────────────────────────────────────────────── */

.hm-pers-sheet {
    position: absolute;
    right: 10%;
    top: 7%;
    bottom: 3%;
    width: 45%;
    overflow-y: auto;
    padding-right: 1.5cqw;
    color: #000;
    font-size: 1.35cqw;
    line-height: 1.5;
}

.hm-pers-sheet h2 {
    font-size: 1.8cqw;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    margin: 0 0 0.8em;
}

.hm-pers-body p {
    margin: 0 0 0.9em;
    line-height: 1.5;
}

.hm-pers-body a {
    color: var(--hotelmodern-accent);
}

.hm-pers-leeg {
    font-style: italic;
}

/* De foto's op het vel: drie kolommen, zoals de `col-img` van 33,33% in het
   origineel. De lightbox is de gedeelde platform-hook, net als in het album.

   Kolommen en geen grid, want de scènefoto's staan door elkaar liggend en
   staand. In een grid bepaalt de hoogste foto de rijhoogte en houdt elke rij
   een strook roze over; `columns` laat ze in elkaar schuiven. Dat de volgorde
   dan per kolom loopt en niet per rij is hier geen bezwaar: een fotoblad kent
   geen leesrichting. */
.hm-pers-album {
    columns: 3;
    column-gap: 1cqw;
}

.hm-pers-album a {
    display: block;
    break-inside: avoid;
    margin-bottom: 1cqw;
}

.hm-pers-album img {
    display: block;
    width: 100%;
    height: auto;
}

/* ── De bladwissel ───────────────────────────────────────────────── */

/* LiveView verwisselt het vel sneller dan je kunt zien: klik je op een andere
   titel, dan staat er een andere tekst zonder dat er iets bewoog, en bij twee
   persberichten die met dezelfde kop beginnen mis je dat. Een korte fade geeft
   de wissel terug.

   Geen transitie maar een animatie, en dat is geen stijlkeuze: het vel draagt
   zijn keuze in zijn `id` (`hm-pers-sheet-<register>-<voorstelling>`), dus bij
   elke andere keuze zet de patch er een nieuw element neer in plaats van het
   bestaande bij te werken. Een transitie heeft dan geen beginwaarde om vanaf te
   vertrekken; een animatie start opnieuw bij elk vers element — precies bij elke
   wissel dus, en nooit bij een patch die het vel ongemoeid laat. */
@keyframes hm-pers-blad {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.hm-pers-sheet {
    animation: hm-pers-blad 260ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
    .hm-pers-sheet {
        animation-duration: 0s;
    }
}


/* De ringen liggen alleen in portret tussen het register en het vel; liggend
   zitten ze gewoon in de achtergrondfoto. */
.hm-pers-rings {
    display: none;
}

/* ── Portret: de ordner een kwartslag ────────────────────────────── */

/* Twee vellen naast elkaar passen niet op een telefoonbreedte, maar een
   kwartslag gedraaid past dezelfde ordner wél: het blauwe vel wordt de
   menubalk, de ringen lopen horizontaal en het roze vel krijgt de rest. Het is
   hetzelfde voorwerp, alleen omgeslagen als een schrijfblok.

   Geen gedraaide plaat maar drie losse lagen (zie
   `bin/build_hotelmodern_pers_portrait.py`). Eén plaat zou dezelfde valkuil
   hebben als de liggende versie: alle panelen hangen dan aan één
   beeldverhouding, en zodra `cover` bijsnijdt schuift de foto onder de panelen
   vandaan. Nu is er in portret helemaal geen stelsel percentages meer nodig. */
@media (orientation: portrait) {
    .hm-pers {
        align-items: stretch;
    }

    .hm-pers-room {
        /* Eén maat voor de linkerkant van beide vellen, zodat het register en de
           tekst eronder op dezelfde lijn beginnen. Een tablet krijgt hier bijna
           het dubbele van een telefoon: op 768px is de marge van een telefoon
           een kantlijn van niks, en dan plakt de tekst tegen de ordnerrand. */
        --hm-pers-kantlijn: clamp(1rem, 4cqw, 3rem);
        /* Rechts houdt het papier op bij 95% van de breedte — daarna komt de
           kartonnen rand van het vel, de gele ordner en de muur. Die grens
           schuift mee met de breedte, dus deze marge moet een percentage zijn
           en geen rem-plafond: met een vast plafond loopt de tekst op een breed
           scherm alsnog van het papier af. */
        --hm-pers-papierrand: max(2.2rem, 8cqw);

        aspect-ratio: auto;
        width: 100%;
        border-width: 0;
        display: flex;
        flex-direction: column;
    }

    .hm-pers-bg {
        display: none;
    }

    /* 1. Het blauwe vel. De hoogte volgt het register — de titels breken af over
          zoveel regels als ze nodig hebben — met een plafond zodat een lang
          register het persbericht niet van het scherm duwt. */
    .hm-pers-index {
        position: static;
        /* Niet krimpen: als flex-item zou het register de helft van zijn regels
           inleveren zodra het vel eronder om ruimte vraagt, en dan sta je weer
           te scrollen in een menu dat juist volledig zichtbaar moest zijn. */
        flex: 0 0 auto;
        width: auto;
        /* Het plafond is wat het vel eronder minstens nodig heeft, niet een
           percentage van het scherm. Een percentage knipt op een kleine telefoon
           net de laatste regels van het fotoregister (22 titels) weg terwijl er
           onderin ruimte over is; zo groeit het register mee tot het echt niet
           meer kan. `overflow-y` blijft de noodrem voor dat geval. */
        max-height: calc(100dvh - 17rem);
        background: url(/assets/hotelmodern/pers/binder-index-60c68bd797fe264cdebc6b2c1f2301f0.jpg?vsn=d) top center / 100% auto repeat-y;
        /* Rechts blijft een strook vrij voor de bel, over de volle hoogte: hij
           hangt in de hoek en zou anders het eind van de eerste titelregels
           opeten. */
        /* Rechts minstens de strook die de bel nodig heeft (zijn `right` plus
           zijn eigen breedte); op een breed scherm wint de papierrand. Het vel
           eronder heeft die ondergrens niet, want daar hangt geen bel boven. */
        padding: 0.85rem max(4.25rem, var(--hm-pers-papierrand)) 0.75rem var(--hm-pers-kantlijn);
        font-size: clamp(0.83rem, 2.4cqw, 1.05rem);
    }

    .hm-pers-index > ul {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        column-gap: 1.1em;
    }

    /* De titels horen ná alle drie de registers op een eigen regel, maar ze staan
       in de bron ín hun register — liggend springen ze daar immers onder in.
       `display: contents` laat de `li` als doos verdwijnen zonder de opsomming te
       breken, zodat kop en titels allebei meedoen in dezelfde flexregel. */
    .hm-pers-section {
        display: contents;
    }

    .hm-pers-tab {
        margin-top: 0;
    }

    .hm-pers-index .hm-pers-titles {
        order: 1;
        flex: 0 0 100%;
        display: flex;
        flex-wrap: wrap;
        column-gap: 1em;
        row-gap: 0.15em;
        /* Ruim, want dit is de enige scheiding tussen het register en de titels
           daarbinnen: liggend doet de inspringing dat werk, maar naast elkaar op
           één balk lezen twee dicht opeen staande regels als één menu. */
        margin: 1.15em 0 0;
        font-size: 0.94em;
    }

    /* 2. De ringen. Vaste verhouding op volle breedte, dus altijd heel. */
    .hm-pers-rings {
        display: block;
        flex: 0 0 auto;
        width: 100%;
        height: auto;
    }

    /* 3. Het roze vel neemt wat er over is. Onderin ruimte voor de bel. */
    .hm-pers-sheet {
        position: static;
        flex: 1 1 auto;
        min-height: 0;
        width: auto;
        background: url(/assets/hotelmodern/pers/binder-page-0f7fabba9eeab0edbaea6b95eed896cb.jpg?vsn=d) top center / 100% auto repeat-y;
        padding: var(--hm-pers-kantlijn) var(--hm-pers-papierrand) 2.5rem var(--hm-pers-kantlijn);
        /* De ondergrens houdt de telefoon vlak (daar telt elke regel), het
           plafond laat een tablet doorgroeien. De helling ertussen is bewust
           flauw: met een steile factor zou een brede telefoon al op tabletcorps
           staan. */
        font-size: clamp(0.95rem, 2.6cqw, 1.25rem);
    }

    .hm-pers-sheet h2 {
        font-size: clamp(1.15rem, 3.2cqw, 1.6rem);
    }

    .hm-pers-album {
        columns: 2;
        column-gap: var(--hm-pers-albumgat, 0.6rem);
    }

    .hm-pers-album a {
        margin-bottom: var(--hm-pers-albumgat, 0.6rem);
    }
}

/* Tablet in portret. Zelfde breekpunt als de rest van deze tenant: vanaf 600px
   is er breedte genoeg voor de derde kolom van het liggende fotoblad, en met
   twee kolommen worden de scènefoto's daar zo groot dat je per scherm nog maar
   een handvol ziet. Corps en kantlijnen groeien hierboven al mee via hun
   clamp; alleen het aantal kolommen is een sprong en geen helling. */
@media (orientation: portrait) and (width >= 600px) {
    .hm-pers-album {
        --hm-pers-albumgat: 1rem;

        columns: 3;
    }
}

/* Taalwissel: onder de bel, in dezelfde hoek en op dezelfde afstand als in de
   gang en de vitrine (zie corridor.css voor de rekensom). Het uiterlijk staat in
   scene.css (`.hm-langs-plaque`). */
.hm-pers-langs {
    position: absolute;
    top: calc(var(--hm-bell-inset) * 2 + var(--hm-bell-size) * 1.33);
    right: var(--hm-bell-inset);
    z-index: 1000;
    display: flex;
    gap: 0.35rem;
    line-height: 1;
}

/* ── Ruimte voor de kopregel ─────────────────────────────────────── */

/* Het register begint bovenaan het vel en dus onder de balk (scene.css,
   `.hm-topbar`). Een binnenmarge en geen verschuiving: het blauwe vel hoort
   dóór te lopen tot de bovenrand van het scherm — dat is het papier, en dat
   houdt niet op waar de balk begint. Alleen de regels erop schuiven eronderuit.

   Achteraan het bestand, want de staande omslag hierboven zet een `padding`-
   shorthand op ditzelfde register en die zou een regel eerder in het bestand
   overschrijven. De 0,85rem is de marge die daar stond; liggend-maar-laag staat
   het register absoluut en is die lucht ook niet verkeerd. */
@media (max-aspect-ratio: 6/5) {
    .hm-pers-index {
        padding-top: calc(var(--hm-topbar-h) + 0.85rem);
    }
}


/* ── components/modal.css ── */
/* Hotel Modern — de modals.
   Panelen die vanuit de props opengaan (nieuwsbrief, contact, media). */

.hm-modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 100;
}

.hm-modal.hm-modal-open {
    display: block;
}

body.hm-no-scroll {
    overflow: hidden;
}

.hm-modal-bg {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
}

.hm-modal-panel {
    position: relative;
    margin: 5vh auto;
    max-width: 640px;
    max-height: 90vh;
    overflow-y: auto;
    background: var(--hotelmodern-paper);
    color: var(--hotelmodern-fg);
    border: 3px solid var(--hotelmodern-border);
    padding: 2.5rem;
    box-sizing: border-box;
    line-height: 1.5;
}

.hm-modal-close {
    position: absolute;
    top: 0.5rem;
    right: 0.75rem;
    border: 0;
    background: none;
    font-size: 2rem;
    line-height: 1;
    cursor: pointer;
    color: var(--hotelmodern-accent);
}

.hm-modal-title {
    margin: 0 0 1rem;
    color: var(--hotelmodern-accent);
}

/* De nieuws-lijst stond hier ook in een modal. Die is vervangen door /nieuws
   (zie components/news.css): de krant op de balie is nu een link. Hetzelfde geldt
   voor de social-links: die liggen nu als badges op de balie (reception.css) en
   op de wand van het kantoor (contact.css), zonder tussenstap. */

/* ── Het inschrijfformulier (post-it en bel) ─────────────────────────
   Op de oude site was dit een Mailchimp-formulier met een reCAPTCHA erboven;
   hier staat het als gastenboek in het modal-papier. Eén kolom, want het paneel
   is smal en de velden zijn kort. */

.hm-newsletter {
    margin-top: 1.25rem;
}

.hm-newsletter-required {
    margin: 0 0 0.75rem;
    font-size: 0.85rem;
    opacity: 0.75;
}

.hm-required {
    color: var(--hotelmodern-accent);
    padding-left: 0.15rem;
}

.hm-field {
    display: block;
    margin-bottom: 0.9rem;
}

.hm-field-label {
    display: block;
    margin-bottom: 0.2rem;
    font-size: 0.9rem;
}

/* Lijn onder het veld in plaats van een doos eromheen: het papier van het
   paneel blijft zo het vlak, zoals de regels in een gastenboek. */
.hm-field-input {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 0.4rem 0.15rem;
    border: 0;
    border-bottom: 0.09rem solid var(--hotelmodern-border);
    background: transparent;
    color: inherit;
    font: inherit;
}

.hm-field-input:focus-visible {
    outline: 0.13rem solid var(--hotelmodern-accent);
    outline-offset: 0.13rem;
}

/* De honingpot. Niet `display: none`: een deel van de bots slaat verborgen
   velden over, maar invult wat het wél kan bereiken. */
.hm-newsletter-trap {
    position: absolute;
    left: -100vw;
    width: 1rem;
    height: 1rem;
    overflow: hidden;
}

.hm-newsletter-submit {
    margin-top: 0.5rem;
    padding: 0.5rem 1.5rem;
    border: 0;
    background: var(--hotelmodern-accent);
    color: var(--hotelmodern-paper);
    font: inherit;
    cursor: pointer;
}

.hm-newsletter-submit:hover,
.hm-newsletter-submit:focus-visible {
    background: var(--hotelmodern-accent-dark);
}

.hm-newsletter-submit:disabled {
    opacity: 0.6;
    cursor: progress;
}

.hm-newsletter-privacy {
    margin: 0.75rem 0 0;
    font-size: 0.8rem;
}

.hm-newsletter-message {
    margin: 0.9rem 0 0;
    padding: 0.6rem 0.75rem;
    border-left: 0.25rem solid var(--hotelmodern-accent);
    background: rgba(135, 29, 15, 0.06);
}

.hm-newsletter-message-ok {
    font-weight: 700;
}

/* ── De nieuwsbrief als gastenboek ───────────────────────────────────
   Het paneel is de gescande registerpagina van de oude site
   (reception/prop/note.png): "HOTEL MODERN — gastenboek & check-in nr. 44578".
   Het formulier ligt er als ingevulde regels overheen.

   De maat komt van de hoogte, niet van de breedte: op de oude site vulde de
   pagina bijna de hele scène, en de scène zelf schaalt met het venster mee. De
   letter schaalt mee met dezelfde vh-maat, en alles binnen het papier staat in
   `em`, zodat het formulier op elk scherm dezelfde plek op de pagina houdt. */

.hm-modal-guestbook.hm-modal-open {
    display: flex;
    align-items: center;
    justify-content: center;
}

.hm-modal-guestbook .hm-modal-panel {
    /* Drie plafonds: de hoogte van het venster, een absolute grens zodat het
       papier op een enorm scherm niet doorgroeit, en de breedte — 106vw is de
       hoogte waarbij het papier (668 : 757) net 94vw breed wordt, wat op een
       telefoon in portret de bindende maat is. */
    height: min(88vh, 46rem, 106vw);
    width: auto;
    max-width: 94vw;
    max-height: none;
    aspect-ratio: 668 / 757;
    margin: 0;
    padding: 0;
    border: 0;
    background: url("reception/prop/note-efdd43730f0b653290df23f6581ca2c1.png?vsn=d") no-repeat center / 100% 100%;
    /* Niets valt van het papier af; loopt het formulier toch over (een melding
       erbij op een laag venster), dan schuift de inhoud binnen de pagina. */
    overflow: hidden;
    color: #2b1a10;
    font-size: clamp(0.7rem, 1.65vh, 1.1rem);
    line-height: 1.4;
}

/* De kop staat al op de plaat gedrukt; hij blijft in de DOM voor wie hem niet
   ziet staan. */
.hm-modal-guestbook .hm-modal-title {
    position: absolute;
    width: 0.06rem;
    height: 0.06rem;
    margin: -0.06rem;
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    clip-path: inset(50%);
}

/* Onder de gedrukte kop beginnen en boven de onderrand eindigen; de maten zijn
   percentages van de breedte van het papier. Overlappen met de gelinieerde
   vakken eronder mag: dat is een ingevuld register. `auto` is de noodklep voor
   een venster dat te laag is voor het formulier. */
.hm-modal-guestbook .hm-modal-body {
    padding: 19% 9% 5%;
    height: 100%;
    box-sizing: border-box;
    overflow-y: auto;
}

.hm-modal-guestbook .hm-modal-close {
    top: 0.6em;
    right: 1.25em;
    width: 2.2em;
    height: 2.2em;
    background: url("reception/prop/times-076f65f07efbde2bc13b6cbbcf62311b.png?vsn=d") no-repeat center / contain;
    /* Het ×-teken uit de knop verbergen; het staat in de plaat. */
    font-size: inherit;
    color: transparent;
}

/* De twee lopende teksten liggen over de gedrukte lijnen en het vouwspoor van
   het papier heen. Ze liggen als losse velletjes op de pagina: dekkend wit, een
   zachte slagschaduw eronder en een halve graad scheef, elk de andere kant op.
   De negatieve marges houden ze in lijn met de velden. De oude site deed
   hetzelfde, daar met een streepje roze. */
.hm-modal-guestbook .hm-newsletter-intro,
.hm-modal-guestbook .hm-newsletter-privacy {
    padding: 0.25em 0.4em;
    margin-left: -0.4em;
    margin-right: -0.4em;
    background: #fff;
    box-shadow: 0 0 1rem rgba(0, 0, 0, 0.1);
    transform: rotate(-0.5deg);
}

.hm-modal-guestbook .hm-newsletter-intro {
    margin-top: 0;
    margin-bottom: 0.7em;
    font-size: 0.95em;
}

.hm-modal-guestbook .hm-newsletter {
    margin-top: 0.9em;
}

.hm-modal-guestbook .hm-newsletter-required {
    margin: 0 0 0.6em;
    font-size: 0.85em;
    opacity: 0.7;
}

.hm-modal-guestbook .hm-field {
    margin-bottom: 0.35em;
}

.hm-modal-guestbook .hm-field-label {
    margin-bottom: 0.15em;
    font-size: 0.85em;
}

/* Ingevulde regels: wit vlak op het papier, zoals op het oude formulier. */
.hm-modal-guestbook .hm-field-input {
    padding: 0.3em 0.5em;
    border: 0.07em solid rgba(43, 26, 16, 0.35);
    background: rgba(255, 255, 255, 0.88);
}

.hm-modal-guestbook .hm-newsletter-submit {
    margin-top: 0.4em;
    padding: 0.45em 1.4em;
}

.hm-modal-guestbook .hm-newsletter-privacy {
    margin-top: 0.5em;
    margin-bottom: 0;
    font-size: 0.75em;
    /* De andere kant op scheef dan de intro, zodat het twee velletjes zijn en
       geen kolom. */
    transform: rotate(0.5deg);
}

.hm-modal-guestbook .hm-newsletter-message {
    margin-top: 0.5em;
    padding: 0.4em 0.6em;
    border-left-width: 0.25em;
}




/* Het chroom van de achterkant: header, menu, voet en de grond eronder. Staat
   ná de scènes en ná base/admin-delfts-blauw.css, zodat het daar bovenop ligt. */
/* ── components/admin.css ── */
/* Hotel Modern — de dienstingang.

   Elke publieke pagina van deze tenant is een scène (`.hm-stage`), en die
   verbergt de platform-header en -footer. De koptekst, het menu en de
   body-achtergrond die je hieronder ziet zijn dus in de praktijk uitsluitend
   CMS-chroom: je krijgt ze alleen te zien als je bent ingelogd, of op de
   inlogpagina zelf. Ze waren daarom nooit aangekleed — het menu was een kale
   <ul> en de bordeaux body-kleur (die op een scène onder het zwart verdwijnt)
   stond op de rest van de pagina in volle sterkte aan.

   Vandaar dat alles hier aan `:not(:has(.hm-stage))` hangt: dat is precies de
   verzameling pagina's zonder scène, en dat is de achterkant van de site. De
   scène-regels in components/scene.css blijven onaangeroerd.

   De lijn is die van de receptiebalie: papier, inkt, en het hotelrood alleen
   waar het iets betekent (waar je bent, waar je heen kunt). Het blauwe
   formulier-thema uit base/admin-delfts-blauw.css blijft eronder liggen; dit
   bestand raakt alleen het chroom eromheen. */

:root {
  /* Lichter en minder verzadigd dan `--hotelmodern-bg`: het perkament van de
     receptie is een decor-kleur, over een heel scherm formulier wordt hij
     zwaar. Dit is dezelfde warmte, een paar tinten opgetrokken. */
  --hm-admin-paper: #efe9df;
  --hm-admin-ink: #1c1512;
  --hm-admin-muted: #6f6156;
  --hm-admin-line: rgba(28, 21, 18, 0.16);
}

/* ── De grond ────────────────────────────────────────────────────── */

body.hotelmodern:not(:has(.hm-stage)) {
  background: var(--hm-admin-paper);
  color: var(--hm-admin-ink);
}

/* Lucht om de witte kaart heen: zonder dit plakt het formulier op brede
   schermen tegen beide vensterranden en leest de grond niet als grond. */
body.hotelmodern:not(:has(.hm-stage)) .inner.wrap {
  padding-inline: 1.5rem;
}

/* ── De balie: kop en menu ───────────────────────────────────────── */

body.hotelmodern:not(:has(.hm-stage)) .header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 2rem;
  padding: 1.75rem 0 1rem;
  border-bottom: 0.0625rem solid var(--hm-admin-line);
}

body.hotelmodern:not(:has(.hm-stage)) .header h1 {
  margin: 0;
  font-size: 1.5rem;
  line-height: 1.2;
}

body.hotelmodern:not(:has(.hm-stage)) .header h1 a {
  color: var(--hm-admin-ink);
  text-decoration: none;
}

/* Een stempeltje naast de naam: de header hoort bij het beheer, niet bij de
   site. Op de basislijn van de titel, en met de kleine kapitalen van een
   bordje. */
body.hotelmodern:not(:has(.hm-stage)) .hm-admin-badge {
  margin: 0;
  padding: 0.15rem 0.45rem 0.2rem;
  border: 0.0625rem solid var(--hotelmodern-accent);
  border-radius: 0.125rem;
  color: var(--hotelmodern-accent);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Het menu staat rechts van de naam, op dezelfde basislijn: samen lezen ze als
   één regel briefhoofd in plaats van als twee blokken. */
body.hotelmodern:not(:has(.hm-stage)) .navi {
  margin-left: auto;
}

body.hotelmodern:not(:has(.hm-stage)) .navi ul {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* De onderrand ligt er altijd al, doorzichtig: zo verspringt er niets als hij
   bij hover of op de actieve pagina kleur krijgt. */
body.hotelmodern:not(:has(.hm-stage)) .navi a {
  display: inline-block;
  padding: 0.35rem 0;
  border-bottom: 0.125rem solid transparent;
  color: var(--hm-admin-muted);
  font-size: 0.95rem;
  text-decoration: none;
  transition:
    color 0.15s ease,
    border-color 0.15s ease;
}

body.hotelmodern:not(:has(.hm-stage)) .navi a:hover,
body.hotelmodern:not(:has(.hm-stage)) .navi a:focus-visible {
  color: var(--hm-admin-ink);
  border-bottom-color: var(--hm-admin-line);
}

body.hotelmodern:not(:has(.hm-stage)) .navi a.active {
  color: var(--hotelmodern-accent);
  border-bottom-color: var(--hotelmodern-accent);
}

/* Taalwissel en uitloggen zijn geen secties van de site maar knoppen aan het
   scherm; een haarlijn ervoor zegt dat zonder er een tweede menu van te maken. */
body.hotelmodern:not(:has(.hm-stage)) .navi .navi-language,
body.hotelmodern:not(:has(.hm-stage)) .navi li:has(.logout-link) {
  padding-left: 1.5rem;
  margin-left: -0.5rem;
  border-left: 0.0625rem solid var(--hm-admin-line);
}

/* Uitloggen staat in andere tenants als blokje onder een knop; daar hoort het
   woord klein en in kapitalen onder het pictogram. Hier staat het in een regel
   menu, dus terug naar één inline woord dat niet afbreekt. */
body.hotelmodern:not(:has(.hm-stage)) .navi .logout-link {
  white-space: nowrap;
}

body.hotelmodern:not(:has(.hm-stage)) .navi .logout-link span {
  display: inline;
  margin: 0;
  font-size: inherit;
  text-transform: none;
}

/* Het hamburgermenu is een mask-icoon: zonder achtergrondkleur valt er niets te
   maskeren en blijft de knop onzichtbaar. */
body.hotelmodern:not(:has(.hm-stage)) .header-right button {
  background-color: var(--hm-admin-ink);
  border: none;
  cursor: pointer;
}

/* ── De voet ─────────────────────────────────────────────────────── */

body.hotelmodern:not(:has(.hm-stage)) .footer {
  border-top: 0.0625rem solid var(--hm-admin-line);
  color: var(--hm-admin-muted);
  font-size: 0.85rem;
}

body.hotelmodern:not(:has(.hm-stage)) .footer p {
  margin: 0.25rem 0;
}

/* ── Smal scherm ─────────────────────────────────────────────────── */

/* Onder 48rem neemt de hamburger het over (icons.css verbergt hem daarboven).
   Het menu wordt dan een lijst onder de naam in plaats van een regel ernaast. */
@media (width < 48rem) {
  body.hotelmodern:not(:has(.hm-stage)) .navi {
    display: none;
    width: 100%;
    margin-left: 0;
  }

  body.hotelmodern:not(:has(.hm-stage)) .navi.visible {
    display: block;
  }

  body.hotelmodern:not(:has(.hm-stage)) .navi ul {
    display: block;
  }

  body.hotelmodern:not(:has(.hm-stage)) .navi a {
    display: block;
    padding: 0.6rem 0;
  }

  body.hotelmodern:not(:has(.hm-stage)) .navi .navi-language,
  body.hotelmodern:not(:has(.hm-stage)) .navi li:has(.logout-link) {
    padding-left: 0;
    margin-left: 0;
    border-left: none;
    border-top: 0.0625rem solid var(--hm-admin-line);
  }

  body.hotelmodern:not(:has(.hm-stage)) .inner.wrap {
    padding-inline: 1rem;
  }
}

/* ── Pictogrammen ────────────────────────────────────────────────── */

/* De iconen zijn maskers: ze zijn precies zo zichtbaar als hun
   achtergrondkleur, en zonder kleur helemaal niet. base/admin-delfts-blauw.css
   zet ze op wit (`.index.admin [class*="icon-"]` en `.modal-overlay
   [class*="icon-"]`) — kloppend in dat blauwe thema, waar ze op donkere knoppen
   liggen. Hier liggen ze op perkament en op de witte kaarten van de
   fotobibliotheek, en dan is wit letterlijk onzichtbaar: het potloodje en de
   prullenbak per foto waren er wel, maar niet te zien.

   Vandaar inkt als standaard, en wit alleen terug waar de knop eronder donker
   is. */
body.hotelmodern:not(:has(.hm-stage)) [class*="icon-"] {
  background-color: var(--hm-admin-ink);
}

/* De knoppen met een donker vlak: de blauwe voetbalk-knoppen uit het
   admin-thema en de zwarte `.admin.actions`-knoppen. */
body.hotelmodern:not(:has(.hm-stage)) button.button [class*="icon-"],
body.hotelmodern:not(:has(.hm-stage)) footer.actions .button [class*="icon-"],
body.hotelmodern:not(:has(.hm-stage)) .admin.actions .button [class*="icon-"] {
  background-color: var(--hotelmodern-paper);
}

/* Potlood en prullenbak per foto krijgen hun vorm uit base/gallery.css, samen
   met de sorteerbare galerij: één uiterlijk voor beide beheerschermen. Hier
   stond een eigen versie die dat overstemde — weg, anders wijkt deze tenant af
   zodra de gedeelde regels veranderen. */

/* Hun kléúr zeggen ze ook zelf: base/gallery.css zet die op `currentColor`,
   zodat het pictogram meeloopt met het woord ernaast — inclusief het rood van
   verwijderen zodra je erop staat.

   De inktregel hierboven overstemde dat. Niet door volgorde maar door gewicht:
   er staat een `body` voor, en dat ene type-deel weegt zwaarder dan de drie
   klassen van de gedeelde regel. Gevolg: "Verwijder" werd rood en het
   prullenbakje ernaast bleef zwart.

   Vandaar deze uitzondering, met dezelfde `body`-voorvoeging zodat hij het
   terugwint. Alleen voor de knopjes óp een fotokaart; overal elders blijft de
   inkt uit de regel hierboven staan. */
body.hotelmodern:not(:has(.hm-stage)) .sortable-gallery .gallery-item-delete [class*="icon-"],
body.hotelmodern:not(:has(.hm-stage)) .sortable-gallery .drag-handle [class*="icon-"],
body.hotelmodern:not(:has(.hm-stage)) .image-grid.masonry .image-actions [class*="icon-"] {
  background-color: currentColor;
}

/* ── De gang onder het formulier ─────────────────────────────────── */

/* Het formulier van een voorstelling stond op een leeg vel perkament: correct,
   maar het staat daarmee nergens. Nu ligt de gangfoto van de index eronder,
   achter glas — je kijkt vanuit het kantoor de gang in die je net verlaten
   hebt. Alles hieronder hangt aan `.hm-admin-backdrop`; dat element rendert
   alleen als de redactie een gangfoto heeft ingesteld, dus zonder foto blijft
   het scherm precies zoals het was.

   `.outer` krijgt een eigen stapelcontext. Zonder die context zou de
   `z-index: -1` hieronder de backdrop achter de perkamentkleur van de body
   duwen, en dan zie je hem nooit; binnen de context landt hij precies waar hij
   hoort: onder de pagina-inhoud, boven de grond. */
body.hotelmodern:has(.hm-admin-backdrop) .outer {
  position: relative;
  z-index: 0;
}

.hm-admin-backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}

.hm-admin-backdrop img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* De gang is een druk beeld — rood tapijt met een medaillon erin. Een tikje
     onscherp en iets ontkleurd blijft hij decor in plaats van een concurrent
     van het formulier; genoeg scherpte om te zien wáár je bent. De opschaling
     houdt de uitgelopen randen van de blur buiten beeld. */
  filter: blur(0.125rem) saturate(0.85);
  transform: scale(1.06);
}

/* Het glas zelf: een waas perkament over de foto, zodat de inkt van kop,
   menu en voet — die buiten de kaart op de foto liggen — leesbaar blijft. */
.hm-admin-backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--hm-admin-paper) 32%, transparent);
}

/* De kaart was een dicht wit vlak (base/admin-delfts-blauw.css). Nu laat hij de
   gang er net doorheen schemeren en blijft verder gewoon het witte werkblad:
   dertig secties formulier moeten leesbaar blijven, dus de foto is hier een
   herinnering, geen decor. De rand wordt inkt in plaats van admin-blauw — een
   haarlijn is tegen een foto rustiger dan een blauwe. */
body.hotelmodern:has(.hm-admin-backdrop) .index.admin.wrap {
  background: color-mix(in srgb, var(--admin-white) 85%, transparent);
  border-color: var(--hm-admin-line);
  box-shadow: 0 0.125rem 1.5rem rgba(28, 21, 18, 0.18);
}

/* Kop en voet liggen buiten de kaart, dus rechtstreeks op de gang: boven op het
   plafond, onder op het tapijt. Een halo van perkament om de letters houdt ze
   daar leesbaar zonder dat er een balk overheen moet — dezelfde truc als het
   woord onder de bel in de scènes (components/corridor.css). */
body.hotelmodern:has(.hm-admin-backdrop) .header,
body.hotelmodern:has(.hm-admin-backdrop) .footer {
  text-shadow:
    0 0 0.25rem var(--hm-admin-paper),
    0 0 0.75rem var(--hm-admin-paper);
}

/* Het grijs van de voet is gekozen tegen een egale grond; op een foto is het te
   licht. Inkt, en de haarlijn erboven iets steviger. */
body.hotelmodern:has(.hm-admin-backdrop) .footer {
  color: var(--hm-admin-ink);
  border-top-color: rgba(28, 21, 18, 0.3);
}

/* ── De bordjes naar de site: de props uit de kamers ─────────────────

   In een kamer wijzen twee dingen de weg naar buiten: de gouden bel met HOME
   eronder, en het houten bordje VOORSTELLINGEN. Op de achterkant van de site
   zijn dat dezelfde twee wegen, dus zijn het hier dezelfde twee platen — geen
   nabootsing in randjes en letters, maar de opnamen zelf.

   Ze hangen op de gang: kop en voet liggen hier ook buiten de kaart,
   rechtstreeks op de foto. Waar ze precies hangen staat in base/admin.css — in
   de hoek en onder elkaar zodra er kantlijn genoeg is, en anders boven de
   kaart in een strook. */

body.hotelmodern:not(:has(.hm-stage)) .beheer-bordjes {
  align-items: flex-end;
  gap: 1.5rem;
}

/* De plaat draagt het woord; het kader eromheen moet niets meer zeggen. */
body.hotelmodern:not(:has(.hm-stage)) .beheer-bordje {
  padding: 0;
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
}

/* De bel met HOME eronder: dezelfde opbouw als `.hm-bell` in de scènes —
   plaatje boven, woord eronder in de propletter, krap tegen het voetje omdat
   de plaat onderaan nog een stuk slagschaduw draagt (zie components/scene.css
   voor die meting). */
body.hotelmodern:not(:has(.hm-stage)) .bordje-home {
  --bel: 3.75rem;
  flex-direction: column;
  align-items: center;
  gap: 0;
  width: var(--bel);
  color: #000;
  font-family: var(--hotelmodern-font-prop);
  /* Opgemeten aan het origineel: HOME is ongeveer even breed als het belletje
     zelf. Dezelfde verhouding als in de kamers. */
  font-size: calc(var(--bel) * 0.34);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1;
  text-transform: uppercase;
  /* Zwart met een halo perkament, zoals de kop en de voet hierboven: de props
     liggen op de foto van de gang en moeten daar leesbaar blijven. */
  text-shadow:
    0 0 0.25rem var(--hm-admin-paper),
    0 0 0.625rem var(--hm-admin-paper);
}

body.hotelmodern:not(:has(.hm-stage)) .bordje-home::before {
  content: "";
  width: 100%;
  aspect-ratio: 85 / 74;
  margin-bottom: calc(var(--bel) * -0.06);
  background: url("./bell-7b1ddce21dad3a9d4d56e09ed6d01773.png?vsn=d") center / contain no-repeat;
}

/* Het houten bordje van de receptie. Het woord staat in de plaat gebakken, dus
   de tekst in de HTML is hier alleen voor wie het scherm niet ziet — vandaar
   dat hij de doos uit geschoven wordt en niet op `display: none` staat. */
body.hotelmodern:not(:has(.hm-stage)) .bordje-lijst {
  width: 9.5rem;
  aspect-ratio: 330 / 147;
  background: url("reception/prop/productions-a1de85181cf2a136e0479ff9e4931034.png?vsn=d") center / contain no-repeat;
  overflow: hidden;
  text-indent: -100vw;
  white-space: nowrap;
}

/* Aanwijzen doet hetzelfde als in de kamers: een haartje groter en iets
   helderder. De verschuiving van het algemene bordje past niet bij een prop. */
body.hotelmodern:not(:has(.hm-stage)) .beheer-bordje:hover,
body.hotelmodern:not(:has(.hm-stage)) .beheer-bordje:focus-visible {
  transform: scale(1.04);
  filter: brightness(1.12);
  box-shadow: none;
}

/* ── De documentbibliotheek ──────────────────────────────────────

   base/documents.css zet naam, soort en grootte elk in een grijs blok met
   witte letters, en de soort zelfs in grijs op grijs: onleesbaar. De andere
   tenants met een documentbibliotheek hebben daar een eigen versie overheen
   gelegd; dit is die van Hotel Modern. Een lichte kaart, de naam in inkt en de
   rest eronder in gedempt grijs.

   En je moet kunnen zien wat je gekozen hebt. Het vinkje was wit op wit en de
   gekozen kaart had geen eigen opmaak; nu krijgt hij een rand in het hotelrood
   en een rood rondje met het vinkje. */
body.hotelmodern .document-library .document-item {
  justify-content: flex-start;
  gap: 0.5rem;
  padding: 1rem;
  background: #fff;
  border: 0.0625rem solid var(--hm-admin-line);
  box-shadow: none;
}

body.hotelmodern .document-library .document-item p {
  margin: 0;
}

body.hotelmodern .document-library .document-title,
body.hotelmodern .document-library .document-type,
body.hotelmodern .document-library .document-size,
body.hotelmodern .document-library .document-description {
  display: block;
  width: auto;
  padding: 0;
  background: none;
  color: var(--hm-admin-muted);
  font-size: 0.8125rem;
  line-height: 1.35;
}

body.hotelmodern .document-library .document-title {
  color: var(--hm-admin-ink);
  font-size: 0.9375rem;
}

body.hotelmodern .document-library .document-title span,
body.hotelmodern .document-library .document-type span {
  font-size: inherit;
  font-style: normal;
  font-variant: normal;
  letter-spacing: normal;
  text-transform: none;
  color: inherit;
}

body.hotelmodern .document-library .document-title span {
  font-weight: 600;
}

body.hotelmodern .document-library .document-item.selected {
  border-color: var(--hotelmodern-accent, #871d0f);
  box-shadow: 0 0 0 0.125rem var(--hotelmodern-accent, #871d0f);
}

body.hotelmodern .document-library .selection-indicator {
  background: var(--hotelmodern-accent, #871d0f);
  color: #fff;
  font-size: 0.875rem;
}



/* ── ../vendors/quill-editor.css ── */
.quill-container {
  background: white;
  border-radius: .25rem;
  border: none;
  max-width: 50rem;
}

.quill-container .ql-toolbar {
  border-bottom: .0625rem solid #ccc;
  border-top: none;
  border-left: none;
  border-right: none;
}

.quill-container .ql-container {
  border: none;
  font-family: inherit;
}

.quill-container .ql-editor {
  min-height: 9.25rem;
  font-size: .875rem;
  line-height: 1.5;
}

.quill-container .ql-editor p {
  margin: .75rem 0;
  min-height: 1.5em;
}

.quill-container .ql-editor.ql-blank::before {
  color: #999;
  font-style: italic;
}

.quill-container .ql-softbreak {
  font-size: 1rem;
  width: auto !important;
  padding: 0 .5rem !important;
}

