/*
Theme Name: Transformation
Theme URI: https://transformation-festival.example
Author: Transformation Festival
Description: Custom block theme for Transformation Festival.
Version: 0.1.0
Requires at least: 6.6
Tested up to: 6.9
Requires PHP: 7.4
License: GPL-2.0-or-later
Text Domain: transformation
*/

@import url('https://fonts.googleapis.com/css2?family=Anton&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap');

:root {
    --tf-acid-glow: 0 4px 24px oklch(0.82 0.19 120 / 0.45);
    --tf-acid-glow-strong: 0 6px 36px oklch(0.82 0.19 120 / 0.6);
    --tf-grunge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.55'/></svg>");
}

body {
    background-color: var(--wp--preset--color--ink-deep);
    color: var(--wp--preset--color--bone);
    background-image: var(--tf-grunge);
    background-attachment: fixed;
    background-size: 240px 240px;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Sticky-footer pattern: short pages (FAQ, Impressum, etc.) should still
     * fill the viewport so the footer never floats mid-page. body grows to
     * 100dvh, .wp-site-blocks flexes to fill it, and the .wp-block-post-content
     * area between header and footer takes the remaining vertical space. */
    min-height: 100vh;
    min-height: 100dvh; /* mobile-aware (excludes browser chrome on iOS Safari) */
    display: flex;
    flex-direction: column;
}
.wp-site-blocks {
    flex: 1;
    display: flex;
    flex-direction: column;
}
/* Grow whatever direct child is "the content area" between header and footer:
 *  - front-page.html / page-styleguide.html → .wp-block-post-content (direct)
 *  - page.html / page-editorial.html / index.html / single.html → <main> wrapper
 * Both share one property: they are NOT .wp-block-template-part (the class WP
 * applies to all template-part wrappers — banner, header, footer). One :not()
 * rule covers every template uniformly. */
.wp-site-blocks > :not(.wp-block-template-part) {
    flex: 1;
}

a {
    color: var(--wp--preset--color--acid);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    transition: text-decoration-thickness 120ms cubic-bezier(0.22, 1, 0.36, 1);
}
a:hover, a:focus-visible {
    text-decoration-thickness: 3px;
}

::selection {
    background: var(--wp--preset--color--acid);
    color: var(--wp--preset--color--ink-deep);
}

/* === Buttons === */

.tf-cta {
    display: inline-block;
    padding: 0.95rem 2.25rem;
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: 1.0625rem;
    font-weight: 400;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-decoration: none;
    background: var(--wp--preset--color--acid);
    color: var(--wp--preset--color--ink-deep);
    border: 2px solid var(--wp--preset--color--acid);
    border-radius: 0;
    box-shadow: var(--tf-acid-glow);
    transition:
        background-color 160ms cubic-bezier(0.22, 1, 0.36, 1),
        color 160ms cubic-bezier(0.22, 1, 0.36, 1),
        transform 80ms cubic-bezier(0.22, 1, 0.36, 1),
        box-shadow 200ms cubic-bezier(0.22, 1, 0.36, 1);
}
.tf-cta:hover, .tf-cta:focus-visible {
    background: var(--wp--preset--color--ink-deep);
    color: var(--wp--preset--color--acid);
    box-shadow: var(--tf-acid-glow-strong);
    text-decoration: none;
}
.tf-cta:focus-visible {
    outline: 3px solid var(--wp--preset--color--acid);
    outline-offset: 2px;
}
.tf-cta:active {
    transform: scale(0.98);
}
.tf-cta[aria-disabled="true"], .tf-cta:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    box-shadow: none;
}

/* Plan 04-10 gap closure (cta-arrow-iconfont): the ticket-cta arrow was
 * literal U+2192 inside an Anton-stack button. Anton has no native arrow
 * glyph, fallback to Inter/system rendered as visible typeface mismatch.
 * Replace with inline SVG inheriting currentColor — visually consistent
 * with surrounding Anton text, no font dependency, no GDPR exposure.
 * The base .tf-cta rule is preserved verbatim (lines 73-92); the new
 * children rules below position <span class="tf-cta__label"> + <svg
 * class="tf-cta__arrow"> inside the inline-block anchor. */
.tf-cta__label {
    vertical-align: baseline;
}
.tf-cta__arrow {
    display: inline-block;
    width: 1em;
    height: 1em;
    margin-inline-start: 0.5em;
    vertical-align: -0.125em;     /* optical baseline tweak — Anton sits higher than the SVG midline */
    flex-shrink: 0;
}

/* === Marquee === */

.tf-marquee {
    overflow: hidden;
    border-block: 1px solid var(--wp--preset--color--asphalt);
    background: var(--wp--preset--color--ink);
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: 1rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    padding: 0.85rem 0;
}
.tf-marquee__track {
    display: inline-flex;
    gap: 2.5rem;
    white-space: nowrap;
    animation: tf-marquee-scroll 112s linear infinite;
    padding-inline-end: 2.5rem;
    will-change: transform;
}
.tf-marquee__item { color: var(--wp--preset--color--bone); }
.tf-marquee__item--accent { color: var(--wp--preset--color--acid); }

/* Fixed-to-bottom variant. Pinned by render.php when the block's `fixed`
 * attribute is true (default). The :has() rule below reserves bottom padding
 * on <body> so page content is not occluded by the bar. */
.tf-marquee--fixed {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 40;
}
body:has(.tf-marquee--fixed) {
    padding-block-end: var(--tf-marquee-fixed-height, 3.25rem);
}

@keyframes tf-marquee-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/* === Sticky banner === */

/* Plan 04-08 gap closure (banner-not-sticky): position:sticky must live on
 * the OUTER .wp-block-template-part wrapper, not the inner .tf-banner.
 * The wrapper is a flex item in .wp-site-blocks (column flex via sticky-footer
 * pattern lines 22-53); inner sticky was defeated because its containing block
 * (the wrapper) sized to content (~64px) and scrolled away in ~64px. Hoisting
 * sticky to the wrapper makes .wp-site-blocks (full document height) the
 * containing block, so the pin holds across full-page scroll on every template.
 * Banner is ALWAYS the first template-part in all 6 templates (verified Plan 04-03). */
.wp-site-blocks > .wp-block-template-part:first-child {
    position: sticky;
    top: 0;
    z-index: 50;
}

.tf-banner {
    width: 100%;
    background: var(--wp--preset--color--ink-deep);
    color: var(--wp--preset--color--bone);
    border-block-end: 1px solid var(--wp--preset--color--asphalt);
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: 0.875rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.tf-banner__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    height: 56px;
    padding-inline: 1.25rem;
    max-width: 1280px;
    margin-inline: auto;
}
@media (min-width: 768px) {
    .tf-banner__inner { height: 64px; padding-inline: 2rem; }
}
.tf-banner__meta { color: var(--wp--preset--color--ash); }
.tf-banner__count {
    color: var(--wp--preset--color--acid);
    font-weight: 700;
    /* Endcaps must never wrap — when the marquee body squeezes the row at narrow
     * viewports, "JETZT LIVE" and the CTA pill should shrink the body, not break
     * mid-word. */
    white-space: nowrap;
    flex: 0 0 auto;
}
/* Pre-phase: true geometric centering — grid 1fr auto 1fr anchors the count
 * column dead center regardless of meta-left vs cta-right width disparity
 * (flex space-between drifts the middle child when siblings are unequal).
 * Live phase keeps flex (its .tf-banner__live-clip marquee relies on
 * flex: 1 1 auto + min-width: 0 to grow-then-clip the scrolling track). */
