/* Platea - base theme (Themes/_base fallback per CLAUDE.md rendering rules) */

:root {
    /* Spacing scale (mijlpaal 6 design tokens, MIJLPALEN.md) */
    --space-3xs: 0.25rem;
    --space-2xs: 0.5rem;
    --space-xs: 0.75rem;
    --space-sm: 1rem;
    --space-md: 1.5rem;
    --space-lg: 2.5rem;
    --space-xl: 4rem;
    --space-2xl: 6rem;

    /* Radius scale: a theme overrides these under body[data-theme="..."] to change its
       character (e.g. "modern" flattens everything to 0, "warm" rounds it further). */
    --radius-sm: 6px;
    --radius-md: 14px;
    --radius-lg: 24px;
    --radius-full: 999px;

    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
    --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.12);

    /* Layout (DESIGN-MIJLPALEN.md, D3): content widths and a reading measure of 60-75
       characters, instead of 960px/640px/60ch repeated throughout this file.
       Mockup alignment: the mockups use ~88% of the screen width with only a slim edge (on a
       1440px screen: ~1270px of content, ~80px either side) - 960px left 240px empty on each
       side. --gutter is that slim, fluid edge; --content-max the widest the content gets. */
    --gutter: clamp(1rem, 5vw, 5rem);
    --content-max: 1280px;
    --content-narrow: 640px;
    --measure: 65ch;

    /* Standard image aspect ratios (D3), so every photo slot crops the same way. */
    --ratio-photo: 4 / 3;
    --ratio-wide: 16 / 9;
    --ratio-poster: 2 / 3;
    --ratio-square: 1 / 1;

    /* Status colors (D4): platform-fixed, not tenant colors - "uitverkocht" or "nog enkele
       plaatsen" must read the same on every site. Text/background pairs are well above AA. */
    --status-success-bg: #e3f1e6;
    --status-success-text: #1f5c30;
    --status-warning-bg: #fcefcf;
    --status-warning-text: #6b4800;
    --status-danger: #b3261e;

    --line-height-tight: 1.15;
    --line-height-normal: 1.6;
    --letter-spacing-normal: normal;
    --letter-spacing-wide: 0.04em;
}

/* Modular type scale (D3). Declared on body rather than :root on purpose: a custom property
   is computed on the element that declares it, so the steps must live on the same element as
   the theme's own --type-ratio override (body[data-theme="..."]) to pick that ratio up. A theme
   changes the whole scale by setting only --type-ratio (and, for its hero, --font-size-hero). */
body {
    --type-base: 1.0625rem;
    --type-ratio: 1.25;
    --step--1: calc(var(--type-base) / var(--type-ratio));
    --step-0: var(--type-base);
    --step-1: calc(var(--step-0) * var(--type-ratio));
    --step-2: calc(var(--step-1) * var(--type-ratio));
    --step-3: calc(var(--step-2) * var(--type-ratio));
    --step-4: calc(var(--step-3) * var(--type-ratio));
    --step-5: calc(var(--step-4) * var(--type-ratio));

    /* Only h1 (hero) needs a fluid clamp; the rest stays legible at any width. */
    --font-size-hero: clamp(2.25rem, 4vw + 1rem, 3.75rem);
    /* Section titles scale down on narrow phones instead of overflowing; wider screens keep
       the theme's own step. */
    --font-size-h2: min(var(--step-3), 1.1rem + 4vw);
    --font-size-h3: var(--step-1);
    --font-size-body: var(--step-0);
    --font-size-small: max(var(--step--1), 0.8125rem);
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
}

/* Full-bleed elements (Modern's hero, dark bands) reach the screen edge; clip - unlike hidden -
   never creates a scroll container, so sticky headers keep working. */
html {
    overflow-x: clip;
}

body {
    background-color: var(--color-background);
    color: var(--color-text);
    font-family: var(--font-body);
    font-size: var(--font-size-body);
    line-height: var(--line-height-normal);
}

h1, h2, h3, h4 {
    font-family: var(--font-heading);
    /* Mockup alignment: each theme sets its own heading weight - light and elegant (Sober),
       heavy (Expressief, Jeugdig). */
    font-weight: var(--heading-weight, 700);
    /* Dutch is full of long compounds ("jongerengroep", "toneelvereniging"): a heading hyphenates
       where the browser can (the page is lang="nl") and, as a last resort, breaks inside the
       word - it never runs out of its box on a narrow phone. "anywhere" (not "break-word") also
       lets flex and grid columns around it shrink instead of being pushed wider. */
    overflow-wrap: anywhere;
    -webkit-hyphens: auto;
    hyphens: auto;
    color: var(--color-primary-text);
    line-height: var(--line-height-tight);
    letter-spacing: var(--letter-spacing-normal);
    margin: 0 0 var(--space-sm);
}

