/**
 * Year Navigation — ArtistFolio
 * ==============================
 * Optional year-based works navigation.
 * Three variants: top-bar, left-rail, floating-dots.
 *
 * All variants share:
 *   - opacity 0 / pointer-events none → show via .is-visible (JS)
 *   - Active year via .is-active on .year-nav__item
 *   - CSS custom props from 00-base.css
 */

/* ── Shared base ──────────────────────────────────────────────────────────── */

.year-nav {
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--t, 0.25s ease);
    z-index: 90;
}

.year-nav.is-visible {
    opacity: 1;
    pointer-events: auto;
}

.year-nav__count {
    opacity: 0.5;
    font-weight: 400;
    margin-left: 2px;
}

/* A year with no works under the active facet filter (jp-works-filter.js emits
   'works:filtered'; jp-year-nav.js reflects it). Dimmed + non-interactive —
   the filter stays the single owner of visibility, this only mirrors it.
   Applies across all three variants via the shared base class. */
/* USER-Request (Jan): Jahre ohne Werke des aktiven Filters (Medium/Serie/
   Sammlung) GAR NICHT zeigen statt nur dimmen — die Jahres-Nav listet so nur
   Jahre, in denen für den aktiven Filter wirklich Werke existieren. Klasse wird
   von jp-year-nav.js (works:filtered aus jp-works-filter.js) gesetzt und bei
   „Alle" wieder entfernt. Doppelte Item-Klasse + Varianten-Prefix (0,3,0) schlägt
   die `.year-nav--<variante> .year-nav__item`-Displayregel (0,2,0) sicher,
   unabhängig von der Quell-Reihenfolge. Gilt für alle drei Varianten. */
/* Die OBERE Leiste ist die erste Ebene — sie bleibt VOLLSTÄNDIG (Jan
   2026-08-12: „wenn die Jahresleiste oben ist, sollen immer alle Jahre aller
   Arbeiten vollständig vorhanden sein"). Ein Jahr, das der Filter darunter
   gerade leerräumt, wird deshalb nur zurückgenommen, nicht entfernt.

   Warum das der Unterschied ist: Verschwindende Einträge lassen die Leiste bei
   jedem Filterklick springen und nehmen dem Besucher den Überblick, welche
   Jahre es überhaupt gibt — gemessen 2026-08-12 blieb beim Filter „Aquarell"
   von sechs Jahren genau eines stehen. Das Werk ist ja nicht weg, es passt nur
   nicht zur aktuellen Auswahl. aria-disabled + tabindex=-1 setzt
   jp-year-nav.js ohnehin, der Eintrag ist also weder klickbar noch im
   Tab-Fluss — nur eben weiterhin sichtbar. */
.year-nav--top-bar .year-nav__item.year-nav__item--empty {
    /* Zurückgenommen, aber BEDIENBAR. Kein pointer-events:none — ein hellgraues
       Jahr ist in der ersten Ebene kein toter Eintrag, sondern der Weg zurück
       zum vollen Bestand dieses Jahres (Jan 2026-08-12: „wenn ich auf einem
       Medium bin, möchte ich trotzdem über die hellgrauen Zahlen auf alle aus
       dem Jahr zugreifen"). Der Klick hebt unten den Filter auf und springt hin.
       Etwas heller als .3 (dort verschwand es fast) und mit sichtbarer Reaktion
       auf hover/focus, damit die Bedienbarkeit auch sichtbar ist. */
    opacity: .38;
}

.year-nav--top-bar .year-nav__item.year-nav__item--empty:hover,
.year-nav--top-bar .year-nav__item.year-nav__item--empty:focus-visible {
    opacity: 1;
}

/* Seitenleiste und Punkte blenden weiter aus: beide sind räumliche
   Sprung-Navigationen entlang der tatsächlich vorhandenen Abschnitte — ein
   Sprungziel, das es gerade nicht gibt, wäre dort eine Sackgasse statt einer
   Übersicht. */
.year-nav--left-rail .year-nav__item.year-nav__item--empty,
.year-nav--floating-dots .year-nav__item.year-nav__item--empty {
    display: none;
}

/*
 * Dedicated keyboard focus ring for all three variants (WCAG 2.4.7/2.4.13).
 * The global :focus-visible (00-base.css) uses outline-offset: 3px, which the
 * top-bar's overflow-x:auto inner scroll container clips away. An inset offset
 * is never clipped and keeps a strong-contrast ring on every variant.
 */
.year-nav__item:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
    border-radius: var(--radius-sm, 4px);
}

/* ── Variant 1: top-bar ───────────────────────────────────────────────────── */
/*
 * Fixed bar docked directly below the site header.
 * Slides in via opacity when works section is in view (JS adds .is-visible).
 */