.tf-banner[data-phase="pre"] .tf-banner__inner {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
}
/* Explicit grid-column assignment per role — robust to missing middle slot.
 * If .tf-banner__count--pre is absent (e.g. festival window unresolved), the
 * CTA still lands in column 3 / right edge instead of collapsing into column 2. */
.tf-banner[data-phase="pre"] .tf-banner__meta       { grid-column: 1; justify-self: start; }
.tf-banner[data-phase="pre"] .tf-banner__count--pre { grid-column: 2; justify-self: center; }
.tf-banner[data-phase="pre"] .tf-banner__cta        { grid-column: 3; justify-self: end; }
/* Pre-phase prominent D/H/M/S countdown — sits as the middle child between
 * .tf-banner__meta (left) and .tf-banner__cta (right). Carries
 * data-tf-countdown so countdown view.js ticks the .tf-countdown__digit
 * children once per second. */
.tf-banner__count--pre {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    white-space: nowrap;
}
.tf-banner__count-unit {
    display: inline-flex;
    align-items: baseline;
    gap: 0.25rem;
}
.tf-banner__count-label {
    font-size: 0.7rem;
    font-weight: 400;
    color: var(--wp--preset--color--ash);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.tf-banner__count-sep {
    color: var(--wp--preset--color--ash);
    opacity: 0.55;
}
/* Banner-scoped digit override — the in-page countdown block uses
 * clamp(2rem, 5vw, 3rem) which would burst the 56-64px bar. Bump weight + size
 * for prominence without overflow. */
.tf-banner .tf-countdown__digit {
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--wp--preset--color--acid);
    font-variant-numeric: tabular-nums;
    min-width: 2ch;
    text-align: center;
    display: inline-block;
    letter-spacing: 0.04em;
}
@media (min-width: 768px) {
    .tf-banner .tf-countdown__digit { font-size: 1.5rem; }
    .tf-banner__count-label         { font-size: 0.75rem; }
}
/* Plan 04-08 gap closure (banner-mobile-overflow): pre-state row doesn't fit
 * narrow viewports. At 375px, three nowrap children (.tf-banner__meta ~245px +
 * .tf-banner__count--pre ~218px + .tf-banner__cta ~110px = ~573px) overflow
 * the ~335px available width. Meta is the least-urgent signal (date string
 * also rendered in the hero meta-row one scroll-line down); drop it on mobile,
 * switch grid to 1fr auto (countdown left + CTA right), compress countdown to
 * fit 320px worst case. Compact D/H/M/S labels are validated user UX preference
 * — markup unchanged. Live-state and post-state untouched (selector scoped to
 * .tf-banner[data-phase="pre"]).
 *
 * Plan 04-11 cycle-2 gap closure (banner-tablet-dead-zone): ceiling extended
 * 767 → 909px. UAT cycle-2 Test 2 confirmed wrapping observed at all widths
 * below 911px — the 768-909px tablet range falls into the same overflow regime
 * as <=767px (meta + count + cta ≈ 573px content + 2rem inline padding exceeds
 * the practical fit threshold around 910px). Tablet range 768-909px now joins
 * the mobile branch — meta drop + 1fr auto grid + compressed countdown apply
 * through the full <910px range. Rule body byte-identical to cycle-1; only the
 * breakpoint value changed. */
@media (max-width: 909px) {
    .tf-banner[data-phase="pre"] .tf-banner__inner {
        grid-template-columns: 1fr auto;
    }
    .tf-banner[data-phase="pre"] .tf-banner__meta       { display: none; }
    .tf-banner[data-phase="pre"] .tf-banner__count--pre { grid-column: 1; justify-self: start; }
    .tf-banner[data-phase="pre"] .tf-banner__cta        { grid-column: 2; justify-self: end; }
    .tf-banner__count--pre { gap: 0.35rem; }
    .tf-banner .tf-countdown__digit { font-size: 1.1rem; }
    .tf-banner__count-unit { gap: 0.15rem; }
    .tf-banner__count-label { font-size: 0.625rem; }
}
/* Plan 04-11 cycle-2 gap closure (banner-cta-overflow-narrow-mobile): at <390px
 * the cycle-1 mobile rule's CTA padding (0.45rem 0.95rem) plus four-unit D/H/M/S
 * labels still bursts the right edge. Closes UAT cycle-2 Test 2 sub_gap_a.
 *
 * Tighter padding-inline 0.95 → 0.5rem reclaims ~14.4px on the CTA pill; hiding
 * the four D/H/M/S labels reclaims an additional ~40px across the row; the
 * pre-state container gap tighten 0.35 → 0.2rem reclaims ~6px. Total reclaim
 * ~60px easily clears overflow at 320-389px worst case. Compact digits remain
 * — only the labels drop, preserving the urgency signal (D · H · M · S is still
 * legible from digit + separator rhythm). The .tf-banner__count-label selector
 * is the bare class; hiding labels at <390px is safe because all rendered
 * label nodes live inside .tf-banner__count--pre (data-phase=pre scoped). */
@media (max-width: 389px) {
    .tf-banner[data-phase="pre"] .tf-banner__cta {
        padding-inline: 0.5rem;
    }
    .tf-banner[data-phase="pre"] .tf-banner__count-label {
        display: none;
    }
    .tf-banner__count--pre {
        gap: 0.2rem;
    }
}
.tf-banner--live .tf-countdown__digit,
.tf-banner--live .tf-banner__count-label,
.tf-banner--live .tf-banner__count-sep {
    color: var(--wp--preset--color--ink-deep);
}
.tf-banner__cta {
    background: var(--wp--preset--color--acid);
    color: var(--wp--preset--color--ink-deep);
    padding: 0.45rem 0.95rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    flex: 0 0 auto;
    transition: filter 160ms cubic-bezier(0.22, 1, 0.36, 1);
}
.tf-banner__cta:hover { filter: brightness(1.1); text-decoration: none; }
.tf-banner__cta:focus-visible {
    outline: 3px solid var(--wp--preset--color--acid);
    outline-offset: 2px;
}
/* Plan 04-10 gap closure (cta-arrow-iconfont): banner pill arrow uses the
 * same SVG path as ticket-cta but smaller — scoped to the 56-64px banner row.
 * JetBrains Mono on .tf-banner__cta DOES include U+2192, so the original
 * pill arrow rendered consistently — but debug Option A applies the SVG
 * symmetrically across both CTA surfaces for design-system uniformity.
 * One-Glow Rule preserved: zero box-shadow on the arrow rule. */
.tf-banner__cta-label {
    vertical-align: baseline;
}
.tf-banner__cta-arrow {
    display: inline-block;
    width: 0.95em;
    height: 0.95em;
    margin-inline-start: 0.4em;
    vertical-align: -0.1em;
    flex-shrink: 0;
}
.tf-banner--live {
    background: var(--wp--preset--color--acid);
    color: var(--wp--preset--color--ink-deep);
}
.tf-banner--live .tf-banner__count,
.tf-banner--live .tf-banner__meta { color: var(--wp--preset--color--ink-deep); }
.tf-banner--live .tf-banner__cta {
    background: var(--wp--preset--color--ink-deep);
    color: var(--wp--preset--color--acid);
}

/* B-260507-01: live-row body — bold linked area + multi-row marquee scroll. */
.tf-banner__live-area {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid currentColor;
    transition: opacity 160ms cubic-bezier(0.22, 1, 0.36, 1);
}
.tf-banner__live-area:hover,
.tf-banner__live-area:focus-visible {
    opacity: 0.75;
    text-decoration: none;
}
.tf-banner__live-static { min-width: 0; } /* allow flex shrink so cta stays visible */
.tf-banner__live-clip {
    overflow: hidden;
    flex: 1 1 auto;
    min-width: 0;
}
.tf-banner__live-track {
    display: block;
    white-space: nowrap;
    will-change: transform;
}
.tf-banner__live-track > span {
    display: inline-block;
}
/* Same translateX(-50%) trick as .tf-marquee__track: content rendered twice
 * end-to-end (each copy ends with " · ") so the loop point is exactly the
 * start of the second copy = seamless. Speed tuned for banner-scale content. */