h1 {
    font-size: var(--font-size-hero);
}

h2 {
    font-size: var(--font-size-h2);
}

h3 {
    font-size: var(--font-size-h3);
}

a {
    color: var(--color-primary-text);
}

a:focus-visible,
button:focus-visible,
.btn:focus-visible {
    outline: 3px solid var(--color-secondary);
    outline-offset: 2px;
}

/* Toegankelijkheid (mijlpaal 12): laat toetsenbordgebruikers de header/navigatie overslaan. */
.skip-link {
    position: absolute;
    top: -100%;
    left: var(--space-sm);
    z-index: 100;
    background-color: var(--color-background);
    color: var(--color-text);
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    text-decoration: none;
    font-weight: 700;
}

.skip-link:focus-visible {
    top: var(--space-sm);
}

/* Header en navigatie (mijlpaal 7, MIJLPALEN.md). */

.site-header {
    position: relative;
    background-color: var(--color-primary);
    color: var(--color-on-primary);
}

.site-header__inner {
    position: relative;
    max-width: calc(var(--content-max) + 2 * var(--gutter));
    margin: 0 auto;
    padding: var(--space-sm) var(--gutter);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
}

.site-header__brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    color: var(--color-on-primary);
    font-family: var(--font-heading);
    font-size: 1.5rem;
    text-decoration: none;
    /* Flex items don't shrink below their content's intrinsic width by default (min-width:
       auto), so a long verenigingsnaam could push the hamburger toggle off-screen on a narrow
       phone. min-width: 0 lets it actually shrink; the rest makes that shrinking graceful. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.site-header__logo {
    display: block;
    height: 2.25rem;
    width: auto;
    flex-shrink: 0;
}

.site-header__name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.site-header__nav {
    display: flex;
    align-items: center;
    gap: var(--space-lg);
}

.site-header__menu {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    list-style: none;
    margin: 0;
    padding: 0;
}

.site-header__menu a {
    color: inherit;
    text-decoration: none;
    font-weight: 600;
    font-size: var(--font-size-small);
    white-space: nowrap;
}

.site-header__menu a:hover {
    text-decoration: underline;
    text-underline-offset: 4px;
}

.site-header__menu a[aria-current="page"] {
    text-decoration: underline;
    text-underline-offset: 4px;
}

.site-header__cta {
    white-space: nowrap;
}

.site-header__toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: none;
    background: transparent;
    color: inherit;
    cursor: pointer;
    flex-shrink: 0;
}

.site-header__toggle span {
    display: block;
    height: 2px;
    background-color: currentColor;
    border-radius: 2px;
}

/* Hamburger (elk thema, dezelfde vormgeving): een flyout die vanaf links inschuift over
   ongeveer een derde van de schermbreedte, en terug dichtschuift bij Escape, een klik buiten
   het menu, of een klik op een menu-item/actieknop (site.js).
   D6: driven by .site-header--compact instead of a fixed breakpoint. An inline script right
   after the header (Header.cshtml) sets it before the first paint, both on a narrow screen
   and whenever the menu items simply don't fit next to each other - so 8+ items never overflow
   the bar on a desktop either. Without JavaScript the class is never set and the menu just
   stays a (wrapping) row of links, which beats a hamburger that cannot open. */
.site-header--compact .site-header__toggle {
    display: flex;
}

.site-header--compact .site-header__nav {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: clamp(240px, 33vw, 320px);
    max-width: 85vw;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--space-md);
    /* The flyout has the primary color as its own background, so it needs the matching text
       color - inheriting the header's text color left dark links on a dark flyout in every
       theme whose header is light (Klassiek, Speels). */
    background-color: var(--color-primary);
    color: var(--color-on-primary);
    text-shadow: none;
    padding: var(--space-xl) var(--space-md) var(--space-md);
    box-shadow: var(--shadow-md);
    z-index: 40;
    overflow-y: auto;
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform 0.25s ease, visibility 0s linear 0.25s;
}

.site-header--compact .site-header__nav[data-open] {
    transform: translateX(0);
    visibility: visible;
    transition: transform 0.25s ease, visibility 0s linear 0s;
}

.site-header--compact .site-header__menu {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-sm);
}