.year-nav--top-bar {
    position: fixed;
    top: var(--header-height, 112px);
    left: 0;
    right: 0;
    height: var(--year-nav-height, 36px);
    background: var(--bg);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    border-bottom: var(--hairline-w) solid var(--border);
}

/* Jan-Design: keine Hairline ZWISCHEN den beiden gedockten Leisten — wenn die
   Technik-Filter-Bar direkt darunter sitzt, lesen Jahr+Filter als EIN ruhiger
   Block; die Unterkante zum Inhalt trägt die Filter-Bar. Ohne Filter-Bar
   (andere Instanz-Konfigurationen) behält die Jahres-Leiste ihre Kante. */
body:has(.works-filter) .year-nav--top-bar {
    border-bottom: none;
    display: flex;
    align-items: center;
    z-index: 90;
}

.year-nav--top-bar .year-nav__inner {
    display: flex;
    align-items: center;
    width: 100%;
    max-width: var(--max-width, 1100px);
    margin: 0 auto;
    /* iOS notch safe-area (index.php ships viewport-fit=cover) — this is a FIXED
       full-bleed bar, so in landscape on a notched device the leading/trailing
       year sat under the notch/rounded corner. Inset the scroll track; the bar
       background stays edge-to-edge. 0px off-notch → byte-identical. DES-P13B-SAFEBAR. */
    padding-inline: var(--safe-left, 0px) var(--safe-right, 0px);
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    gap: 0;

    /* FILTER-DISCOVER-1 (Geschwister-Fundstelle): identische Mechanik wie in
       16-filter-nav.css — waagerecht scrollender Track mit versteckter Scrollleiste.
       Hier faellt es erst bei vielen Jahrgaengen auf (6 Jahre passen auf 411px), es
       ist aber dieselbe Klasse: ohne Zeichen am Rand liest sich die Reihe als
       vollstaendig. Deckel in Bar-Farbe fahren mit dem Inhalt (local), Schatten
       kleben am Rand (scroll) → das Zeichen erscheint genau dann, wenn dort noch
       etwas liegt, und nie sonst. Deckel 14px = das Innenpolster eines
       .year-nav__item, faellt also nie auf die Jahreszahl selbst. */
    background:
        linear-gradient(var(--bg), var(--bg)) left center / 14px 100% no-repeat local,
        linear-gradient(var(--bg), var(--bg)) right center / 14px 100% no-repeat local,
        linear-gradient(to right, color-mix(in srgb, var(--fg) 16%, transparent), transparent)
            left center / 12px 100% no-repeat scroll,
        linear-gradient(to left, color-mix(in srgb, var(--fg) 16%, transparent), transparent)
            right center / 12px 100% no-repeat scroll;
}

.year-nav--top-bar .year-nav__inner::-webkit-scrollbar {
    display: none;
}

.year-nav--top-bar .year-nav__item {
    display: inline-flex;
    align-items: center;
    height: var(--year-nav-height, 36px);
    padding: 0 14px;
    font-size: 10px;
    letter-spacing: var(--af-track-caps-lg);
    text-transform: uppercase;
    color: var(--muted);
    text-decoration: none;
    white-space: nowrap;
    position: relative;
    transition: color var(--t-fast, 0.15s ease);
    flex-shrink: 0;
}

/* Separator dots between items */
.year-nav--top-bar .year-nav__item + .year-nav__item::before {
    content: '·';
    position: absolute;
    left: -1px;
    color: var(--border);
    font-size: 14px;
    line-height: 1;
    pointer-events: none;
}
/* Kein verwaister „·" vor dem ERSTEN noch sichtbaren Jahr, wenn davor
   ausgeblendete (leere) Jahre stehen: jp-year-nav.js taggt das erste sichtbare
   Item mit --lead. Nur dessen Trenner wird unterdrückt — Überlebende danach
   behalten ihren „·" (auch bei Lücken dazwischen). Zwei Item-Klassen → (0,3,1),
   gleich der Basis-Trennerregel, danach platziert → gewinnt. */
.year-nav--top-bar .year-nav__item.year-nav__item--lead::before {
    content: none;
}

.year-nav--top-bar .year-nav__item:hover {
    color: var(--fg);
}

.year-nav--top-bar .year-nav__item.is-active {
    color: var(--fg);
    font-weight: 600;
}

/* Active underline indicator */
.year-nav--top-bar .year-nav__item.is-active::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 14px;
    right: 14px;
    height: 2px;
    background: var(--accent, var(--fg));
    border-radius: 1px 1px 0 0;
}