.tf-banner__live-track--marquee {
    animation: tf-marquee-scroll 28s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
    .tf-banner__live-track--marquee { animation: none; }
}

/* === Ticket CTA block wrapper === */

.tf-ticket-cta-block {
    text-align: center;
    margin-block: 2.5rem;
}

/* === Display typography === */

.tf-hero-title {
    font-family: 'Anton', 'Cooper BT', Georgia, serif;
    font-size: clamp(3.5rem, 11vw, 9rem);
    line-height: 0.92;
    letter-spacing: -0.01em;
    color: var(--wp--preset--color--acid);
    margin: 0;
    text-wrap: balance;
}

.tf-headliner {
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: clamp(2rem, 5vw, 3.5rem);
    line-height: 1;
    letter-spacing: 0.01em;
    text-transform: uppercase;
    transform: skew(-8deg);
    transform-origin: 0 100%;
    display: inline-block;
    color: var(--wp--preset--color--bone);
}

.tf-mono { font-family: 'JetBrains Mono', 'Roboto Mono', monospace; }

.tf-meta {
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: 0.875rem;
    letter-spacing: 0.06em;
    color: var(--wp--preset--color--ash);
    text-transform: uppercase;
}

/* Acid section rule */
.tf-rule {
    height: 2px;
    background: var(--wp--preset--color--acid);
    border: 0;
    margin: 2.5rem 0;
}

/* Surface helpers */
.tf-surface {
    background: var(--wp--preset--color--ink);
    padding: 1.75rem;
    border: 1px solid var(--wp--preset--color--asphalt);
}

/* === Reduced motion === */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
    .tf-marquee__track { animation-play-state: paused; }
}

/* ============================================================================ */
/* === Phase 2: Site chrome — header + footer + social + nav-Kontakt-link === */
/* ============================================================================ */

/* --- Site title (wordmark, header) --------------------------------------- */

.wp-block-site-title,
.wp-block-site-title a {
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: 1.125rem;
    line-height: 1;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--wp--preset--color--bone);
    text-decoration: none;
    /* No skew on the wordmark — Skew-Is-The-Italic Rule reserves skew for artist names */
}
.wp-block-site-title a:hover,
.wp-block-site-title a:focus-visible {
    text-decoration: underline;
    text-decoration-color: var(--wp--preset--color--acid);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.2em;
}

/* --- Header padding promotion at md+ ------------------------------------- */

@media (min-width: 768px) {
    header.wp-block-group {
        padding-block: 1.5rem !important;
        padding-inline: 2rem !important;
    }
}

/* --- Banner → header zero-gap override ----------------------------------- */

/* WP's default `:where(.wp-site-blocks) > *` rule applies margin-block-start:
 * 24px (blockGap) to every direct child of <body>'s site-blocks wrapper. The
 * banner template-part renders as the first child (no top margin), but the
 * header — being the 2nd child — inherits the gap, producing a visible 24px
 * void between the candy-stripe banner and the header. Reset to 0 so the
 * header sits flush against the banner.
 *
 * `:where(.wp-site-blocks) > header` has specificity (0,0,1) (header tag,
 * because `:where()` contributes 0) which beats WP's own `:where(...) > *`
 * (specificity (0,0,0)). No !important needed.
 *
 * Post-sweep #3 (2026-05-20). */
:where(.wp-site-blocks) > header {
    margin-block-start: 0;
}

/* --- Header / Primary nav ------------------------------------------------- */

header .wp-block-navigation .wp-block-navigation-item__content {
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: 1rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--wp--preset--color--bone);
    text-decoration: none;
    transition: text-decoration-thickness 120ms cubic-bezier(0.22, 1, 0.36, 1);
}
header .wp-block-navigation .wp-block-navigation-item__content:hover,
header .wp-block-navigation .wp-block-navigation-item__content:focus-visible,
header .wp-block-navigation .current-menu-item .wp-block-navigation-item__content,
header .wp-block-navigation .wp-block-navigation-item__content[aria-current="page"] {
    text-decoration: underline;
    text-decoration-color: var(--wp--preset--color--acid);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.2em;
}
header .wp-block-navigation ul {
    gap: 1.5rem;
}

/* --- Footer body row ------------------------------------------------------- */

.tf-footer__body {
    display: block;
    /* Cap the wrapper at 1280px to match the header's visible content width.
     * The WP-generated `is-layout-constrained > *` rule caps each child but not
     * the flex track below; without this, justify-content:space-between would
     * push nav and social-nav to the viewport edges on >1280px screens.
     * Mirrors .tf-banner__inner and .tf-hero__content. */
    max-width: 1280px;
    margin-inline: auto;
}
@media (min-width: 768px) {
    .tf-footer__body {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 2.5rem;
        flex-wrap: nowrap; /* one row: nav left, social right */
    }
    /* WP's per-container constrained-layout rule applies
     * `margin-left/right: auto !important` to direct children. On flex items
     * those auto margins absorb all available space and cluster the children
     * in the middle, defeating justify-content: space-between. Reset to 0 so
     * the flex layout owns horizontal placement.
     *
     * Post-sweep #3 (2026-05-20): also reset `margin-block-start` /
     * `margin-top` so .tf-social (the 2nd flex child) sits aligned with the
     * footer nav. WP's `:where(.is-layout-constrained) > *` blockGap rule
     * applies a 24px top margin to non-first children — harmless under the
     * stacked block layout (mobile), but at desktop flex the row should be
     * vertically centred (align-items:center already does the heavy lifting,
     * but residual top margin still pushed social-nav down by 24px).
     * Plain `margin-block-start: 0` (no !important) is enough because
     * `:where(...)` contributes zero specificity. `margin-top: 0` is the
     * legacy parity for older WP-emitted rules using the long-form property. */
    .tf-footer__body > * {
        margin-left: 0 !important;
        margin-right: 0 !important;
        margin-block-start: 0;
        margin-top: 0;
    }
}

/* --- Footer / Footer nav --------------------------------------------------- */

.tf-footer__body .wp-block-navigation .wp-block-navigation-item__content {
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: 0.9375rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--wp--preset--color--bone);
    text-decoration: none;
    transition: text-decoration-thickness 120ms cubic-bezier(0.22, 1, 0.36, 1);
}
.tf-footer__body .wp-block-navigation .wp-block-navigation-item__content:hover,
.tf-footer__body .wp-block-navigation .wp-block-navigation-item__content:focus-visible,
.tf-footer__body .wp-block-navigation .current-menu-item .wp-block-navigation-item__content,
.tf-footer__body .wp-block-navigation .wp-block-navigation-item__content[aria-current="page"] {
    text-decoration: underline;
    text-decoration-color: var(--wp--preset--color--acid);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.2em;
}
.tf-footer__body .wp-block-navigation ul {
    gap: 1.5rem;
    flex-wrap: wrap;
}

/* --- Social icons ---------------------------------------------------------- */