.site-header--compact .site-header__menu a {
    font-size: var(--font-size-body);
}

/* The action button sits on the primary-colored flyout here; a theme whose primary button is
   itself primary-colored (Klassiek) would make it vanish, so it is inverted in the flyout. */
.site-header.site-header--compact .site-header__cta {
    background-color: var(--color-on-primary);
    color: var(--color-primary);
    filter: none;
}

/* Without JavaScript the menu stays a row that wraps instead of overflowing. */
.site-header:not(.site-header--compact) .site-header__nav,
.site-header:not(.site-header--compact) .site-header__menu {
    flex-wrap: wrap;
}

/* Set only for a moment by the inline layout script, to measure the unwrapped menu width. */
.site-header.site-header--measuring .site-header__nav,
.site-header.site-header--measuring .site-header__menu {
    flex-wrap: nowrap;
    width: max-content;
    flex-shrink: 0;
}

/* No flyout animation while the layout script switches states (see Header.cshtml). */
.site-header.site-header--measuring .site-header__nav {
    transition: none;
}

.site-header--sticky {
    position: sticky;
    top: 0;
    z-index: 20;
}

.site-header--transparent {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 20;
    background-color: transparent;
    /* D6: a soft readability gradient over the photo, on top of the text shadow. Contrast
       (mijlpaal 12): the text sits directly on an arbitrary uploaded photo here, so a fixed
       color pair can't guarantee WCAG contrast - both keep it legible regardless. Dropped again
       once .scrolled gives the header a solid background of its own. */
    background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
    /* A background is drawn from inside the border and repeats by default: under a theme's
       transparent bottom border (Modern, 2px) the darkest top of the gradient came back as a
       black line across the photo. Draw it once, over the border too. */
    background-repeat: no-repeat;
    background-origin: border-box;
    transition: background-color 0.2s ease;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
}

.site-header--transparent.site-header--scrolled {
    position: sticky;
    background-color: var(--color-primary);
    background-image: none;
    text-shadow: none;
}

.site-main {
    max-width: calc(var(--content-max) + 2 * var(--gutter));
    margin: 0 auto;
    padding: var(--space-xl) var(--gutter);
    min-height: 60vh;
}

/* Footer (D7): brand, contact, social media, sponsors and the privacy statement. The footer
   takes its colors from --footer-* hooks, so a theme can make it dark (Modern). */
.site-footer {
    background-color: var(--footer-bg, transparent);
    color: var(--footer-text, var(--color-text));
    font-size: var(--font-size-small);
    border-top: var(--footer-border, 1px solid var(--color-border));
}

.site-footer__inner {
    max-width: calc(var(--content-max) + 2 * var(--gutter));
    margin: 0 auto;
    padding: var(--space-xl) var(--gutter) var(--space-md);
}

.site-footer__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    gap: var(--space-lg);
}

.site-footer__logo {
    display: block;
    height: 3rem;
    width: auto;
    margin-bottom: var(--space-2xs);
}

.site-footer__name {
    margin: 0;
    font-family: var(--font-heading);
    font-size: var(--step-1);
    color: var(--footer-heading, var(--color-primary-text));
}

.site-footer__heading {
    margin: 0 0 var(--space-2xs);
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: var(--letter-spacing-wide);
    text-transform: uppercase;
    color: var(--footer-muted, var(--color-muted));
}

.site-footer__contact {
    display: flex;
    flex-direction: column;
    gap: var(--space-3xs);
    font-style: normal;
}

.site-footer a {
    color: inherit;
}

.site-footer__social {
    display: flex;
    flex-direction: column;
    gap: var(--space-3xs);
    list-style: none;
    margin: 0;
    padding: 0;
}

.site-footer__social a {
    font-weight: 600;
}

.site-footer__sponsors {
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid var(--footer-rule, var(--color-border));
}

.site-footer__sponsors .inline-list {
    gap: var(--space-md);
    align-items: center;
}

.site-footer__sponsors img {
    display: block;
    max-height: 40px;
    max-width: 120px;
}

.site-footer__bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-2xs) var(--space-md);
    margin-top: var(--space-lg);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--footer-rule, var(--color-border));
    color: var(--footer-muted, var(--color-muted));
}

.site-footer__bottom p {
    margin: 0;
}

.accent {
    color: var(--color-secondary);
}