/* Mobile top-bar */
@media (max-width: 900px) {
    /* DESIGN-PUB-1a: lift the year sub-nav to a >=44px touch target on phones/tablets
       (Apple-HIG / WCAG 2.5.5). Redefining the var keeps every consumer consistent —
       bar height, item height, #works padding-top, scroll-margins and the filter dock
       all read var(--year-nav-height), so the offsets follow automatically. */
    :root { --year-nav-height: 44px; }

    .year-nav--top-bar {
        top: var(--header-height-mobile, 80px);
    }

    .year-nav--top-bar .year-nav__item {
        padding: 0 13px;
        font-size: 9px;
    }
}


/* Suppress the header's bottom border when year nav sits flush below it */
body.has-year-nav .site-header {
    border-bottom: none;
}

/* Push the whole #works section down so the page title clears the year nav */
body.has-year-nav #works {
    padding-top: calc(var(--year-nav-height, 36px) + 24px);
}
/* USER-FB 2026-07-25 („Warum ist ‚Werke' jetzt plötzlich immer sichtbar?!"):
   der Sticky-Pin der Überschrift (eingeführt 2026-07-20 gegen die verdeckte
   Überschrift beim Scrollen) ist zurückgenommen — die Überschrift scrollt
   wieder normal unter den fixen Balkenturm. Der Ruhe-/Anker-Fall bleibt durch
   padding-top (oben) + scroll-margin (unten) abgedeckt. */
/* USER-FB-check (Titel unter der Bar): the anchor jump on a fresh #works load
   happens BEFORE JS can add has-year-nav, so a conditional scroll-margin never
   applied to that first snap and the section title landed under the fixed bar.
   Unconditional margin; --year-nav-height falls back to 0 when no bar exists
   (jp-year-nav.js sets the real value early via positionTopBar). */
#works {
    scroll-margin-top: calc(var(--header-height, 112px) + var(--year-nav-height, 0px) + 8px);
}

/* Year-section headings: generous scroll-offset so they land with comfortable
   spacing. SWEEP-css-scrollmargin-rule-collision: the single declaration for
   `body.has-year-nav .works-year` now lives in 16-filter-nav.css (it also
   accounts for the fixed filter bar). Do NOT re-add a scroll-margin-top rule
   for this selector here — it has the exact same specificity as the one
   there, so whichever file the cascade loads last would silently win again. */

/* ── Variant 2: left-rail ─────────────────────────────────────────────────── */
/*
 * Fixed vertical strip in the left gutter beside the content column.
 * Years listed top→bottom (newest first), active one has a longer line.
 * Hidden below 1200px where there's no gutter.
 */

.year-nav--left-rail {
    position: fixed;
    /* Sit in the left gutter: half of (viewport - max-width) minus own width */
    left: max(12px, calc((100vw - var(--max-width, 1100px)) / 2 - 68px));
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    align-items: flex-end;
}

.year-nav--left-rail .year-nav__inner {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.year-nav--left-rail .year-nav__item {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 10px;
    letter-spacing: var(--af-track-caps);
    color: var(--muted);
    text-decoration: none;
    padding: 4px 0;
    white-space: nowrap;
    justify-content: flex-end;
    transition: color var(--t-fast, 0.15s ease);
}

/* Horizontal tick mark on the right of the label */
.year-nav--left-rail .year-nav__item::after {
    content: '';
    display: block;
    width: 14px;
    height: 1px;
    background: currentColor;
    opacity: 0.3;
    transition: width var(--t-fast, 0.15s ease), opacity var(--t-fast, 0.15s ease);
    flex-shrink: 0;
}

.year-nav--left-rail .year-nav__item:hover {
    color: var(--fg);
}

.year-nav--left-rail .year-nav__item:hover::after {
    width: 20px;
    opacity: 0.6;
}

.year-nav--left-rail .year-nav__item.is-active {
    color: var(--fg);
    font-weight: 600;
}

.year-nav--left-rail .year-nav__item.is-active::after {
    width: 24px;
    height: 2px;
    background: var(--accent, var(--fg));
    opacity: 1;
}

/* Hide when no gutter space */
@media (max-width: 1200px) {
    .year-nav--left-rail {
        display: none;
    }
}


/* ── Variant 3: floating-dots ─────────────────────────────────────────────── */
/*
 * Compact fixed dots on the right edge, year label revealed on hover/active.
 * All sizes — on mobile the dots sit at bottom-right.
 */

.year-nav--floating-dots {
    position: fixed;
    /* Clear the landscape notch/rounded corner on the right edge (viewport-fit=cover);
       0px off-notch → byte-identical. DES-P13B-SAFEBAR. */
    right: calc(20px + var(--safe-right, 0px));
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    align-items: flex-end;
}

.year-nav--floating-dots .year-nav__inner {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
}

.year-nav--floating-dots .year-nav__item {
    display: flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    cursor: pointer;
}

/* Year label — hidden until hover or active */
.year-nav--floating-dots .year-nav__label {
    font-size: 10px;
    letter-spacing: var(--af-track-caps);
    color: var(--fg);
    background: var(--bg);
    border: var(--hairline-w) solid var(--border);
    padding: 3px 7px;
    border-radius: 3px;
    opacity: 0;
    transform: translateX(6px);
    transition: opacity var(--t-fast, 0.15s ease), transform var(--t-fast, 0.15s ease);
    pointer-events: none;
    white-space: nowrap;
    box-shadow: var(--shadow-sm, 0 2px 8px rgba(0,0,0,0.06));
}

.year-nav--floating-dots .year-nav__item:hover .year-nav__label,
.year-nav--floating-dots .year-nav__item.is-active .year-nav__label {
    opacity: 1;
    transform: translateX(0);
}

/* The dot */
.year-nav--floating-dots .year-nav__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--muted);
    opacity: 0.35;
    transition:
        width var(--t-fast, 0.15s ease),
        height var(--t-fast, 0.15s ease),
        opacity var(--t-fast, 0.15s ease),
        background var(--t-fast, 0.15s ease);
    flex-shrink: 0;
}