.tf-social {
    display: flex;
    align-items: center;
    gap: 1rem;
}
.tf-social__link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;     /* a11y touch min */
    height: 44px;
    color: var(--wp--preset--color--bone);
    text-decoration: none;
    transition: color 160ms cubic-bezier(0.22, 1, 0.36, 1);
}
.tf-social__link:hover,
.tf-social__link:focus-visible {
    color: var(--wp--preset--color--acid);
    outline: none;
    text-decoration: none;
}
.tf-social__link:focus-visible {
    outline: 3px solid var(--wp--preset--color--acid);
    outline-offset: 2px;
}
.tf-social__link svg {
    width: 24px;
    height: 24px;
    display: block;
}

/* --- Mobile burger overlay (RESEARCH Pattern 6) --------------------------- */
/* WP Navigation block has hardcoded 600px JS breakpoint; project md = 768px.
   Suppress the burger in 600-767 range so desktop nav shows; reapply burger below 600px (default behaviour kept). */
@media screen and (min-width: 600px) and (max-width: 767px) {
    .wp-block-navigation__responsive-container-open {
        display: none !important;
    }
    .wp-block-navigation__responsive-container:not(.is-menu-open.has-modal-open) {
        display: block !important;
    }
}

/* Burger trigger — default closed state */
.wp-block-navigation__responsive-container-open {
    color: var(--wp--preset--color--bone);
    background: transparent;
    border: none;
    padding: 0.75rem;
    width: 44px;     /* a11y touch min */
    height: 44px;
    cursor: pointer;
    border-radius: 0;
    transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1);
}
.wp-block-navigation__responsive-container-open svg {
    stroke: var(--wp--preset--color--bone);
    width: 20px;
    height: 20px;
}
.wp-block-navigation__responsive-container-open:focus-visible {
    outline: 3px solid var(--wp--preset--color--acid);
    outline-offset: 2px;
}

/* Burger trigger — open state (when overlay visible) */
body.has-modal-open .wp-block-navigation__responsive-container-open svg,
.wp-block-navigation__responsive-container-open[aria-expanded="true"] svg {
    stroke: var(--wp--preset--color--acid);
}

/* Acid-on-ink overlay container */
.wp-block-navigation__responsive-container.is-menu-open {
    background-color: var(--wp--preset--color--ink-deep) !important;
    background-image: var(--tf-grunge);
    background-attachment: fixed;
    background-size: 240px 240px;
    position: fixed !important;
    inset: 0 !important;
    z-index: 60 !important;
    display: flex !important;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    padding-inline: 2rem;
    padding-block: 6rem;
    border-radius: 0;
    /* Open transition (transform/opacity only — motion contract) */
    transition:
        opacity 200ms cubic-bezier(0.22, 1, 0.36, 1),
        transform 200ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Overlay nav links */
.wp-block-navigation__responsive-container.is-menu-open
    .wp-block-navigation-item__content {
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: clamp(1.75rem, 6vw, 2.25rem);
    line-height: 1;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--wp--preset--color--bone) !important;
    text-decoration: none;
    /* No skew — wordmark-class typography is unskewed */
}
.wp-block-navigation__responsive-container.is-menu-open
    .wp-block-navigation-item__content:hover,
.wp-block-navigation__responsive-container.is-menu-open
    .wp-block-navigation-item__content:focus-visible {
    text-decoration: underline;
    text-decoration-color: var(--wp--preset--color--acid);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.2em;
}
.wp-block-navigation__responsive-container.is-menu-open ul {
    gap: 1.25rem;
    list-style: none;
    padding: 0;
    margin: 0;
}

/* Close button (top-right inside overlay) */
.wp-block-navigation__responsive-container-close {
    position: absolute;
    top: 1rem;
    right: 1.5rem;
    width: 44px;
    height: 44px;
    color: var(--wp--preset--color--bone);
    background: transparent;
    border: none;
    border-radius: 0;
    cursor: pointer;
}
.wp-block-navigation__responsive-container-close svg {
    stroke: var(--wp--preset--color--acid);
    width: 24px;
    height: 24px;
}
.wp-block-navigation__responsive-container-close:focus-visible {
    outline: 3px solid var(--wp--preset--color--acid);
    outline-offset: 2px;
}

/* ============================================================================ */
/* === Phase 2: Hero block + Display-Once post-title demotion === */
/* ============================================================================ */

/* --- Display-Once Rule: demote post-title to Headliner -------------------
 *
 * theme.json declares h1 as Display tier (Anton, monumental).
 * Without this override, every conversion / archive / editorial page's
 * .wp-block-post-title would render in Display, violating the
 * Display-Once Rule (UI-SPEC §7 + DESIGN.md §typography).
 *
 * The hero's <h1> wears class .tf-hero-title — class-level specificity
 * outranks element-level, so it keeps Display. Every other page H1 is
 * demoted to Headliner here.
 *
 * !important is load-bearing — theme.json element styles carry high
 * specificity and would otherwise win.
 * ----------------------------------------------------------------------- */
.wp-block-post-title {
    font-family: 'Anton', 'Inter', sans-serif !important;
    font-size: clamp(2.25rem, 5vw, 3.5rem) !important;
    line-height: 1 !important;
    letter-spacing: 0.01em !important;
    text-transform: uppercase !important;
    color: var(--wp--preset--color--bone) !important;
    margin-block: 2.5rem 4rem !important;
}

/* --- Hero block (Phase 2) ----------------------------------------------- */

.tf-hero {
    position: relative;
    overflow: hidden;
    isolation: isolate;     /* contain mix-blend-mode within the hero */
    min-height: clamp(60vh, 80vh, 90vh);
    padding: clamp(3rem, 8vw, 6rem) 1.5rem;
    background: var(--wp--preset--color--ink-deep);
}

.tf-hero__backdrop {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: clamp(60vw, 80vw, 900px);
    height: auto;
    opacity: 0.35;
    mix-blend-mode: lighten;   /* dark ground punches through acid silhouette */
    pointer-events: none;
    z-index: 0;
}

.tf-hero__content {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 2.5rem;
    max-width: 1280px;
    margin-inline: auto;
}

.tf-hero__top-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.tf-hero__cta-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.5rem;
}

/* Two-line brush lockup at every viewport — the literal <br/> is intentional and stays.
   Single-line at lg+ overflowed the viewport edge-to-edge per UAT Test 4 (02-UAT.md Gap 2);
   canonical lockup is two-line. */
.tf-hero-title br {
    display: inline;
}

/* ============================================================================ */
/* === Phase 2: Editorial template typography === */
/* ============================================================================ */
/*
 * Scoped to the body class WordPress emits when _wp_page_template = 'page-editorial'.
 * Per RESEARCH A1 + Plan 06 Task 1 fixture (wave0-a1-result.txt), the canonical
 * class is `.page-template-page-editorial` (PASS branch). VARIANT / NULL outcomes
 * substitute their own scope into .page-template-page-editorial via the sed step at the end of Task 2.
 *
 * D-12 DEVIATION: CONTEXT.md D-12 says `wp-template-page-editorial`. RESEARCH
 * Pattern 7 + A1 verification corrects this to `page-template-page-editorial`.
 * The plans use the corrected value; documented in Plan 06 must_haves.truths
 * and propagated to 02-06-SUMMARY.md.
 *
 * Sharp Corners + Sentence Case + Skew-Is-The-Italic Rule + No-Side-Stripe-Borders
 * all apply.
 */

/* Post-title margin tweak (the global Plan-05 demotion gives Anton uppercase 2.5rem 4rem;
   editorial pages need 0 before, 4rem after — section-break feel for the title). */
.page-template-page-editorial .wp-block-post-title {
    margin-block: 0 4rem !important;
}

/* H2 — section break */
.page-template-page-editorial .wp-block-post-content h2 {
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    line-height: 1;
    letter-spacing: 0.01em;
    text-transform: uppercase;
    color: var(--wp--preset--color--bone);
    margin-block-start: 4rem;
    margin-block-end: 1rem;
}