/* ==========================================================================
   Basiscomponenten (DESIGN-MIJLPALEN.md, D4)

   Every block is built from these; a block's own rules further down only do layout (grid,
   flex, sizes). A theme changes a component's look through the --card-*, --panel-*,
   --badge-* and --media-* hooks below (or by restyling the component itself), and every block
   using that component follows. No theme rule targets a single block's visuals anymore,
   except the hero, which is each theme's signature. All shown on /dev/styleguide.
   ========================================================================== */

/* Knoppen: primair (de ene belangrijkste actie), secundair (contour), tekst (een link met pijl).
   Always a verb plus an arrow (D2, principle 7). */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 1.25rem;
    /* Sober has near-square buttons, Jeugdig pills: a theme sets --btn-radius. */
    border-radius: var(--btn-radius, var(--radius-full));
    font-family: inherit;
    font-weight: 700;
    font-size: var(--font-size-small);
    line-height: 1.2;
    text-decoration: none;
    border: 2px solid transparent;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, gap 0.15s ease;
}

.btn::after {
    content: "\2192";
}

.btn:hover {
    gap: 0.6rem;
}

.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn-primary {
    background-color: var(--color-secondary);
    color: var(--color-on-secondary);
}

.btn-primary:hover {
    filter: brightness(0.95);
}

.btn-secondary {
    background-color: transparent;
    border-color: currentColor;
    color: inherit;
}

.btn-secondary:hover {
    background-color: color-mix(in srgb, currentColor 8%, transparent);
}

.btn-text {
    padding-left: 0;
    padding-right: 0;
    border-radius: 0;
    background: none;
    color: var(--color-primary-text);
}

.btn-text:hover {
    text-decoration: underline;
    text-underline-offset: 0.2em;
}

.btn-sm {
    padding: var(--space-3xs) var(--space-sm);
}

/* Badges: korte statuslabels. The status colors are platform-fixed on purpose (they mean the
   same thing on every site); the neutral badge follows the tenant's colors. */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.35rem 0.85rem;
    border-radius: var(--radius-full);
    border: var(--badge-border, 1px solid transparent);
    background-color: var(--badge-bg, var(--color-primary-soft));
    color: var(--badge-text, var(--color-text));
    font-size: var(--font-size-small);
    font-weight: var(--badge-weight, 400);
    line-height: 1.3;
    white-space: nowrap;
}

/* A datum + locatie can run long ("Cultuurcentrum De Schouwburg"): let it wrap instead of
   pushing the page wider than a phone screen (mijlpaal 12). */
.badge--wrap {
    white-space: normal;
    text-align: left;
}

.badge--accent {
    background-color: var(--color-secondary);
    color: var(--color-on-secondary);
}

.badge--success {
    background-color: var(--status-success-bg);
    color: var(--status-success-text);
    border-color: transparent;
}

.badge--warning {
    background-color: var(--status-warning-bg);
    color: var(--status-warning-text);
    border-color: transparent;
}

.badge--sold-out {
    background-color: transparent;
    color: var(--color-muted);
    border: 1px solid var(--color-border);
}

/* Tag: a small, quiet category label (genre, soort voorstelling). */
.tag {
    display: inline-block;
    padding: 0.15rem var(--space-2xs);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    color: var(--color-muted);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: var(--letter-spacing-wide);
    text-transform: uppercase;
}

/* Tekststijlen */
.lead {
    font-size: var(--step-1);
    line-height: 1.45;
    max-width: 46ch;
}

.meta {
    color: var(--color-muted);
    font-size: var(--font-size-small);
}

.byline {
    color: var(--color-muted);
    font-style: italic;
}

/* A block without content yet: a calm sentence, never an admin instruction (CLAUDE.md). */
.empty-state {
    color: var(--color-muted);
    font-style: italic;
}

/* Sectiekop: optional eyebrow, the title, optional lead. */
.section-head {
    margin-bottom: var(--space-md);
}

.section-head > :last-child {
    margin-bottom: 0;
}

.eyebrow {
    display: block;
    margin-bottom: var(--space-3xs);
    color: var(--color-muted);
    font-size: var(--font-size-small);
    font-weight: 700;
    letter-spacing: var(--letter-spacing-wide);
    text-transform: uppercase;
}

.section-title {
    margin-bottom: 0;
}

.section-head .lead {
    margin: var(--space-2xs) 0 0;
    color: var(--color-muted);
    max-width: var(--measure);
}

/* Paginatitel: the top of a page that has no hero (tickets, bevestiging, abonnementen). */
.page-header {
    margin-bottom: var(--space-lg);
}