.year-nav--floating-dots .year-nav__item:hover .year-nav__dot {
    opacity: 0.7;
    width: 7px;
    height: 7px;
}

.year-nav--floating-dots .year-nav__item.is-active .year-nav__dot {
    width: 8px;
    height: 8px;
    background: var(--accent, var(--fg));
    opacity: 1;
}

/*
 * The floating dots sit over arbitrary gallery artwork, so the inset --accent
 * ring alone is not guaranteed >=3:1 (WCAG 2.4.13). A white halo behind the
 * dark ring keeps the focus indicator visible on any backdrop, and the year
 * label is revealed (mirroring :hover) so keyboard users get the same context
 * as pointer users. No clipping container here, so the outline can be outset.
 */
.year-nav--floating-dots .year-nav__item:focus-visible {
    outline-offset: 2px;
    border-radius: var(--radius-full, 999px);
    box-shadow: 0 0 0 4px var(--bg);
}

.year-nav--floating-dots .year-nav__item:focus-visible .year-nav__label {
    opacity: 1;
    transform: translateX(0);
}

/* Mobile: move to bottom-right, horizontal layout */
@media (max-width: 768px) {
    .year-nav--floating-dots {
        right: 12px;
        bottom: 24px;
        top: auto;
        transform: none;
    }

    .year-nav--floating-dots .year-nav__inner {
        flex-direction: row;
        align-items: center;
        gap: 6px;
    }

    /* WCAG 2.5.5/2.5.8: pad the 6px dot into a >=44px-tall tap target. Height is
       the safe axis for this bottom-anchored horizontal strip; horizontal padding
       widens the hit zone without a fixed width that would push older years
       off-screen when many years exist. Dot visual size stays unchanged. */
    .year-nav--floating-dots .year-nav__item {
        min-height: 44px;
        padding: 0 6px;
    }

    /* Reveal the active year label on mobile so the current section is
       identifiable — dots alone are anonymous. Mirrors the hover/active reveal
       and supersedes the earlier dot-only (display:none) rule. */
    .year-nav--floating-dots .year-nav__item.is-active .year-nav__label {
        opacity: 1;
        transform: translateX(0);
    }
}


/* ── Dark mode ────────────────────────────────────────────────────────────── */

[data-theme="dark"] .year-nav--top-bar,
.dark-mode .year-nav--top-bar {
    background: var(--bg);
}

[data-theme="dark"] .year-nav--floating-dots .year-nav__label,
.dark-mode .year-nav--floating-dots .year-nav__label {
    background: var(--bg);
    border-color: var(--border);
}


/* ── Reduced motion ───────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    .year-nav,
    .year-nav__item,
    .year-nav__dot,
    .year-nav__label {
        transition: none !important;
    }
}

/* Custom pages carry free-form artist text (essay, statement, imprint-like
   pages) — the year rail belongs to the works timeline and means nothing above
   a running text, where it reads as a stray filter bar. Hide it while a custom
   page section is the active one. Scoped via :has() so it stays CSS-only: the
   one-pager marks the visible section with .active and every custom page uses
   the id prefix "page-", so no JS hook is needed. Works/exhibitions/galleries
   keep the rail unchanged. */
body:has(.section.page.active[id^="page-"]) .year-nav,
body:has(.section.accordion.active[id^="page-"]) .year-nav {
    display: none;
}