/* H3 — sub-section break */
.page-template-page-editorial .wp-block-post-content h3 {
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: 1.25rem;
    line-height: 1.1;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--wp--preset--color--bone);
    margin-block-start: 2.5rem;
    margin-block-end: 0.75rem;
}

/* H4 — data-label voice (Mono-For-Data) */
.page-template-page-editorial .wp-block-post-content h4 {
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: 1rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--wp--preset--color--ash);
    margin-block-start: 2rem;
    margin-block-end: 0.5rem;
}

/* Body copy — Inter, 1.65 line-height, 65ch reading column */
.page-template-page-editorial .wp-block-post-content p,
.page-template-page-editorial .wp-block-post-content li {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 1rem;
    line-height: 1.65;
    color: var(--wp--preset--color--bone);
    max-width: 65ch;
}

.page-template-page-editorial .wp-block-post-content ul,
.page-template-page-editorial .wp-block-post-content ol {
    padding-inline-start: 1.5rem;
}

/* Blockquote — Inter italic; under-line border (NEVER side-stripe) */
.page-template-page-editorial .wp-block-post-content blockquote {
    padding-inline-start: 1.5rem;
    border-block-end: 1px solid var(--wp--preset--color--asphalt);
    padding-block-end: 1rem;
    margin-block: 2.5rem;
    font-style: italic;
    font-size: 1.0625rem;
    color: var(--wp--preset--color--bone);
}

/* Anchors — acid underline, thickness scales on hover/focus */
.page-template-page-editorial .wp-block-post-content a {
    color: var(--wp--preset--color--bone);
    text-decoration: underline;
    text-decoration-color: var(--wp--preset--color--acid);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    transition: text-decoration-thickness 120ms cubic-bezier(0.22, 1, 0.36, 1);
}
.page-template-page-editorial .wp-block-post-content a:hover,
.page-template-page-editorial .wp-block-post-content a:focus-visible {
    text-decoration-thickness: 3px;
}

/* Images — full-width, asphalt hairline, sharp corners */
.page-template-page-editorial .wp-block-post-content img {
    max-width: 100%;
    height: auto;
    border: 1px solid var(--wp--preset--color--asphalt);
    border-radius: 0;
}

/* ============================================================================ */
/* === Phase 4: Countdown block (D-07/D-08) === */
/* ============================================================================ */

.tf-countdown {
    display: flex;
    align-items: baseline;
    gap: 1.5rem;
    justify-content: center;
}
.tf-countdown__unit {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35rem;
}
.tf-countdown__sep {
    color: var(--wp--preset--color--ash);
    opacity: 0.55;
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
}
.tf-countdown__digit {
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: clamp(2rem, 5vw, 3rem);
    font-weight: 700;
    color: var(--wp--preset--color--acid);
    font-variant-numeric: tabular-nums;
    min-width: 2ch;
    text-align: center;
    display: inline-block;
    letter-spacing: 0.06em;
}
.tf-countdown__label {
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: 0.875rem;
    font-weight: 400;
    color: var(--wp--preset--color--ash);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* 999.4: large variant — hero-scale countdown for /de/ home page */
.tf-countdown--large {
    gap: clamp(1.5rem, 4vw, 3rem);
    padding-block: clamp(2rem, 6vw, 4rem);
}
.tf-countdown--large .tf-countdown__digit {
    font-size: clamp(3.5rem, 11vw, 7rem);
    letter-spacing: 0.04em;
}
.tf-countdown--large .tf-countdown__label {
    font-size: clamp(1rem, 1.5vw, 1.25rem);
}
.tf-countdown--large .tf-countdown__sep {
    font-size: clamp(2.5rem, 8vw, 5rem);
}

/* Plan 04-11 cycle-2 gap closure (hero-countdown-tablet-dead-zone): at
 * 768-1099px the base clamp(3.5rem, 11vw, 7rem) lower bound (3.5rem = 56px)
 * holds the digits chunky and the hero composition dominates the tablet
 * viewport — 11vw of 1024px resolves to 112.6px (clamp upper 7rem); 11vw of
 * 800px resolves to 5.5rem. Closes UAT cycle-2 Test 3.
 *
 * Intermediate clamp(2.5rem, 6vw, 3.5rem) shifts the lower bound down by 1rem
 * and the middle term from 11vw → 6vw: at 1024px viewport this resolves to
 * digit ~61.4px (6vw) clamped at 3.5rem upper = 56px — markedly slimmer than
 * the 112.6px the base produced, but still hero-class compared to the cycle-1
 * mobile rule's 1.75-2.5rem at <=767px. Sep clamp scales proportionally
 * (8vw → 5vw; lower 2.5rem → 1.75rem) to maintain digit/sep ratio. Label
 * starts at 0.875rem (down from 1rem) so the label maintains its under-digit
 * visual weight.
 *
 * Cascade order: base (lines 980-993) → intermediate (1099px) → mobile (767px).
 * At 1100px+ the desktop base wins (chunky-hero restored). At 768-1099px the
 * intermediate rule wins. At <=767px the cycle-1 mobile rule wins — UNCHANGED
 * from Plan 04-08 (narrower-mobile digit 1.75-2.5rem, sep 1.25-1.75rem,
 * label 0.75rem, gap 0.5rem, padding-block 1.5rem all preserved). */
@media (max-width: 1099px) {
    .tf-countdown--large .tf-countdown__digit {
        font-size: clamp(2.5rem, 6vw, 3.5rem);
        letter-spacing: 0.03em;
    }
    .tf-countdown--large .tf-countdown__sep {
        font-size: clamp(1.75rem, 5vw, 2.5rem);
    }
    .tf-countdown--large .tf-countdown__label {
        font-size: clamp(0.875rem, 1.2vw, 1rem);
    }
}

/* Plan 04-08 gap closure (countdown-mobile-overflow): .tf-countdown--large
 * clamp() lower bounds (digit 3.5rem, sep 2.5rem, gap 1.5rem) lock at narrow
 * viewports — total row width ~496px at 375px, overflows by ~121px (block
 * carries align:full so no parent max-width clips). Shrink each clamp lower
 * bound so the single-row D · H · M · S composition still fits at 320px.
 * Math: 4 × 33px digit + 3 × 21px sep + 6 × 8px gap ≈ 228px (vs 320px → 92px headroom).
 * Preserves brand-statement single-row layout per backlog 999.4 design intent. */
@media (max-width: 767px) {
    .tf-countdown--large {
        gap: 0.5rem;
        padding-block: 1.5rem;
    }
    .tf-countdown--large .tf-countdown__digit {
        font-size: clamp(1.75rem, 9vw, 2.5rem);
        letter-spacing: 0.02em;
    }
    .tf-countdown--large .tf-countdown__sep {
        font-size: clamp(1.25rem, 6vw, 1.75rem);
    }
    .tf-countdown--large .tf-countdown__label {
        font-size: 0.75rem;
    }
}

/* ============================================================================ */
/* === Phase 5: Timetable (Single Area) (Plan 05-05, decoupled per 999.3) ===== */
/* ============================================================================ */

.tf-timetable-single { display: block; }
.tf-timetable-single--empty { padding-block: 6rem; text-align: center; }
.tf-timetable-single__empty-text {
    font-size: clamp(2.5rem, 6vw, 4.5rem); /* Typography Exception b */
    color: var(--wp--preset--color--bone);
    transform: skew(-8deg);
    transform-origin: 0 100%;
    display: inline-block;
}
.tf-band {
    width: 100%;
    padding-block: 2.5rem;
    padding-inline: 1.5rem;
    /* background-color set inline via PHP per area_color */
}
.tf-band__title {
    font-size: clamp(2rem, 5vw, 3.5rem);
    color: var(--wp--preset--color--bone);
    text-transform: uppercase;
}
.tf-lineup-rows {
    border-top: 1px solid var(--wp--preset--color--asphalt);
}
.tf-row {
    display: grid;
    grid-template-columns: 110px 1fr;
    gap: 1.5rem;
    align-items: baseline;
    padding-block: 1.25rem; /* lg */
    border-bottom: 1px solid var(--wp--preset--color--asphalt);
    position: relative;
}
@media (max-width: 767px) {
    .tf-row { padding-block: 1rem; gap: 1rem; }
}
.tf-row__time {
    color: var(--wp--preset--color--ash);
    font-size: 0.95rem;
    padding-top: 0.5rem;
}
.tf-row--live .tf-row__time,
.tf-row--live .tf-row__live-label {
    color: var(--wp--preset--color--acid);
}
.tf-row--live::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 2px;
    background: var(--wp--preset--color--acid);
    box-shadow: 0 0 18px oklch(0.82 0.19 120 / 0.7);
}
.tf-row__act .tf-headliner {
    font-size: clamp(1.75rem, 4vw, 2.75rem); /* Typography Exception a */
}
.tf-row__crew {
    color: var(--wp--preset--color--ash);
    font-size: 0.8125rem; /* Typography Exception c */
    margin-top: 0.5rem;
}
.tf-b2b {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.875rem;
    color: var(--wp--preset--color--ash);
    display: inline;
    margin-inline: 0.25rem;
}
/* ── Phase 5: Area Card (Plan 05-06) ──────────────────────────────────────── */
.tf-area-card {
    display: block;
    margin-block: 2rem;
    background: var(--wp--preset--color--ink);
}
.tf-area-card__hero {
    position: relative;
    min-height: clamp(240px, 30vw, 400px);
    background-size: cover;
    background-position: center;
    background-color: var(--wp--preset--color--ink);
    display: flex;
    align-items: flex-end;
}
.tf-area-card__hero--has-image::before {
    /* 65% dark overlay for image legibility (D-09 — rgba No-Hex Rule exception) */
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0.65) 100%);
}
.tf-area-card__hero-content {
    position: relative;
    z-index: 1;
    padding: 1.5rem;
    width: 100%;
}
.tf-area-card__name {
    font-size: clamp(2rem, 5vw, 3.5rem);
    color: var(--wp--preset--color--bone);
}
.tf-area-card__slogan {
    font-size: clamp(1.25rem, 3vw, 2rem);
    color: var(--wp--preset--color--ash);
    margin-top: 0.5rem;
}
.tf-area-card__hosts {
    color: var(--wp--preset--color--ash);
    font-size: 0.875rem;
    margin-top: 0.75rem;
}
.tf-area-card__body {
    padding: 1.5rem;
}
.tf-area-card__desc {
    font-size: 1rem;
    line-height: 1.65;
    color: var(--wp--preset--color--bone);
    max-width: 65ch;
}