.page-title {
    font-size: var(--step-4);
    margin-bottom: var(--space-2xs);
}

.page-header > :last-child {
    margin-bottom: 0;
}

/* Kaart: a self-contained item in a grid (productie, persoon). */
.card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: var(--radius-lg);
    background-color: var(--card-bg, var(--color-surface));
    border: var(--card-border, 0);
    box-shadow: var(--card-shadow, none);
}

.card__media {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: var(--ratio-photo);
    object-fit: cover;
}

.card__media--poster {
    aspect-ratio: var(--ratio-poster);
}

/* No image yet: a calm, typographic stand-in of the same shape, so a grid of cards stays even
   (CLAUDE.md: always professional, even with little content). */
.card__media--empty {
    display: flex;
    align-items: flex-end;
    padding: var(--space-md);
    background-color: var(--color-primary-soft);
    color: var(--color-primary-text);
    font-family: var(--font-heading);
    font-size: var(--step-4);
    line-height: 1;
}

.card__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-3xs);
    padding: var(--space-md);
}

.card__title {
    font-size: var(--font-size-h3);
    margin: 0;
}

.card__body > p {
    margin: 0;
}

/* Paneel: a tinted area that sets one section apart (productie in de kijker, oproep). */
.panel {
    padding: var(--panel-padding, var(--space-lg));
    border-radius: var(--radius-lg);
    background-color: var(--panel-bg, var(--color-primary-soft));
    color: var(--panel-text, inherit);
    border: var(--panel-border, 0);
    box-shadow: var(--panel-shadow, none);
    /* A neutral badge takes the panel's own tint by default - invisible on a panel of that
       same tint. Inside a panel it stands out on the page background instead (a theme can
       choose otherwise with --panel-badge-bg). */
    --badge-bg: var(--panel-badge-bg, var(--color-background));
    --badge-text: var(--panel-badge-text, var(--color-text));
    --badge-border: var(--panel-badge-border, 1px solid transparent);
}

/* A theme can make its panels dark (Modern): headings and quiet text follow via these hooks. */
.panel :is(h1, h2, h3) {
    color: var(--panel-heading, var(--color-primary-text));
}

.panel :is(.meta, .byline, .eyebrow, .empty-state) {
    color: var(--panel-muted, var(--color-muted));
}

.panel .divided-list > * {
    border-bottom-color: var(--panel-rule, var(--color-border));
}

.panel .badge--sold-out {
    color: var(--panel-muted, var(--color-muted));
    border-color: var(--panel-rule, var(--color-border));
}

.panel--primary {
    background-color: var(--color-primary);
    color: var(--color-on-primary);
    border: 0;
}

.panel--inverse {
    background-color: var(--color-inverse-bg);
    color: var(--color-inverse-text);
    border: 0;
}

.panel--primary :is(h1, h2, h3),
.panel--inverse :is(h1, h2, h3) {
    color: inherit;
}

/* Beeld: every photo slot crops to a standard ratio (D3). */
.media {
    display: block;
    width: 100%;
    height: auto;
    object-fit: cover;
    border-radius: var(--radius-md);
    border: var(--media-border, 0);
}

.media--photo { aspect-ratio: var(--ratio-photo); }
.media--wide { aspect-ratio: var(--ratio-wide); }
.media--poster { aspect-ratio: var(--ratio-poster); }
.media--square { aspect-ratio: var(--ratio-square); }

.avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: min(140px, 100%);
    height: auto;
    aspect-ratio: 1 / 1;
    margin: 0 auto;
    object-fit: cover;
    border-radius: var(--radius-full);
    background-color: var(--color-primary-soft);
    color: var(--color-primary-text);
    font-family: var(--font-heading);
    font-size: 2.5rem;
    font-weight: 700;
}

/* Citaat */
.quote {
    max-width: var(--measure);
    margin: 0 auto;
    padding: 0;
    text-align: center;
}

.quote__text {
    font-family: var(--font-heading);
    font-size: var(--font-size-h2);
    line-height: 1.3;
}

.quote__source {
    display: block;
    margin-top: var(--space-sm);
    color: var(--color-muted);
    font-size: var(--font-size-small);
    font-style: normal;
}

/* Volgende voorstelling (D2 principle 2, D5): sits in the hero, whatever its background, so
   it takes its colors from the surrounding text color instead of the tenant palette. */