/* D-19: clickable area-card on /de/areas/ overview (NOT on /de/areas/<slug>/ single). */
.tf-area-card__link {
    display: block;
    color: inherit;
    text-decoration: none;
    transition: border-color 120ms ease-out;
    border: 1px solid transparent;
}
.tf-area-card__link:hover,
.tf-area-card__link:focus-visible {
    border-color: var(--wp--preset--color--ash);
}
.tf-area-card__link:focus-visible {
    outline: 3px solid var(--wp--preset--color--acid);
    outline-offset: 2px;
}

/* ── Phase 5: Program Item (Plan 05-07) ───────────────────────────────────── */
.tf-program-row {
    /* extends .tf-row from Plan 05-05 */
}
.tf-program-row--missing {
    padding-block: 1rem;
    color: var(--wp--preset--color--ash);
}
.tf-row__icon {
    /* 110px column, same width as .tf-row__time */
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem; /* Typography Exception e — decoration glyph, not text */
    color: var(--wp--preset--color--ash);
    padding-top: 0.5rem;
}
.tf-cta--sm {
    padding: 0.45rem 1rem;
    font-size: 0.875rem;
    margin-top: 0.75rem;
    display: inline-block;
}
.tf-cta--flat {
    box-shadow: none; /* suppresses Acid Glow Default — One-Glow Rule guard (UI-SPEC §Acid as Signal) */
}

/* ── Phase 5: Timetable (Plan 05-08) ──────────────────────────────────────── */
.tf-timetable {
    width: 100%;
}
.tf-timetable__title {
    font-size: clamp(2rem, 5vw, 3.5rem);
    margin-bottom: 2rem;
}
/* D-21: restructured grid — header row (auto) above body row (1fr).
 * Removes the per-area column wrapper; area-headers and area-bodies are now
 * direct grid children so ticks and cells share the same Y=0 baseline (row 2). */
.tf-timetable__grid {
    display: grid;
    grid-template-columns: 60px repeat(var(--tf-area-count, 3), 1fr);
    grid-template-rows: auto 1fr; /* row 1 = header strip; row 2 = body grid */
    gap: 0;
    border: 1px solid var(--wp--preset--color--asphalt);
}
.tf-timetable__axis-corner {
    /* row 1, column 1 — empty space above the time-axis */
    border-right: 1px solid var(--wp--preset--color--asphalt);
    border-bottom: 1px solid var(--wp--preset--color--asphalt);
    background: var(--wp--preset--color--ink);
}
.tf-timetable__area-header {
    /* row 1, columns 2..N+1 — area name labels above each body */
    padding: 0.75rem 0.5rem;
    font-size: clamp(1rem, 2vw, 1.5rem);
    border-right: 1px solid var(--wp--preset--color--asphalt);
    border-bottom: 1px solid var(--wp--preset--color--asphalt);
    background: var(--wp--preset--color--ink);
}
.tf-timetable__area-header:last-child { border-right: none; }
.tf-timetable__area-header .tf-headliner {
    font-size: clamp(1rem, 2.5vw, 1.75rem); /* Typography Exception b — half of default headliner */
}
.tf-timetable__area-header a { color: inherit; text-decoration: none; }
.tf-timetable__area-header a:hover { opacity: 0.75; text-decoration: none; }
.tf-timetable__area-header a:focus-visible {
    outline: 3px solid var(--wp--preset--color--acid);
    outline-offset: 2px;
}
.tf-timetable__time-axis {
    /* row 2, column 1 — time labels */
    position: relative;
    overflow: hidden; /* clip the terminal tick (top = grid_height) whose label would otherwise spill below the container; mirrors area-body's WR-01 clip */
    border-right: 1px solid var(--wp--preset--color--asphalt);
}
.tf-timetable__tick {
    position: absolute;
    left: 0; right: 0;
    font-size: 0.75rem; /* Typography Exception d */
    color: var(--wp--preset--color--ash);
    padding-left: 0.25rem;
    border-top: 1px solid var(--wp--preset--color--asphalt);
}
.tf-timetable__area-body {
    /* row 2, columns 2..N+1 — absolute-positioned cells */
    position: relative;
    overflow: hidden; /* WR-01: clip cells that exceed grid height */
    border-right: 1px solid var(--wp--preset--color--asphalt);
}
.tf-timetable__area-body:last-child { border-right: none; }
.tf-timetable__cell {
    position: absolute;
    left: 0;
    right: 0;
    padding: 0.5rem;
    border: 1px solid var(--wp--preset--color--asphalt);
    overflow: hidden;
    box-sizing: border-box;
}
/* D-17 (revised): live cell = dim acid bg + acid border around the whole cell.
 * Replaces the previous ::after 2px bar + glow — also removes the One-Glow Rule
 * pressure since the timetable no longer emits a box-shadow surface. */