.next-up {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.15rem var(--space-md);
    align-items: center;
    width: 100%;
    max-width: 30rem;
    margin-top: var(--space-lg);
    padding: var(--space-sm) var(--space-md);
    border: 1px solid color-mix(in srgb, currentColor 30%, transparent);
    border-left: 4px solid var(--color-secondary);
    border-radius: var(--radius-md);
}

.next-up__label {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: var(--letter-spacing-wide);
    text-transform: uppercase;
    color: color-mix(in srgb, currentColor 80%, transparent);
}

.next-up__title {
    font-family: var(--font-heading);
    font-size: var(--step-1);
    line-height: var(--line-height-tight);
}

.next-up__when {
    font-size: var(--font-size-small);
}

.next-up__label,
.next-up__title,
.next-up__when {
    grid-column: 1;
}

.next-up__action {
    grid-column: 2;
    grid-row: 1 / span 3;
}

.next-up .btn-text {
    color: inherit;
}

.next-up__sales-start {
    font-size: var(--font-size-small);
    font-weight: 700;
    text-align: right;
}

@media (max-width: 480px) {
    .next-up {
        grid-template-columns: 1fr;
    }

    .next-up__action {
        grid-column: 1;
        grid-row: auto;
        justify-self: start;
        margin-top: var(--space-2xs);
    }
}

/* Logo-link (sponsors): a clear hover and focus state on an otherwise quiet image link. */
.logo-link {
    display: inline-block;
    border-radius: var(--radius-sm);
    transition: transform 0.15s ease;
}

.logo-link:hover {
    transform: translateY(-2px);
}

/* Lopende tekst (privacyverklaring, lange pagina's): leesbreedte en rustige kopjes (D7). */
.prose {
    max-width: var(--measure);
}

.prose h2 {
    font-size: var(--step-2);
    margin: var(--space-lg) 0 var(--space-2xs);
}

/* "Blijf op de hoogte" (D8): the empty state of a block about what's coming. */
.stay-tuned > p {
    max-width: var(--measure);
}

.stay-tuned__links {
    margin-top: var(--space-sm);
}

/* Systeempagina (D7): niet gevonden, nog niet gepubliceerd, fout. */
.system-page {
    max-width: var(--measure);
    padding: var(--space-xl) 0;
}

.system-page__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

/* Lijsten */
.inline-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
    list-style: none;
    padding: 0;
    margin: 0;
}

.divided-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.divided-list > * {
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--color-border);
}

.divided-list > :first-child {
    padding-top: 0;
}

.divided-list > :last-child {
    border-bottom: none;
}

/* Tabel */
.table {
    width: 100%;
    border-collapse: collapse;
    margin: var(--space-md) 0;
}

.table th,
.table td {
    text-align: left;
    padding: var(--space-2xs);
    border-bottom: 1px solid var(--color-border);
}

/* Formuliervelden. The border uses --color-muted: that is AA against the background, so the
   field outline also clears WCAG's 3:1 for non-text contrast. */
.form-stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}

.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-3xs);
}

.field__label {
    font-weight: 600;
    font-size: var(--font-size-small);
}

.field__hint {
    color: var(--color-muted);
    font-size: var(--font-size-small);
}

.input,
.select,
.textarea {
    width: 100%;
    padding: var(--space-2xs) var(--space-sm);
    border: 1px solid var(--color-muted);
    border-radius: var(--radius-sm);
    background-color: var(--color-background);
    color: var(--color-text);
    font: inherit;
}

.textarea {
    min-height: 7rem;
    resize: vertical;
}

.input:focus-visible,
.select:focus-visible,
.textarea:focus-visible {
    outline: 3px solid var(--color-secondary);
    outline-offset: 1px;
}

.input--compact {
    width: 4.5rem;
    padding: var(--space-3xs) var(--space-2xs);
}

.form-error {
    color: var(--status-danger);
    font-weight: 600;
}

/* ==========================================================================
   Blocks (CLAUDE.md "Eerste set blokken", mijlpaal 9). Layout only: everything visual comes
   from the components above.
   ========================================================================== */

.block {
    margin-bottom: var(--space-2xl);
}

/* Gesplitste hero (tekst + een echte foto ernaast), zoals bijna elke mockup: geen tekst
   overlappend op een achtergrondfoto, maar twee kolommen naast elkaar. Zonder foto (lege
   toestand) neemt de tekst gewoon de volledige breedte in - geen kunstmatig leeg vak.
   The hero is the one block themes still style directly: it is each theme's signature. */
.block-header-hero {
    display: flex;
    align-items: stretch;
    gap: var(--space-xl);
    margin: calc(var(--space-xl) * -1) calc(var(--gutter) * -1) var(--space-2xl);
    overflow: hidden;
}