.tf-timetable__cell--live {
    background: oklch(0.82 0.19 120 / 0.12);
    border-color: var(--wp--preset--color--acid);
}
.tf-timetable__cell-act {
    font-size: clamp(0.875rem, 1.5vw, 1.25rem);
    display: block;
}
.tf-timetable__cell-time {
    font-size: 0.75rem;
    color: var(--wp--preset--color--ash);
    margin-top: 0.25rem;
}

/* ── D-16: Mobile (<768px) — degenerate to per-area stacked vertical lists ── */
@media (max-width: 767px) {
    /* Flat DOM order is corner, H1..H3, axis, B1..B3 — at desktop the 4x2
     * CSS Grid auto-places those into header-row / body-row, but on mobile
     * we want each area-header immediately followed by its area-body.
     * Switch to flex column and use `order` to interleave H1 B1 H2 B2 H3 B3.
     * `:nth-child(N of selector)` is Selectors Level 4 (Chrome 111+, Firefox 113+,
     * Safari 9+). Hardcoded for up to 3 areas; extend if a 4th area is added. */
    .tf-timetable__grid {
        display: flex;
        flex-direction: column;
    }
    .tf-timetable__area-header:nth-child(1 of .tf-timetable__area-header) { order: 1; }
    .tf-timetable__area-body:nth-child(1 of .tf-timetable__area-body)     { order: 2; }
    .tf-timetable__area-header:nth-child(2 of .tf-timetable__area-header) { order: 3; }
    .tf-timetable__area-body:nth-child(2 of .tf-timetable__area-body)     { order: 4; }
    .tf-timetable__area-header:nth-child(3 of .tf-timetable__area-header) { order: 5; }
    .tf-timetable__area-body:nth-child(3 of .tf-timetable__area-body)     { order: 6; }
    .tf-timetable__axis-corner,
    .tf-timetable__time-axis { display: none; }
    .tf-timetable__area-header {
        display: block;
        border-right: none;
        background: var(--wp--preset--color--ink);
        padding: 1rem 0.5rem;
    }
    .tf-timetable__area-body {
        position: static;
        height: auto !important;
        border-right: none;
        border-bottom: 1px solid var(--wp--preset--color--asphalt);
        margin-bottom: 2rem;
    }
    .tf-timetable__cell {
        position: static;
        height: auto !important;
        top: auto !important;
        display: grid;
        grid-template-columns: 110px 1fr;
        gap: 1rem;
        padding-block: 1rem;
        border-bottom: 1px solid var(--wp--preset--color--asphalt);
        border-left: none;
    }
    .tf-timetable__cell-time {
        order: -1;
        font-size: 0.875rem;
        padding-top: 0.25rem;
    }
    .tf-timetable__cell-act {
        font-size: clamp(1.75rem, 4vw, 2.75rem); /* Typography Exception a — full Headliner on mobile */
    }
}

/* ── Phase 5 D-22: Act + Side-Program presentation blocks (Plan 05-12) ──── */

.tf-act,
.tf-side-program {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    width: 100%;
    margin-block: 3rem;
    background: var(--wp--preset--color--ink);
    align-items: stretch;
}

.tf-act--image-right .tf-act__image,
.tf-side-program--image-right .tf-side-program__image {
    order: 2;
}

.tf-act__image,
.tf-side-program__image {
    background-size: cover;
    background-position: center;
    background-color: var(--wp--preset--color--ink);
    min-height: clamp(320px, 40vw, 450px);
    /* When this class is on an <img> (act block, post Plan 01), behave as a cover-fitted cell.
     * When it's on a <div> (side-program empty-state, side-program with inline background-image),
     * width/height/object-fit/display are no-ops — safe to apply universally. */
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
}
.tf-act__image--empty,
.tf-side-program__image--empty {
    background-image: none;
    background-color: var(--wp--preset--color--asphalt);
}
.tf-side-program__image--glyph {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--wp--preset--color--ink);
    border: 1px solid var(--wp--preset--color--asphalt);
}
.tf-side-program__glyph {
    font-size: clamp(6rem, 15vw, 12rem);
    line-height: 1;
}

.tf-act__meta,
.tf-side-program__meta {
    padding: clamp(1.5rem, 4vw, 3rem);
    display: flex;
    flex-direction: column;
    gap: 1rem;
    justify-content: center;
}

.tf-act__title,
.tf-side-program__title {
    font-size: clamp(2rem, 4vw, 3rem);
    color: var(--wp--preset--color--bone);
    margin: 0;
}
.tf-act__crew,
.tf-side-program__short {
    font-size: 0.875rem;
    color: var(--wp--preset--color--ash);
    margin: 0;
}
.tf-act__bio,
.tf-side-program__long {
    font-size: 1rem;
    line-height: 1.65;
    color: var(--wp--preset--color--bone);
    max-width: 65ch;
    margin: 0;
}

.tf-act__social {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.5rem;
}
.tf-social-pill {
    display: inline-block;
    padding: 0.4rem 0.9rem;
    border: 1px solid var(--wp--preset--color--ash);
    color: var(--wp--preset--color--bone);
    text-decoration: none;
    font-size: 0.75rem;
    letter-spacing: 0.05em;
    transition: background-color 120ms ease-out, color 120ms ease-out;
}
.tf-social-pill:hover,
.tf-social-pill:focus-visible {
    background: var(--wp--preset--color--bone);
    color: var(--wp--preset--color--ink-deep);
}
.tf-social-pill:focus-visible {
    outline: 3px solid var(--wp--preset--color--acid);
    outline-offset: 2px;
}

.tf-act--missing,
.tf-side-program--missing {
    display: block; /* drop the 2-col grid for the empty admin notice */
    padding: 1rem;
}

/* Mobile column-stack: image on top, meta below — regardless of imagePosition. */
@media (max-width: 767px) {
    .tf-act,
    .tf-side-program {
        display: block;
    }
    .tf-act--image-right .tf-act__image,
    .tf-side-program--image-right .tf-side-program__image {
        order: 0; /* reset; image always first on mobile */
    }
    .tf-act__image,
    .tf-side-program__image {
        min-height: clamp(240px, 60vw, 360px);
    }
}

/* ============================================================================ */
/* === Backlog 999.1 — page-wide butterfly background (wing-flap animation) === */
/* ============================================================================ */
/* The image is split in half (left/right wings) via background-position +
 * background-size: 200% 100%. perspective on the container creates the 3D
 * pivot space; each wing rotates around its inner edge so the meeting point
 * at the body stays anchored. mix-blend-mode: lighten drops out the dark
 * image background so only the acid wings glow through (mirrors .tf-hero
 * pattern at line ~526). z-index: -1 keeps it behind all content. */

:root {
    --tf-butterfly-speed: 2.4s;
}

.tf-butterfly-bg {
    position: fixed;
    inset: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    pointer-events: none;
    z-index: -1;
    perspective: 1200px;
    opacity: 0.18;
    mix-blend-mode: lighten;
}

.tf-butterfly-bg__wing {
    width: min(38vw, 460px);
    aspect-ratio: 4 / 5; /* matches each half of the source butterfly's proportion */
    background-image: var(--tf-butterfly-image);
    background-size: 200% 100%; /* render full image at 2x wing-width so each wing displays one half */
    background-repeat: no-repeat;
    will-change: transform;
}
.tf-butterfly-bg__wing--left {
    background-position: left center;
    transform-origin: right center; /* hinge at the body — the inner edge */
    animation: tf-butterfly-flap-left var(--tf-butterfly-speed) infinite ease-in-out alternate;
}
.tf-butterfly-bg__wing--right {
    background-position: right center;
    transform-origin: left center;
    animation: tf-butterfly-flap-right var(--tf-butterfly-speed) infinite ease-in-out alternate;
}

@keyframes tf-butterfly-flap-left {
    from { transform: rotateY(-12deg); }
    to   { transform: rotateY(12deg); }
}
@keyframes tf-butterfly-flap-right {
    from { transform: rotateY(12deg); }
    to   { transform: rotateY(-12deg); }
}

@media (prefers-reduced-motion: reduce) {
    .tf-butterfly-bg__wing--left,
    .tf-butterfly-bg__wing--right { animation: none; }
}

/* === Phase 6: Partner Grid + Partner Detail ================================ */

/* --- partner-grid block --------------------------------------------------- */
.tf-partner-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 4rem 1.5rem;
    max-width: 1280px;
    margin-inline: auto;
}

.tf-partner__tile {
    display: block;
    padding: 1rem 1.5rem;
    min-width: 200px;
    border: 2px solid;             /* color set by modifier */
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    /* No transition — static collage; no hover visual per REQ-partner-wall */
    /* No border-radius — sharp corners per design system */
    /* No box-shadow — One-Glow Rule reserves acid glow for the ticket CTA */
}

.tf-partner__tile--primary {
    background: var(--wp--preset--color--acid);
    color: var(--wp--preset--color--ink-deep);
    border-color: var(--wp--preset--color--acid);
}

.tf-partner__tile--secondary {
    background: var(--wp--preset--color--ink);
    color: var(--wp--preset--color--bone);
    border-color: var(--wp--preset--color--asphalt);
}

.tf-partner__name {
    font-family: 'Anton', 'Inter', sans-serif;
    font-size: 1.25rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 1;
}

.tf-partner__role {
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: 0.75rem;
    font-weight: 400;
    letter-spacing: 0.06em;
    margin-top: 0.5rem;
    line-height: 1.4;
}

.tf-partner__tile--primary .tf-partner__role {
    color: var(--wp--preset--color--ink-deep);
}

.tf-partner__tile--secondary .tf-partner__role {
    color: var(--wp--preset--color--ash);
}

/* Focus-visible: acid outline (NOT box-shadow) — mirrors .tf-area-card__link:focus-visible */
.tf-partner__tile:focus-visible {
    outline: 3px solid var(--wp--preset--color--acid);
    outline-offset: 2px;
}

/* Empty state */
.tf-partner__empty {
    width: 100%;
    color: var(--wp--preset--color--ash);
}

/* --- partner-detail block ------------------------------------------------- */
.tf-partner-detail {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

.tf-partner-detail__role {
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: 0.875rem;
    font-weight: 400;
    letter-spacing: 0.06em;
    line-height: 1.4;
    text-transform: uppercase;
    color: var(--wp--preset--color--ash);
    margin: 0;
}

.tf-partner-detail__bio-short,
.tf-partner-detail__bio-long {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.65;
    color: var(--wp--preset--color--bone);
}

.tf-partner-detail__bio-short p,
.tf-partner-detail__bio-long p {
    margin-block: 0 1rem;
}

.tf-partner-detail__url {
    /* no additional layout — .tf-cta is inline-block */
}

/* .tf-cta--flat variants — base rule lives at line 1215. Only :hover and :focus-visible new. */
.tf-cta--flat:hover,
.tf-cta--flat:focus-visible {
    box-shadow: none; /* do NOT inherit --tf-acid-glow-strong on editorial CTAs */
}

/* ============================================================================ */
/* === PHASE 7: RCB Banner Override (Channel A — outer wrappers only) ========= */
/* ============================================================================ */
/* IMPORTANT: RCB 5.x uses CSS-in-JS with hashed inner class names.            */
/* Inner elements (buttons, description, typography) CANNOT be styled here.   */
/* All inner-element styling lives in 54 native rcb-banner-*-design-* options */
/* seeded by scripts/seed-rcb-config.sh — Channel B (rcb-banner-custom-css-css)*/
/* is intentionally EMPTY per the 2026-05-12 architecture pivot (see 07-05-   */
/* SUMMARY.md). RCB renders the native option values via its own CSS-in-JS.   */
/* ============================================================================ */

.rcb-banner,
.real-cookie-banner {
    background: var(--wp--preset--color--ink-deep) !important;
    border-top: 1px solid var(--wp--preset--color--asphalt) !important;
    border-radius: 0 !important;
    padding: 1rem 1.5rem !important;
    position: fixed !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    z-index: 49 !important; /* tf-banner sticky sits at z-index:50 (top) — no spatial overlap */
}

/* Entrance fade — opacity only per CON-motion (no translateY) */
@media (prefers-reduced-motion: no-preference) {
    .rcb-banner,
    .real-cookie-banner {
        transition: opacity 240ms cubic-bezier(0.22, 1, 0.36, 1);
    }
}

/* Override any RCB slide-in under reduce — [Motion verification tautology] memory:
   must be tested at runtime under BOTH prefers-reduced-motion states, not just
   by grepping for this media query. */
@media (prefers-reduced-motion: reduce) {
    .rcb-banner,
    .real-cookie-banner {
        transform: none !important;
        transition: none !important;
        animation: none !important;
    }
}

/* ============================================================================ */
/* === PHASE 7: Per-Embed Content Blocker Override (Channel A — outer only) === */
/* ============================================================================ */

.rcb-content-blocker {
    background: var(--wp--preset--color--ink) !important;
    border: 1px solid var(--wp--preset--color--asphalt) !important;
    border-radius: 0 !important;
    padding: 1rem 1.5rem !important;
    min-height: 80px !important;
    /* box-shadow: NONE — One-Glow Rule: only the primary 'Akzeptieren' CTA in the
       banner may glow; placeholder accept link is a flat acid text link (no glow) */
}

@media (prefers-reduced-motion: reduce) {
    .rcb-banner *,
    .rcb-content-blocker * {
        transform: none !important;
        transition: none !important;
        animation: none !important;
    }
}

/* ============================================================================ */
/* === 999.18 — Wartung page ================================================== */
/* ============================================================================ */
/* Content overlay for the /wartung/ maintenance page rendered by LightStart
 * via wpmm_settings.design.page_id. The page-wartung FSE template is full-bleed
 * (no header/footer parts); this wrapper sits in the post_content above the
 * .tf-butterfly-bg animation (which is z-index:-1 and covers the full viewport).
 * Body background is #050805 (ink-deep) — set in seed-lightstart.sh design.bg_color.
 */

.tf-wartung-page {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    min-height: 60vh;
    padding: clamp(2rem, 6vw, 5rem) clamp(1rem, 4vw, 3rem);
    text-align: center;
    color: #F5F4E8; /* bone — Strobe Bone, text on dark */
}

.tf-wartung-page__heading {
    font-family: Anton, sans-serif;
    font-size: clamp(2.25rem, 6vw, 5rem);
    line-height: 1.05;
    letter-spacing: 0.01em;
    color: #B6D41C; /* acid — Wet-Paint Lime, canvas-verified */
    margin: 0 0 1rem;
}

.tf-wartung-page__text {
    font-family: Inter, system-ui, sans-serif;
    font-size: clamp(1rem, 2vw, 1.375rem);
    line-height: 1.55;
    color: #F5F4E8; /* bone */
    margin: 0;
    max-width: 36ch;
}