.block-header-hero__content {
    flex: 1 1 420px;
    padding: var(--space-2xl) var(--gutter);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
}

/* D8: without a photo the hero spans the full width - a 640px text panel next to an empty
   half looked unbalanced. The heading, lead and "volgende voorstelling" keep their own
   reading widths inside it. */
.block-header-hero--no-media .block-header-hero__content {
    flex: 1 1 100%;
}

.block-header-hero__media {
    position: relative;
    flex: 1 1 420px;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.block-header-hero__media img {
    display: block;
    width: 100%;
    flex: 1 1 auto;
    height: 100%;
    min-height: 320px;
    object-fit: cover;
    border-radius: var(--radius-lg);
}

.block-header-hero .lead {
    margin: 0 0 var(--space-md);
}

/* The *accent* in a hero title (HeroTitle): each theme gives it its own form. */
.hero-accent {
    color: var(--color-secondary);
}

/* The second, quiet text layer (D2 principle 4). Default: a small italic line under the photo,
   as in the "Sober" mockups; Modern and Speels move it onto the photo. */
.block-header-hero__caption {
    margin: var(--space-2xs) 0 0;
    color: var(--color-muted);
    font-size: var(--font-size-small);
    font-style: italic;
    text-align: right;
}

.block-header-hero__cta {
    margin-top: var(--space-2xs);
}

@media (max-width: 720px) {
    .block-header-hero {
        flex-direction: column;
    }

    .block-header-hero__media img {
        min-height: 220px;
    }
}

.block-text-with-image {
    display: flex;
    gap: var(--space-lg);
    align-items: center;
    flex-wrap: wrap;
}

.block-text-with-image--left {
    flex-direction: row-reverse;
}

.block-text-with-image > .media,
.block-text-with-image__content {
    flex: 1 1 280px;
    min-width: 0;
}

/* Leesbreedte (D5): running text never wider than 60-75 characters. */
.block-text-with-image__content {
    max-width: var(--measure);
}

.block-production-spotlight,
.block-affiche-hero {
    display: flex;
    gap: var(--space-lg);
    align-items: flex-start;
    flex-wrap: wrap;
}

/* min-width: 0 - a flex item never shrinks below its own content width by default, and for an
   image that is its intrinsic width: a 600px-wide poster ignored the 240px basis and filled the
   whole row. */
.block-production-spotlight__poster {
    flex: 0 0 240px;
    min-width: 0;
    max-width: 100%;
}

.block-production-spotlight__dates {
    margin-top: var(--space-md);
}

.block-production-spotlight__date {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2xs) var(--space-sm);
}

.block-production-spotlight__when {
    display: flex;
    flex-direction: column;
    flex: 1 1 12rem;
}

.block-production-spotlight__content,
.block-affiche-hero__content {
    flex: 1 1 280px;
    /* A flex item never shrinks below its widest word by default: a long title pushed the whole
       column - and its dates - past the edge of a phone screen. */
    min-width: 0;
    max-width: var(--measure);
}

.block-production-spotlight .inline-list,
.block-affiche-hero .inline-list {
    margin-top: var(--space-sm);
}

.block-affiche-hero {
    gap: var(--space-xl);
    align-items: center;
    padding-top: var(--space-2xl);
    padding-bottom: var(--space-2xl);
}

.block-affiche-hero__cta {
    margin-top: var(--space-md);
}

.block-affiche-hero__media {
    flex: 0 0 280px;
    max-width: 100%;
}

/* D5: min(140px, 45%) keeps two columns on a phone - with a flat 180px minimum these grids
   fell back to one full-width column and the homepage grew to over 11,000px tall. */
.block-production-archive__grid,
.block-photo-gallery__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(180px, 45%), 1fr));
    gap: var(--space-md);
}

.block-photo-gallery__grid {
    gap: var(--space-sm);
}

.block-sponsors .inline-list {
    gap: var(--space-lg);
    align-items: center;
}

.block-sponsors img {
    display: block;
    max-height: 60px;
    max-width: 160px;
}

.block-performance-schedule__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
}

.block-performance-schedule__title {
    flex: 1 1 200px;
}

.block-cast__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(160px, 45%), 1fr));
    gap: var(--space-lg) var(--space-sm);
    text-align: center;
}

.block-cast__item h3 {
    margin: var(--space-sm) 0 0.2rem;
}

.block-quote .quote + .quote {
    margin-top: var(--space-lg);
}

.block-cta-banner {
    text-align: center;
    padding: var(--space-2xl) var(--space-lg);
}

.block-cta-banner p {
    max-width: var(--measure);
    margin: 0 auto;
}

.block-cta-banner__cta {
    margin-top: var(--space-md);
}

@media (max-width: 720px) {
    .block-cta-banner {
        padding: var(--space-xl) var(--space-md);
    }
}

.block-news h3 {
    margin: var(--space-3xs) 0 0.2rem;
}

.block-news p {
    margin: 0;
}

.block-contact-map {
    display: flex;
    gap: var(--space-lg);
    flex-wrap: wrap;
    align-items: stretch;
}

.block-contact-map__content {
    flex: 1 1 280px;
    min-width: 0;
}

.block-contact-map__frame {
    flex: 1 1 320px;
    min-width: 0;
    min-height: 280px;
}

.block-empty-home {
    text-align: center;
    padding: var(--space-2xl) var(--space-sm);
}

/* Ticketpagina's (T2 e.v.): layout only, built from the same components. */
.ticket-order {
    max-width: var(--content-narrow);
    margin: 0 auto;
    padding: var(--space-xl) var(--space-md);
}

.ticket-order__head {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.ticket-order__poster {
    flex: 0 0 96px;
    min-width: 0;
}

.ticket-order .panel > :last-child {
    margin-bottom: 0;
}

.ticket-order__summary {
    list-style: none;
    padding: 0;
    margin: var(--space-sm) 0;
}

.ticket-order__total {
    font-weight: 700;
}

/* Zaalplan (mijlpaal T9): eigen kleuren, bewust los van de thema-variabelen - een plattegrond
   moet in elk thema even leesbaar blijven (zone-kleuren zijn door de vereniging zelf gekozen). */

.seatmap-svg-wrapper {
    position: relative;
    border: 1px solid #e5e7eb;
    border-radius: var(--radius-md, 12px);
    background: #f9fafb;
    overflow: hidden;
    touch-action: none;
}

#seatmap-svg {
    width: 100%;
    height: min(70vh, 480px);
    display: block;
    cursor: grab;
}

.seatmap-controls {
    position: absolute;
    right: 0.5rem;
    top: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.seatmap-controls button {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 8px;
    border: 1px solid #d1d5db;
    background: #fff;
    font-size: 1.1rem;
    cursor: pointer;
}

.seatmap-stage {
    fill: #1f2a44;
}

.seatmap-stage-label {
    fill: #fff;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.1em;
}

.seatmap-row-label {
    font-size: 9px;
    fill: #6b7280;
    text-anchor: middle;
    dominant-baseline: middle;
}

.seatmap-seat {
    stroke: #ffffff;
    stroke-width: 1;
    cursor: default;
}

.seatmap-seat--free {
    cursor: pointer;
}

.seatmap-seat--held,
.seatmap-seat--sold {
    opacity: 0.35;
}

.seatmap-seat--blocked {
    opacity: 0.2;
}

.seatmap-seat--selected {
    stroke: #1f2a44;
    stroke-width: 2.5;
}

.seatmap-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin: 0.75rem 0;
    font-size: 0.85rem;
}

.seatmap-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.seatmap-legend__swatch {
    width: 0.85rem;
    height: 0.85rem;
    border-radius: 50%;
    display: inline-block;
}

.seatmap-auto-assign {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 1rem 0;
    padding: 0.75rem;
    background: #f3f4f6;
    border-radius: 8px;
}

.seatmap-auto-assign select,
.seatmap-auto-assign input {
    font: inherit;
    padding: 0.4rem 0.6rem;
    border-radius: 6px;
    border: 1px solid #d1d5db;
}

.seatmap-auto-assign input[type="number"] {
    width: 4rem;
}

.seatmap-selection {
    margin-top: 1rem;
}

.seatmap-selection-row {
    display: grid;
    grid-template-columns: 3rem 1fr auto auto;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid #e5e7eb;
}

.seatmap-selection-row select {
    font: inherit;
    padding: 0.3rem;
    border-radius: 6px;
    border: 1px solid #d1d5db;
}

.seatmap-selection-row button {
    width: auto;
    background: transparent;
    border: 0;
    font-size: 1.1rem;
    color: #b3261e;
    cursor: pointer;
}

.seatmap-total {
    font-weight: 700;
    margin-top: 0.5rem;
}

.seatmap-error {
    color: #b3261e;
    margin-top: 0.5rem;
}
